amps-python-client 5.3.4.1__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- amps-python-client-5.3.4.1/HISTORY +7 -0
- amps-python-client-5.3.4.1/LICENSE +157 -0
- amps-python-client-5.3.4.1/PKG-INFO +112 -0
- amps-python-client-5.3.4.1/README.md +96 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/ack-messages.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/content-messages.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/intro.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/logon.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/protocol-reference.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/publishing.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/query-delimiters.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/query-subscribe.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/removing.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/utilities.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/environment.pickle +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/index.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/.buildinfo +4 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_images/caution.svg +25 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/ack-messages.rst.txt +32 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/content-messages.rst.txt +27 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/intro.rst.txt +43 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/logon.rst.txt +231 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/protocol-reference.rst.txt +1474 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/publishing.rst.txt +25 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/query-delimiters.rst.txt +12 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/query-subscribe.rst.txt +23 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/removing.rst.txt +6 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/utilities.rst.txt +13 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/index.rst.txt +56 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/ajax-loader.gif +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/alabaster.css +699 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/basic.css +632 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/comment-bright.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/comment-close.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/comment.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/custom.css +192 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/custom.css.backup +161 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/doctools.js +287 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/down-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/down.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/file.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/flag_logo.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/flag_logo.svg +153 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/jquery-3.1.0.js +10074 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/jquery.js +4 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/minus.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/plus.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/pygments.css +74 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/searchtools.js +758 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/underscore-1.3.1.js +999 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/underscore.js +31 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/up-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/up.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/websupport.js +808 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/ack-messages.html +417 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/content-messages.html +417 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/intro.html +126 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/logon.html +295 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/protocol-reference.html +1190 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/publishing.html +436 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/query-delimiters.html +173 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/query-subscribe.html +2123 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/removing.html +299 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/utilities.html +287 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/genindex.html +97 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/index.html +138 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/objects.inv +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/search.html +107 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/searchindex.js +1 -0
- amps-python-client-5.3.4.1/docs/html/.buildinfo +4 -0
- amps-python-client-5.3.4.1/docs/html/_sources/code.rst.txt +6 -0
- amps-python-client-5.3.4.1/docs/html/_sources/index.rst.txt +29 -0
- amps-python-client-5.3.4.1/docs/html/_static/ajax-loader.gif +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/basic.css +632 -0
- amps-python-client-5.3.4.1/docs/html/_static/classic.css +261 -0
- amps-python-client-5.3.4.1/docs/html/_static/comment-bright.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/comment-close.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/comment.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/default.css +1 -0
- amps-python-client-5.3.4.1/docs/html/_static/doctools.js +287 -0
- amps-python-client-5.3.4.1/docs/html/_static/down-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/down.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/file.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/jquery-3.1.0.js +10074 -0
- amps-python-client-5.3.4.1/docs/html/_static/jquery.js +4 -0
- amps-python-client-5.3.4.1/docs/html/_static/minus.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/plus.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/pygments.css +74 -0
- amps-python-client-5.3.4.1/docs/html/_static/searchtools.js +758 -0
- amps-python-client-5.3.4.1/docs/html/_static/sidebar.js +159 -0
- amps-python-client-5.3.4.1/docs/html/_static/underscore-1.3.1.js +999 -0
- amps-python-client-5.3.4.1/docs/html/_static/underscore.js +31 -0
- amps-python-client-5.3.4.1/docs/html/_static/up-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/up.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/websupport.js +808 -0
- amps-python-client-5.3.4.1/docs/html/code.html +6503 -0
- amps-python-client-5.3.4.1/docs/html/genindex.html +1361 -0
- amps-python-client-5.3.4.1/docs/html/index.html +131 -0
- amps-python-client-5.3.4.1/docs/html/objects.inv +0 -0
- amps-python-client-5.3.4.1/docs/html/py-modindex.html +111 -0
- amps-python-client-5.3.4.1/docs/html/search.html +107 -0
- amps-python-client-5.3.4.1/docs/html/searchindex.js +1 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/advanced-topics.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/cpp-compiler-list.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/cpp-feature-table.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/creating-commands.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/deltas.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/error-handling.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/exceptions.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/first-program.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/high-availability.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/installing.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/introduction.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/moving-from-python-lite.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/performance-tips.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/queues.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/sow.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/subscriptions.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/utilities.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/environment.pickle +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/index.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/html/.buildinfo +4 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/caution.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/caution.svg +25 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/connection_string.svg +461 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/important.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/important.svg +25 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/tip.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/tip.svg +31 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/warning.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/advanced-topics.rst.txt +398 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/cpp-compiler-list.rst.txt +6 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/cpp-feature-table.rst.txt +26 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/creating-commands.rst.txt +159 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/deltas.rst.txt +79 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/error-handling.rst.txt +482 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/exceptions.rst.txt +128 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/first-program.rst.txt +142 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/high-availability.rst.txt +876 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/installing.rst.txt +184 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/introduction.rst.txt +50 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/moving-from-python-lite.rst.txt +32 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/performance-tips.rst.txt +434 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/queues.rst.txt +282 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/sow.rst.txt +292 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/subscriptions.rst.txt +374 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/utilities.rst.txt +214 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/index.rst.txt +44 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/ajax-loader.gif +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/alabaster.css +699 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/basic.css +632 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/comment-bright.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/comment-close.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/comment.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/custom.css +192 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/custom.css.backup +161 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/doctools.js +287 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/down-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/down.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/file.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/flag_logo.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/flag_logo.svg +153 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/jquery-3.1.0.js +10074 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/jquery.js +4 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/minus.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/plus.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/pygments.css +74 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/searchtools.js +758 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/underscore-1.3.1.js +999 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/underscore.js +31 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/up-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/up.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/websupport.js +808 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/advanced-topics.html +447 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/cpp-compiler-list.html +92 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/cpp-feature-table.html +156 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/creating-commands.html +2837 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/deltas.html +169 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/error-handling.html +746 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/exceptions.html +272 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/first-program.html +499 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/high-availability.html +1014 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/installing.html +264 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/introduction.html +245 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/moving-from-python-lite.html +118 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/performance-tips.html +499 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/queues.html +352 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/sow.html +381 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/subscriptions.html +535 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/utilities.html +302 -0
- amps-python-client-5.3.4.1/docs/python/html/genindex.html +351 -0
- amps-python-client-5.3.4.1/docs/python/html/index.html +380 -0
- amps-python-client-5.3.4.1/docs/python/html/objects.inv +0 -0
- amps-python-client-5.3.4.1/docs/python/html/search.html +107 -0
- amps-python-client-5.3.4.1/docs/python/html/searchindex.js +1 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/doctrees/chapters/crankitup.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/doctrees/chapters/equipment.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/doctrees/environment.pickle +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/doctrees/index.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/.buildinfo +4 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_sources/chapters/crankitup.rst.txt +155 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_sources/chapters/equipment.rst.txt +19 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_sources/index.rst.txt +20 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/ajax-loader.gif +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/alabaster.css +699 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/basic.css +632 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/comment-bright.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/comment-close.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/comment.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/custom.css +192 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/custom.css.backup +161 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/doctools.js +287 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/down-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/down.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/file.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/flag_logo.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/flag_logo.svg +153 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/jquery-3.1.0.js +10074 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/jquery.js +4 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/minus.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/plus.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/pygments.css +74 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/searchtools.js +758 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/underscore-1.3.1.js +999 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/underscore.js +31 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/up-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/up.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/websupport.js +808 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/chapters/crankitup.html +271 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/chapters/equipment.html +105 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/genindex.html +97 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/index.html +382 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/objects.inv +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/search.html +107 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/searchindex.js +1 -0
- amps-python-client-5.3.4.1/docs/resources/custom.css +9 -0
- amps-python-client-5.3.4.1/docs/resources/flag_logo.svg +153 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/acks.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/actions.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/amps-statistics.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/amps_expressions.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/amps_functions.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/auxiliary_modules.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/config-file-shortcuts.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/conflated_topics.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/constructing-fields.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/daemon.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/delta.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/distribution.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/enrichment.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/events.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/file_format_versions.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/glossary.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/ha.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/installing_and_starting.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/intro.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/logging.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/messageTypes.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/monitoring.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/oof.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/operation.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/pub_sub.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/queues.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/replication.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/securing.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/sow.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/sow_queries.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/spark.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/transports.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/troubleshooting.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/txlog.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/usecases.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/utilities.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/views.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/environment.pickle +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/index.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/.buildinfo +4 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/AMPS-Queues-Intro.svg +1330 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/GeoRepl.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/HA_async_ack.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/HA_sync_ack.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/Hot-Hot-Replication.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/MessageOrdering.svg +235 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/OOF5.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/OOF6.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/OOF7.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/OOF8.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/PubSub1.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/PubSub2.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/SOWAndSubscribeAndReplace.svg +684 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/SOWQuery1.svg +402 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/SOWQuery2.svg +505 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/UseCaseFig1.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/UseCaseFig2.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/UseCaseFig3.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/UseCaseFig4.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/caution.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/caution.svg +25 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/chicago_group.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/delta_original_messages.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/delta_update_message.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/important.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/important.svg +25 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/inline_view_conflation.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/paginated_subs_pub.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/paginated_subs_sub.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/queue_usage_overview.svg +627 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/replication_hub.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/replication_scenario_with_ha.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/sow_overview_1.svg +248 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/sow_overview_2.svg +183 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/sow_update_sequence.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/tip.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/tip.svg +31 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/warning.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/warning.svg +23 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/acks.rst.txt +232 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/actions.rst.txt +111 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/amps-statistics.rst.txt +358 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/amps_expressions.rst.txt +83 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/amps_functions.rst.txt +11 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/auxiliary_modules.rst.txt +86 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/config-file-shortcuts.rst.txt +9 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/conflated_topics.rst.txt +111 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/constructing-fields.rst.txt +269 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/daemon.rst.txt +232 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/delta.rst.txt +556 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/distribution.rst.txt +186 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/enrichment.rst.txt +191 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/events.rst.txt +39 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/file_format_versions.rst.txt +203 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/glossary.rst.txt +101 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/ha.rst.txt +465 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/installing_and_starting.rst.txt +23 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/intro.rst.txt +116 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/logging.rst.txt +34 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/messageTypes.rst.txt +1398 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/monitoring.rst.txt +326 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/oof.rst.txt +312 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/operation.rst.txt +27 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/pub_sub.rst.txt +49 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/queues.rst.txt +1351 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/replication.rst.txt +1228 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/securing.rst.txt +657 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/sow.rst.txt +57 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/sow_queries.rst.txt +25 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/spark.rst.txt +824 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/transports.rst.txt +291 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/troubleshooting.rst.txt +517 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/txlog.rst.txt +62 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/usecases.rst.txt +21 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/utilities.rst.txt +62 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/views.rst.txt +175 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/index.rst.txt +110 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/ajax-loader.gif +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/alabaster.css +695 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/basic.css +632 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/comment-bright.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/comment-close.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/comment.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/custom.css +192 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/custom.css.backup +161 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/doctools.js +287 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/down-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/down.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/file.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/flag_logo.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/flag_logo.svg +153 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/jquery-3.1.0.js +10074 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/jquery.js +4 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/minus.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/plus.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/pygments.css +74 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/searchtools.js +758 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/underscore-1.3.1.js +999 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/underscore.js +31 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/up-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/up.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/websupport.js +808 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/acks.html +289 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/actions.html +3782 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/amps-statistics.html +439 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/amps_expressions.html +1552 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/amps_functions.html +1626 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/auxiliary_modules.html +2548 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/config-file-shortcuts.html +508 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/conflated_topics.html +328 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/constructing-fields.html +447 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/daemon.html +295 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/delta.html +609 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/distribution.html +246 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/enrichment.html +264 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/events.html +449 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/file_format_versions.html +229 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/glossary.html +215 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/ha.html +978 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/installing_and_starting.html +357 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/intro.html +572 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/logging.html +972 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/messageTypes.html +1280 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/monitoring.html +718 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/oof.html +341 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/operation.html +1515 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/pub_sub.html +934 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/queues.html +1767 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/replication.html +1777 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/securing.html +697 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/sow.html +1038 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/sow_queries.html +621 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/spark.html +819 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/transports.html +352 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/troubleshooting.html +530 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/txlog.html +1013 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/usecases.html +288 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/utilities.html +133 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/views.html +1120 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/genindex.html +1261 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/index.html +163 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/objects.inv +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/search.html +106 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/searchindex.js +1 -0
- amps-python-client-5.3.4.1/include/ampspy_bookmarkstore.hpp +63 -0
- amps-python-client-5.3.4.1/include/ampspy_compat.h +63 -0
- amps-python-client-5.3.4.1/include/ampspy_defs.hpp +181 -0
- amps-python-client-5.3.4.1/include/ampspy_recoverypointadapter.hpp +52 -0
- amps-python-client-5.3.4.1/include/ampspy_shims.hpp +113 -0
- amps-python-client-5.3.4.1/include/ampspy_type_object.hpp +242 -0
- amps-python-client-5.3.4.1/include/ampspy_types.hpp +1139 -0
- amps-python-client-5.3.4.1/include/ampspyver.h +30 -0
- amps-python-client-5.3.4.1/index.html +66 -0
- amps-python-client-5.3.4.1/samples/AMPSConsolePublisher.py +59 -0
- amps-python-client-5.3.4.1/samples/AMPSConsoleSubscriber.py +63 -0
- amps-python-client-5.3.4.1/samples/AMPSFIXBuilderPublisher.py +71 -0
- amps-python-client-5.3.4.1/samples/AMPSFIXShredderSubscriber.py +69 -0
- amps-python-client-5.3.4.1/samples/AMPSNVFIXBuilderPublisher.py +71 -0
- amps-python-client-5.3.4.1/samples/AMPSNVFIXShredderSubscriber.py +67 -0
- amps-python-client-5.3.4.1/samples/AMPSPublishForReplay.py +81 -0
- amps-python-client-5.3.4.1/samples/AMPSQueueConsumer.py +69 -0
- amps-python-client-5.3.4.1/samples/AMPSQueuePublisher.py +59 -0
- amps-python-client-5.3.4.1/samples/AMPSSOWConsolePublisher.py +67 -0
- amps-python-client-5.3.4.1/samples/AMPSSOWConsoleSubscriber.py +77 -0
- amps-python-client-5.3.4.1/samples/AMPSSOWandSubscribeConsoleSubscriber.py +79 -0
- amps-python-client-5.3.4.1/samples/AMPSSOWandSubscribeWithOOF.py +108 -0
- amps-python-client-5.3.4.1/samples/AMPSSubscribeForReplay.py +128 -0
- amps-python-client-5.3.4.1/samples/AMPSUpdateForOOF.py +123 -0
- amps-python-client-5.3.4.1/samples/CompositeMessagePublisher.py +84 -0
- amps-python-client-5.3.4.1/samples/CompositeMessageSubscriber.py +87 -0
- amps-python-client-5.3.4.1/samples/RandomServerChooser.py +41 -0
- amps-python-client-5.3.4.1/samples/sample.xml +335 -0
- amps-python-client-5.3.4.1/setup.py +209 -0
- amps-python-client-5.3.4.1/setup_amps.py +94 -0
- amps-python-client-5.3.4.1/src/ampspy_shims.cpp +203 -0
- amps-python-client-5.3.4.1/src/ampspy_type_object.cpp +484 -0
- amps-python-client-5.3.4.1/src/authenticator.cpp +128 -0
- amps-python-client-5.3.4.1/src/bookmarkstore.cpp +238 -0
- amps-python-client-5.3.4.1/src/client.cpp +2430 -0
- amps-python-client-5.3.4.1/src/client_docs.h +956 -0
- amps-python-client-5.3.4.1/src/cmessagehandler.cpp +151 -0
- amps-python-client-5.3.4.1/src/command.cpp +164 -0
- amps-python-client-5.3.4.1/src/command_docs.h +194 -0
- amps-python-client-5.3.4.1/src/compositemessagebuilder.cpp +111 -0
- amps-python-client-5.3.4.1/src/compositemessageparser.cpp +146 -0
- amps-python-client-5.3.4.1/src/conflatingrecoverypointadapter.cpp +194 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/BlockPublishStore.hpp +2053 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/BlockStore.hpp +677 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/BookmarkStore.hpp +542 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/Buffer.hpp +214 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/CompositeMessageBuilder.hpp +174 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/CompositeMessageParser.hpp +151 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/DefaultServerChooser.hpp +162 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/Field.hpp +719 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/HAClient.hpp +370 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/HAClientImpl.hpp +460 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/HybridPublishStore.hpp +481 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/LoggedBookmarkStore.hpp +1255 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/MMapBookmarkStore.hpp +1283 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/MMapStoreBuffer.hpp +290 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/MemoryBookmarkStore.hpp +1622 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/MemoryPublishStore.hpp +66 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/MemoryStoreBuffer.hpp +244 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/MemorySubscriptionManager.hpp +850 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/Message.hpp +1819 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/MessageRouter.hpp +618 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/PublishStore.hpp +158 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ReconnectDelayStrategy.hpp +106 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ReconnectDelayStrategyImpl.hpp +317 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/RecoveryPoint.hpp +323 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/RecoveryPointAdapter.hpp +501 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/RingBookmarkStore.hpp +669 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/SOWRecoveryPointAdapter.hpp +490 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ServerChooser.hpp +145 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ServerChooserImpl.hpp +95 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/amps.h +775 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/amps_generated.h +46 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/amps_impl.h +204 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/amps_ssl.h +78 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ampscrc.hpp +210 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ampsplusplus.hpp +8817 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ampsuri.h +84 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ampsver.h +41 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ampsver.h.in +41 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/constants.hpp +194 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/util.hpp +1692 -0
- amps-python-client-5.3.4.1/src/cpp/src/amps_protocol.c +688 -0
- amps-python-client-5.3.4.1/src/cpp/src/amps_protocol_generated.h +80 -0
- amps-python-client-5.3.4.1/src/cpp/src/amps_ssl.c +489 -0
- amps-python-client-5.3.4.1/src/cpp/src/atfork.c +446 -0
- amps-python-client-5.3.4.1/src/cpp/src/client.c +483 -0
- amps-python-client-5.3.4.1/src/cpp/src/makefile +92 -0
- amps-python-client-5.3.4.1/src/cpp/src/message.c +837 -0
- amps-python-client-5.3.4.1/src/cpp/src/message_generated.h +611 -0
- amps-python-client-5.3.4.1/src/cpp/src/tcp.c +1489 -0
- amps-python-client-5.3.4.1/src/cpp/src/tcps.c +1894 -0
- amps-python-client-5.3.4.1/src/cpp/src/transports.c +123 -0
- amps-python-client-5.3.4.1/src/cpp/src/unix.c +984 -0
- amps-python-client-5.3.4.1/src/cpp/src/uri.c +301 -0
- amps-python-client-5.3.4.1/src/exponentialdelaystrategy.cpp +137 -0
- amps-python-client-5.3.4.1/src/failedwritehandler.cpp +116 -0
- amps-python-client-5.3.4.1/src/fixbuilder.cpp +146 -0
- amps-python-client-5.3.4.1/src/fixeddelaystrategy.cpp +114 -0
- amps-python-client-5.3.4.1/src/fixshredder.cpp +105 -0
- amps-python-client-5.3.4.1/src/fixshredder_docs.h +38 -0
- amps-python-client-5.3.4.1/src/haclient.cpp +691 -0
- amps-python-client-5.3.4.1/src/haclient_docs.h +132 -0
- amps-python-client-5.3.4.1/src/hybridpublishstore.cpp +137 -0
- amps-python-client-5.3.4.1/src/hybridpublishstore_docs.h +31 -0
- amps-python-client-5.3.4.1/src/memorybookmarkstore.cpp +373 -0
- amps-python-client-5.3.4.1/src/memorybookmarkstore_docs.h +39 -0
- amps-python-client-5.3.4.1/src/memorypublishstore.cpp +160 -0
- amps-python-client-5.3.4.1/src/memorypublishstore_docs.h +32 -0
- amps-python-client-5.3.4.1/src/message.cpp +765 -0
- amps-python-client-5.3.4.1/src/message_docs.h +306 -0
- amps-python-client-5.3.4.1/src/messagestream.cpp +623 -0
- amps-python-client-5.3.4.1/src/messagestream_docs.h +45 -0
- amps-python-client-5.3.4.1/src/mmapbookmarkstore.cpp +422 -0
- amps-python-client-5.3.4.1/src/nvfixbuilder.cpp +160 -0
- amps-python-client-5.3.4.1/src/nvfixbuilder_docs.h +33 -0
- amps-python-client-5.3.4.1/src/nvfixshredder.cpp +99 -0
- amps-python-client-5.3.4.1/src/nvfixshredder_docs.h +39 -0
- amps-python-client-5.3.4.1/src/publishstore.cpp +183 -0
- amps-python-client-5.3.4.1/src/raw_wrapper.cpp +756 -0
- amps-python-client-5.3.4.1/src/reason.cpp +71 -0
- amps-python-client-5.3.4.1/src/recoverypoint.cpp +135 -0
- amps-python-client-5.3.4.1/src/recoverypointadapter.cpp +171 -0
- amps-python-client-5.3.4.1/src/ringbookmarkstore.cpp +360 -0
- amps-python-client-5.3.4.1/src/serverchooser.cpp +245 -0
- amps-python-client-5.3.4.1/src/serverchooser_docs.h +39 -0
- amps-python-client-5.3.4.1/src/sowrecoverypointadapter.cpp +248 -0
- amps-python-client-5.3.4.1/src/store.cpp +62 -0
- amps-python-client-5.3.4.1/src/versioninfo.cpp +175 -0
|
@@ -0,0 +1,1255 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////
|
|
2
|
+
//
|
|
3
|
+
// Copyright (c) 2010-2023 60East Technologies Inc., All Rights Reserved.
|
|
4
|
+
//
|
|
5
|
+
// This computer software is owned by 60East Technologies Inc. and is
|
|
6
|
+
// protected by U.S. copyright laws and other laws and by international
|
|
7
|
+
// treaties. This computer software is furnished by 60East Technologies
|
|
8
|
+
// Inc. pursuant to a written license agreement and may be used, copied,
|
|
9
|
+
// transmitted, and stored only in accordance with the terms of such
|
|
10
|
+
// license agreement and with the inclusion of the above copyright notice.
|
|
11
|
+
// This computer software or any other copies thereof may not be provided
|
|
12
|
+
// or otherwise made available to any other person.
|
|
13
|
+
//
|
|
14
|
+
// U.S. Government Restricted Rights. This computer software: (a) was
|
|
15
|
+
// developed at private expense and is in all respects the proprietary
|
|
16
|
+
// information of 60East Technologies Inc.; (b) was not developed with
|
|
17
|
+
// government funds; (c) is a trade secret of 60East Technologies Inc.
|
|
18
|
+
// for all purposes of the Freedom of Information Act; and (d) is a
|
|
19
|
+
// commercial item and thus, pursuant to Section 12.212 of the Federal
|
|
20
|
+
// Acquisition Regulations (FAR) and DFAR Supplement Section 227.7202,
|
|
21
|
+
// Government's use, duplication or disclosure of the computer software
|
|
22
|
+
// is subject to the restrictions set forth by 60East Technologies Inc..
|
|
23
|
+
//
|
|
24
|
+
////////////////////////////////////////////////////////////////////////////
|
|
25
|
+
|
|
26
|
+
#include <amps/ampsplusplus.hpp>
|
|
27
|
+
|
|
28
|
+
#ifndef _LOGGEDBOOKMARKSTORE_H_
|
|
29
|
+
#define _LOGGEDBOOKMARKSTORE_H_
|
|
30
|
+
|
|
31
|
+
#include <amps/MemoryBookmarkStore.hpp>
|
|
32
|
+
#include <amps/RecoveryPoint.hpp>
|
|
33
|
+
#include <amps/RecoveryPointAdapter.hpp>
|
|
34
|
+
#include <string>
|
|
35
|
+
#ifdef _WIN32
|
|
36
|
+
#include <windows.h>
|
|
37
|
+
#else
|
|
38
|
+
#include <sys/mman.h>
|
|
39
|
+
#include <unistd.h>
|
|
40
|
+
#include <sys/uio.h>
|
|
41
|
+
#endif
|
|
42
|
+
#include <sys/types.h>
|
|
43
|
+
#include <sys/stat.h>
|
|
44
|
+
#include <fcntl.h>
|
|
45
|
+
#include <map>
|
|
46
|
+
#include <set>
|
|
47
|
+
|
|
48
|
+
#if defined(sun)
|
|
49
|
+
typedef char* amps_iovec_base_ptr;
|
|
50
|
+
#else
|
|
51
|
+
typedef void* amps_iovec_base_ptr;
|
|
52
|
+
#endif
|
|
53
|
+
|
|
54
|
+
/// \file LoggedBookmarkStore.hpp
|
|
55
|
+
/// \brief Provides AMPS::LoggedBookmarkStore, a bookmark store that
|
|
56
|
+
/// uses a file to track received messages. This bookmark store provides
|
|
57
|
+
/// resumable subscriptions even when the application restarts.
|
|
58
|
+
|
|
59
|
+
namespace AMPS
|
|
60
|
+
{
|
|
61
|
+
///
|
|
62
|
+
/// A BookmarkStoreImpl implementation that logs all messages to a file. This
|
|
63
|
+
/// class provides resumable subscriptions even when the application restarts.
|
|
64
|
+
class LoggedBookmarkStore : public MemoryBookmarkStore
|
|
65
|
+
{
|
|
66
|
+
private:
|
|
67
|
+
static void _clearBookmark(std::pair<const Message::Field, size_t>& pair)
|
|
68
|
+
{
|
|
69
|
+
Message::Field f(pair.first);
|
|
70
|
+
f.clear();
|
|
71
|
+
}
|
|
72
|
+
#ifdef _WIN32
|
|
73
|
+
typedef HANDLE FileType;
|
|
74
|
+
#else
|
|
75
|
+
typedef int FileType;
|
|
76
|
+
#endif
|
|
77
|
+
public:
|
|
78
|
+
///
|
|
79
|
+
/// Creates a LoggedBookmarkStore using fileName_ as its file storage. If
|
|
80
|
+
/// fileName_ already exists and has valid bookmarks in it, it will be
|
|
81
|
+
/// recovered to determine the most recent bookmark and other messages
|
|
82
|
+
/// received.
|
|
83
|
+
/// \param fileName_ The name of the file to use.
|
|
84
|
+
/// \param useLastModifiedTime_ If the file already exists, the last
|
|
85
|
+
/// modification time of the file will be included in the bookmark
|
|
86
|
+
/// list returned from `getMostRecent` for any subscription ID that exists
|
|
87
|
+
/// in the file upon recovery.
|
|
88
|
+
LoggedBookmarkStore(const char* fileName_,
|
|
89
|
+
bool useLastModifiedTime_ = false)
|
|
90
|
+
: MemoryBookmarkStore()
|
|
91
|
+
#ifdef _WIN32
|
|
92
|
+
, _file(INVALID_HANDLE_VALUE)
|
|
93
|
+
#else
|
|
94
|
+
, _file(0)
|
|
95
|
+
#endif
|
|
96
|
+
, _fileName(fileName_)
|
|
97
|
+
{
|
|
98
|
+
init();
|
|
99
|
+
recover(useLastModifiedTime_, false);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
///
|
|
103
|
+
/// Creates a LoggedBookmarkStore using a file name fileName_
|
|
104
|
+
/// \param fileName_ The name of the file to use.
|
|
105
|
+
/// \param useLastModifiedTime_ If the file already exists, the last
|
|
106
|
+
/// modification time of the file will be included in the bookmark
|
|
107
|
+
/// list returned from `getMostRecent` for any subscription ID that exists
|
|
108
|
+
/// in the file upon recovery.
|
|
109
|
+
LoggedBookmarkStore(const std::string& fileName_,
|
|
110
|
+
bool useLastModifiedTime_ = false)
|
|
111
|
+
: MemoryBookmarkStore()
|
|
112
|
+
#ifdef _WIN32
|
|
113
|
+
, _file(INVALID_HANDLE_VALUE)
|
|
114
|
+
#else
|
|
115
|
+
, _file(0)
|
|
116
|
+
#endif
|
|
117
|
+
, _fileName(fileName_)
|
|
118
|
+
{
|
|
119
|
+
init();
|
|
120
|
+
recover(useLastModifiedTime_, false);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
///
|
|
124
|
+
/// Creates a LoggedBookmarkStore using fileName_ as its file storage. If
|
|
125
|
+
/// fileName_ already exists and has valid bookmarks in it, it will be
|
|
126
|
+
/// recovered to determine the most recent bookmark and other messages
|
|
127
|
+
/// received.
|
|
128
|
+
/// \param adapter_ The {@link RecoveryPointAdapter} to notify
|
|
129
|
+
/// about updates.
|
|
130
|
+
/// \param fileName_ The name of the file to use.
|
|
131
|
+
/// \param factory_ An optional factory function to use
|
|
132
|
+
/// to create the {@link RecoveryPoint} objects sent to the recoveryPointAdapter_.
|
|
133
|
+
/// \param useLastModifiedTime_ If the file already exists, the last
|
|
134
|
+
/// modification time of the file will be included in the bookmark
|
|
135
|
+
/// list returned from `getMostRecent` for any subscription ID that exists
|
|
136
|
+
/// in the file upon recovery.
|
|
137
|
+
LoggedBookmarkStore(const RecoveryPointAdapter& adapter_,
|
|
138
|
+
const char* fileName_,
|
|
139
|
+
RecoveryPointFactory factory_ = NULL,
|
|
140
|
+
bool useLastModifiedTime_ = false)
|
|
141
|
+
: MemoryBookmarkStore(adapter_, factory_)
|
|
142
|
+
#ifdef _WIN32
|
|
143
|
+
, _file(INVALID_HANDLE_VALUE)
|
|
144
|
+
#else
|
|
145
|
+
, _file(0)
|
|
146
|
+
#endif
|
|
147
|
+
, _fileName(fileName_)
|
|
148
|
+
{
|
|
149
|
+
init();
|
|
150
|
+
recover(useLastModifiedTime_, true);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
///
|
|
154
|
+
/// Creates a LoggedBookmarkStore using a file name fileName_
|
|
155
|
+
/// \param adapter_ The {@link RecoveryPointAdapter} to notify
|
|
156
|
+
/// about updates.
|
|
157
|
+
/// \param fileName_ The name of the file to use.
|
|
158
|
+
/// \param factory_ An optional factory function to use
|
|
159
|
+
/// to create the {@link RecoveryPoint} objects sent to the recoveryPointAdapter_.
|
|
160
|
+
/// \param useLastModifiedTime_ If the file already exists, the last
|
|
161
|
+
/// modification time of the file will be included in the bookmark
|
|
162
|
+
/// list returned from `getMostRecent` for any subscription ID that exists
|
|
163
|
+
/// in the file upon recovery.
|
|
164
|
+
LoggedBookmarkStore(const RecoveryPointAdapter& adapter_,
|
|
165
|
+
const std::string& fileName_,
|
|
166
|
+
RecoveryPointFactory factory_ = NULL,
|
|
167
|
+
bool useLastModifiedTime_ = false)
|
|
168
|
+
: MemoryBookmarkStore(adapter_, factory_)
|
|
169
|
+
#ifdef _WIN32
|
|
170
|
+
, _file(INVALID_HANDLE_VALUE)
|
|
171
|
+
#else
|
|
172
|
+
, _file(0)
|
|
173
|
+
#endif
|
|
174
|
+
, _fileName(fileName_)
|
|
175
|
+
{
|
|
176
|
+
init();
|
|
177
|
+
recover(useLastModifiedTime_, true);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
virtual ~LoggedBookmarkStore()
|
|
181
|
+
{
|
|
182
|
+
close();
|
|
183
|
+
// In case _lock gets acquired by reader thread between end of this
|
|
184
|
+
// destructor and start of base class destructor, prevent write()
|
|
185
|
+
_recoveringFile = true;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
void close()
|
|
189
|
+
{
|
|
190
|
+
#ifdef _WIN32
|
|
191
|
+
CloseHandle(_file);
|
|
192
|
+
#else
|
|
193
|
+
::close(_file);
|
|
194
|
+
#endif
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
///
|
|
198
|
+
/// Log a bookmark to the persistent log and return the corresponding
|
|
199
|
+
/// sequence number for this bookmark.
|
|
200
|
+
/// \param message_ The Message to log.
|
|
201
|
+
///
|
|
202
|
+
virtual size_t log(Message& message_)
|
|
203
|
+
{
|
|
204
|
+
Message::Field bookmark = message_.getBookmark();
|
|
205
|
+
Subscription* sub = (Subscription*)(message_.getSubscriptionHandle());
|
|
206
|
+
Lock<Mutex> guard(_lock);
|
|
207
|
+
if (!sub)
|
|
208
|
+
{
|
|
209
|
+
Message::Field subId = message_.getSubscriptionId();
|
|
210
|
+
if (subId.empty())
|
|
211
|
+
{
|
|
212
|
+
subId = message_.getSubscriptionIds();
|
|
213
|
+
}
|
|
214
|
+
sub = find(subId);
|
|
215
|
+
message_.setSubscriptionHandle(static_cast<amps_subscription_handle>(sub));
|
|
216
|
+
}
|
|
217
|
+
write(_file, sub->id(), ENTRY_BOOKMARK, bookmark);
|
|
218
|
+
return MemoryBookmarkStore::_log(message_);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
///
|
|
222
|
+
/// Log a Message as discarded from the store.
|
|
223
|
+
/// \param message_ The Message to discard.
|
|
224
|
+
///
|
|
225
|
+
virtual void discard(const Message& message_)
|
|
226
|
+
{
|
|
227
|
+
Message::Field bookmark = message_.getBookmark();
|
|
228
|
+
Message::Field subId = message_.getSubscriptionId();
|
|
229
|
+
if (subId.empty())
|
|
230
|
+
{
|
|
231
|
+
subId = message_.getSubscriptionIds();
|
|
232
|
+
}
|
|
233
|
+
Lock<Mutex> guard(_lock);
|
|
234
|
+
write(_file, subId, ENTRY_DISCARD, bookmark);
|
|
235
|
+
MemoryBookmarkStore::_discard(message_);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
///
|
|
239
|
+
/// Log a discard-bookmark entry to the persistent log
|
|
240
|
+
/// based on a bookmark sequence number. Use the \ref discard(const Message&)
|
|
241
|
+
/// function instead when you have the full Message object available..
|
|
242
|
+
/// \param subId_ The id of the subscription to which the bookmark applies.
|
|
243
|
+
/// \param bookmarkSeqNo_ The bookmark sequence number to discard.
|
|
244
|
+
///
|
|
245
|
+
virtual void discard(const Message::Field& subId_, size_t bookmarkSeqNo_)
|
|
246
|
+
{
|
|
247
|
+
Lock<Mutex> l(_lock);
|
|
248
|
+
Subscription::Entry* entry = find(subId_)->getEntryByIndex(bookmarkSeqNo_);
|
|
249
|
+
if (!entry || entry->_val.empty())
|
|
250
|
+
{
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
write(_file, subId_, ENTRY_DISCARD, entry->_val);
|
|
254
|
+
MemoryBookmarkStore::_discard(subId_, bookmarkSeqNo_);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
///
|
|
258
|
+
/// Returns the most recent bookmark from the log that
|
|
259
|
+
/// ought to be used for (re-)subscriptions.
|
|
260
|
+
/// \param subId_ The id of the subscription to check.
|
|
261
|
+
///
|
|
262
|
+
virtual Message::Field getMostRecent(const Message::Field& subId_)
|
|
263
|
+
{
|
|
264
|
+
Lock<Mutex> l(_lock);
|
|
265
|
+
return MemoryBookmarkStore::_getMostRecent(subId_);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
///
|
|
269
|
+
/// Called for each arriving message to determine if
|
|
270
|
+
/// the application has already seen this bookmark and should
|
|
271
|
+
/// not be reprocessed. Returns 'true' if the bookmark is
|
|
272
|
+
/// in the log and should not be re-processed, false otherwise.
|
|
273
|
+
/// \param message_ The Message to check.
|
|
274
|
+
/// \return Whether or not the Message has been discarded from this store.
|
|
275
|
+
///
|
|
276
|
+
virtual bool isDiscarded(Message& message_)
|
|
277
|
+
{
|
|
278
|
+
Lock<Mutex> l(_lock);
|
|
279
|
+
bool retVal = MemoryBookmarkStore::_isDiscarded(message_);
|
|
280
|
+
if (retVal)
|
|
281
|
+
{
|
|
282
|
+
Message::Field subId = message_.getSubscriptionId();
|
|
283
|
+
if (subId.empty())
|
|
284
|
+
{
|
|
285
|
+
subId = message_.getSubscriptionIds();
|
|
286
|
+
}
|
|
287
|
+
write(_file, subId, ENTRY_BOOKMARK, message_.getBookmark());
|
|
288
|
+
write(_file, subId, ENTRY_DISCARD, message_.getBookmark());
|
|
289
|
+
}
|
|
290
|
+
return retVal;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
///
|
|
294
|
+
/// Called to purge the contents of this store.
|
|
295
|
+
/// Removes any tracking history associated with publishers and received
|
|
296
|
+
/// messages, and may delete or truncate on-disk representations as well.
|
|
297
|
+
///
|
|
298
|
+
virtual void purge()
|
|
299
|
+
{
|
|
300
|
+
Lock<Mutex> guard(_lock);
|
|
301
|
+
#ifdef _WIN32
|
|
302
|
+
if (_file != INVALID_HANDLE_VALUE)
|
|
303
|
+
{
|
|
304
|
+
CloseHandle(_file);
|
|
305
|
+
}
|
|
306
|
+
DeleteFileA(_fileName.c_str());
|
|
307
|
+
_file = CreateFileA(_fileName.c_str(), GENERIC_READ | GENERIC_WRITE, 0,
|
|
308
|
+
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
309
|
+
if ( _file == INVALID_HANDLE_VALUE )
|
|
310
|
+
{
|
|
311
|
+
DWORD err = getErrorNo();
|
|
312
|
+
std::ostringstream os;
|
|
313
|
+
os << "Failed to recreate log file after purge for LoggedBookmarkStore" << _fileName << " for LoggedBookmarkStore";
|
|
314
|
+
error(os.str(), err);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
#else
|
|
318
|
+
::close(_file);
|
|
319
|
+
::unlink(_fileName.c_str());
|
|
320
|
+
_file = open(_fileName.c_str(), O_RDWR | O_CREAT, (mode_t)0644);
|
|
321
|
+
if (_file == -1)
|
|
322
|
+
{
|
|
323
|
+
error("Failed to recreate log file after purge for LoggedBookmarkStore", getErrorNo());
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
#endif
|
|
327
|
+
MemoryBookmarkStore::_purge();
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
///
|
|
331
|
+
/// Called to purge the contents of this store for particular subId.
|
|
332
|
+
/// Removes any tracking history associated with publishers and received
|
|
333
|
+
/// messages, and will remove the subId from the file as well.
|
|
334
|
+
///
|
|
335
|
+
virtual void purge(const Message::Field& subId_)
|
|
336
|
+
{
|
|
337
|
+
Lock<Mutex> guard(_lock);
|
|
338
|
+
MemoryBookmarkStore::_purge(subId_);
|
|
339
|
+
std::string tmpFileName = _fileName + ".tmp";
|
|
340
|
+
__prune(tmpFileName);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
void setServerVersion(const VersionInfo& version_)
|
|
344
|
+
{
|
|
345
|
+
MemoryBookmarkStore::setServerVersion(version_);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
void setServerVersion(size_t version_)
|
|
349
|
+
{
|
|
350
|
+
MemoryBookmarkStore::setServerVersion(version_);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Yes, the argument is a non-const copy of what is passed in
|
|
354
|
+
void _prune(const std::string& tmpFileName_)
|
|
355
|
+
{
|
|
356
|
+
Lock<Mutex> guard(_lock);
|
|
357
|
+
// If nothing's changed with most recent, don't rewrite the file
|
|
358
|
+
if (!_recentChanged)
|
|
359
|
+
{
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
if (tmpFileName_.empty())
|
|
363
|
+
{
|
|
364
|
+
__prune(_fileName + ".tmp");
|
|
365
|
+
}
|
|
366
|
+
else
|
|
367
|
+
{
|
|
368
|
+
__prune(tmpFileName_);
|
|
369
|
+
}
|
|
370
|
+
_recentChanged = false;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
void __prune(const std::string& tmpFileName_)
|
|
374
|
+
{
|
|
375
|
+
#ifdef _WIN32
|
|
376
|
+
HANDLE tmpFile;
|
|
377
|
+
tmpFile = CreateFileA(tmpFileName_.c_str(), GENERIC_READ | GENERIC_WRITE, 0,
|
|
378
|
+
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
379
|
+
if (tmpFile == INVALID_HANDLE_VALUE )
|
|
380
|
+
{
|
|
381
|
+
DWORD err = getErrorNo();
|
|
382
|
+
std::ostringstream os;
|
|
383
|
+
os << "Failed to create temp log file " << tmpFileName_ <<
|
|
384
|
+
" to prune LoggedBookmarkStore " << _fileName;
|
|
385
|
+
error(os.str(), err);
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
#else
|
|
389
|
+
int tmpFile;
|
|
390
|
+
tmpFile = open(tmpFileName_.c_str(), O_RDWR | O_CREAT, (mode_t)0644);
|
|
391
|
+
if (tmpFile == -1)
|
|
392
|
+
{
|
|
393
|
+
int err = getErrorNo();
|
|
394
|
+
std::ostringstream os;
|
|
395
|
+
os << "Failed to create temp log file " << tmpFileName_ <<
|
|
396
|
+
" to prune LoggedBookmarkStore " << _fileName;
|
|
397
|
+
error(os.str(), err);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
#endif
|
|
401
|
+
try
|
|
402
|
+
{
|
|
403
|
+
for (SubscriptionMap::iterator i = _subs.begin();
|
|
404
|
+
i != _subs.end(); ++i)
|
|
405
|
+
{
|
|
406
|
+
Message::Field subId = i->first;
|
|
407
|
+
assert(!subId.empty());
|
|
408
|
+
Subscription* subPtr = i->second;
|
|
409
|
+
const BookmarkRange& range = subPtr->getRange();
|
|
410
|
+
if (range.isValid())
|
|
411
|
+
{
|
|
412
|
+
write(tmpFile, subId, ENTRY_BOOKMARK, range);
|
|
413
|
+
}
|
|
414
|
+
Message::Field recent = subPtr->getMostRecent(false);
|
|
415
|
+
amps_uint64_t recentPub, recentSeq;
|
|
416
|
+
Subscription::parseBookmark(recent, recentPub, recentSeq);
|
|
417
|
+
Subscription::PublisherMap publishersDiscarded =
|
|
418
|
+
subPtr->_publishers;
|
|
419
|
+
MemoryBookmarkStore::EntryPtrList recovered;
|
|
420
|
+
subPtr->getRecoveryEntries(recovered);
|
|
421
|
+
subPtr->setPublishersToDiscarded(&recovered,
|
|
422
|
+
&publishersDiscarded);
|
|
423
|
+
char tmpBookmarkBuffer[128];
|
|
424
|
+
for (Subscription::PublisherIterator pub =
|
|
425
|
+
publishersDiscarded.begin(),
|
|
426
|
+
e = publishersDiscarded.end();
|
|
427
|
+
pub != e; ++pub)
|
|
428
|
+
{
|
|
429
|
+
// Don't log EPOCH if it got in the map
|
|
430
|
+
if (pub->first == 0 || pub->second == 0)
|
|
431
|
+
{
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
// Don't log the most recent yet
|
|
435
|
+
if (pub->first == recentPub)
|
|
436
|
+
{
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
439
|
+
int written = AMPS_snprintf_amps_uint64_t(
|
|
440
|
+
tmpBookmarkBuffer,
|
|
441
|
+
sizeof(tmpBookmarkBuffer),
|
|
442
|
+
pub->first);
|
|
443
|
+
*(tmpBookmarkBuffer + written++) = '|';
|
|
444
|
+
written += AMPS_snprintf_amps_uint64_t(
|
|
445
|
+
tmpBookmarkBuffer + written,
|
|
446
|
+
sizeof(tmpBookmarkBuffer)
|
|
447
|
+
- (size_t)written,
|
|
448
|
+
pub->second);
|
|
449
|
+
*(tmpBookmarkBuffer + written++) = '|';
|
|
450
|
+
Message::Field tmpBookmark(tmpBookmarkBuffer, (size_t)written);
|
|
451
|
+
write(tmpFile, subId, ENTRY_BOOKMARK, tmpBookmark);
|
|
452
|
+
write(tmpFile, subId, ENTRY_DISCARD, tmpBookmark);
|
|
453
|
+
}
|
|
454
|
+
if (isWritableBookmark(recent.len()))
|
|
455
|
+
{
|
|
456
|
+
write(tmpFile, subId, ENTRY_BOOKMARK, recent);
|
|
457
|
+
write(tmpFile, subId, ENTRY_DISCARD, recent);
|
|
458
|
+
}
|
|
459
|
+
else // set up _recentList
|
|
460
|
+
{
|
|
461
|
+
subPtr->getMostRecentList();
|
|
462
|
+
}
|
|
463
|
+
if (isWritableBookmark(subPtr->getLastPersisted().len()))
|
|
464
|
+
{
|
|
465
|
+
write(tmpFile, subId, ENTRY_PERSISTED,
|
|
466
|
+
subPtr->getLastPersisted());
|
|
467
|
+
}
|
|
468
|
+
subPtr->getActiveEntries(recovered);
|
|
469
|
+
for (MemoryBookmarkStore::EntryPtrList::iterator entry =
|
|
470
|
+
recovered.begin();
|
|
471
|
+
entry != recovered.end(); ++entry)
|
|
472
|
+
{
|
|
473
|
+
if ((*entry)->_val.empty() ||
|
|
474
|
+
!isWritableBookmark((*entry)->_val.len()))
|
|
475
|
+
{
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
write(tmpFile, subId, ENTRY_BOOKMARK, (*entry)->_val);
|
|
479
|
+
if (!(*entry)->_active)
|
|
480
|
+
{
|
|
481
|
+
write(tmpFile, subId, ENTRY_DISCARD, (*entry)->_val);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
catch (StoreException& ex)
|
|
487
|
+
{
|
|
488
|
+
#ifdef _WIN32
|
|
489
|
+
CloseHandle(tmpFile);
|
|
490
|
+
DeleteFileA(tmpFileName_.c_str());
|
|
491
|
+
#else
|
|
492
|
+
::close(tmpFile);
|
|
493
|
+
unlink(tmpFileName_.c_str());
|
|
494
|
+
#endif
|
|
495
|
+
std::ostringstream os;
|
|
496
|
+
os << "Exception during prune: " << ex.what();
|
|
497
|
+
throw StoreException(os.str());
|
|
498
|
+
}
|
|
499
|
+
#ifdef _WIN32
|
|
500
|
+
CloseHandle(_file);
|
|
501
|
+
CloseHandle(tmpFile);
|
|
502
|
+
_file = INVALID_HANDLE_VALUE;
|
|
503
|
+
tmpFile = INVALID_HANDLE_VALUE;
|
|
504
|
+
// Replace file with pruned file
|
|
505
|
+
int retryCount = 3;
|
|
506
|
+
while (!MoveFileExA(tmpFileName_.c_str(), _fileName.c_str(),
|
|
507
|
+
MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH))
|
|
508
|
+
{
|
|
509
|
+
DWORD err = getErrorNo();
|
|
510
|
+
if (--retryCount > 0)
|
|
511
|
+
{
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
514
|
+
// Try to set _file to the tmp file that won't move then throw
|
|
515
|
+
std::string desiredFileName = _fileName;
|
|
516
|
+
_fileName = tmpFileName_;
|
|
517
|
+
init();
|
|
518
|
+
std::ostringstream os;
|
|
519
|
+
os << "Failed to move completed temp file " << tmpFileName_
|
|
520
|
+
<< " to " << desiredFileName
|
|
521
|
+
<< " in prune in LoggedBookmarkStore. Continuing by using "
|
|
522
|
+
<< tmpFileName_ << " as the LoggedBookmarkStore file.";
|
|
523
|
+
error(os.str(), err);
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
init();
|
|
527
|
+
SetFilePointer(_file, 0, NULL, FILE_END);
|
|
528
|
+
#else
|
|
529
|
+
::close(tmpFile);
|
|
530
|
+
::close(_file);
|
|
531
|
+
if (-1 == ::unlink(_fileName.c_str()))
|
|
532
|
+
{
|
|
533
|
+
int err = getErrorNo();
|
|
534
|
+
// Try to set _file to the tmp file then throw
|
|
535
|
+
std::string desiredFileName = _fileName;
|
|
536
|
+
_fileName = tmpFileName_;
|
|
537
|
+
init();
|
|
538
|
+
std::ostringstream os;
|
|
539
|
+
os << "Failed to delete file " << desiredFileName
|
|
540
|
+
<< " after creating temporary file " << tmpFileName_
|
|
541
|
+
<< " in prune in LoggedBookmarkStore. Continuing by using "
|
|
542
|
+
<< tmpFileName_ << " as the LoggedBookmarkStore file.";
|
|
543
|
+
error(os.str(), err);
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
if (-1 == ::rename(tmpFileName_.c_str(), _fileName.c_str()))
|
|
547
|
+
{
|
|
548
|
+
int err = getErrorNo();
|
|
549
|
+
// Try to set _file to the tmp file that won't move then throw
|
|
550
|
+
std::string desiredFileName = _fileName;
|
|
551
|
+
_fileName = tmpFileName_;
|
|
552
|
+
init();
|
|
553
|
+
std::ostringstream os;
|
|
554
|
+
os << "Failed to move completed temp file " << tmpFileName_
|
|
555
|
+
<< " to " << desiredFileName
|
|
556
|
+
<< " in prune in LoggedBookmarkStore. Continuing by using "
|
|
557
|
+
<< tmpFileName_ << " as the LoggedBookmarkStore file.";
|
|
558
|
+
error(os.str(), err);
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
init();
|
|
562
|
+
struct stat fst;
|
|
563
|
+
if (-1 == ::fstat(_file, &fst))
|
|
564
|
+
{
|
|
565
|
+
int err = getErrorNo();
|
|
566
|
+
std::ostringstream os;
|
|
567
|
+
os << "Failed to get size of pruned file " << _fileName
|
|
568
|
+
<< " in prune in LoggedBookmarkStore. ";
|
|
569
|
+
error(os.str(), err);
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
::lseek(_file, (off_t)fst.st_size, SEEK_SET);
|
|
573
|
+
#endif
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
private:
|
|
577
|
+
virtual void _persisted(Subscription* subP_,
|
|
578
|
+
const Message::Field& bookmark_)
|
|
579
|
+
{
|
|
580
|
+
Lock<Mutex> guard(_lock);
|
|
581
|
+
write(_file, subP_->id(), ENTRY_PERSISTED, bookmark_);
|
|
582
|
+
MemoryBookmarkStore::_persisted(subP_, bookmark_);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
virtual Message::Field _persisted(Subscription* subP_, size_t bookmark_)
|
|
586
|
+
{
|
|
587
|
+
Lock<Mutex> l(_lock);
|
|
588
|
+
Subscription::Entry* entryPtr = subP_->getEntryByIndex(bookmark_);
|
|
589
|
+
if (!entryPtr || entryPtr->_val.empty())
|
|
590
|
+
{
|
|
591
|
+
return Message::Field();
|
|
592
|
+
}
|
|
593
|
+
Message::Field bookmarkField = entryPtr->_val;
|
|
594
|
+
write(_file, subP_->id(), ENTRY_PERSISTED, bookmarkField);
|
|
595
|
+
MemoryBookmarkStore::_persisted(subP_, bookmarkField);
|
|
596
|
+
return bookmarkField;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
#ifdef _WIN32
|
|
600
|
+
typedef DWORD ERRTYPE ;
|
|
601
|
+
ERRTYPE getErrorNo() const
|
|
602
|
+
{
|
|
603
|
+
return GetLastError();
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
void error(const std::string& message_, ERRTYPE err)
|
|
607
|
+
{
|
|
608
|
+
std::ostringstream os;
|
|
609
|
+
static const DWORD msgSize = 2048;
|
|
610
|
+
char pMsg[msgSize];
|
|
611
|
+
DWORD sz = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
|
|
612
|
+
FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
|
613
|
+
NULL, err, LANG_NEUTRAL,
|
|
614
|
+
pMsg, msgSize, NULL);
|
|
615
|
+
os << "File: " << _fileName << ". " << message_;
|
|
616
|
+
if (err != 0)
|
|
617
|
+
{
|
|
618
|
+
os << " with error " << pMsg;
|
|
619
|
+
}
|
|
620
|
+
throw StoreException(os.str());
|
|
621
|
+
}
|
|
622
|
+
#else
|
|
623
|
+
typedef int ERRTYPE;
|
|
624
|
+
ERRTYPE getErrorNo() const
|
|
625
|
+
{
|
|
626
|
+
return errno;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
void error(const std::string& message_, ERRTYPE err)
|
|
630
|
+
{
|
|
631
|
+
std::ostringstream os;
|
|
632
|
+
os << "File: " << _fileName << ". " << message_;
|
|
633
|
+
if (err != 0)
|
|
634
|
+
{
|
|
635
|
+
os << " with error " << strerror(err);
|
|
636
|
+
}
|
|
637
|
+
close();
|
|
638
|
+
throw StoreException(os.str());
|
|
639
|
+
}
|
|
640
|
+
#endif
|
|
641
|
+
|
|
642
|
+
void init()
|
|
643
|
+
{
|
|
644
|
+
#ifdef _WIN32
|
|
645
|
+
_file = CreateFileA(_fileName.c_str(), GENERIC_READ | GENERIC_WRITE, 0,
|
|
646
|
+
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
647
|
+
if ( _file == INVALID_HANDLE_VALUE )
|
|
648
|
+
{
|
|
649
|
+
DWORD err = getErrorNo();
|
|
650
|
+
std::ostringstream os;
|
|
651
|
+
os << "Failed to initialize log file " << _fileName << " for LoggedBookmarkStore";
|
|
652
|
+
error(os.str(), err);
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
#else
|
|
656
|
+
_file = open(_fileName.c_str(), O_RDWR | O_CREAT, (mode_t)0644);
|
|
657
|
+
if (_file == -1)
|
|
658
|
+
{
|
|
659
|
+
int err = getErrorNo();
|
|
660
|
+
std::ostringstream os;
|
|
661
|
+
os << "Failed to initialize log file " << _fileName << " for LoggedBookmarkStore";
|
|
662
|
+
error(os.str(), err);
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
#endif
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// This implementation will only ever use this when logging a bookmark
|
|
669
|
+
// Could be used to add a feature where discarded bookmark fields are logged in
|
|
670
|
+
// addition to the generated bookmark.
|
|
671
|
+
void write(FileType file_, const Message::Field& subId_, char type_,
|
|
672
|
+
const Message::Field& bookmark_)
|
|
673
|
+
{
|
|
674
|
+
Lock<Mutex> guard(_fileLock);
|
|
675
|
+
if (!_recoveringFile && isWritableBookmark(bookmark_.len()))
|
|
676
|
+
{
|
|
677
|
+
#ifdef _WIN32
|
|
678
|
+
DWORD written;
|
|
679
|
+
size_t len = subId_.len();
|
|
680
|
+
BOOL ok = WriteFile(file_, (LPVOID)&len, sizeof(size_t), &written, NULL);
|
|
681
|
+
ok |= WriteFile(file_, (LPVOID)subId_.data(), (DWORD)len, &written, NULL);
|
|
682
|
+
ok |= WriteFile(file_, (LPVOID)&type_, 1, &written, NULL);
|
|
683
|
+
len = bookmark_.len();
|
|
684
|
+
ok |= WriteFile(file_, (LPVOID)&len, sizeof(size_t), &written, NULL);
|
|
685
|
+
ok |= WriteFile(file_, (LPVOID)bookmark_.data(), (DWORD)len,
|
|
686
|
+
&written, NULL);
|
|
687
|
+
if (!ok)
|
|
688
|
+
{
|
|
689
|
+
error("Failed to write to bookmark log.", getErrorNo());
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
#else
|
|
694
|
+
if (file_ == -1)
|
|
695
|
+
{
|
|
696
|
+
file_ = open(_fileName.c_str(), O_RDWR | O_CREAT, (mode_t)0644);
|
|
697
|
+
if (file_ == -1)
|
|
698
|
+
{
|
|
699
|
+
int err = getErrorNo();
|
|
700
|
+
std::ostringstream os;
|
|
701
|
+
os << "Failed to open file " << _fileName
|
|
702
|
+
<< " for write in LoggedBookmarkStore. ";
|
|
703
|
+
error(os.str(), err);
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
struct iovec data[5];
|
|
708
|
+
size_t len = subId_.len();
|
|
709
|
+
data[0].iov_base = (amps_iovec_base_ptr)(void*)&len;
|
|
710
|
+
data[0].iov_len = sizeof(size_t);
|
|
711
|
+
data[1].iov_base = (amps_iovec_base_ptr)(void*)subId_.data();
|
|
712
|
+
data[1].iov_len = len;
|
|
713
|
+
data[2].iov_base = (amps_iovec_base_ptr)(void*)&type_;
|
|
714
|
+
data[2].iov_len = 1;
|
|
715
|
+
size_t bookmarkLen = bookmark_.len();
|
|
716
|
+
data[3].iov_base = (amps_iovec_base_ptr)(void*)&bookmarkLen;
|
|
717
|
+
data[3].iov_len = sizeof(size_t);
|
|
718
|
+
data[4].iov_base = (amps_iovec_base_ptr)(void*)bookmark_.data();
|
|
719
|
+
data[4].iov_len = bookmarkLen;
|
|
720
|
+
ssize_t written = ::writev(file_, data, 5);
|
|
721
|
+
if (written == -1)
|
|
722
|
+
{
|
|
723
|
+
error("Failed to write to bookmark log.", getErrorNo());
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
#endif
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
// This implementation will only ever use this when discarding a bookmark
|
|
731
|
+
// Could be used to add a feature where generated bookmarks are logged in
|
|
732
|
+
// addition to the bookmark field.
|
|
733
|
+
void write(FileType file_, const Message::Field& subId_,
|
|
734
|
+
char type_, size_t bookmark_)
|
|
735
|
+
{
|
|
736
|
+
Lock<Mutex> guard(_fileLock);
|
|
737
|
+
if (!_recoveringFile)
|
|
738
|
+
{
|
|
739
|
+
#ifdef _WIN32
|
|
740
|
+
DWORD written;
|
|
741
|
+
size_t len = subId_.len();
|
|
742
|
+
BOOL ok = WriteFile(file_, (LPVOID)&len, sizeof(size_t), &written, NULL);
|
|
743
|
+
ok |= WriteFile(file_, (LPVOID)subId_.data(), (DWORD)len, &written, NULL);
|
|
744
|
+
ok |= WriteFile(file_, (LPVOID)&type_, 1, &written, NULL);
|
|
745
|
+
ok |= WriteFile(file_, (LPVOID)&bookmark_, sizeof(size_t),
|
|
746
|
+
&written, NULL);
|
|
747
|
+
if (!ok)
|
|
748
|
+
{
|
|
749
|
+
error("Failed to write bookmark sequence to file.", getErrorNo());
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
#else
|
|
754
|
+
if (file_ == -1)
|
|
755
|
+
{
|
|
756
|
+
file_ = open(_fileName.c_str(), O_RDWR | O_CREAT, (mode_t)0644);
|
|
757
|
+
if (file_ == -1)
|
|
758
|
+
{
|
|
759
|
+
int err = getErrorNo();
|
|
760
|
+
std::ostringstream os;
|
|
761
|
+
os << "Failed to open file " << _fileName
|
|
762
|
+
<< " to write bookmark sequence in LoggedBookmarkStore. ";
|
|
763
|
+
error(os.str(), err);
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
struct iovec data[4];
|
|
768
|
+
size_t len = subId_.len();
|
|
769
|
+
data[0].iov_base = (amps_iovec_base_ptr)(void*)&len;
|
|
770
|
+
data[0].iov_len = sizeof(size_t);
|
|
771
|
+
data[1].iov_base = (amps_iovec_base_ptr)(void*)subId_.data();
|
|
772
|
+
data[1].iov_len = len;
|
|
773
|
+
data[2].iov_base = (amps_iovec_base_ptr)(void*)&type_;
|
|
774
|
+
data[2].iov_len = 1;
|
|
775
|
+
data[3].iov_base = (amps_iovec_base_ptr)(void*)&bookmark_;
|
|
776
|
+
data[3].iov_len = sizeof(size_t);
|
|
777
|
+
ssize_t written = ::writev(file_, data, 4);
|
|
778
|
+
if (written == -1)
|
|
779
|
+
{
|
|
780
|
+
error("Failed to write bookmark sequence to file.", getErrorNo());
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
#endif
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
#ifdef _WIN32
|
|
788
|
+
#define VOID_P(buf) (LPVOID)buf
|
|
789
|
+
bool readFileBytes(LPVOID buffer, size_t numBytes, DWORD* bytesRead)
|
|
790
|
+
{
|
|
791
|
+
return (ReadFile(_file, buffer, (DWORD)numBytes, bytesRead, NULL) == TRUE);
|
|
792
|
+
}
|
|
793
|
+
#else
|
|
794
|
+
#define VOID_P(buf) (void*)buf
|
|
795
|
+
bool readFileBytes(void* buffer, size_t numBytes, ssize_t* bytesRead)
|
|
796
|
+
{
|
|
797
|
+
*bytesRead = ::read(_file, buffer, numBytes);
|
|
798
|
+
return (*bytesRead >= 0);
|
|
799
|
+
}
|
|
800
|
+
#endif
|
|
801
|
+
|
|
802
|
+
void recover(bool useLastModifiedTime_, bool hasAdapter_)
|
|
803
|
+
{
|
|
804
|
+
size_t bufferLen = 128;
|
|
805
|
+
char* buffer = new char[bufferLen];
|
|
806
|
+
size_t subIdBufferLen = 128;
|
|
807
|
+
char* subIdBuffer = new char[bufferLen];
|
|
808
|
+
Message::Field sub;
|
|
809
|
+
size_t subLen = 0;
|
|
810
|
+
Message::Field bookmarkField;
|
|
811
|
+
size_t bookmarkLen = 0;
|
|
812
|
+
Lock<Mutex> l(_lock);
|
|
813
|
+
Lock<Mutex> guard(_fileLock);
|
|
814
|
+
_recoveringFile = true;
|
|
815
|
+
char* fileTimestamp = new char[AMPS_TIMESTAMP_LEN];
|
|
816
|
+
fileTimestamp[0] = '\0';
|
|
817
|
+
#ifdef _WIN32
|
|
818
|
+
LARGE_INTEGER lifileSize;
|
|
819
|
+
if (GetFileSizeEx(_file, &lifileSize) == 0)
|
|
820
|
+
{
|
|
821
|
+
DWORD err = getErrorNo();
|
|
822
|
+
delete[] buffer;
|
|
823
|
+
delete[] subIdBuffer;
|
|
824
|
+
_recoveringFile = false;
|
|
825
|
+
error("Failure getting file size while trying to recover.", err);
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
#ifdef _WIN64
|
|
829
|
+
size_t fileSize = lifileSize.QuadPart;
|
|
830
|
+
#else
|
|
831
|
+
size_t fileSize = lifileSize.LowPart;
|
|
832
|
+
#endif
|
|
833
|
+
if (useLastModifiedTime_ && fileSize > 0)
|
|
834
|
+
{
|
|
835
|
+
FILETIME ftModifiedTime;
|
|
836
|
+
if (GetFileTime(_file, NULL, NULL, &ftModifiedTime) == 0)
|
|
837
|
+
{
|
|
838
|
+
DWORD err = getErrorNo();
|
|
839
|
+
delete[] buffer;
|
|
840
|
+
delete[] subIdBuffer;
|
|
841
|
+
_recoveringFile = false;
|
|
842
|
+
error("Failure getting file time while trying to recover.", err);
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
SYSTEMTIME st;
|
|
846
|
+
if (FileTimeToSystemTime(&ftModifiedTime, &st) == 0)
|
|
847
|
+
{
|
|
848
|
+
DWORD err = getErrorNo();
|
|
849
|
+
delete[] buffer;
|
|
850
|
+
delete[] subIdBuffer;
|
|
851
|
+
_recoveringFile = false;
|
|
852
|
+
error("Failure converting file time while trying to recover.", err);
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
sprintf_s(fileTimestamp, AMPS_TIMESTAMP_LEN,
|
|
856
|
+
"%04d%02d%02dT%02d%02d%02d", st.wYear, st.wMonth,
|
|
857
|
+
st.wDay, st.wHour, st.wMinute, st.wSecond);
|
|
858
|
+
fileTimestamp[AMPS_TIMESTAMP_LEN - 1] = 'Z';
|
|
859
|
+
}
|
|
860
|
+
else if (fileSize == 0)
|
|
861
|
+
{
|
|
862
|
+
delete[] fileTimestamp;
|
|
863
|
+
delete[] buffer;
|
|
864
|
+
delete[] subIdBuffer;
|
|
865
|
+
_recoveringFile = false;
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
DWORD readBytes = 0;
|
|
869
|
+
OFF_T loc = 0;
|
|
870
|
+
SetFilePointer(_file, 0, NULL, FILE_BEGIN);
|
|
871
|
+
#else
|
|
872
|
+
struct stat fst;
|
|
873
|
+
::fstat(_file, &fst);
|
|
874
|
+
ssize_t fileSize = fst.st_size;
|
|
875
|
+
ssize_t readBytes = 0;
|
|
876
|
+
if (useLastModifiedTime_ && fileSize > 0)
|
|
877
|
+
{
|
|
878
|
+
struct tm timeInfo;
|
|
879
|
+
gmtime_r(&fst.st_mtime, &timeInfo);
|
|
880
|
+
strftime(fileTimestamp, AMPS_TIMESTAMP_LEN,
|
|
881
|
+
"%Y%m%dT%H%M%S", &timeInfo);
|
|
882
|
+
fileTimestamp[AMPS_TIMESTAMP_LEN - 1] = 'Z';
|
|
883
|
+
}
|
|
884
|
+
else if (fileSize == 0)
|
|
885
|
+
{
|
|
886
|
+
delete[] fileTimestamp;
|
|
887
|
+
delete[] buffer;
|
|
888
|
+
delete[] subIdBuffer;
|
|
889
|
+
_recoveringFile = false;
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
OFF_T loc = 0;
|
|
893
|
+
::lseek(_file, loc, SEEK_SET);
|
|
894
|
+
#endif
|
|
895
|
+
// We trust file recovery over Adapter recovery
|
|
896
|
+
if (hasAdapter_)
|
|
897
|
+
{
|
|
898
|
+
MemoryBookmarkStore::__purge();
|
|
899
|
+
}
|
|
900
|
+
if (!readFileBytes(VOID_P(&subLen), sizeof(size_t), &readBytes)
|
|
901
|
+
|| subLen > getMaxSubIdLength())
|
|
902
|
+
{
|
|
903
|
+
delete[] fileTimestamp;
|
|
904
|
+
delete[] buffer;
|
|
905
|
+
delete[] subIdBuffer;
|
|
906
|
+
_recoveringFile = false;
|
|
907
|
+
error("Failure reading file while trying to recover.", getErrorNo());
|
|
908
|
+
return;
|
|
909
|
+
}
|
|
910
|
+
#ifdef _WIN32
|
|
911
|
+
size_t totalBytes = readBytes;
|
|
912
|
+
#else
|
|
913
|
+
ssize_t totalBytes = readBytes;
|
|
914
|
+
#endif
|
|
915
|
+
ERRTYPE err = 0; // 0 no error, -1 corruption, positive is errno file error
|
|
916
|
+
size_t tooManyBytes = 0;
|
|
917
|
+
typedef std::map<Message::Field, size_t,
|
|
918
|
+
Message::Field::FieldHash> BookmarkMap;
|
|
919
|
+
typedef std::map<Message::Field, size_t,
|
|
920
|
+
Message::Field::FieldHash>::iterator BookmarkMapIter;
|
|
921
|
+
// Map of subId to set of recovered bookmarks
|
|
922
|
+
typedef std::map<Message::Field, BookmarkMap*,
|
|
923
|
+
Message::Field::FieldHash> ReadMap;
|
|
924
|
+
typedef std::map<Message::Field, BookmarkMap*,
|
|
925
|
+
Message::Field::FieldHash>::iterator ReadMapIter;
|
|
926
|
+
ReadMap recovered;
|
|
927
|
+
while (subLen > 0 && (size_t)readBytes == sizeof(size_t) &&
|
|
928
|
+
(size_t)totalBytes <= (size_t)fileSize)
|
|
929
|
+
{
|
|
930
|
+
if (subLen >= ((size_t)fileSize - (size_t)totalBytes)
|
|
931
|
+
|| subLen > getMaxSubIdLength())
|
|
932
|
+
{
|
|
933
|
+
err = (ERRTYPE) - 1;
|
|
934
|
+
tooManyBytes = subLen + 1;
|
|
935
|
+
break;
|
|
936
|
+
}
|
|
937
|
+
else
|
|
938
|
+
{
|
|
939
|
+
if (subIdBufferLen < subLen)
|
|
940
|
+
{
|
|
941
|
+
delete [] subIdBuffer;
|
|
942
|
+
subIdBufferLen = 2 * subLen;
|
|
943
|
+
subIdBuffer = new char[subIdBufferLen];
|
|
944
|
+
}
|
|
945
|
+
if (!readFileBytes(VOID_P(subIdBuffer), subLen, &readBytes))
|
|
946
|
+
{
|
|
947
|
+
err = getErrorNo();
|
|
948
|
+
tooManyBytes = subLen;
|
|
949
|
+
break;
|
|
950
|
+
}
|
|
951
|
+
totalBytes += readBytes;
|
|
952
|
+
sub.assign(subIdBuffer, subLen);
|
|
953
|
+
if (!readFileBytes(VOID_P(buffer), 1, &readBytes))
|
|
954
|
+
{
|
|
955
|
+
err = getErrorNo();
|
|
956
|
+
tooManyBytes = 1;
|
|
957
|
+
break;
|
|
958
|
+
}
|
|
959
|
+
totalBytes += readBytes;
|
|
960
|
+
switch (buffer[0])
|
|
961
|
+
{
|
|
962
|
+
case ENTRY_BOOKMARK:
|
|
963
|
+
{
|
|
964
|
+
if ((size_t)totalBytes + sizeof(size_t) >= (size_t)fileSize)
|
|
965
|
+
{
|
|
966
|
+
// Corrupt final record is ok
|
|
967
|
+
err = (ERRTYPE) - 1;
|
|
968
|
+
tooManyBytes = sizeof(size_t);
|
|
969
|
+
break;
|
|
970
|
+
}
|
|
971
|
+
if (!readFileBytes(VOID_P(&bookmarkLen), sizeof(size_t), &readBytes))
|
|
972
|
+
{
|
|
973
|
+
err = getErrorNo();
|
|
974
|
+
tooManyBytes = sizeof(size_t);
|
|
975
|
+
break;
|
|
976
|
+
}
|
|
977
|
+
totalBytes += readBytes;
|
|
978
|
+
if (bookmarkLen > (size_t)fileSize - (size_t)totalBytes)
|
|
979
|
+
{
|
|
980
|
+
// Corrupt final record is ok
|
|
981
|
+
err = (ERRTYPE) - 1;
|
|
982
|
+
tooManyBytes = bookmarkLen;
|
|
983
|
+
break;
|
|
984
|
+
}
|
|
985
|
+
if (bufferLen < bookmarkLen)
|
|
986
|
+
{
|
|
987
|
+
delete [] buffer;
|
|
988
|
+
bufferLen = 2 * bookmarkLen;
|
|
989
|
+
buffer = new char[bufferLen];
|
|
990
|
+
}
|
|
991
|
+
if (!readFileBytes(VOID_P(buffer), bookmarkLen, &readBytes))
|
|
992
|
+
{
|
|
993
|
+
err = getErrorNo();
|
|
994
|
+
tooManyBytes = bookmarkLen;
|
|
995
|
+
break;
|
|
996
|
+
}
|
|
997
|
+
totalBytes += readBytes;
|
|
998
|
+
bookmarkField.assign(buffer, bookmarkLen);
|
|
999
|
+
Subscription* subP = find(sub);
|
|
1000
|
+
BookmarkMap* bookmarks = NULL;
|
|
1001
|
+
ReadMapIter iter = recovered.find(sub);
|
|
1002
|
+
if (iter == recovered.end())
|
|
1003
|
+
{
|
|
1004
|
+
Message::Field subKey;
|
|
1005
|
+
subKey.deepCopy(sub);
|
|
1006
|
+
bookmarks = new BookmarkMap();
|
|
1007
|
+
recovered[subKey] = bookmarks;
|
|
1008
|
+
}
|
|
1009
|
+
else
|
|
1010
|
+
{
|
|
1011
|
+
bookmarks = iter->second;
|
|
1012
|
+
}
|
|
1013
|
+
if (bookmarks->find(bookmarkField) != bookmarks->end())
|
|
1014
|
+
{
|
|
1015
|
+
std::for_each(bookmarks->begin(), bookmarks->end(),
|
|
1016
|
+
_clearBookmark);
|
|
1017
|
+
bookmarks->clear();
|
|
1018
|
+
subP->getMostRecent(true);
|
|
1019
|
+
}
|
|
1020
|
+
if (BookmarkRange::isRange(bookmarkField))
|
|
1021
|
+
{
|
|
1022
|
+
subP->log(bookmarkField);
|
|
1023
|
+
}
|
|
1024
|
+
else if (!subP->isDiscarded(bookmarkField))
|
|
1025
|
+
{
|
|
1026
|
+
size_t sequence = subP->log(bookmarkField);
|
|
1027
|
+
Message::Field copy;
|
|
1028
|
+
copy.deepCopy(bookmarkField);
|
|
1029
|
+
bookmarks->insert(std::make_pair(copy, sequence));
|
|
1030
|
+
}
|
|
1031
|
+
else
|
|
1032
|
+
{
|
|
1033
|
+
// We know it's discarded, but there may still be a
|
|
1034
|
+
// discard entry in the log, so avoid a search.
|
|
1035
|
+
Message::Field copy;
|
|
1036
|
+
copy.deepCopy(bookmarkField);
|
|
1037
|
+
bookmarks->insert(std::make_pair(copy, 0));
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
break;
|
|
1041
|
+
|
|
1042
|
+
case ENTRY_DISCARD:
|
|
1043
|
+
{
|
|
1044
|
+
if ((size_t)totalBytes + sizeof(size_t) >= (size_t)fileSize)
|
|
1045
|
+
{
|
|
1046
|
+
// Corrupt final record is ok
|
|
1047
|
+
err = (ERRTYPE) - 1;
|
|
1048
|
+
tooManyBytes = sizeof(size_t);
|
|
1049
|
+
break;
|
|
1050
|
+
}
|
|
1051
|
+
if (!readFileBytes(VOID_P(&bookmarkLen), sizeof(size_t), &readBytes))
|
|
1052
|
+
{
|
|
1053
|
+
err = getErrorNo();
|
|
1054
|
+
tooManyBytes = sizeof(size_t);
|
|
1055
|
+
break;
|
|
1056
|
+
}
|
|
1057
|
+
totalBytes += readBytes;
|
|
1058
|
+
if (bookmarkLen > (size_t)fileSize - (size_t)totalBytes)
|
|
1059
|
+
{
|
|
1060
|
+
// Corrupt final record is ok
|
|
1061
|
+
err = (ERRTYPE) - 1;
|
|
1062
|
+
tooManyBytes = bookmarkLen;
|
|
1063
|
+
break;
|
|
1064
|
+
}
|
|
1065
|
+
if (bufferLen < bookmarkLen)
|
|
1066
|
+
{
|
|
1067
|
+
delete [] buffer;
|
|
1068
|
+
bufferLen = 2 * bookmarkLen;
|
|
1069
|
+
buffer = new char[bufferLen];
|
|
1070
|
+
}
|
|
1071
|
+
if (!readFileBytes(VOID_P(buffer), bookmarkLen, &readBytes))
|
|
1072
|
+
{
|
|
1073
|
+
err = getErrorNo();
|
|
1074
|
+
tooManyBytes = bookmarkLen;
|
|
1075
|
+
break;
|
|
1076
|
+
}
|
|
1077
|
+
totalBytes += readBytes;
|
|
1078
|
+
bookmarkField.assign(buffer, bookmarkLen);
|
|
1079
|
+
size_t sequence = AMPS_UNSET_INDEX;
|
|
1080
|
+
ReadMapIter iter = recovered.find(sub);
|
|
1081
|
+
if (iter != recovered.end())
|
|
1082
|
+
{
|
|
1083
|
+
BookmarkMap* bookmarks = iter->second;
|
|
1084
|
+
BookmarkMapIter bookmarkIter = bookmarks->find(bookmarkField);
|
|
1085
|
+
if (bookmarkIter != bookmarks->end())
|
|
1086
|
+
{
|
|
1087
|
+
sequence = bookmarkIter->second;
|
|
1088
|
+
Message::Field bookmarkToClear(bookmarkIter->first);
|
|
1089
|
+
bookmarkToClear.clear();
|
|
1090
|
+
bookmarks->erase(bookmarkIter);
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
Subscription* subP = find(sub);
|
|
1094
|
+
if (!BookmarkRange::isRange(bookmarkField))
|
|
1095
|
+
{
|
|
1096
|
+
if (sequence != AMPS_UNSET_INDEX)
|
|
1097
|
+
{
|
|
1098
|
+
// A sequence of 0 means it was already discarded
|
|
1099
|
+
if (sequence)
|
|
1100
|
+
{
|
|
1101
|
+
subP->discard(sequence);
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
else // Shouldn't end up here, but just in case we'll search
|
|
1105
|
+
{
|
|
1106
|
+
subP->discard(bookmarkField);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
break;
|
|
1111
|
+
case ENTRY_PERSISTED:
|
|
1112
|
+
{
|
|
1113
|
+
if ((size_t)totalBytes + sizeof(size_t) >= (size_t)fileSize)
|
|
1114
|
+
{
|
|
1115
|
+
// Corrupt final record is ok
|
|
1116
|
+
err = (ERRTYPE) - 1;
|
|
1117
|
+
tooManyBytes = sizeof(size_t);
|
|
1118
|
+
break;
|
|
1119
|
+
}
|
|
1120
|
+
if (!readFileBytes(VOID_P(&bookmarkLen), sizeof(size_t), &readBytes))
|
|
1121
|
+
{
|
|
1122
|
+
err = getErrorNo();
|
|
1123
|
+
tooManyBytes = sizeof(size_t);
|
|
1124
|
+
break;
|
|
1125
|
+
}
|
|
1126
|
+
totalBytes += readBytes;
|
|
1127
|
+
if (bookmarkLen > (size_t)fileSize - (size_t)totalBytes)
|
|
1128
|
+
{
|
|
1129
|
+
// Corrupt final record is ok
|
|
1130
|
+
err = (ERRTYPE) - 1;
|
|
1131
|
+
tooManyBytes = bookmarkLen;
|
|
1132
|
+
break;
|
|
1133
|
+
}
|
|
1134
|
+
if (bufferLen < bookmarkLen)
|
|
1135
|
+
{
|
|
1136
|
+
delete [] buffer;
|
|
1137
|
+
bufferLen = 2 * bookmarkLen;
|
|
1138
|
+
buffer = new char[bufferLen];
|
|
1139
|
+
}
|
|
1140
|
+
if (!readFileBytes(VOID_P(buffer), bookmarkLen, &readBytes))
|
|
1141
|
+
{
|
|
1142
|
+
err = getErrorNo();
|
|
1143
|
+
tooManyBytes = bookmarkLen;
|
|
1144
|
+
break;
|
|
1145
|
+
}
|
|
1146
|
+
totalBytes += readBytes;
|
|
1147
|
+
bookmarkField.assign(buffer, bookmarkLen);
|
|
1148
|
+
Subscription* subP = find(sub);
|
|
1149
|
+
MemoryBookmarkStore::_persisted(subP, bookmarkField);
|
|
1150
|
+
}
|
|
1151
|
+
break;
|
|
1152
|
+
default:
|
|
1153
|
+
{
|
|
1154
|
+
// Corrupt final record is ok
|
|
1155
|
+
err = (ERRTYPE) - 1;
|
|
1156
|
+
tooManyBytes = (size_t)fileSize - (size_t)totalBytes;
|
|
1157
|
+
}
|
|
1158
|
+
break;
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
loc = (OFF_T)totalBytes;
|
|
1162
|
+
if ((size_t)totalBytes > (size_t)fileSize)
|
|
1163
|
+
{
|
|
1164
|
+
loc = (OFF_T)fileSize;
|
|
1165
|
+
break;
|
|
1166
|
+
}
|
|
1167
|
+
if (!readFileBytes(VOID_P(&subLen), sizeof(size_t), &readBytes))
|
|
1168
|
+
{
|
|
1169
|
+
err = getErrorNo();
|
|
1170
|
+
tooManyBytes = sizeof(size_t);
|
|
1171
|
+
break;
|
|
1172
|
+
}
|
|
1173
|
+
totalBytes += readBytes;
|
|
1174
|
+
}
|
|
1175
|
+
delete[] buffer;
|
|
1176
|
+
delete[] subIdBuffer;
|
|
1177
|
+
if (err == 0)
|
|
1178
|
+
{
|
|
1179
|
+
for (SubscriptionMap::iterator i = _subs.begin(); i != _subs.end(); ++i)
|
|
1180
|
+
{
|
|
1181
|
+
if (recovered.count(i->first) && !recovered[i->first]->empty())
|
|
1182
|
+
{
|
|
1183
|
+
Subscription* subPtr = i->second;
|
|
1184
|
+
if (subPtr->getMostRecent(false).len() > 1)
|
|
1185
|
+
{
|
|
1186
|
+
subPtr->justRecovered();
|
|
1187
|
+
}
|
|
1188
|
+
else
|
|
1189
|
+
{
|
|
1190
|
+
// Unlikely, but we may have recovered only undiscarded bookmarks
|
|
1191
|
+
// so we should really just restart as a new subscription.
|
|
1192
|
+
delete subPtr;
|
|
1193
|
+
_subs[i->first] = new Subscription(this, i->first);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
if (useLastModifiedTime_ && fileTimestamp[0] != '\0')
|
|
1197
|
+
{
|
|
1198
|
+
_subs[i->first]->setRecoveryTimestamp(fileTimestamp);
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
for (ReadMapIter i = recovered.begin(), e = recovered.end(); i != e; ++i)
|
|
1203
|
+
{
|
|
1204
|
+
std::for_each(i->second->begin(), i->second->end(), _clearBookmark);
|
|
1205
|
+
delete i->second;
|
|
1206
|
+
Message::Field f = i->first;
|
|
1207
|
+
f.clear();
|
|
1208
|
+
}
|
|
1209
|
+
delete[] fileTimestamp;
|
|
1210
|
+
_recoveringFile = false;
|
|
1211
|
+
if (err != 0)
|
|
1212
|
+
{
|
|
1213
|
+
// Arbitrary guess if we're on the last record
|
|
1214
|
+
// We set err to -1 if we read a corrupt value or
|
|
1215
|
+
// to errno/last error if a read failed.
|
|
1216
|
+
if (err != (ERRTYPE) - 1 || loc == 0 || fileSize - loc > 128)
|
|
1217
|
+
{
|
|
1218
|
+
std::ostringstream os;
|
|
1219
|
+
os << "Error while recovering LoggedBookmarkStore from "
|
|
1220
|
+
<< _fileName
|
|
1221
|
+
<< ". Record starting at " << loc
|
|
1222
|
+
<< " reading at " << totalBytes
|
|
1223
|
+
<< " requested " << tooManyBytes
|
|
1224
|
+
<< " and file size is " << fileSize;
|
|
1225
|
+
error(os.str(), (err != (ERRTYPE) - 1 ? err : 0));
|
|
1226
|
+
}
|
|
1227
|
+
else
|
|
1228
|
+
{
|
|
1229
|
+
#ifdef _WIN32
|
|
1230
|
+
#ifdef _WIN64
|
|
1231
|
+
LONG low = (LONG)loc;
|
|
1232
|
+
LONG high = (LONG)((loc >> 32) & 0xffffffff);
|
|
1233
|
+
SetFilePointer(_file, low, &high, FILE_BEGIN);
|
|
1234
|
+
#else
|
|
1235
|
+
SetFilePointer(_file, loc, NULL, FILE_BEGIN);
|
|
1236
|
+
#endif
|
|
1237
|
+
#else
|
|
1238
|
+
::lseek(_file, loc, SEEK_SET);
|
|
1239
|
+
#endif
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
private:
|
|
1245
|
+
FileType _file;
|
|
1246
|
+
Mutex _fileLock;
|
|
1247
|
+
std::string _fileName;
|
|
1248
|
+
bool _recoveringFile;
|
|
1249
|
+
};
|
|
1250
|
+
|
|
1251
|
+
} // end namespace AMPS
|
|
1252
|
+
|
|
1253
|
+
|
|
1254
|
+
#endif // _LOGGEDBOOKMARKSTORE_H_
|
|
1255
|
+
|