1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-22 03:43:03 +04:00

Compare commits

..

1287 Commits

Author SHA1 Message Date
Alexander Alekhin b0dc474160 release: OpenCV 4.6.0 2022-06-05 15:32:44 +00:00
Juan López Rubio adf89bbb33 Merge pull request #22047 from jlopezr:trackbar-ordered-in-mac
* In Mac highgui now shows trackbars in creation order

* In Mac highgui trackbars show current value

* Remove trailing spaces in objectivec code
2022-06-05 15:30:16 +00:00
Alexander Alekhin 583bd1a6e2 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-06-04 19:10:35 +00:00
Alexander Panov 53eda42da7 Merge pull request #22025 from AleksandrPanov:fix_samplingForVersion_multiplyingFactor
Fix sampling for version multiplying factor

* reduce experimentalFrequencyElem and listFrequencyElem

* fix large resize

* fix tile in postIntermediate

* add getMinSideLen(), add corrected_index

* add test decode_regression_21929 author Kumataro, add test decode_regression_version_25
2022-06-04 17:33:08 +03:00
Alexander Alekhin c26c4a61c6 Merge pull request #22061 from alalek:imgproc_color_hsv_use_singleton 2022-06-03 09:03:33 +00:00
Alexander Alekhin 65fcf22670 imgproc: use singleton in color_hsv.simd.hpp 2022-06-01 19:02:56 +00:00
Alexander Alekhin d0572538ff Merge pull request #22059 from Kumataro:3.4-fix21899 2022-06-01 18:38:22 +00:00
Kumataro 3577265508 highgui: Qt: waitKey() supports Cyrillic/Japanese keyboard layout 2022-06-01 21:45:53 +09:00
Kumataro 1a24e316d5 Merge pull request #22030 from Kumataro:3.4-fix22029
* objdetect: qrcode_encoder: fix to missing timing pattern

* objdetect: qrcode_encoder: Add SCOPED_TRACE() and replace CV_Assert() to ASSERT_EQ().

- Add SCOPED_TRACE() for version loop.

- Replace CV_Assert() to ASSERT_EQ().

- Rename expect_msg to msg.
2022-05-31 13:58:17 +03:00
Alexander Alekhin 9da9e8244b Merge pull request #22041 from nglee:fix_return_by_const_value 2022-05-31 10:51:55 +00:00
Alexander Alekhin 8d51ef0f35 Merge pull request #22054 from asenyaev:asen/fix_matching_xcode_version 2022-05-31 06:39:10 +00:00
Andrey Senyaev 9cfae823a7 Fix Xcode version matching 2022-05-31 01:58:50 +03:00
Alexander Alekhin d6151eae23 Merge pull request #22019 from victor1234:calib3d-fix-cameracalibration-test 2022-05-30 18:27:14 +00:00
Alexander Alekhin 4a0a3281c6 Merge pull request #22021 from victor1234:issue-10947_calib3d-update-fisheye-distortpoint-doc 2022-05-30 18:21:02 +00:00
Victor 1230075011 Merge pull request #22045 from victor1234:calib3d-fisheye-model-reference
* Add fisheye camera model summary description with reference

* Fix layout

* Move reference to bibtex
2022-05-30 18:03:08 +00:00
Alexander Alekhin 7459954377 Merge pull request #21843 from Rufflewind:doc 2022-05-28 11:44:19 +00:00
Alexander Alekhin cf38098ba8 Merge pull request #22034 from alalek:update_ffmpeg_4.x 2022-05-28 02:57:55 +00:00
Lukas-Alexander Weber 8ca394efaf Merge pull request #22005 from lukasalexanderweber:delete_stitching_tool
Move stitching package and tool to a dedicated repository

* deleted moved files

* Update README.md
2022-05-26 22:30:24 +03:00
Alexander Alekhin f9c7931800 Merge pull request #22035 from mohawk2:patch-1 2022-05-26 19:15:39 +00:00
Namgoo Lee 24547f40ff remove const from functions returning by value 2022-05-26 21:30:41 +09:00
mohawk2 72debee125 typo: Minkowsky is actually Minkowski 2022-05-26 12:54:26 +01:00
Alexander Alekhin 08c270f65a Merge pull request #22033 from alalek:windows_skip_failed_videoio_tests 2022-05-25 11:51:31 +00:00
Alexander Alekhin e585453c2e videoio(test): skip failed tests in misconfigured environments 2022-05-25 06:40:03 +00:00
Alexander Alekhin 86f4524010 Merge pull request #22028 from alalek:build_warnings_4.x 2022-05-25 06:39:37 +00:00
Alexander Alekhin 6d098cc230 ffmpeg/4.x: update FFmpeg wrapper 2022.05
- FFmpeg 4.4.2
- libvpx 1.11
2022-05-24 23:44:10 +00:00
Alexander Alekhin 434c96e625 build: eliminate warnings 2022-05-24 23:34:11 +00:00
Alexander Alekhin d6e9616256 Merge pull request #22027 from alalek:update_version_4.6.0-pre 2022-05-24 21:37:18 +00:00
Alexander Alekhin e9187ae38c Merge pull request #22026 from alalek:update_version_3.4.18-pre 2022-05-24 20:23:28 +00:00
Alexander Alekhin 978dc76653 Merge pull request #22006 from rogday:21947_fix 2022-05-24 19:26:02 +00:00
Alexander Alekhin b409fd32ac Merge pull request #22024 from berak:patch-1 2022-05-24 08:20:26 +00:00
rogday a2ad997e97 fix vector access in TF::sortByExecutionOrder 2022-05-24 00:05:13 +03:00
Alexander Alekhin e9428726ca pre: OpenCV 4.6.0 (version++) 2022-05-23 19:25:16 +00:00
Alexander Alekhin 400906b433 pre: OpenCV 3.4.18 (version++) 2022-05-23 19:18:02 +00:00
berak 50d7c61c01 Update darknet_importer.cpp
make it more obvious, that this is a '404', not a 'parsing' problem
2022-05-23 19:18:31 +02:00
Alexander Alekhin d9bf522b27 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-05-23 16:06:14 +00:00
rogday 93dc0679ec Merge pull request #21818 from rogday:revert_renaming
* add prefixes to layer names and layer output names

* dnn: OPENCV_DNN_ONNX_USE_LEGACY_NAMES runtime parameter

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2022-05-23 14:50:42 +00:00
Kataev Victor 1ddc51cfd1 Update fisheye::distortPoints() documentation 2022-05-23 14:30:09 +03:00
Kataev Victor 50bf0e10f5 Fix cameracalibration test
* Remove transpose for rvec after calibration
* Change compare threshold from 110% to 10% for perViewErrors
* Add transpose to goodRotMatrs load
2022-05-23 14:07:34 +03:00
Phil Ruffwind d1ccb7e47f Update js_usage.markdown to use onRuntimeInitialized
The Emscripten library is not guaranteed to be fully loaded during the
script element's onload event. Module.onRuntimeInitialized seems to be
more reliable.
2022-05-22 20:53:35 -07:00
Alexander Alekhin 7e845a3b87 Merge pull request #22013 from asenyaev:asen/move_workflows_4.x 2022-05-22 13:42:34 +00:00
Alexander Alekhin ea1c970190 Merge pull request #22001 from asenyaev:asen/move_workflows 2022-05-22 13:41:56 +00:00
Andrey Senyaev 3d207ccf11 Move workflows to a dedicated repository for 4.x branch 2022-05-20 19:46:56 +03:00
Andrey Senyaev aaf7f5ae02 Move workflows to a dedicated repository 2022-05-20 14:29:43 +03:00
Alexander Alekhin 50e8ad285b Merge pull request #22008 from zachlowry:umat-format-string 2022-05-19 21:51:02 +00:00
Alexander Alekhin bb5462e327 Merge pull request #21991 from fengyuentau:qconv_asympad 2022-05-19 17:20:04 +00:00
Martin Tůma df2e7fa6eb Merge pull request #21992 from tumicdq:v4l2
* Added support for 4B RGB V4L2 pixel formats

Added support for V4L2_PIX_FMT_XBGR32 and V4L2_PIX_FMT_ABGR32 pixel
formats.

* Added workaround for missing V4L2_PIX_FMT_ABGR32 and V4L2_PIX_FMT_XBGR32
defines
2022-05-19 12:37:10 +00:00
Alexander Alekhin 11f36bdf9a Merge pull request #21941 from cpoerschke:4.x-fix-imgproc-typos 2022-05-17 21:42:36 +00:00
Alexander Alekhin bc0d4585b3 Merge pull request #21984 from xiong-jie-y:add_make_capture_for_camera_stream 2022-05-17 21:22:17 +00:00
Alexander Alekhin 70917f291c Merge pull request #21988 from alalek:fix_warnings_gcc12_3.4 2022-05-17 16:27:15 +00:00
Alexander Alekhin 9f6f0c7424 Merge pull request #21987 from alalek:gapi_test_reduce_used_memory 2022-05-17 16:26:14 +00:00
Alexander Alekhin 4722a8df3c Merge pull request #21998 from alalek:gha_fix_git_merge_fixup_21986 2022-05-17 16:24:25 +00:00
Andrey Senyaev 7be8a71c60 Merge pull request #21994 from asenyaev:asen/extra_dnn_testing
Extended DNN testing in GHA

* Extended DNN testing in GHA for 3.4 branch

* Updated docker images in Linux GitHub Actions

* Added OPENCV_DOWNLOAD_PATH flag for ARM build to use pre-downloaded binaries
2022-05-17 16:23:32 +00:00
Alexander Alekhin ce859edba8 GHA: fix git merge (part 2) 2022-05-17 15:06:46 +00:00
Alexander Alekhin 90820cd044 Merge pull request #21986 from alalek:gha_fix_git_merge 2022-05-16 14:35:56 +00:00
xiong-jie-y c929f1b62f Add make_capture_src for video stream to Python 2022-05-16 20:46:08 +09:00
fengyuentau ff88132620 support asymmetric paddings for qconv 2022-05-16 19:01:37 +08:00
Alexander Alekhin 89f8d4ae12 build: GCC12 warnings 2022-05-15 16:21:16 +00:00
dbudnikov 3f4ffe7844 Merge pull request #21909 from dbudnikov:dbudnikov/reduce_gapi_tests_number
Reduce G-API tests number

* reduce number of G-API tests

* reduce number of G-API tests

* Address more comments from Dmitry.
2022-05-15 10:07:01 +00:00
Alexander Alekhin ed567a2dd1 Merge pull request #21907 from fengyuentau:workflow_arm_4.x 2022-05-15 10:04:55 +00:00
Alexander Alekhin 22a00036e2 gapi(test): reduce used amount of memory 2022-05-15 09:41:25 +00:00
Alexander Alekhin 2aac0a5a26 GHA: fix git merge 2022-05-15 09:35:51 +00:00
fengyuentau 07ad6a437e add ARM64 workflow for 4.x
add opencv_contrib fork check

use image hosted on quay.io
2022-05-14 15:26:56 +00:00
OpenCV Developers d9a444ca1a Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-05-14 11:23:21 +00:00
OpenCV Pushbot 766f58ed7e Merge pull request #21980 from asenyaev:asen/move_variables_to_the_host 2022-05-14 11:03:17 +00:00
Andrey Senyaev 1099b4c881 Move environment variables on a host side (GHA Windows) 2022-05-14 09:03:21 +00:00
OpenCV Pushbot 7c0f49fc36 Merge pull request #21977 from asenyaev:asen/win_contrib 2022-05-13 20:59:51 +00:00
OpenCV Pushbot 761e796201 Merge pull request #21964 from Julian-Sz:patch-1
Documentation Fix: Python and Java switched in Explanation
2022-05-13 18:13:30 +00:00
Manolis Lourakis 8d0fbc6a1e Merge pull request #21702 from mlourakis:4.x
Fixes and optimizations for the SQPnP solver

* Fixes and optimizations

- optimized the calculation of qa_sum by moving equal elements outside the loop
- unrolled copying of the lower triangle of omega
- substituted SVD with eigendecomposition in the factorization of omega (2-3 times faster)
- fixed the initialization of lambda in FOAM
- added a cheirality test that checks a solution on all 3D points rather than on their mean. The old test rejected valid poses in some cases
- fixed some typos & errors in comments

* reverted to SVD

Eigen decomposition seems to yield larger errors in certain tests, reverted to SVD

* nearestRotationMatrixSVD

Added nearestRotationMatrixSVD()
Previous nearestRotationMatrix() renamed to nearestRotationMatrixFOAM() and reverts to nearestRotationMatrixSVD() for singular matrices

* fixed checks order

Fixed the order of checks in PoseSolver::solveInternal()
2022-05-13 18:11:14 +00:00
Andrey Senyaev affcea8822 Added opencv_contrib branch check on Windows 2022-05-13 17:37:54 +00:00
OpenCV Pushbot 53f0be00a9 Merge pull request #21975 from asenyaev:asen/fix_terminating_windows_actions 2022-05-13 17:34:30 +00:00
Kumataro 602caa9cd6 Merge pull request #21937 from Kumataro:4.x-fix-21911
* Fix warnings for clang15

* Fix warnings: Remove unnecessary code

* Fix warnings: Remove unnecessary code
2022-05-13 17:32:05 +00:00
OpenCV Pushbot f35ec8c955 Merge pull request #21935 from Yulv-git:3.4-typos3 2022-05-13 17:30:57 +00:00
OpenCV Pushbot 1316491e50 Merge pull request #21933 from Yulv-git:3.4-typos1 2022-05-13 17:28:08 +00:00
Yuantao Feng 2cc4309bf8 Merge pull request #21924 from fengyuentau:workflow_arm64_3.4
Workflow to build and test on ARM64 for 3.4 branch

* add ARM64 workflow for 3.4

* add opencv_contrib fork check

* rename RET to OPENCV_EXTRA_FORK
2022-05-13 17:27:01 +00:00
OpenCV Pushbot 612d43f284 Merge pull request #21871 from xiongzhen:apply-predictor-to-lzw-only
TIFFTAG_PREDICTOR should not be applied unless LZW, DEFLATE or ADOBE_DEFLATE
2022-05-13 17:25:59 +00:00
OpenCV Pushbot 56824d1769 Merge pull request #21847 from lamm45:imgproc-tform-doc
Minor documentation fixes for geometric image transformations
2022-05-13 17:23:23 +00:00
xiongzhen 2238ac7d59 Apply TIFFTAG_PREDICTOR option for LZW, DEFLATE and ADOBE_DEFLATE compression cases for smaller files. 2022-05-13 09:44:25 +03:00
Andrey Senyaev 2b5b192cd7 Moved from https to ssh for Windows in Github Actions 2022-05-13 01:37:55 +03:00
Julian Szigethy 64e1d23cba Fix: Python and Java switched in Explanation 2022-05-12 20:35:05 +02:00
OpenCV Pushbot 40d2904f3d Merge pull request #21916 from chenjunnn:patch-1 2022-05-12 10:01:11 +00:00
OpenCV Pushbot 9712cc479b Merge pull request #21963 from hellodoge:imwrite_fix 2022-05-12 09:02:54 +00:00
OpenCV Pushbot 0ef1fb0b67 Merge pull request #21954 from Darkyenus:patch-1 2022-05-12 08:59:10 +00:00
Victor 2b67bc448d Merge pull request #21931 from victor1234:calib3d-add-undistortImagePoints
Add undistortImagePoints function

* Add undistortImagePoints function
undistortPoints has unclear interface and additional functionality. New function computes only undistorted image points position

* Add undistortImagePoints test

* Add TermCriteria

* Fix layout
2022-05-12 08:56:58 +00:00
Andrey Senyaev a3f81b79ed Merge pull request #21917 from asenyaev:asen/self_hosted_runner_linux_3.4
Workflow to use a self-hosted Github runner on Linux x86_64 for 3.4 branch

* Changed a workflow to use a self-hosted Github runner for 3.4 branch
2022-05-12 08:52:23 +00:00
Chen Jun 8d0dae4cec Fix KalmanFilter comment error
If there will be measurement before the next predict, `statePost` would be assigned to updated value. So I guess these steps are meant to handle when no measurement and KF only do the predict step.
```cpp
statePre.copyTo(statePost);
errorCovPre.copyTo(errorCovPost);
```
2022-05-12 08:48:23 +00:00
OpenCV Pushbot dda96264df Merge pull request #21608 from zihaomu:depth2space
DNN: add depth2space and space2depth layer for onnx importer
2022-05-12 08:46:36 +00:00
OpenCV Pushbot 4af8e5c5c4 Merge pull request #21974 from cxcorp:fix-js-test-globals 2022-05-12 08:44:00 +00:00
Sergey eff5605be5 Merge pull request #21883 from SergeyIvanov87:gapi_vpl_linux
G-API: VPL Source turn on Linux CPU version

* Turn on linux compilation

* Apply comments

* Change new files headline

* Add license header
2022-05-12 08:42:38 +00:00
OpenCV Pushbot 2b53ab23c0 Merge pull request #21882 from duanqn:improve-doc 2022-05-12 07:41:39 +00:00
OpenCV Pushbot 2010de9104 Merge pull request #21971 from asenyaev:asen/filtering_tests_4.x
GTest filtered list for 4.x
2022-05-12 07:40:06 +00:00
OpenCV Pushbot 280a99b3b6 Merge pull request #21970 from asenyaev:asen/filtering_tests_3.4
GTest filtered list for 3.4 branch
2022-05-12 07:39:05 +00:00
Joona Heikkilä 646025589b Fix global variable assignment in JS test suite
In test_imgproc.js, the test_filter suite's last test assigns a variable
to `size` without declaring it with `let`, polluting the global scope.
This commit adds `let` to the statement, so that the variable is scoped
to the test block.
2022-05-11 23:15:34 +03:00
Andrey Senyaev 4502003e61 GTest filtered list for 4.x 2022-05-11 18:08:44 +03:00
Andrey Senyaev 07abb6240e GTest filtered list 2022-05-11 17:53:40 +03:00
Jan Polák dea0815199 Small imencode documentation improvement
It was previously not clear that the extension should include the period, [and I am not the only person that encountered this problem](https://stackoverflow.com/questions/4254460/opencv-could-not-find-encoder-for-the-specified-extension).

I assume that this is true for all supported extensions, but I haven't checked the source.
2022-05-11 14:57:38 +02:00
hellodoge e4ed2d2e42 fix JpegEncoder::write
3rdparty/libjpeg-turbo/src/jpeglib.h:
`* NB: you must set up the error-manager BEFORE calling jpeg_create_xxx.`
2022-05-11 13:08:02 +03:00
Andrey Senyaev c8228e5789 Merge pull request #21896 from asenyaev:asen/worflow_windows_4.x
Added workflow for Github Actions to build and test OpenCV on Windows for 4.x branch
2022-05-05 08:09:20 +00:00
Vincent Rabaud 667e5e4f89 Merge pull request #21943 from vrabaud:3.4_proc
* Fix compilation with non glibc.

_SC_NPROCESSORS_ONLN is non standard as defined on https://man7.org/linux/man-pages/man3/sysconf.3.html
It seems to only be on glibc, cf https://www.gnu.org/software/libc/manual/html_node/Processor-Resources.html

* Fix to defined(_SC_NPROCESSORS_ONLN)
2022-05-05 07:59:29 +00:00
OpenCV Pushbot ada703a73a Merge pull request #21940 from hakaboom:python_wrap 2022-05-04 09:40:39 +00:00
Christine Poerschke 9e1e960116 imgproc: fix two typos (imput, magnutude) 2022-05-01 19:59:55 +01:00
huangziqing 82ae9ef541 Wrap gpuMat::release to Python 2022-05-02 00:54:17 +08:00
OpenCV Developers 1b07274e34 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-04-30 18:54:20 +00:00
Yulv-git 15ac54d5d6 Fix some typos in modules/. 2022-04-30 13:40:07 +08:00
Yulv-git 1cdd8510fd Fix some typos in doc. 2022-04-30 13:29:25 +08:00
OpenCV Pushbot 039f3d01a0 Merge pull request #21856 from LaurentBerger:I21853
Try to solve I21853 mouse wheel problem with GTK3
2022-04-29 18:18:02 +00:00
OpenCV Pushbot f63feea05e Merge pull request #21920 from asenyaev:asen/contrib_fork_check 2022-04-29 18:14:06 +00:00
OpenCV Pushbot fbac38d98b Merge pull request #21923 from victor1234:calib3d-undistortPoints-R-P-test 2022-04-29 18:12:56 +00:00
LaurentBerger ca2ab3387f Try to solve I21853 mouse wheel problem with GTK3 2022-04-29 08:59:29 +03:00
Zihao Mu 64ded50bbf parsing depth2space and space2depth of ONNX importer 2022-04-29 10:17:02 +08:00
OpenCV Pushbot d44ac61033 Merge pull request #21919 from asmorkalov:as/cuda_buffer_pool_python 2022-04-28 19:11:40 +00:00
Andrey Senyaev 18ada77d8a Merge pull request #21888 from asenyaev:asen/workflow_only_windows_3.4
Added workflow for Github Actions to build and test OpenCV on Windows for 3.4 branch

* Added workflow for Github Actions to build and test OpenCV on Windows

* Updated Github Actions for 3.4 branch on Windows using self-hosted runner

* Fixed url for a fork in Windows workflow (3.4 branch)

* opencv_extra fork usage in Github Actions
2022-04-28 19:07:07 +00:00
Kataev Victor 6d0f1275c2 Add use of R and P parameters to cv::undistortPoints test 2022-04-28 21:47:53 +03:00
Andrey Senyaev a848eccfc6 opencv_contrib fork usage in Github Actions (3.4 branch) 2022-04-28 16:19:00 +03:00
Alexander Smorkalov 2402fa4824 Fix #21894: Wrap constructor to Python to create initialized cuda::BufferPool object. 2022-04-28 12:18:26 +03:00
OpenCV Pushbot 2bf4135afc Merge pull request #21915 from asenyaev:asen/fork_opencv_extra_4_x 2022-04-27 17:26:01 +00:00
OpenCV Pushbot c677f132cd Merge pull request #21914 from asenyaev:asen/fork_opencv_extra 2022-04-27 17:25:30 +00:00
Andrey Senyaev ec4015d73c opencv_extra fork usage in Github Actions (4.x branch) 2022-04-26 14:20:44 +03:00
Andrey Senyaev 8c42dbf71c opencv_extra fork usage in Github Actions 2022-04-26 14:05:21 +03:00
OpenCV Pushbot 4ca679180d Merge pull request #21905 from asenyaev:asen/fix_fork_url_4.x 2022-04-26 05:27:43 +00:00
OpenCV Pushbot 64da959619 Merge pull request #21904 from asenyaev:asen/fix_fork_url 2022-04-25 19:06:52 +00:00
Andrey Senyaev 88123e2512 Fixed url for a fork (4.x branch) 2022-04-24 01:53:53 +03:00
Andrey Senyaev 87e98e8788 Fixed url for a fork 2022-04-24 01:44:15 +03:00
OpenCV Developers 767857c516 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-04-23 19:00:10 +00:00
OpenCV Pushbot 2b60166e5c Merge pull request #21811 from fengyuentau:update_mirrors
Support mirrors for TIM-VX and others 3rdparty components in opencv_contrib
2022-04-22 18:46:23 +00:00
Andrey Senyaev 2e41db39f5 Merge pull request #21876 from asenyaev:asen/workflow_only_linux_4x
Added workflow for Github Actions to build and test OpenCV on Linux for 4.x

* Added workflow for Github Actions to build and test OpenCV

* Merged a build and tests jobs into one, split tests by steps, renamed job names
2022-04-21 15:04:22 +00:00
Andrey Senyaev a55fa8389e Merge pull request #21875 from asenyaev:asen/workflow_only_linux
Added workflow for Github Actions to build and test OpenCV on Linux

* Added workflow for Github Actions to build and test OpenCV

* Merged a build and tests in one job, changed naming

* Renamed job names, split workflows by branch, removed and added some cmake flags, save unit tests results as a html file

* Split tests by steps, removed workflows for 4.x and 5.x branches
2022-04-21 14:59:56 +00:00
fengyuentau d23142027f add mirrors for tim-vx and others in opencv_contrib 2022-04-21 14:48:40 +08:00
rogday 438fe3f9db Merge pull request #21805 from rogday:pretty_fix
Mat pretty printer: fix submatrix indexation

* fix submatrix indexation

* fix channels
2022-04-20 04:55:04 +00:00
Victor 5cc154147f Merge pull request #21841 from victor1234:calib3d-undistortPoints-tests
Add distort/undistort test for fisheye::undistortPoints()

* Add distort/undistort test for fisheye::undistortPoints()

Lack of test has allowed error described in 19138 to be unnoticed.
In addition to random points, four corners and principal center
added to point set

* Add random distortion coefficients set

* Move undistortPoints test to google test, refactor

* Add fisheye::undistortPoints() perf test

* Add negative distortion coefficients to undistortPoints test, increase value

* Move to theRNG()

* Change test check from cvtest::norm(L2) to EXPECT_MAT_NEAR()

* Layout fix

* Add points number parameters, comments
2022-04-19 18:07:34 +00:00
rogday 9cd5a0a1e6 Merge pull request #21884 from rogday:cuda_cleanup
Fix CUDA compilation issues and adjust thresholds.

* Fix CUDA compilation issues and adjust thresholds.

* add conformance tests to denylist
2022-04-19 16:40:25 +00:00
Qingnan Duan 2958142e31 Remove extra not in doc 2022-04-18 14:18:27 +08:00
Victor 27c15bed60 Merge pull request #21834 from victor1234:issue-19138_add_termcriteria_to_fisheye_undistortpoints
* Add termination criteria to cv::fisheye::undistortPoints()

* Add criteria.type check
2022-04-16 17:59:53 +00:00
OpenCV Developers 2985739b8c Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-04-16 14:41:15 +00:00
OpenCV Pushbot 2465d93330 Merge pull request #21873 from asmorkalov:as/jpeg_options
Document defaults for JPEG settings.
2022-04-15 18:49:49 +00:00
OpenCV Pushbot 556d211136 Merge pull request #21864 from rogday:21851_fix 2022-04-15 18:07:38 +00:00
Alexander Smorkalov 0ee2a58cdc Document defaults for JPEG settings. 2022-04-15 14:36:48 +03:00
rogday 7daf84fb44 address security concerns in persistence 2022-04-14 22:18:00 +03:00
OpenCV Pushbot 9aff01c9a9 Merge pull request #21861 from rogday:21852_fix
Add assert to address tf simplifier security concerns
2022-04-14 09:59:44 +00:00
rogday a2b84e9897 add assert to tf graph simplifier to address security concerns 2022-04-13 22:50:27 +03:00
OpenCV Pushbot 66f3c2673c Merge pull request #21831 from zihaomu:sign_layer_onnx
DNN: Add sign, shrink and reciprocal for onnx_impoter
2022-04-13 17:08:30 +00:00
luzpaz 554d08c3a1 Merge pull request #21775 from luzpaz:typos/gapi
* GAPI: fix various gapi related typos

Fixes source comments and documentation related to gapi code.

* Fix source typos

* Fixed typos requested

* Follow-up typo fix
2022-04-13 17:06:37 +00:00
OpenCV Pushbot 3a595ea5c4 Merge pull request #21855 from opencv-pushbot:dnn_test_update_checks_face_detector_3.4 2022-04-12 17:33:13 +00:00
OpenCV Pushbot 03c9648f2e Merge pull request #21854 from opencv-pushbot:dnn_test_update_checks_face_detector_4.x 2022-04-12 17:20:22 +00:00
OpenCV Developers e3a55af336 dnn(test): update opencv_face_detector checks
original commit: be4a432bea
2022-04-11 20:27:06 +00:00
OpenCV Developers be4a432bea dnn(test): update opencv_face_detector checks 2022-04-11 20:26:25 +00:00
lamm45 0d32a24cba Fix some doc references in geometric image transformations module 2022-04-10 13:13:30 -04:00
zihaomu e36948cfbc add ONNX OP sign, shrink and reciprocal 2022-04-07 15:32:12 +08:00
Alexander Alekhin 9aa647068b Merge pull request #21822 from alalek:dnn_test_update_openvino_4.x 2022-04-05 18:08:46 +00:00
Alexander Alekhin 092030c1ca Merge pull request #21819 from alalek:fix_videoio_ffmpeg_memory_leak_4.x 2022-04-05 18:03:59 +00:00
Alexander Alekhin 0bd261ded4 Merge pull request #21820 from alalek:fix_videoio_ffmpeg_memory_leak_3.4 2022-04-05 18:03:27 +00:00
Alexey Smirnov 7ed557497d Merge pull request #21504 from smirnov-alexey:as/oak_infer
[GAPI] Support basic inference in OAK backend

* Combined commit which enables basic inference and other extra capabilities of OAK backend

* Remove unnecessary target options from the cmakelist
2022-04-05 21:00:32 +03:00
eplankin d793ec2ffe Merge pull request #21779 from eplankin:fix_11303
Fixed out-of-bounds read in parallel version of ippGaussianBlur()

* Fixed out-of-memory read in parallel version of ippGaussianBlur()

* Fixed check

* Revert changes in CMakeLists.txt
2022-04-05 15:58:15 +00:00
Alexander Alekhin 271f7df343 videoio(ffmpeg): avoid memory leaks 2022-04-05 15:51:56 +00:00
Alexander Alekhin 08d44f588f dnn(test): update OpenVINO tests 2022.1.0 (OpenCV 4.x) 2022-04-05 14:13:38 +00:00
Alexander Alekhin 84b4a5a495 Merge pull request #21821 from alalek:update_zlib
* 3rdparty: zlib 1.2.11 => 1.2.12

https://github.com/madler/zlib/releases/tag/v1.2.12

* 3rdparty(zlib): re-apply patch 20190330-ununitialized-use-state-check.diff
2022-04-05 14:29:36 +03:00
Alexander Alekhin b2e20a82ba Merge pull request #21812 from cpoerschke:BackgroundSubtractor-getDefaultName 2022-04-04 18:57:00 +00:00
Alexander Alekhin 1b3a06a02a videoio(ffmpeg): avoid memory leaks 2022-04-04 18:52:24 +00:00
Anastasiya(Asya) Pronina 91a5e75151 Merge pull request #21731 from AsyaPronina:asyadev/fix_new_stream_event
Fixed handling of new stream, especially for stateful OCV kernels

* Fixed handling of new stream, especially for stateful OCV kernels

* Removed duplication from StateInitOnce tests

* Addressed review comments for PR #21731
- Fixed explanation comments
- Expanded test for stateful OCV kernels in Regular mode

* Addressed review comments for PR #21731
- Moved notification about new stream to the constructor
- Added test on state reset for Regular mode

* Addresed review comments

* Addressed review comments

Co-authored-by: Ruslan Garnov <ruslan.garnov@intel.com>
2022-04-04 17:39:02 +00:00
Alexander Alekhin 4754b0e253 Merge pull request #21815 from sivanov-work:gapi_fix_ov_warning 2022-04-04 12:20:25 +00:00
sivanov-work 84b517f5a0 Fix warning 2022-04-04 08:25:03 +03:00
Christine Poerschke 8ac88cf069 add BackgroundSubtractor(KNN|MOG2).getDefaultName() implementation 2022-04-03 20:35:55 +01:00
Alexander Alekhin 13a995cc1d Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-04-02 19:45:44 +00:00
Alexander Alekhin a93fb52632 Merge pull request #21795 from alalek:dnn_test_update_openvino_3.4 2022-04-02 19:36:48 +00:00
Alexander Alekhin 4d927e73f1 dnn(test): update OpenVINO tests 2022.1.0 2022-04-02 17:42:53 +00:00
Alexander Alekhin 38228709c8 Merge pull request #21644 from sturkmen72:patch-5 2022-04-01 22:43:33 +00:00
Oguzhan Guclu 38788a3161 Merge pull request #21803 from oguzhanguclu:matches_info_pybinding
python binding for matches and inliers_mask attributes of cv2.detail_MatchesInfo class

* making matches and inliers_mask attributes of cv2.detail_MatchesInfo class accessible from python interface

* binding test for cv2.detail_MatchesInfo class
2022-04-01 22:13:14 +00:00
Alexander Alekhin 46b6973c05 Merge pull request #21798 from gititgo:4.x 2022-04-01 22:11:57 +00:00
Alexander Alekhin af2b7708a8 Merge pull request #21794 from yash112-lang:3.4 2022-04-01 22:10:51 +00:00
Alexander Alekhin a233982931 Merge pull request #20938 from JulieBar:lstm_cuda2 2022-04-01 22:10:08 +00:00
Alexander Alekhin ed1439fbc6 Merge pull request #21754 from mshabunin:fix-ffmpeg5 2022-04-01 18:34:30 +00:00
Yuantao Feng b379b67a32 Merge pull request #21752 from fengyuentau:add_github_actions_for_timvx_backend
CI for TIM-VX backend

* github actions for TIM-VX backend https://github.com/opencv/opencv/pull/21036

* add reference to yuentau/ocv_ubuntu:20.04; remove extra quotes; enable BUILD_TESTS

* rename to timvx_backend_tests.yml

* add image source prefix

* remove if condition for x86_64 simulator
2022-04-01 12:35:12 +00:00
Sergey Ivanov f3945fbddb Merge pull request #21688 from sivanov-work:vpp_ie_integration
G-API: VPP preprocessing GIEBackend integration

* Add ROI in VPP prepro

* Apply comments

* Integration to IE

* Removed extra invocations

* Fix no-vpl compilation

* Fix compilations

* Apply comments

* Use thin wrapper for device & ctx

* Implement Device/Context constructor functions

* Apply samples comment

* Fix compilation

* Fix compilation

* Fix build

* Separate Device&Context from selector, apply other comments

* Fix typo

* Intercept OV exception with pretty print out
2022-04-01 10:06:47 +00:00
shengwenxue 8b44ee2ce1 fix MSA sum overflow issue 2022-04-01 08:37:28 +00:00
Zihao Mu 7b582b71ba Merge pull request #21036 from fengyuentau:timvx_backend_support
dnn: TIM-VX NPU backend support

* Add TimVX NPU backend for DNN module.

* use official branch from tim-vx repo; fix detecting viv sdk

Co-authored-by: fytao <yuantao.feng@outlook.com>
2022-03-31 21:42:11 +00:00
Yash Singhal 4e8c507276 Update Condition
Update connectedcomponents.cpp
2022-03-31 21:03:06 +00:00
Anatoliy Talamanov 9390c56831 Merge pull request #21782 from TolyaTalamanov:at/fix-1d-mat-problems
[G-API] Fix problems with 1D cv::Mat as graph output

* Fix issues with 1D cv::Mat

* Fix cv::Mat::create

* Fix standalone build

* Add test on 1d mat

* Fix warning

* Add additional condition

* Add more tests
2022-03-31 21:00:45 +00:00
Smirnov Egor abebbf04b1 Add CUDA support for LSTM.
Co-authored-by: Julia Bareeva <jbareeva@gmail.com>
2022-03-31 16:38:22 +03:00
Alexander Alekhin 5e434073d4 Merge pull request #21796 from alalek:dnn_reduce_fixup_21601 2022-03-30 22:26:28 +00:00
HAN Liutong 3e4a566e46 Merge pull request #21351 from hanliutong:rvv-clang
* Update universal intrinsics of RVV back-end.

* Use array instead of malloc.
2022-03-30 20:04:34 +00:00
Alexander Alekhin 6f5cf8c15f dnn: fix ReduceLayer implementation, update OpenVINO tests 2022-03-30 20:03:41 +00:00
Alexander Alekhin b687bc807a dnn(test): update OpenVINO tests 2021.4.2 2022-03-30 18:58:35 +00:00
Maksim Shabunin 5440fd6cb4 videoio: initial FFmpeg 5.0 support 2022-03-30 18:15:53 +03:00
Suleyman TURKMEN b060151625 add test (DISABLED_open_from_web) 2022-03-30 15:01:02 +03:00
Anna Khakimova be38d4ea93 Merge pull request #21777 from anna-khakimova:ak/convertto_simd
GAPI Fluid: SIMD for ConvertTo.

* GAPI Fluid: SIMD for convertto.

* Applied comments
2022-03-29 21:14:01 +00:00
Alexander Alekhin 56f21c4fd5 Merge pull request #21785 from alalek:python_fix_subclass_order 2022-03-28 12:16:56 +00:00
Alexander Alekhin 386df457a9 python: ensure publishing of subclasses before derived types 2022-03-27 12:49:22 +00:00
Alexander Alekhin e4abf6e723 Merge pull request #21781 from VadimLevin:dev/vlevin/skip-inline-namespaces 2022-03-26 21:40:45 +00:00
Alexander Alekhin 1339ebaa84 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-03-26 16:00:28 +00:00
Alexander Alekhin c9b90884da Merge pull request #21601 from zihaomu:add_reduceLayer 2022-03-26 10:20:10 +00:00
Alexander Alekhin 9b2b2c88df Merge pull request #21750 from alalek:dnn_fix_index_access 2022-03-25 18:26:10 +00:00
Anna Khakimova e5bdab0355 Merge pull request #21728 from anna-khakimova:ak/resize_f32c1_avx_simd
GAPI Fluid: SIMD AVX2 Resize F32C1.

* GAPI Fluid: Resize F32C1 scalar.

* Final version

* GAPI Fluid: SIMD AVX2 for Resize F32C1.

* Applied comments.

* Deleted warning suppression.

* Applied comments.
2022-03-25 18:11:01 +03:00
Vadim Levin 4d46958c82 fix: inline namespace handling in header parser
`inline namespace` should be skipped in header parser namespaces list.
Example:
```cpp
namespace cv {
inline namespace inlined {
namespace inner {
// content
} // namespace inner
} // namespace inlined
} // namespace cv
```
Before fix `inner` is registered as `cv..inner`
After fix: `cv.inner`
2022-03-25 15:36:31 +03:00
Anatoliy Talamanov 9dd8e4df7f Merge pull request #21719 from TolyaTalamanov:at/pipeline_modeling_tool-skip-frames-for-nodes
[G-API] Pipeline modeling tool: Skip frames

* Add skip feature

* Refactoring

* Fix warning

* Put more comments

* Fix comments to review

* Agregate common params into structure

* Fix warning

* Clean up & add test

* Add assert

* Fix warning on Mac

* Update modules/gapi/samples/pipeline_modeling_tool.cpp

Co-authored-by: Dmitry Matveev <dmitry.matveev@intel.com>
2022-03-25 08:22:45 +00:00
Anatoliy Talamanov d98e07c3d3 Merge pull request #21660 from TolyaTalamanov:at/handle-exception-in-streamingexecutor
[G-API] Handle exceptions in streaming executor

* Handle exceptions in streaming executor

* Rethrow exception in non-streaming executor

* Clean up

* Put more tests

* Handle exceptions in IE backend

* Handle exception in IE callbacks

* Handle exception in GExecutor

* Handle all exceptions in IE backend

* Not only (std::exception& e)

* Fix comments to review

* Handle input exception in generic way

* Fix comment

* Clean up

* Apply review comments

* Put more comments
* Fix alignment
* Move test outside of HAVE_NGRAPH

* Fix compilation
2022-03-25 08:19:53 +00:00
Alexander Alekhin 78bc11465b Merge pull request #21772 from luzpaz:typo/dnn 2022-03-24 16:32:46 +00:00
luz paz 8e8e4bbabc dnn: fix various dnn related typos
Fixes source comments and documentation related to dnn code.
2022-03-23 18:12:12 -04:00
Alexander Alekhin 90671233c6 Merge pull request #21743 from luzpaz:typos 2022-03-23 19:14:03 +00:00
Alexander Alekhin 12bae51384 Merge pull request #21759 from pkubaj:patch-1 2022-03-23 19:13:12 +00:00
Alexander Alekhin 7b848e215f Merge pull request #21764 from alexanderconner:fixes/CameraBridgeViewBase-error-message 2022-03-23 19:11:30 +00:00
Alexander Alekhin 21872e2fb0 Merge pull request #21768 from stal12:4.x 2022-03-23 19:10:19 +00:00
Stefano Allegretti 2a218b96c4 Fix VideoCapture::open() brief description 2022-03-23 15:55:30 +01:00
Alexander Conner e76cda6923 Update CameraBridgeViewBase error message
Update CameraBridgeViewBase error message - Change "you device does" to "your device does"
2022-03-22 15:40:23 -04:00
Alexander Alekhin 9d16612a9b Merge pull request #21756 from komakai:fix-pow 2022-03-22 13:45:35 +00:00
Alexander Alekhin 63c865ace6 Merge pull request #21746 from anna-khakimova:ak/dynamic_dispatch_sub 2022-03-21 17:10:40 +00:00
Alexander Alekhin 0a62de0d4f Merge pull request #21739 from mshabunin:fix-cart-polar 2022-03-21 17:10:11 +00:00
Maksim Shabunin 593996216f cartToPolar/polarToCart: disable inplace mode 2022-03-21 16:06:12 +03:00
Maksim Shabunin 4eae23a2cc ts: fix some EXPECT_MAT macros 2022-03-21 16:06:02 +03:00
pkubaj f3699b5ac8 Fix build with LLVM 13 on ppc64le
/wrkdirs/usr/ports/graphics/opencv/work/opencv-4.5.5/modules/core/include/opencv2/core/vsx_utils.hpp:352:12: warning: 'vec_permi' macro redefined [-Wmacro-redefined]
#   define vec_permi(a, b, c) vec_xxpermdi(b, a, (3 ^ (((c) & 1) << 1 | (c) >> 1)))
           ^
/usr/lib/clang/13.0.0/include/altivec.h:13077:9: note: previous definition is here
#define vec_permi(__a, __b, __c)                                               \
        ^
/wrkdirs/usr/ports/graphics/opencv/work/opencv-4.5.5/modules/core/include/opencv2/core/vsx_utils.hpp:370:25: error: redefinition of 'vec_promote'
VSX_FINLINE(vec_dword2) vec_promote(long long a, int b)
                        ^
/usr/lib/clang/13.0.0/include/altivec.h:14604:1: note: previous definition is here
vec_promote(signed long long __a, int __b) {
^
/wrkdirs/usr/ports/graphics/opencv/work/opencv-4.5.5/modules/core/include/opencv2/core/vsx_utils.hpp:377:26: error: redefinition of 'vec_promote'
VSX_FINLINE(vec_udword2) vec_promote(unsigned long long a, int b)
                         ^
/usr/lib/clang/13.0.0/include/altivec.h:14611:1: note: previous definition is here
vec_promote(unsigned long long __a, int __b) {
^
/wrkdirs/usr/ports/graphics/opencv/work/opencv-4.5.5/modules/core/include/opencv2/core/hal/intrin_vsx.hpp:1045:22: error: call to 'vec_rsqrt' is ambiguous
{ return v_float32x4(vec_rsqrt(x.val)); }
                     ^~~~~~~~~
/usr/lib/clang/13.0.0/include/altivec.h:8472:34: note: candidate function
static vector float __ATTRS_o_ai vec_rsqrt(vector float __a) {
                                 ^
/wrkdirs/usr/ports/graphics/opencv/work/opencv-4.5.5/modules/core/include/opencv2/core/vsx_utils.hpp:362:29: note: candidate function
    VSX_FINLINE(vec_float4) vec_rsqrt(const vec_float4& a)
                            ^
/wrkdirs/usr/ports/graphics/opencv/work/opencv-4.5.5/modules/core/include/opencv2/core/hal/intrin_vsx.hpp:1047:22: error: call to 'vec_rsqrt' is ambiguous
{ return v_float64x2(vec_rsqrt(x.val)); }
                     ^~~~~~~~~
/usr/lib/clang/13.0.0/include/altivec.h:8477:35: note: candidate function
static vector double __ATTRS_o_ai vec_rsqrt(vector double __a) {
                                  ^
/wrkdirs/usr/ports/graphics/opencv/work/opencv-4.5.5/modules/core/include/opencv2/core/vsx_utils.hpp:365:30: note: candidate function
    VSX_FINLINE(vec_double2) vec_rsqrt(const vec_double2& a)
                             ^
1 warning and 4 errors generated.

The specific functions were added to altivec.h in LLVM's 1ff93618e58df210def48d26878c20a1b414d900, c3da07d216dd20fbdb7302fd085c0a59e189ae3d and 10cc5bcd868c433f9a781aef82178b04e98bd098.
2022-03-21 02:05:05 +00:00
Giles Payne 9ce0e51305 Objective-C wrapper header fix-ups to avoid clashes with system macros 2022-03-20 18:47:26 +09:00
Alexander Alekhin 4c79318694 dnn: fix index access 2022-03-19 06:54:07 +00:00
Yuantao Feng f7ac724c5d Merge pull request #21531 from fengyuentau:add_3rdparty_mirrors
Support downloading 3rdparty resources from Gitcode & Gitlab-style mirrors

* replace github.com with gitcode.net for ocv_download

* replace raw.githubusercontent.com with gitcode.net for ocv_download

* rename funtions and remove some comments

* add options for custom mirrors, which simply replace domain github.com & githubusercontent.com

* run ocv_init_download once; replace DL_URL with mirrored one when calling ocv_download

* fix for empty download links when not using mirror

* fix bugs: set(.. .. PARENT_SCOPE) for ocv_init_download; correct macro names for replace github archives and raw githubusercontent

* adjusted mirror swapping impl: replace with mirrored link before each ocv_download; update md5sum for archives

* fix a bug: macro invoked with incorrect arguments by non-set vars

* enclose if statement

* workable impl

* shorten the var names of two key options

* scalable implementation of downloading from mirror and using custom mirror

* improve ocv_init_download help message

* fix the different extracted directory name in case of ADE & TBB which are downloaded from release page

* improve help message printing

* Download ADE & TBB using commit ids instead of from release pages

* support custom mirrors on downloading archives

* improve hints

* add missing parentheses

* reset ocv_download calls

* mirror support implementation using ocv_cmake_hook & ocv_cmake_hook_append

* move ocv_init_download into cmake/OpenCVDownload.cmake

* move ocv_cmake_hook before checking CMake cache

* improve hints when not fetching as git repo

* add WORKING_DIRECTORY  in execute_process in ocv_init_download

* use OPENCV_DOWNLOAD_MIRROR_ID

* add custom.cmake for custom mirror

* detect github origin

* fix broken var name

* download from github by default if custom tbb is set

* add checksum checks for gitcode.cmake before replacing urls and checksums

* add checksum checks for custom.cmake before replacing urls and checkusms

* use description specify instead of set for messages in custom.cmake; use warning message for warnings

* updates and fixes
2022-03-18 09:50:21 +00:00
Anna Khakimova ee9fe1239a GAPI Fluid: Enable dynamic dispatching for the Sub kernel. 2022-03-18 12:34:19 +03:00
Zihao Mu b6b5c27cec Support for some reduce layers for onnx 2022-03-18 10:19:13 +08:00
luz paz 632e07b749 Fix typos in tutorials within docs/
Fix various typos found within tutorial documentation
2022-03-17 16:06:54 -04:00
Anna Khakimova 48cd2d190f Merge pull request #21678 from anna-khakimova:ak/resize_f32c1_scalar
GAPI Fluid: Resize F32C1 scalar version.

* GAPI Fluid: Resize F32C1 scalar.

* Final version

* Applied comments
2022-03-17 19:45:14 +03:00
Alexander Alekhin 685797f403 Merge pull request #21662 from alalek:dnn_split 2022-03-17 16:09:17 +00:00
Pierre Chatelier ef6f421f89 Merge pull request #21677 from chacha21:rectangle_intersection
* better accuracy of _rotatedRectangleIntersection

instead of just migrating to double-precision (which would work), some computations are scaled by a factor that depends on the length of the smallest vectors.
There is a better accuracy even with floats, so this is certainly better for very sensitive cases

* Update intersection.cpp

use L2SQR norm to tune the numeric scale

* Update intersection.cpp

adapt samePointEps with L2 norm

* Update intersection.cpp

move comment

* Update intersection.cpp

fix wrong numericalScalingFactor usage

* added tests

* fixed warnings returned by buildbot

* modifications suggested by reviewer

renaming numericalScaleFctor to normalizationScale
refactor some computations
more "const"

* modifications as suggested by reviewer
2022-03-16 17:46:11 +03:00
Alexander Alekhin e0ffd3e8a5 Merge pull request #21722 from mshabunin:fix-va-link 2022-03-16 09:45:35 +00:00
Maksim Shabunin 0d16b5fc38 Fix libva dynamic loading 2022-03-15 19:08:20 +03:00
Alexander Alekhin ac8a27cba9 Merge pull request #21686 from anna-khakimova:ak/dynamic_disp_add_kernel 2022-03-15 15:28:48 +00:00
Anatoliy Talamanov e5f2a8ebf2 Merge pull request #21636 from TolyaTalamanov:at/gapi_modeling_tool_drop_frames
[G-API] Pipeline modeling tool - support frame dropping for source

* Implement drop frames functionality for dummy src

* Reconsider frame dropping

* Fix comments
2022-03-15 18:27:39 +03:00
Sergey Ivanov 54733eba6f Merge pull request #21687 from sivanov-work:vpp_pp_integr
G-API: Add VPP preproc CPU/GPU dispatcher

* Add VPP preproc acceleration dispatcher & UTs

* Fix compilation

* Apply some comments
2022-03-15 11:01:03 +03:00
rogday 93353aea70 Merge pull request #21522 from rogday:lstm
Fix LSTM support in ONNX

* fix LSTM and add peephole support

* disable old tests

* turn lambdas into functions

* more hacks for  c++98

* add assertions

* slice fixes

* backport of cuda-related fixes

* address review comments
2022-03-15 09:14:05 +03:00
rogday e16cb8b4a2 Merge pull request #21703 from rogday:transpose
Add n-dimensional transpose to core

* add n-dimensional transpose to core

* add performance test, write sequentially and address review comments
2022-03-14 13:10:04 +00:00
Alexander Alekhin 5bf3c1df24 Merge pull request #21715 from ilyachur:change_type_info_creation 2022-03-14 09:18:58 +00:00
Ilya Churaev 419918076e Changed call of NodeTypeInfo constructor 2022-03-14 10:55:33 +03:00
Alexander Alekhin fb768c420d Merge pull request #21710 from alalek:fix_21696 2022-03-13 13:59:03 +00:00
Alexander Alekhin eb067fee55 videoio(ffmpeg): fix memory leak 2022-03-13 04:08:51 +00:00
Pierre Chatelier 6390b50d6e Merge pull request #21701 from chacha21:tiff_10_12_14
Add 10-12-14bit (integer) TIFF decoding support

* Add 12bit (integer) TIFF decoding support

An (slow) unpacking step is inserted when the native bpp is not equal to the dst_bpp

Currently, I do not know if there can be several packing flavours in TIFF data.

* added tests

* move sample files to opencv_extra

* added 10b and 14b unpacking

* fix compilation for non MSVC compilers by using more standard typedefs

* yet another typdef usage change to fix buildbot Mac compilation

* fixed unpacking of partial packets

* fixed warnings returned by buildbot

* modifications as suggested by reviewer
2022-03-11 21:07:12 +03:00
Alexander Alekhin 5d8134ed32 Merge pull request #21684 from vrabaud:34_vec 2022-03-11 18:03:35 +00:00
Alexander Alekhin 852904e1a4 Merge pull request #21669 from rgarnov:rg/cpu_backend_reshape 2022-03-09 17:25:44 +00:00
Alexander Alekhin a120adde63 dnn: add dnn.cpp file with information about git commits history 2022-03-08 19:22:47 +00:00
Alexander Alekhin a80af177b6 dnn: split dnn.cpp code
base commit: 19926e2979
original dnn.cpp content: https://github.com/opencv/opencv/blame/19926e2979ef049a89dd029e2231555db40c2776/modules/dnn/src/dnn.cpp
2022-03-08 19:22:46 +00:00
Tsukasa Sugiura 8db7d435b9 Merge pull request #21692 from UnaNancyOwen:add_softmax
* add apply softmax option to ClassificationModel

* remove default arguments of ClassificationModel::setSoftMax()

* fix build for python

* fix docs warning for setSoftMax()

* add impl for ClassficationModel()

* fix failed build for docs by trailing whitespace

* move to implement classify() to ClassificationModel_Impl

* move to implement softmax() to ClassificationModel_Impl

* remove softmax from public method in ClassificationModel
2022-03-07 20:26:15 +00:00
Alexander Alekhin 901e0ddfe4 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-03-05 19:46:28 +00:00
Ruslan Garnov ecb30409f6 Added reshape() functionality to CPU backend 2022-03-05 14:18:13 +03:00
Sergey Ivanov 44c2c77548 Merge pull request #21658 from sivanov-work:vpp_core_add_roi
G-API: Add ROI processing in VPP preproc

* Add ROI in VPP prepro

* Apply comments
2022-03-05 13:50:40 +03:00
Anna Khakimova 5be5efdacf GAPI Fluid: Dynamic dispatching for Add kernel. 2022-03-05 00:18:29 +03:00
Vincent Rabaud 057c3da82a Allow Matx static function to work with Vec. 2022-03-04 14:06:20 +01:00
Alexander Alekhin 8fa429caef Merge pull request #21674 from jeremyephron:patch-1 2022-03-04 09:50:29 +00:00
Alexander Alekhin 87f526d82f Merge pull request #21676 from masa-iwm:fix-convertFromD3D11Texture2D 2022-03-03 08:46:46 +00:00
masa-iwm 1ae2320e09 bugfix convertFromD3D11Texture2D 2022-03-03 07:21:53 +09:00
Jeremy Ephron 54693cf7b1 Update stitching_detailed.py
###  Critical bugs fixed:
- `seam_finder.find()` returns None and overwrites `masks_warped`
- `indices` is only 1-dimensional

### Nice-to-have bugs fixed:
- avoid invalid value in sqrt and subsequent runtime warning
- avoid printing help string on each run (use argparse builtin behavior)

### New features:
- added graphcut seam finder support

### Test Summary:
Tested on Ubuntu 20.04 with python 3.8.10 and opencv-python-contrib 4.5.5.62
2022-03-02 11:01:53 -08:00
Alexander Alekhin a082375d57 Merge pull request #21488 from VadimLevin:dev/vlevin/scope-for-classes 2022-03-02 18:44:00 +00:00
Anna Khakimova 9c7adb7248 Merge pull request #21530 from anna-khakimova:ak/simd_divrc
* GAPI Fluid: SIMD for DivRC kernel.

* Fluid: Div kernel's SIMD refactoring

* SIMD for DivRC 3 channel case

* Applied comments
2022-03-02 13:36:16 +00:00
Vadim Levin ccebbbc0ac feature: submodule or a class scope for exported classes
All classes are registered in the scope that corresponds to C++
namespace or exported class.

Example:
`cv::ml::Boost` is exported as `cv.ml.Boost`
`cv::SimpleBlobDetector::Params` is exported as
`cv.SimpleBlobDetector.Params`

For backward compatibility all classes are registered in the global
module with their mangling name containing scope information.
Example:
`cv::ml::Boost` has `cv.ml_Boost` alias to `cv.ml.Boost` type
2022-03-02 14:30:52 +03:00
Pierre Chatelier ebb6915e58 Merge pull request #21645 from chacha21:applyColorMap_8UC1_optimized
Optimize cv::applyColorMap() for simple case

* Optimize cv::applyColorMap() for simple case

PR for 21640
For regular cv::Mat CV_8UC1 src, applying the colormap is simpler than calling the cv::LUT() mechanism.

* add support for src as CV_8UC3

src as CV_8UC3 is handled with a BGR2GRAY conversion, the same optimized code being used afterwards

* code style

rely on cv::Mat.ptr() to index data

* Move new implementation to ColorMap::operator()

Changes as suggested by reviewer

* style

improvements suggsted by reviewer

* typo

* tune parallel work

* better usage of parallel_for_

use nstripes parameter of parallel_for_
assume _lut is continuous to bring faster pixel indexing
optimize src/dst access by contiguous rows of pixels
do not locally copy the LUT any more, it is no more relevant with the new optimizations
2022-03-01 19:55:00 +03:00
Alexander Alekhin 5cc27fd3b5 Merge pull request #21542 from rogday:split_expand 2022-02-28 22:38:24 +00:00
Sinitsina Maria a332509e02 Merge pull request #21458 from SinM9:speech_recognition_cpp
AudioIO: add dnn speech recognition sample on C++

* add speech recognition cpp

* fix warnings

* fixes

* fix warning

* microphone fix
2022-02-28 18:23:00 +03:00
Egor Smirnov 375fe81311 fix slice and expand 2022-02-28 17:18:07 +03:00
Tatsuro Shibamura d354ad1c34 Merge pull request #21630 from shibayan:arm64-msvc-neon
* Added NEON support in builds for Windows on ARM

* Fixed `HAVE_CPU_NEON_SUPPORT` display broken during compiler test

* Fixed a build error prior to Visual Studio 2022
2022-02-26 17:35:03 +00:00
Vadim Levin 119d8b3aca Merge pull request #21553 from VadimLevin:dev/vlevin/scope-for-classes-4x-port
4.x: submodule or a class scope for exported classes

* feature: submodule or a class scope for exported classes

All classes are registered in the scope that corresponds to C++
namespace or exported class.

Example:
`cv::ml::Boost` is exported as `cv.ml.Boost`
`cv::SimpleBlobDetector::Params` is exported as
`cv.SimpleBlobDetector.Params`

For backward compatibility all classes are registered in the global
module with their mangling name containing scope information.
Example:
`cv::ml::Boost` has `cv.ml_Boost` alias to `cv.ml.Boost` type

* refactor: remove redundant GAPI aliases

* fix: use explicit string literals in CVPY_TYPE macro

* fix: add handling for class aliases
2022-02-25 01:17:43 +03:00
Alexander Alekhin cd9edba26f Merge pull request #21625 from hanliutong:rvv1p0 2022-02-24 12:08:55 +00:00
Sergey Ivanov 8f1c502d2b Merge pull request #21618 from sivanov-work:vpp_preproc_core
G-API: Add VPL/VPP preproc core module

* Add BaseMediAdapter for VPL

* Add PreprocSession & PreprocEngine interface part

* Implement preproc UT, Fix base path

* Add common PP interface, add common pp_params

* Rough decoupling VPL & Preproc

* Add syntax sugar for PP interface

* Integrate VPP preproc in GIEbackend

* Add PP bypass

* Add perf tests for PP

* Fix warning in vpl core UT

* Add inner preproc resolution Unit Test

* Remove VPP preproc description from single ROI sample

* Apply SetROIBlob for diferent Infer operations

* Eliminate extra branch-lines for cfg_param_parser & transcode_engine

* Fix UT warning &PreprocSession compile

* Fix compilation & warnings

* Reduce Session&Engine code amount

* Apply some comments

* Revert IE changes, rename preproc

* Fix for DX11 infer for OV: turn off texture array

* Remove dependency PP on IE

* Change fixture tests params

* Apply other comments & turn off ROI for GPU

* Fix compilation: remove forgotten INFER define

* Apply debt comments

* Fix PP UTs: add FrameInfo value comparator

* Fix style

* Remove standalone map for preproc frames storage

* Add other comments
2022-02-24 10:35:52 +00:00
Alexander Alekhin 92312fbc0c Merge pull request #21613 from YusukeKameda:patch-1 2022-02-22 19:23:32 +00:00
Alexander Alekhin 2efcaa9e8e Merge pull request #21534 from alexgiving:atrutnev/simd_for_merge4 2022-02-21 22:17:17 +00:00
Aleksei Trutnev aa53541235 enable dynamic dispatching for merge4 2022-02-22 00:13:22 +03:00
Alexander Alekhin b863c25d21 Merge pull request #21646 from zchrissirhcz:seamless_cloning-remove-const 2022-02-21 16:34:10 +00:00
Yuantao Feng f77c3574af Merge pull request #21607 from fengyuentau:fix_FaceDetectorYN_dynamic_shape
Use YuNet of fixed input shape to fix not-supported-dynamic-zero-shape for FaceDetectorYN

* use yunet with input of fixed shape

* update yunet used in face recognition regression
2022-02-21 13:49:07 +00:00
Zhuo Zhang f5105bac65 remove const in seamless_cloding APIs for better semantics 2022-02-21 20:39:41 +08:00
Alexander Alekhin 5a86592e93 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-02-19 21:04:35 +00:00
Alexander Alekhin 2c83cfc14c Merge pull request #21639 from georgthegreat:patch-1 2022-02-19 20:58:57 +00:00
Alexander Alekhin 863546e125 Merge pull request #21598 from KaurkerDevourer:patch-1 2022-02-19 20:58:35 +00:00
KaurkerDevourer 9198e30688 Fix DpSeamFinder::hasOnlyOneNeighbor
std::lower_bound is linear for set
https://en.cppreference.com/w/cpp/algorithm/lower_bound
2022-02-19 14:24:05 +03:00
Artem Saratovtsev 1890157faa Merge pull request #21635 from DumDereDum:issue_21595_3.4
Issue 21595 fix 3.4 branch

* bug fix; add test

* rewrite tests avoiding vector in tests
2022-02-18 14:58:58 +00:00
Yuriy Chernyshov 0898f372b1 Аix -Winvalid-noreturn under clang-cl 2022-02-18 17:57:46 +03:00
Alexander Alekhin b9e5256cf9 Merge pull request #21628 from anna-khakimova:ak/resize_fix_32bit_builds 2022-02-17 12:16:06 +00:00
Anna Khakimova 6b6d89b911 GAPI Fluid: Fix for 32bit build issue. 2022-02-17 13:13:02 +03:00
Alexander Alekhin d3e0193c8a Merge pull request #21602 from paroj:hidpi 2022-02-16 18:37:15 +00:00
Alexander Alekhin 31881209d6 Merge pull request #21626 from anna-khakimova:ak/workaround_for_16s 2022-02-16 17:47:48 +00:00
Alexander Alekhin 5c7e893393 Merge pull request #21529 from alexgiving:atrutnev/simd_for_merge3 2022-02-16 17:45:19 +00:00
Anna Khakimova 3c814ebf87 GAPI Perf Tests:Workaround for the OpenCV's issue. 2022-02-16 14:22:04 +03:00
Alexander Alekhin 5cf1dca36e Merge pull request #21612 from seanm:tsan-call-once 2022-02-16 09:57:25 +00:00
HAN Liutong 12338c1dc4 Update clang toolchain for RVV. 2022-02-16 16:01:38 +08:00
Sean McBride 5b23752205 Replaced incorrect double checked locking with a static
Thread Sanitizer identified an incorrect implementation of double checked locking.

Replaced it with a static, which therefore can only be created once.
2022-02-15 14:24:21 -05:00
Alexander Alekhin 4e53f301d8 Merge pull request #21622 from alalek:imgcodecs_checks_3.4 2022-02-15 18:19:51 +00:00
Alexander Alekhin 2b7803dbac imgcodecs: add runtime checks to validate input
backport of commit: f9b1dbe2ac
2022-02-15 16:33:35 +00:00
Alexander Alekhin 446a278f3d Merge pull request #21620 from alalek:imgcodecs_checks 2022-02-15 16:30:47 +00:00
Alexander Alekhin 0047d3f81a Merge pull request #21614 from alalek:fix_build_power8_vec_absd 2022-02-15 15:31:23 +00:00
Alexander Alekhin 4e1f17d65b Merge pull request #21617 from mshabunin:disable-onnx-tests-34 2022-02-15 13:11:59 +00:00
Alexander Alekhin f9b1dbe2ac imgcodecs: add runtime checks to validate input 2022-02-15 11:48:09 +00:00
Maksim Shabunin a251474144 Update filters in ONNX tests 2022-02-15 11:56:28 +03:00
Alexander Alekhin 8d88bb06b2 core(vsx): update vec_absd() workaround condition 2022-02-15 07:26:40 +03:00
Alexander Alekhin 9f2ff3ed22 Merge pull request #21609 from mshabunin:disable-onnx-tests 2022-02-14 15:53:24 +00:00
Maksim Shabunin 45cbf70265 Update filters in ONNX tests 2022-02-14 17:16:49 +03:00
Alexander Alekhin 59e16b88ae Merge pull request #21606 from sturkmen72:hog_update 2022-02-14 14:14:30 +00:00
Yusuke Kameda 33f219dfe6 Incorrect kernel matrix size when Scharr
Incorrect Mat size ksize==-1
2022-02-14 19:31:45 +09:00
Suleyman TURKMEN 44db2eea70 update HOGDescriptor documentation 2022-02-13 23:54:27 +03:00
Pavel Rojtberg 12ab54648c highui: qt - enable hidpi by default
can be overriden by environment:
QT_AUTO_SCREEN_SCALE_FACTOR=0
2022-02-12 14:56:42 +01:00
Alexander Alekhin 19926e2979 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-02-11 17:32:37 +00:00
Alexander Alekhin 1620a1e014 Merge pull request #21599 from alalek:winpack_dldt_force_cmake_config 2022-02-11 16:46:55 +00:00
Alexander Alekhin 888546b6f5 build(winpack_dldt): force using CMake config for InferenceEngine 2022-02-11 13:07:25 +00:00
Alexander Alekhin 3215db26aa Merge pull request #21591 from alalek:dnn_drop_legacy_ie 2022-02-10 21:47:30 +00:00
cudawarped 76aff84788 Merge pull request #21561 from cudawarped:ffmpeg_prefer_tcp_default
Default FFMPEG VideoCapture backend to rtsp_flags=prefer_tcp

* Make the VideoCapture ffmpeg backends default rtsp connection type prefer_tcp.

* Ensure that the ffmpeg version of avformat is checked.
2022-02-10 19:45:34 +03:00
Vincent Rabaud fc28ba3156 Merge pull request #21594 from vrabaud:3.4_msan
* Fix harmless MSAN error.

This is similar to https://github.com/opencv/opencv/pull/21527
A macro is also created to simplify the code.

* Declare fallback only once.
2022-02-10 19:44:14 +03:00
Alexander Alekhin effce0573b dnn: drop legacy Inference Engine NN builder API 2022-02-10 11:55:24 +00:00
Alexander Alekhin e8db363431 Merge pull request #21590 from berak:patch-1 2022-02-09 18:49:41 +00:00
Alexander Alekhin 9603b6877d Merge pull request #21582 from gfiumara:3.4 2022-02-09 18:49:24 +00:00
Sergey Ivanov d5ecb5ff5a Merge pull request #21567 from sivanov-work:gapi_streaming_fix
G-API: Fix streaming hangs for ConstSource & Improve troubleshooting logger messages
2022-02-09 18:48:06 +00:00
Greg Fiumara dae73938e8 Fix cv::FileStorage::Mode::Memory doxygen layout 2022-02-09 12:24:50 -05:00
Anatoliy Talamanov 619b6dfae3 Merge pull request #21579 from TolyaTalamanov:at/handle-errors-in-iebackend
[G-API] Handle errors in IEBackend & modeling tool

* Handle errors in IEBackend & modeling tool

* Handle exceptions in callback

* Add const cv to exception
2022-02-09 16:52:23 +00:00
berak 8f9c36b730 Update text_detection.py
there is a recent change, how `std::vector<int>` is wrapped in python, 
it used to be a 2d array (requirig that weird `[0]` indexing), now it is only 1d
2022-02-09 17:14:05 +01:00
Dmitry Budnikov 3eeec4faae Merge pull request #21560 from dbudniko:dbudniko/gapi_media_format_gray_plus_gst_source
G-API gst source gray support
2022-02-08 16:51:53 +03:00
Alexander Alekhin 972a4b95b6 Merge pull request #21577 from sturkmen72:upd_floodfill 2022-02-08 13:30:29 +00:00
Suleyman TURKMEN ffee1a4126 fix cv::floodfill() for calling it with an empty mask 2022-02-08 15:28:19 +03:00
Alexander Alekhin 96e23c2ff6 Merge pull request #21573 from lamm45:lineiterator-doc 2022-02-07 17:55:12 +00:00
Anatoliy Talamanov 08356007c9 Merge pull request #21566 from TolyaTalamanov:at/gapi-modeling-tool_fix_handling_fp16_precision
[G-API] Pipeline modeling tool - Fix generating FP16 Mat

* Fix handling fp16 precision

* Disable preproc in case FP16 input inside IE backend

* Fix isApplicableForResize function
2022-02-07 16:48:43 +00:00
lamm45 5064b6f747 Update LineIterator documentation 2022-02-06 18:42:26 -05:00
Alexander Alekhin 57d3002ee1 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-02-06 16:10:43 +00:00
Alexander Alekhin a00a0dbfcd Merge pull request #21564 from alalek:dnn_fix_openvino_outputs 2022-02-06 16:06:23 +00:00
Alexander Alekhin b41d2c5c14 Merge pull request #21569 from alalek:fixup_18031 2022-02-06 16:04:38 +00:00
Alexander Alekhin 1da48beeec dnn(ngraph): fix output names 2022-02-06 13:08:53 +00:00
Alexander Alekhin b57ff73086 dnn(ngraph): fix outputs handling, drop 'unconnected' logic 2022-02-06 13:08:53 +00:00
Alexander Alekhin 67978b5746 dnn(ngraph): add debuging messages 2022-02-06 13:08:53 +00:00
Alexander Alekhin 062f305d1a dnn: don't fuse 'outputs' with OpenVINO backend 2022-02-06 13:08:53 +00:00
Alexander Alekhin 1f70d4e2a5 dnn(test): re-enable ONNX split tests for OpenVINO 2022-02-06 10:36:15 +00:00
Alexander Alekhin aa5bc20c83 dnn(ngraph): fixup get_output_as_single_output_node() replacement patch 2022-02-06 10:35:59 +00:00
Alexander Alekhin 09af10f635 Merge pull request #21562 from alalek:cmake_carotene_use_cv_disable_optimization 2022-02-03 19:18:26 +00:00
Alexander Alekhin 4d7953aa56 cmake(carotene): disable with CV_DISABLE_OPTIMIZATION 2022-02-03 17:25:52 +00:00
Alexander Alekhin 46e1560678 Merge pull request #21555 from cudawarped:fix_gpumat_dataend_bug 2022-02-03 12:28:49 +00:00
Dmitry Budnikov 4d0148b417 Merge pull request #21511 from dbudniko:dbudniko/gapi_media_format_gray
G-API media format gray
2022-02-03 15:20:21 +03:00
Anna Khakimova 1605d1d24d Merge pull request #21474 from anna-khakimova:ak/simd_for_divc
GAPI Fluid: SIMD for DivC kernel.

* GAPI Fluid:SIMD for DivC

* Applied comment
2022-02-02 18:47:01 +00:00
Alexander Alekhin 5190043e56 Merge pull request #21551 from alalek:cmake_dnn_backport_3.4 2022-02-02 18:04:51 +00:00
cudawarped f66a2ffa1e Fix GpuMat to correctly calculate dataend when using GpuMat::create().
Add output to createMat() to be used by locateROI test cases.
2022-02-02 14:25:46 +00:00
Maksim Shabunin d1e76a34a0 3.4: Use modern OpenVINO package interface
original commit: 437af37b13
2022-02-02 09:04:03 +00:00
Ilya Lavrenov 5b3d5f9f3c 3.4: Support of OpenVINO interface libraries
original commit: c703f1eed6
2022-02-02 08:57:56 +00:00
Alexander Alekhin 415a42f327 Merge pull request #21452 from mshabunin:ov-pkg 2022-02-01 18:59:59 +00:00
Alexander Alekhin 09f6e55338 Merge pull request #21547 from mshabunin:plugin-link 2022-02-01 17:01:36 +00:00
Alexander Alekhin a351e05a17 Merge pull request #21538 from edman007:fixup-21536 2022-02-01 17:01:16 +00:00
Lukas-Alexander Weber d37bcbdc92 Merge pull request #21420 from lukasalexanderweber:4.x
Introduce Cropping to OpenCV Stitching Tool

* Introduced Cropping

* integrate https://github.com/opencv/opencv/pull/21413/

* fixed failing subsetter tests

* updated stuff
2022-02-01 16:56:44 +00:00
Maksim Shabunin 437af37b13 Use modern OpenVINO package interface 2022-02-01 16:52:17 +00:00
Aleksei Trutnev c62367612d Enable dynamic dispatching for Merge3 2022-02-01 16:40:20 +03:00
Anatoliy Talamanov a92cba8484 Merge pull request #21477 from TolyaTalamanov:at/pipeline-builder-tool
[G-API] Implement G-API pipeline modeling tool

* Implement G-API pipeline builder tool

* Remove whitespaces from config

* Remove unused unittest stuff

* Fix comments to review

* Fix MAC warning

* Rename to pipeline_modeling_tool

* Move to opencv apps

* Move config to gapi/samples/data

* gapi: samples sources are installed automatically
2022-02-01 16:32:56 +03:00
Maksim Shabunin 5f7d922b10 Option to enable/disable plugin linking with OpenCV 2022-02-01 14:53:15 +03:00
Ed Martin dc29632d4e Fallback to vaCreateImage + vaPutImage/vaGetImage when vaDeriveImage fails
Per intel docs for libva, when vaDeriveImage fails vaCreateImage +
  vaPutImage should be tried. This is important as mesa with AMD HW
  will always fail because the image is interlaced so a indirect
  method must be used to get the surface to/from and image

Fixes https://github.com/opencv/opencv/issues/21536
2022-01-31 17:12:37 -05:00
Harvey f4a7754cc0 Merge pull request #21428 from Harvey-Huang:TIFF
TiffEncoder write support more depth type

* TiffEncoder write support more depth type

* testing code

* update testing code

* add fallthrough
2022-01-31 17:54:27 +00:00
Alexander Alekhin 6811d3d80b Merge pull request #21508 from tailsu:sd/fix-zlib-png-android 2022-01-31 17:51:23 +00:00
Trutnev Aleksei 245f6273bd Merge pull request #21520 from alexgiving:atrutnev/simd_for_split4
GAPI FLUID: Enable dynamic dispatching for Split4

* Enable dynamic dispatching for split4

* Add tail proc for split3 and split4
2022-01-31 17:45:56 +00:00
Alexander Alekhin 870c8d3c4e dnn(test): fix int8 tolerances 2022-01-31 12:54:01 +00:00
Alexander Alekhin d573472a86 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-01-31 12:53:45 +00:00
Alexander Alekhin 441b6dbda0 Merge pull request #21540 from alalek:dnn_support_outputs_registration_3.4 2022-01-31 12:46:14 +00:00
Alexander Alekhin a7e6a1059c dnn(test): fix outputs handling in ONNX conformance
- ONNX output is 1 tensor per defined output instead of N tensors from outputs of "output" layer
2022-01-29 23:29:51 +00:00
Alexander Alekhin 85719a0a5d dnn: support outputs registration under new names
- fixed ONNX importer
2022-01-29 23:29:51 +00:00
Vincent Rabaud b5b52afd35 Merge pull request #21527 from vrabaud:3.4_msan
* Fix wrong MSAN errors.

Because Fortran is called in Lapack, MSAN does not think the memory
has been written even though it is the case.
MSAN does no support well cross-language memory analysis.

* Make a dedicated check.
2022-01-28 15:35:47 +00:00
Alexander Alekhin dc35633aa4 Merge pull request #21521 from alalek:dnn_ignore_denormals 2022-01-28 15:31:44 +00:00
Zihao Mu 9e3ba487fa Merge pull request #21518 from zihaomu:resize_onnx_opset13
Add resize layer compatible with ONNX opset13 version
2022-01-28 17:55:01 +03:00
Alexander Alekhin aee8425b68 Merge pull request #21533 from alexgiving:atrutnev/tolerance_for_divc_kernel 2022-01-28 13:11:22 +00:00
Aleksei Trutnev 94229bb262 tolerance for divc 2022-01-28 17:12:20 +03:00
Alexander Alekhin 1f6444fbea Merge pull request #21528 from sturkmen72:patch-5 2022-01-28 12:52:25 +00:00
Suleyman TURKMEN 439ef6447d Update window.cpp 2022-01-28 10:20:36 +03:00
Trutnev Aleksei 9cab808c5d Merge pull request #21475 from alexgiving:atrutnev/fix_tests
GAPI: Replace resize perf test to imgproc

* resize + test configs

* fluid kernel "add"

* Add fluid core
2022-01-27 12:27:41 +00:00
Alexander Alekhin d41fcf7345 Merge pull request #21489 from VadimLevin:dev/vlevin/pysubmodules-initialization-fix-backport 2022-01-27 10:16:13 +00:00
Alexander Alekhin ac51ba38f9 Merge pull request #21525 from VadimLevin:dev/vlevin/pysubmodules-refcounter-fix 2022-01-27 10:15:21 +00:00
Vadim Levin ef85b24a78 fix: wrong reference counter after module initialization 2022-01-27 12:05:06 +03:00
Vadim Levin d88730685e fix: submodules creation and registration
- Add special case handling when submodule has the same name as parent
- `PyDict_SetItemString` doesn't steal reference, so reference count
  should be explicitly decremented to transfer object life-time
  ownership
- Add sanity checks for module registration input
- Add Python 2 and Python 3 reference counting handling
2022-01-27 11:06:06 +03:00
Alexander Alekhin 16661847a7 Merge pull request #21517 from alalek:cmake_dont_force_werror 2022-01-26 17:51:52 +00:00
Alexander Alekhin 7f782a1a24 Merge pull request #21499 from sturkmen72:update_documentation 2022-01-26 17:37:51 +00:00
Alexander Alekhin 9188ce68aa Merge pull request #21490 from rogday:optional_outputs 2022-01-26 15:18:07 +00:00
Anatoliy Talamanov 2b79a6ff8f Merge pull request #20832 from TolyaTalamanov:at/python-gstreamer-source
G-API: Wrap GStreamerSource

* Wrap GStreamerSource into python

* Fixed test skipping when can't make Gst-src

* Wrapped GStreamerPipeline class, added dummy test for it

* Fix no_gst testing

* Changed wrap for GStreamerPipeline::getStreamingSource() : now python-specific in-class method GStreamerPipeline::get_streaming_source()

* Added accuracy tests vs OCV:VideoCapture(Gstreamer)

* Add skipping when can't use VideoCapture(GSTREAMER);
Add better handling of GStreamer backend unavailable;
Changed video to avoid terminations

* Applying comments

* back to a separate get_streaming_source function, with comment

Co-authored-by: OrestChura <orest.chura@intel.com>
2022-01-26 14:01:13 +00:00
Alexander Alekhin 70b0274c8e dnn: apply hint to ignore denormals processing 2022-01-26 11:28:35 +00:00
Alexander Alekhin 83ce1de8e7 Merge pull request #21506 from alalek:core_fp_denormals 2022-01-26 08:52:27 +00:00
Alexander Alekhin b1d484f827 core(parallel): propagate FP denormals mode 2022-01-26 05:19:02 +00:00
Alexander Alekhin 123519165d core: FP denormals hints support 2022-01-26 05:19:02 +00:00
Alexander Alekhin 30ff9c6775 cmake: don't force -Werror=...
- improve compatibility with further compiler versions
- warnings are not errors by default
2022-01-26 04:34:51 +00:00
Alexander Alekhin 906f5f7e96 Merge pull request #21514 from pkubaj:patch-1 2022-01-25 18:44:26 +00:00
Alexander Alekhin 9238316cf1 Merge pull request #21441 from alexgiving:atrutnev/split3_simd_fluid 2022-01-25 15:00:54 +00:00
Aleksei Trutnev 5e89b9a455 Dynamic Dispatching for split3 2022-01-25 18:13:30 +03:00
Alexander Alekhin e3a4ff33d2 Merge pull request #21512 from vrabaud:3.4_ub_drawing 2022-01-25 13:42:49 +00:00
pkubaj 5d9ea394ba Fix VSX detection on FreeBSD
hwcap should actually be long.
2022-01-25 13:35:22 +00:00
Vincent Rabaud abb5c9fd92 Fix undefined behavior in line drawing.
Left shift of negative values is undefined.
2022-01-25 11:37:39 +01:00
Sergey Ivanov 266835cd2e Merge pull request #21232 from sivanov-work:vpl_gpu_remote_infer
G-API: oneVPL DX11 inference

* Draft GPU infer

* Fix incorrect subresource_id for array of textures

* Fix for TheOneSurface in different Frames

* Turn on VPP param configuration

* Add cropIn params

* Remove infer sync sample

* Remove comments

* Remove DX11AllocResource extra init

* Add condition for NV12 processing in giebackend

* Add VPP frames pool param configurable

* -M Remove extra WARN & INFOs, Fix custom MAC

* Remove global vars from example, Fix some comments, Disable blobParam due to OV issue

* Conflict resolving

* Revert back pointer cast for cv::any
2022-01-24 17:05:26 +03:00
Alexander Alekhin 92af03579c Merge pull request #21501 from sturkmen72:update_samples 2022-01-24 14:04:14 +00:00
Stefan Dragnev 2e20f2b89f android: set all zlib variables used by downstream packages 2022-01-24 13:52:23 +01:00
Alexander Alekhin e67593673f Merge pull request #21505 from georgthegreat:patch-1 2022-01-24 12:35:54 +00:00
Yuriy Chernyshov d1b533d399 Disable -Wreturn-type-c-linkage under clang-cl
clang-cl defines both __clang__ and _MSC_VER, yet uses `#pragma GCC` to disable certain diagnostics.

At the time `-Wreturn-type-c-linkage` was reported by clang-cl.
This PR fixes this behavior by reordering defines.
2022-01-24 11:42:02 +03:00
Suleyman TURKMEN 2647902fee Update python samples 2022-01-24 11:13:56 +03:00
David Fan 574320ec3f Merge pull request #21500 from Kanaderu:fix-gst-audio-win
videoio: added explicit gst-audio dependency for windows

* Update detect_gstreamer.cmake

videoio: added explicit gst-audio dependency for win32

* Fixed whitespace
2022-01-23 17:02:14 +03:00
Alexander Alekhin 3f2377017c Merge pull request #21497 from alalek:fix_build_gcc12_3.4 2022-01-23 14:00:55 +00:00
Suleyman TURKMEN 2b5bb02817 Update imgcodecs.hpp 2022-01-23 01:24:34 +03:00
Alexander Alekhin 302d14adef build: fix GCC12 compilation 2022-01-22 11:48:44 +00:00
Alexander Alekhin b796ededae Merge pull request #21437 from alalek:dnn_api_explicit_const_4.x 2022-01-21 20:19:50 +00:00
Alexander Alekhin f811ba8777 Merge pull request #21429 from alalek:dnn_api_explicit_const_3.4 2022-01-21 20:04:58 +00:00
Alexander Alekhin eb7b45d26b dnn: fix API - explicit ctors, const methods 2022-01-21 12:38:51 +00:00
Smirnov Egor 17b2d92a3d add optional outputs support and fix graph links 2022-01-21 12:31:46 +03:00
Alexander Alekhin 22f0bcaf8f Merge pull request #21453 from sturkmen72:bigtiff 2022-01-20 20:00:29 +00:00
Alexander Alekhin e61277002c Merge pull request #21349 from alalek:cmake_link_no_undefined 2022-01-20 19:56:17 +00:00
Alexander Alekhin ca5258f140 Merge pull request #21483 from alalek:cmake_highgui_opengl_update_3.4 2022-01-20 14:37:09 +00:00
Alexander Alekhin 8f4473b3e3 Merge pull request #21478 from VadimLevin:dev/vlevin/pysubmodules-initialization-fix 2022-01-20 10:08:00 +00:00
Alexander Alekhin 51e8af9e5f cmake(link): add '-Wl,--no-undefined'
- avoid missing of necessary library dependencies
2022-01-20 02:36:02 +00:00
Alexander Alekhin 82818e7324 cmake(highgui): update handling of OpenGL libraries 2022-01-20 02:31:15 +00:00
Alexander Alekhin 6ae8103022 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-01-19 19:29:58 +00:00
Vadim Levin eca2d92791 fix: submodules creation and registration
- Add special case handling when submodule has the same name as parent
- `PyDict_SetItemString` doesn't steal reference, so reference count
  should be explicitly decremented to transfer object life-time
  ownership
- Add sanity checks for module registration input
2022-01-19 18:06:58 +03:00
Maxim Pashchenkov 6778e19710 Merge pull request #21362 from mpashchenkov:mp/ocv-gapi-suppress-warn
G-API: Suppress ngraph warnings for MSVS2015 (4268)

* 4268 are suppressed

* 1900-->>1910 (v140)

* Two more warnings from ngraph include
2022-01-19 11:40:36 +00:00
Alexander Alekhin 25f25275cd Merge pull request #21468 from VadimLevin:dev/vlevin/handle-pymodule-add-object-result 2022-01-19 11:27:06 +00:00
Alexander Alekhin 7e746ad2a6 Merge pull request #21454 from sturkmen72:update_templates 2022-01-19 11:26:42 +00:00
Alexander Alekhin 6ffa2b01e1 Merge pull request #21357 from rogday:model_diag 2022-01-18 15:50:11 +00:00
Tsukasa Sugiura ed6ca0d7fa Merge pull request #21369 from UnaNancyOwen:fix_uwp
Fix support objdetect module for UWP

* Fix support objdetect module for UWP

* Fix define module for objdetect

* Remove conditional compilation from public headers

* Add StsNotImplemented for FaceDetectorYN/FaceRecognizerSF

* Fix typo error message

* Fix error message

* coding style, eliminate warnings
2022-01-18 18:47:36 +03:00
Alexander Alekhin 8e2a3c1d2f Merge pull request #21470 from alalek:winpack_dldt_fix_21469 2022-01-18 11:06:00 +00:00
Alexander Alekhin 7f6dcc2745 Merge pull request #21467 from alalek:issue_21448 2022-01-18 09:55:13 +00:00
Vadim Levin 76e34d6f2c fix: handle possible PyModule_AddObject failure
Comment from Python documentation:
Unlike other functions that steal references, `PyModule_AddObject()` only
decrements the reference count of value on success.
This means that its return value must be checked, and calling code must
`Py_DECREF()` value manually on error.
2022-01-18 11:38:33 +03:00
Alexander Alekhin e613b17c05 build(winpack_dldt): repair build with MSVS 2019 (16.11.9) 2022-01-18 08:20:54 +00:00
Alexander Alekhin 5ba9a089e1 core(persistence): avoid NULL pointer dereference 2022-01-18 04:56:43 +00:00
Alexey Smirnov f2d5d6d24e Merge pull request #20785 from smirnov-alexey:as/oak_backend
GAPI: Add OAK backend

* Initial tests and cmake integration

* Add a public header and change tests

* Stub initial empty template for the OAK backend

* WIP

* WIP

* WIP

* WIP

* Runtime dai hang debug

* Refactoring

* Fix hang and debug frame data

* Fix frame size

* Fix data size issue

* Move test code to sample

* tmp refactoring

* WIP: Code refactoring except for the backend

* WIP: Add non-camera sample

* Fix samples

* Backend refactoring wip

* Backend rework wip

* Backend rework wip

* Remove mat encoder

* Fix namespace

* Minor backend fixes

* Fix hetero sample and refactor backend

* Change linking logic in the backend

* Fix oak sample

* Fix working with ins/outs in OAK island

* Trying to fix nv12 problem

* Make both samples work

* Small refactoring

* Remove meta args

* WIP refactoring kernel API

* Change in/out args API for kernels

* Fix build

* Fix cmake warning

* Partially address review comments

* Partially address review comments

* Address remaining comments

* Add memory ownership

* Change pointer-to-pointer to reference-to-pointer

* Remove unnecessary reference wrappers

* Apply review comments

* Check that graph contains only one OAK island

* Minor refactoring

* Address review comments
2022-01-17 22:56:01 +00:00
Alexander Alekhin a1ec4ea3a9 Merge pull request #21361 from alalek:sample_fix_tracking 2022-01-17 22:26:59 +00:00
rogday 0fe7420638 fix model diagnostic tool 2022-01-18 01:22:22 +03:00
Alexander Alekhin b304730225 dnn: fix API - explicit ctors, const methods 2022-01-17 21:45:29 +00:00
Alexander Alekhin 4801526f35 Merge pull request #21451 from sturkmen72:update_imreadmulti_doc 2022-01-16 15:55:27 +00:00
Suleyman TURKMEN f1857030b5 bigtiff images reading 2022-01-16 11:49:10 +03:00
Suleyman TURKMEN b5b3f4e1c6 Update PULL_REQUEST_TEMPLATE.md and ISSUE_TEMPLATE.md 2022-01-15 13:31:41 +03:00
Suleyman TURKMEN 172bb7887c Update imgcodecs.hpp 2022-01-14 23:36:53 +03:00
Anna Khakimova 60228d30d1 Merge pull request #21144 from anna-khakimova:ak/resize_simd_v2
GAPI Fluid: Resize Linear U8C3 - reworking horizontal pass.

* Reworked horizontal pass

* Fixed valgrind issue and removed unnesesary snippet
2022-01-14 12:48:52 +00:00
Lukas Yoder 9592537840 Merge pull request #20363 from SentToDevNull:master
Updated To Modern Version of Aravis USB 3 Vision Protocol Library

* updated aravis backend to support aravis-0.8

* bugfix for aravis-0.8 support
2022-01-13 23:22:36 +03:00
Alexander Alekhin 8768a80242 Merge pull request #21440 from mshabunin:fix-kw-2022-01 2022-01-13 17:46:04 +00:00
Maksim Shabunin d5f73f89d8 Fixed issues found by static analysis 2022-01-13 14:51:25 +03:00
Dmitry Budnikov 19bbe6c67d Merge pull request #21424 from dbudniko:dbudniko/media_frame_adapter_enabling
Adapt remote inference to operate with NV12 blobs

* Media Frame Adapter support

* address comments
2022-01-12 17:38:14 +00:00
Alexander Alekhin aebb65e983 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2022-01-12 13:26:10 +00:00
Alexander Alekhin 5e327af327 Merge pull request #21426 from alalek:dnn_simd_unaligned_weights_fix 2022-01-12 13:11:45 +00:00
Alexander Alekhin bc1f8813c2 Merge pull request #21422 from alexgiving:atrutnev/wrong_destination_size_deduction_resize 2022-01-12 12:43:09 +00:00
Alexander Alekhin 80d9f624d0 dnn: don't use aligned load without alignment checks
- weights are unaligned in dasiamprn sample (comes from numpy)
2022-01-12 05:11:18 +00:00
Aleksei Trutnev e9c46f38fc fix rounding 2022-01-12 01:11:46 +03:00
cudawarped ecfbaa267d Merge pull request #21374 from cudawarped:fix_cuda_event_flags
Allow cv::cuda::Event to accept combinations of flags
2022-01-11 23:57:25 +03:00
Alexander Alekhin c25fd3349b Merge pull request #21421 from vrabaud:3.4size_t 2022-01-11 18:27:18 +00:00
Harvey c3e27bcf87 Merge pull request #21400 from Harvey-Huang:master
tiff need check TIFFTAG_SAMPLEFORMAT, should not always use unsigned.
2022-01-11 16:51:50 +00:00
Alexander Alekhin a5894f3e6b Merge pull request #21413 from berak:patch-1 2022-01-11 15:41:50 +00:00
Vincent Rabaud 4db3a388dd Fix a potential UBSAN error.
We only use that value as uint64_t below anyway.
2022-01-11 12:01:47 +01:00
Alexander Alekhin 6fd1a2ef52 Merge pull request #21409 from sturkmen72:patch-3 2022-01-10 17:35:39 +00:00
Suleyman TURKMEN fe2a259eb1 Update documentation 2022-01-10 18:34:39 +03:00
Alexander Alekhin 1ba7c2f276 Merge pull request #21416 from alalek:videoio_msmf_sourcereadercb_dtor_message_info 2022-01-10 15:22:09 +00:00
h6197627 649f747f8a Merge pull request #21405 from h6197627:3.4
* Use c++ namespaces explicitly

* Add root cv c++ namespace
2022-01-10 14:51:07 +03:00
Alexander Alekhin 05dbaf7672 videoio(msmf): use info message in SourceReaderCB destructor 2022-01-10 12:16:01 +03:00
Alexander Alekhin 742a08229e Merge pull request #21412 from crackwitz:kmeans-N-ge-K-message 2022-01-09 21:01:28 +00:00
berak 5602d2c7bb Update stitching_detailed.py
resolves: #21406

use constructors consistently
2022-01-09 12:26:24 +01:00
Christoph Rackwitz f3e0479a8f kmeans: assertion "There can't be more clusters than elements" 2022-01-08 23:42:21 +01:00
Alexander Alekhin a1143c4ea0 Merge pull request #21398 from thegrizzlylabs:fix-catalyst-arch 2022-01-06 11:34:48 +00:00
Alexander Alekhin 0314d1dd01 Merge pull request #21394 from vrabaud:3.4_doc 2022-01-06 08:44:04 +00:00
Guillaume Gigaud 751b3f502d apple/build_xcframework.py: fix incorrect catalyst archs 2022-01-06 09:36:28 +01:00
Vincent Rabaud bf5e09d5ab Remove unnecessary use of ref-capture in code example. 2022-01-05 13:42:55 +01:00
Alexander Alekhin 14e4a10312 Merge pull request #21378 from sturkmen72:fix_legacy_constants 2022-01-04 14:33:28 +00:00
Alexander Alekhin 53b89e1ee4 Merge pull request #21382 from stal12:CCL_fix_4conn 2022-01-04 13:21:25 +00:00
Alexander Alekhin 370f878a36 Merge pull request #21375 from JoeHowse:3.4-umatusageflags-docs 2022-01-04 13:08:10 +00:00
Alexander Alekhin 6e4d61c1fd copyright: 2022 2022-01-04 12:49:15 +00:00
Alexander Alekhin f6fe5c07f6 copyright: 2022 2022-01-04 12:48:27 +00:00
Stefano Allegretti c685293297 Fix #21366 2022-01-03 18:15:09 +01:00
Suleyman TURKMEN 0e6a2c0491 fix legacy constants 2022-01-03 15:08:10 +03:00
Joe Howse c2209ad5e4 Doc warnings about experimental UMatUsageFlags 2021-12-31 13:51:06 -04:00
Alexander Alekhin 5f249a3e67 Merge pull request #21356 from alalek:core_ocl_option_to_abort_on_kernel_build_error 2021-12-30 14:04:52 +00:00
Alexander Alekhin 76fb3652fc dnn(ocl): fix fp16 kernel compilation 2021-12-29 19:58:25 +00:00
Alexander Alekhin 92925e846d Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-12-29 15:22:13 +00:00
Trutnev Aleksei 43c04c29ce Merge pull request #21157 from alexgiving:atrutnev/move_resize
GAPI: Move Resize kernel from core to imgproc

* Move Resize kernel from core to imgproc

* Applied style comments

* Adding backward compatibility

* Applied Asya PR
2021-12-29 15:13:43 +00:00
Alexander Alekhin 06b74c87da Merge pull request #21360 from alalek:core_ocl_option_to_abort_on_kernel_build_error_3.4 2021-12-29 15:11:18 +00:00
Alexander Alekhin 7f075b0b15 samples(python): update tracker.py 2021-12-29 01:30:13 +00:00
Alexander Alekhin c5a86c22a4 core(ocl): add option to abort on OpenCL kernel build failure
- exceptions are catched by fallback CPU path
- OPENCV_OPENCL_ABORT_ON_BUILD_ERROR (disabled by default)
2021-12-29 00:04:45 +00:00
Alexander Alekhin 3621c6234c Merge pull request #21354 from alalek:samples_python_3.10 2021-12-28 17:59:48 +00:00
Alexander Alekhin 80c2fefc43 Merge pull request #21318 from alexgiving:atrutnev/move_GKernelPackage 2021-12-28 12:20:41 +00:00
Alexander Alekhin a47952146a samples: query for Python 3.10 setup 2021-12-28 11:49:55 +00:00
Alexander Alekhin a55950865e Merge pull request #21347 from StefanBruens:fix_qt_opengl_link 2021-12-26 14:10:08 +00:00
Stefan Brüns ab181ac329 highgui: Fix unresolved OpenGL functions for Qt backend
The Qt backend directly calls some OpenGL functions (glClear, glHint,
glViewport), but since OCV 4.5.5 the GL libraries are no longer part
of the global extra dependencies. When linking with "-Wl,--no-undefined"
this causes linker errors:

`opencv-4.5.5/modules/highgui/src/window_QT.cpp:3307: undefined reference to `glClear'`

Fixes: #21346
Related issues: #21299
2021-12-26 01:10:45 +01:00
Alexander Alekhin db172d1053 Merge tag '4.5.5' 2021-12-25 11:22:16 +00:00
Alexander Alekhin dad26339a9 release: OpenCV 4.5.5 2021-12-25 03:53:27 +00:00
Alexander Alekhin 3b0ed61826 Merge pull request #21343 from alalek:dnn_onnx_handle_domains 2021-12-25 02:54:21 +00:00
Alexander Alekhin 9699e2b483 dnn(onnx): handle non-default ONNX domains
- re-enable quantized models tests
2021-12-25 01:38:52 +00:00
Rostislav Vasilikhin 3048188b5b Merge pull request #21319 from savuor:backport_levmarqfromscratch
Warning fixes for quaternion headers

* warning fixes for quaternion headers

* a/T(x) => a * T(1/x)
2021-12-24 23:00:21 +00:00
Alexander Alekhin 547bb3b053 Merge pull request #21197 from SinM9:speech_recognition_python 2021-12-24 18:10:47 +00:00
Alexander Alekhin 7c2087cf05 Merge pull request #21339 from AsyaPronina:asyadev/wa_valgrind_issues 2021-12-24 18:10:32 +00:00
Alexander Alekhin 217fea9667 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-12-24 16:48:07 +00:00
Alexander Alekhin 523c3cd50b Merge tag '3.4.17' 2021-12-24 16:45:05 +00:00
Alexander Alekhin 631126c77a release: OpenCV 3.4.17 2021-12-24 16:39:15 +00:00
Alexander Alekhin 655d381ef3 Merge pull request #21341 from alalek:issue_20930_3.4 2021-12-24 16:33:19 +00:00
Aleksei Trutnev c68fec7e97 Move GKernelPackage to cv namespace 2021-12-24 18:04:11 +03:00
Alexander Alekhin cdfa8a668b python: use '((x,y), (w,h), angle)' in std::vector<RotatedRect> 2021-12-24 15:01:45 +00:00
Alexander Alekhin 92651d228d Merge pull request #21329 from alalek:cmake_openexr_find_package 2021-12-24 11:56:12 +00:00
Alexander Alekhin 90e3692603 Merge pull request #21327 from alalek:imgcodecs_openexr_runtime_disabled 2021-12-24 11:55:55 +00:00
Alexander Alekhin 3a8316ab93 Merge pull request #21320 from catree:solvePnP_doc_page 2021-12-24 11:55:34 +00:00
Alexander Alekhin 8d3f0d0eab Merge pull request #21306 from aBITnav:patch-1 2021-12-24 10:49:10 +00:00
Anastasiya Pronina ded0efb955 Disabling SSE4.1 path in GFluidResize due to Valgrind issues 2021-12-24 13:37:16 +03:00
Alexander Alekhin cdd4354256 Merge pull request #21336 from alalek:dnn_pooling_check_array_indexes 2021-12-24 08:35:11 +00:00
Alexander Alekhin bde955fc56 Merge pull request #21335 from alalek:dnn_onnx_dump_input_output 2021-12-24 08:34:47 +00:00
Alexander Alekhin abc9e98625 Merge pull request #21325 from APrigarina:fix_asift_sample 2021-12-24 08:26:16 +00:00
ABHINAV JHA d086ee14dd Fix: Grammatical mistake 2021-12-24 08:01:13 +00:00
Alexander Alekhin f43fec7ee6 cmake: use find_package(OpenEXR) to support OpenEXR 3+ 2021-12-24 00:21:48 +00:00
Alexander Alekhin 6385511e88 dnn: add checks in pooling layer implementation
- to avoid out of buffer access
2021-12-24 00:15:30 +00:00
Alexander Alekhin ed4becf007 dnn(onnx): debug dump of inputs/outputs/initializers in importer 2021-12-23 21:11:40 +00:00
Alexander Alekhin f11ab4c569 Merge pull request #21331 from alalek:issue_21289 2021-12-23 20:09:52 +00:00
Alexander Alekhin b12c2c76d1 Merge pull request #21330 from alalek:fix_highgui_gtk_mouse_callbacks 2021-12-23 20:09:40 +00:00
Alexander Alekhin f5589445b9 Merge pull request #21322 from alalek:dnn_catch_errors 2021-12-23 20:09:22 +00:00
catree 032a61b197 Summarize PnP pose computation on a single separate page. 2021-12-23 19:52:14 +01:00
Alexander Alekhin 011ed380aa Merge pull request #21323 from alalek:dnn_do_not_rebuilt_network_in_setInput 2021-12-23 15:45:28 +00:00
Alexander Alekhin 88a18c8b6a dnn(onnx): emit error in Shape for dynamic input 2021-12-23 15:42:59 +00:00
Alexander Alekhin 51e65db715 dnn(onnx): fix Resize inputs handling 2021-12-23 15:42:59 +00:00
Alexander Alekhin cc02fcd889 dnn: improve debug messages, add ONNX opset version 2021-12-23 15:42:59 +00:00
Alexander Alekhin 9f17c62533 Merge pull request #21321 from alalek:dnn_test_decompose_dynamic_axes 2021-12-23 15:26:21 +00:00
Alexander Alekhin 36bd2a65e3 highgui(gtk): repair scroll events 2021-12-23 13:06:44 +00:00
Alexander Alekhin 85d4e56bb1 highgui(gtk): fix onmouse event flags 2021-12-23 12:15:14 +00:00
Alexander Alekhin 381d9bafdf imgcodecs: disable OpenEXR in runtime for 3rdparty source code
- builtin OpenEXR source code is outdated
- external OpenEXR distributions are allowed
2021-12-23 10:41:18 +00:00
APrigarina ada16fd188 prevent index error in find_obj sample 2021-12-23 11:29:27 +03:00
Alexander Alekhin c408157a4d dnn: do not try to rebuilt network during setInput()
- this doesn't make sense in case of multiple inputs
2021-12-23 02:40:33 +00:00
Alexander Alekhin 6e299b582a dnn(test): decompose 'DynamicAxes' test 2021-12-23 00:47:27 +00:00
Alexander Alekhin 9777fbacf6 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-12-22 15:57:02 +00:00
Alexander Alekhin 643b4dd126 Merge pull request #21314 from alalek:fix_links_4.x 2021-12-22 15:53:43 +00:00
Alexander Alekhin 19ac54277b Merge pull request #21313 from alalek:fix_links_3.4 2021-12-22 15:53:02 +00:00
Alexander Alekhin c78a8dfd2d fix 4.x links 2021-12-22 13:24:30 +00:00
Alexander Alekhin b1a57c4cb2 fix 3.4 links 2021-12-22 12:38:21 +00:00
dwardor 54c180092d Merge pull request #21114 from dwardor:patch-1
* Fix compile against lapack-3.10.0

Fix compilation against lapack >= 3.9.1 and 3.10.0 while not breaking older versions

OpenCVFindLAPACK.cmake & CMakeLists.txt: determine OPENCV_USE_LAPACK_PREFIX from LAPACK_VERSION

hal_internal.cpp : Only apply LAPACK_FUNC to functions whose number of inputs depends on LAPACK_FORTRAN_STR_LEN in lapack >= 3.9.1

lapack_check.cpp : remove LAPACK_FUNC which is not OK as function are not used with input parameters (so lapack.h preprocessing of "LAPACK_xxxx(...)" is not applicable with lapack >= 3.9.1
If not removed lapack_check fails so LAPACK is deactivated in build (not want we want)

use OCV_ prefix and don't use Global, instead generate OCV_LAPACK_FUNC depending on CMake Conditions

Remove CONFIG from find_package(LAPACK) and use LAPACK_GLOBAL and LAPACK_NAME to figure out if using netlib's reference LAPACK implementation and how to #define OCV_LAPACK_FUNC(f)

* Fix typos and grammar in comments
2021-12-22 12:00:00 +00:00
Alexander Alekhin be110d0464 Merge pull request #21303 from alalek:issue_21299_4.x 2021-12-21 18:42:58 +00:00
Alexander Alekhin 6e733b65ae Merge pull request #21302 from alalek:issue_21299_3.4 2021-12-21 18:39:52 +00:00
Alexander Alekhin f948a2d0c0 Merge pull request #21305 from alalek:cmake_plugins_lowercase_internal_names 2021-12-21 18:37:40 +00:00
Alexander Alekhin 2aa47554fc Merge pull request #21301 from alalek:coverity_fixes_4.x 2021-12-21 16:39:04 +00:00
Alexander Alekhin c80b270678 cmake: force lowercase plugins internal names 2021-12-21 16:34:48 +00:00
Alexander Alekhin dcc32e84b9 highgui: fix Win32 with OPENGL=ON 2021-12-21 15:51:22 +00:00
Alexander Alekhin 947d610309 Merge pull request #21297 from rogday:div_fix 2021-12-21 15:48:40 +00:00
Alexander Alekhin 3e01a387ba highgui: fix Win32 with OPENGL=ON 2021-12-21 15:44:59 +00:00
Alexander Alekhin 4dbba5ac98 videoio: add non zero check 2021-12-21 14:32:19 +00:00
Alexander Alekhin 374cc4183e Merge pull request #21296 from alalek:update_ffmpeg_4.x 2021-12-20 18:11:54 +00:00
Alexander Alekhin b9d9730b62 Merge pull request #21295 from alalek:update_ffmpeg_3.4 2021-12-20 18:11:41 +00:00
rogday 0a178a687a fix const/x in Div 2021-12-20 19:53:37 +03:00
Alexander Alekhin c4c43c3d26 ffmpeg/4.x: update FFmpeg wrapper 2021.12
- FFmpeg 4.4.1
2021-12-20 16:30:21 +00:00
Alexander Alekhin 8fa86d4d34 ffmpeg/3.4: update FFmpeg wrapper 2021.12
- FFmpeg 3.4.9
2021-12-20 15:32:05 +00:00
Alexander Alekhin a22dd28e02 videoio: fix ffmpeg standalone build 2021-12-20 15:03:21 +00:00
Alexander Alekhin 0e274fc4be Merge pull request #21294 from mshabunin:fix-gst-audio 2021-12-20 13:13:58 +00:00
Maksim Shabunin bc3da25a4a videoio: added gst-audio dependency 2021-12-20 13:25:08 +03:00
Alexander Alekhin 80492d663e Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-12-18 16:19:06 +00:00
Alexander Alekhin 172c539a5a Merge pull request #21281 from alalek:update_version_4.5.5-pre 2021-12-18 13:46:38 +00:00
Alexander Alekhin a079acc0d9 Merge pull request #21280 from alalek:update_version_3.4.17-pre 2021-12-18 13:46:29 +00:00
Alexander Alekhin 30df77fa4c Merge pull request #21190 from rogday:acts 2021-12-18 13:41:48 +00:00
Smirnov Egor 71a22e45b0 add celu, hardsigmoid, selu, thresholdedrelu layers 2021-12-18 03:19:54 +03:00
Alexander Alekhin defd8a527b Merge pull request #21279 from cabelo:new-example-intelrealsense 2021-12-17 19:41:02 +00:00
Alexander Alekhin 3ce29236f3 Merge pull request #21253 from cabelo:allRrealsense 2021-12-17 19:40:19 +00:00
Alexander Alekhin 04ee99f1a3 Merge pull request #21282 from alalek:dnn_test_vulkan_skip 2021-12-17 19:39:35 +00:00
Stefano Allegretti 91817bffe1 Merge pull request #21275 from stal12:CCL_improvements
Improve CCL with new algorithms and tests

* Improve CCL with new algorithms and tests

* Split CCL test into dedicated tests cases
2021-12-17 19:36:57 +00:00
Alexander Alekhin c39b83667b Merge pull request #21176 from rogday:eltwise_layers 2021-12-17 19:35:13 +00:00
Smirnov Egor 1bd382c1d0 Add acos, acosh, asin, asinh, atan, atanh, cos, cosh, erf, hardswish, sin, sinh, softplus, softsign, tan layers 2021-12-17 18:19:40 +03:00
Alexander Alekhin 49bef1cdbf Merge pull request #21283 from rogday:flatten_fix 2021-12-17 14:27:40 +00:00
Alexander Alekhin 249c508126 dnn(test): skip failed tests on Vulkan backend 2021-12-17 14:01:04 +00:00
Trutnev Aleksei 04b27525fa Merge pull request #21231 from alexgiving:atrutnev/SIMD_SubRC_fluid
GAPI FLUID: SIMD for SubRC kernel

* SIMD for SubRC

* Reverse subrc
2021-12-17 13:42:47 +00:00
eplankin 175bcb1734 Merge pull request #21258 from eplankin:fix_threshold_to_zero_ipp_bug
Fixed threshold(THRESH_TOZERO) at imgproc(IPP)

* Fixed #16085: imgproc(IPP): wrong result from threshold(THRESH_TOZERO)

* 1. Added test cases with float where all bits of mantissa equal 1, min and max float as inputs
2. Used nextafterf instead of cast to hex

* Used float value in test instead of hex and casts

* Changed input value in test
2021-12-17 13:31:37 +00:00
Smirnov Egor fec2c7e715 fix Flatten layer 2021-12-17 16:29:56 +03:00
Alexander Alekhin 07dca8cc03 pre: OpenCV 4.5.5 (version++) 2021-12-17 10:12:11 +00:00
Alexander Alekhin 60c093f086 pre: OpenCV 3.4.17 (version++) 2021-12-17 10:05:52 +00:00
Maxim Milashchenko db4ab1c936 Merge pull request #21264 from MaximMilashchenko:AudioGStreamer
Audio GStreamer: added support .wav .flac audio formats

* added support .wav, lossless compressed audio formats

* fixed docs

* fixes

* videoio(gstreamer-audio): extra tests, improve error handling

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-12-16 19:43:02 +00:00
Alexander Alekhin f071207463 Merge pull request #21277 from alalek:backport_21267 2021-12-16 18:52:23 +00:00
Alexander Alekhin 622b9d9276 Merge pull request #21267 from mshabunin:fix-kw-2021-12 2021-12-16 18:51:47 +00:00
alessandro faria 05bfdeab7a New example for realsense 2021-12-16 15:07:53 -03:00
Gruhuang b4bb98ea60 Merge pull request #21268 from pccvlab:tf_Arg
add argmax and argmin parsing for tensorflow

* add argmax and argmin for tf

* remove whitespace

* remove whitespace

* remove static_cast

Signed-off-by: Crayon-new <1349159541@qq.com>
2021-12-16 17:06:02 +00:00
Maksim Shabunin 792b7e0629 (3.4) Fixed several issues found by static analysis
original commit: a079c2eb7c
2021-12-16 17:02:58 +00:00
Maksim Shabunin a079c2eb7c Fixed several issues found by static analysis 2021-12-16 19:21:25 +03:00
Alexander Alekhin f7aa91e660 Merge pull request #21265 from alalek:dnn_onnx_test_filter_update_4.x 2021-12-16 16:05:50 +00:00
Alexander Alekhin 6d677bbd63 dnn(test): update ONNX conformance filters (4.x) 2021-12-16 12:09:31 +00:00
Alexander Alekhin cee3ec6dc4 Merge pull request #21271 from vrabaud:3.4_clip 2021-12-16 11:19:53 +00:00
Vincent Rabaud 3da17c42a4 Use NaN-safe clip function.
This is to prevent more NaN to int conversions like in #21111.
2021-12-16 11:34:04 +01:00
Alexander Alekhin 2329cbc1a2 Merge pull request #21269 from mshabunin:fix-hardening-o3 2021-12-16 09:17:51 +00:00
Maksim Shabunin b39ee54103 Do not force -O2 flag in hardening-enabled builds 2021-12-16 11:40:42 +03:00
Alexander Alekhin 299f9837b7 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-12-15 16:38:56 +00:00
Alexander Alekhin 6a889ed3e5 Merge pull request #21261 from alalek:dnn_onnx_test_filter_update 2021-12-15 16:24:04 +00:00
Alexander Alekhin f3ba88c87c dnn(test): update ONNX conformance filters 2021-12-15 12:53:53 +00:00
Alexander Alekhin 498f1525b2 Merge pull request #21246 from pccvlab:square 2021-12-15 12:02:20 +00:00
Alexander Alekhin e7c5120682 Merge pull request #21259 from rogday:random_fixes 2021-12-15 10:26:49 +00:00
Alexander Alekhin 19cfaa2be7 Merge pull request #21254 from alalek:build_opencv_winpack_dldt_2021.4.2 2021-12-15 08:17:09 +00:00
Smirnov Egor e97c7e042b fix max_unpool missing attributes, add default value of keepdims in reducemean/max/sum, add support for keepdims=true in full reduction branch, add new padding type to Pad 2021-12-14 22:09:27 +03:00
Sinitsina Maria d8b1fc45aa Merge pull request #20934 from SinM9:spectrogram_samples
AudioIO: add spectrogram samples for C++/python
2021-12-14 17:33:26 +00:00
Alexander Alekhin 35f27d0d3e Merge pull request #21257 from alalek:imgproc_cvtcolor_lab_fix_nan 2021-12-14 16:59:07 +00:00
Alexander Alekhin 330a11861e Merge pull request #21256 from zchrissirhcz:fix-3.4-pyramid-tutorial 2021-12-14 16:58:53 +00:00
rogday 4827fe86bb Merge pull request #21088 from rogday:onnx_tests
Onnx conformance tests

* Add ONNX conformance tests

* dnn(test): add filters for ONNX conformance tests

* add filter lists for OCV backend

* address review comments

* move test_clip_inbounds to all_denylist

* address clip issue

* avoid empty lists

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-12-14 16:58:06 +00:00
Alexander Alekhin 72c55b56f2 imgproc: catch NaNs in clip(), use table index debug check
- no NaN propagation guarantee
2021-12-14 15:31:51 +00:00
Trutnev Aleksei 295da7e5f3 Merge pull request #21150 from alexgiving:atrutnev/fluid_perf
GAPI: Add compare function to perf tests

* Add PhasePerfTest and SqrtPerfTest

* rebasing

* debug tests

* remove spaces

* Disable DivRCPerfTestGPU

* rebase

* Applied comments

* Correction

* Revert parameter changes
2021-12-14 15:16:59 +00:00
Alexander Alekhin 4eab85d364 Merge pull request #21251 from vrabaud:3.4_bayer 2021-12-14 15:15:07 +00:00
Zhuo Zhang 3cc83ce024 docs: correct normalize factor in gaussian pyramid tutorial 2021-12-14 21:06:02 +08:00
Alexander Alekhin 52c423a423 build: winpack_dldt with dldt 2021.4.2 2021-12-14 09:00:43 +00:00
alessandro faria 952f8e38cf Illustration about realsense 2021-12-14 03:21:31 -03:00
Vincent Rabaud 542b3e8a64 Fix harmless signed integer overflow.
When computing:
t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1])*G2Y;
there is a T (unsigned short or char) multiplied by an int which can overflow.
Then again, it is stored to t1 which is unsigned so the overflow disappears.
Keeping all unsigned is safer.
2021-12-13 23:43:49 +01:00
Alexander Alekhin 4f79eb256d Merge pull request #21250 from alalek:videoio_msmf_update_camera_3.4 2021-12-13 22:24:33 +00:00
Alexander Alekhin 7620456486 videoio(MSMF): add queue for async ReadSample() 2021-12-13 21:02:24 +00:00
Alexander Alekhin 052d209901 Merge pull request #21202 from alalek:videoio_msmf_update_camera 2021-12-13 20:38:15 +00:00
Alexander Alekhin e9c45ff406 Merge pull request #21178 from alalek:cmake_fix_soversion 2021-12-13 19:00:58 +00:00
Alexander Alekhin f1053d48a2 Merge pull request #21204 from anna-khakimova:ak/move_simd_absdiffc 2021-12-13 18:03:50 +00:00
Alexander Alekhin ba12f52f6c Merge pull request #21247 from rogday:coverity_fix 2021-12-13 17:16:03 +00:00
Polina Smolnikova 456137fa24 Merge pull request #21166 from rayonnant14:issue_21105
Fix intrinsics processing in case USAC parameters

* fixed USAC intrinsics processing

* change mat to matx33d, added test
2021-12-13 17:12:49 +00:00
rogday 692059e899 initialize members 2021-12-13 18:41:23 +03:00
cqn2219076254 252ce0b581 add square layer 2021-12-13 21:43:13 +08:00
Alexander Alekhin d24befa0bc Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-12-11 15:18:57 +00:00
Alexander Alekhin 5462710103 Merge pull request #21235 from jonay2000:fix-docs 2021-12-11 15:14:43 +00:00
Jonathan Dönszelmann d1b923bee9 Update name from Gunner to Gunnar as that's the name he published his
paper under.
2021-12-11 13:10:52 +01:00
Alexander Alekhin 81a6d1b0d4 cmake: update SOVERSION
- OpenCV 4.x doesn't guarantee or maintain ABI compatibility
- We should increase SO version on each release
2021-12-10 16:14:56 +00:00
Alexander Alekhin 04020f391a Merge pull request #21193 from alalek:imgproc_test_bitexact_cvtcolor_yuv 2021-12-10 16:11:06 +00:00
Alexander Alekhin c4ab0c09ea Merge pull request #21228 from alalek:issue_21198 2021-12-10 16:07:57 +00:00
Alexander Alekhin 6e50e4b9ee Merge pull request #21161 from rogday:elu_alpha_4x 2021-12-10 16:04:01 +00:00
HAN Liutong 1599f9f0c0 Merge pull request #21086 from hanliutong:rvv-dnn
Further optimize DNN for RISC-V Vector.

* Optimize DNN on RVV by using vsetvl.

* Rename vl.

* Update fastConv by using setvl instead of mask.

* Fix fastDepthwiseConv
2021-12-10 16:03:22 +00:00
Alexander Alekhin 0c5b6e5556 videoio(MSMF): add queue for async ReadSample() 2021-12-10 16:01:08 +00:00
Alexander Alekhin e3e04f5dae Merge pull request #21222 from asenyaev:asen/replace_distutils_copy_tree 2021-12-10 14:12:01 +00:00
Gruhuang 17bc8565f6 Merge pull request #21154 from pccvlab:MatMul_with_two_inputs
Add BatchMatMul layer support for tf_importer

* two inputs

* support batch_matmul

* refactor: remove useless code

* refactor: decrease nesting
2021-12-10 14:44:27 +03:00
Simon Wilson c08954c18b Merge pull request #21227 from sbwilson:fix_framework_unicode_headers
* fix unicode errors for framework headers

This would crash if the header file included non-ASCII characters. This change ensures that headers are read and written as UTF-8 encoded files instead of ascii.

* Adds spaces after commas
2021-12-10 14:36:14 +03:00
Alexander Alekhin 7ba56a4b88 Merge pull request #21194 from whalenpt:qt_opengl_build_fix 2021-12-10 11:33:17 +00:00
Alexander Alekhin 9b7f40ce4d Merge pull request #21074 from vrabaud:3.4_rect 2021-12-10 11:32:03 +00:00
Sergey Ivanov b70370f3fd Merge pull request #21230 from sivanov-work:gapi_win32_vpl_fix
G-API: Fix Win32 build: uint64_t ->size_t

* Fix Win32 build: uint64_t ->size_t

* Fix for MAC
2021-12-10 08:58:59 +00:00
Andrey Senyaev 4d3cf77ad5 Replaced distutils to shutil when copying files in a tree 2021-12-10 11:46:27 +03:00
Patrick Whalen b2005ccaef Fix broken build for Qt6 with options: WITH_QT=ON and WITH_OPENGL=ON
- QGLWidget changed to QOpenGLWidget in window_QT.h for Qt6 using
  typedef OpenCVQtWidgetBase for handling Qt version

- Implement Qt6/OpenGL functionality in window_QT.cpp

- Swap QGLWidget:: function calls for OpenCVQtWidgetBase:: function calls

- QGLWidget::updateGL deprecated, swap to QOpenGLWidget::update for Qt6

- Add preprocessor definition to detect Qt6 -- HAVE_QT6

- Add OpenGLWidgets to qdeps list in highgui CMakeLists.txt

- find_package CMake command added for locating Qt module OpenGLWidgets

- Added check that Qt6::OpenGLWidgets component is found. Shut off Qt-openGL functionality if not found.
2021-12-09 13:22:20 -08:00
Alexander Alekhin 659cf7249e imgproc(ocl): fix resizeLN, avoid integer overflow 2021-12-09 20:30:26 +00:00
UncleLLD 62a010a25d Merge pull request #21224 from UncleLLD:fix-cvtColor-error
fix cvtColor-error

* fix gray image channel error

* fix gray image channel error

* fix cvtColor error after the video end

* fix cvtColor error after the video end and change next variable

* fix cvtColor error after the video end

* reset next variable

* fix cvtColor error after the video end

* fix cvtColor error after the video end
2021-12-09 19:11:05 +00:00
Vincent Rabaud 6b4ea68bc7 Solve Rect overflow issues.
Fow now, it is possible to define valid rectangle for which some
functions overflow (e.g. br(), ares() ...).
This patch fixes the intersection operator so that it works with
any rectangle.
2021-12-09 12:04:26 +01:00
Andrey Senyaev d6891c705e Merge pull request #21219 from asenyaev:asen/remove_distutils
* Replaced distutils module to sysconfig

* Fixed getting a path to python lib
2021-12-08 18:51:34 +00:00
Alexander Alekhin 9bcb006ec7 Merge pull request #21218 from alalek:cmake_gapi_gstreamer_option 2021-12-08 12:36:10 +00:00
Alexander Alekhin 02ac6ec81c cmake: option to disable GStreamer in G-API
- OPENCV_GAPI_GSTREAMER
2021-12-08 11:07:32 +00:00
Sergey Ivanov 5c91f5b71d Merge pull request #21049 from sivanov-work:vpl_dx11_merge
G-API: oneVPL merge DX11 acceleration

* Merge DX11 initial

* Fold conditions row in MACRO in utils

* Inject DeviceSelector

* Turn on DeviceSelector in DX11

* Change sharedLock logic & Move FMT checking in FrameAdapter c-tor

* Move out NumSuggestFrame to configure params

* Drain file source fix

* Fix compilation

* Force zero initializetion of SharedLock

* Fix some compiler warnings

* Fix integer comparison warnings

* Fix integers in sample

* Integrate Demux

* Fix compilation

* Add predefined names for some CfgParam

* Trigger CI

* Fix MultithreadCtx bug, Add Dx11 GetBlobParam(), Get rif of ATL CComPtr

* Fix UT: remove unit test with deprecated video from opencv_extra

* Add creators for most usable CfgParam

* Eliminate some warnings

* Fix warning in GAPI_Assert

* Apply comments

* Add VPL wrapped header with MSVC pragma to get rid of global warning masking
2021-12-08 07:09:33 +00:00
Alexander Alekhin 16b674b984 Merge pull request #21213 from alalek:issue_20850_case1 2021-12-07 16:34:54 +00:00
Alexander Alekhin 65392d5e6b cmake: fix OPENGL_LIBRARIES handling 2021-12-07 12:12:42 +00:00
Alexander Alekhin 41d108ead6 Merge pull request #21208 from rogday:argminmax_dnn 2021-12-07 12:11:39 +00:00
Alexander Alekhin 0c9dbc61a1 Merge pull request #21212 from OrestChura:oc/fix_openvino_standalone_build 2021-12-07 11:32:28 +00:00
Alexander Alekhin 6788fdb0d6 Merge pull request #21205 from anna-khakimova:ak/fix_for_muldouble_gpu 2021-12-07 10:24:50 +00:00
Anna Khakimova 3a4b61579d GAPI GPU: fix for tests failure. 2021-12-07 11:21:04 +03:00
OrestChura 51d7ba7446 Bring updates from openvino version of standalone files 2021-12-07 06:56:48 +03:00
Smirnov Egor e608adea60 add ArgMax and ArgMin layers 2021-12-06 20:49:54 +03:00
Anastasiya(Asya) Pronina 8dd6882222 Merge pull request #20709 from AsyaPronina:asyadev/integrate_gstreamer_source
Ported GStreamerSource to OpenCV

* Ported GStreamerSource to OpenCV

* Fixed CI failures

* Whitespaces

* Whitespaces + removed exception from destructors C4722

* Removed assert for Priv's getSS and descr_of

* Removed assert for pull

* Fixed last review comment

Co-authored-by: Pashchenkov Maxim <maxim.pashchenkov@intel.com>
2021-12-06 16:54:21 +00:00
UncleLLD 5aef565fb6 Merge pull request #21188 from UncleLLD:fix-markdown-error
fix issue 21187: markdown file: gray image does not have three dimensions
2021-12-06 16:14:17 +00:00
Anna Khakimova a4d6bcba09 GAPI Fluid: Enable dynamic dispatching for AbsDiffC kernel. 2021-12-06 15:15:47 +03:00
Sinitsina Maria f09a577ab5 add OpenCV audio reading 2021-12-05 17:58:44 +03:00
Maksim Shabunin 973e1acb67 Merge pull request #21182 from mshabunin:split-cv2cpp
Split cv2.cpp

* split cv2.cpp: util, numpy

* split cv2.cpp: convert

* split cv2.cpp: highgui, more utils

* split cv2.cpp: fix numpy import
2021-12-05 12:49:36 +00:00
Tejas M R 676a724491 Merge pull request #21180 from tezz-io:4.x
Added CV_PROP_RW macro to keypoints

* Added CV_PROP_RW macro to keypoints

As outlined in the feature request in the issue https://github.com/opencv/opencv/issues/21171 : the keypoints field has been made parsable by the bindings.

* Added test for keypoints

Added test to check if the CV_PROP_RW macro added in the previous commit makes keypoints public and accessible through the python API.
2021-12-05 12:47:44 +00:00
Alexander Alekhin 73318fd514 Merge pull request #21167 from alalek:dnn_test_reenable_ov_2021_4 2021-12-04 22:12:18 +00:00
MaximMilashchenko cb08c15616 Merge pull request #21145 from MaximMilashchenko:AudioUpdate
Audio MSMF: added the ability to set sample per second

* Audio MSMF: added the ability to set sample per second

* changed the valid sampling rate check

* fixed docs

* add test

* fixed warning

* fixed error

* fixed error
2021-12-04 10:37:10 +00:00
Alexander Alekhin a3287b85c5 carotene: disable YUV color conversions (bit-exact issue) 2021-12-04 07:32:57 +00:00
Alexander Alekhin 0c0b1ec9ae imgproc(test): add bit-exact tests for YUV cvtColor conversions 2021-12-04 04:36:57 +00:00
Michael Davis d2f87ca76c Merge pull request #21147 from mjmdavis:4.x
* remove tickmarks on NSSlider
2021-12-03 16:40:49 +00:00
HAN Liutong 4935b14539 Merge pull request #21012 from hanliutong:rvv_clang
Update RVV backend for using Clang.

* Update cmake file of clang.

* Modify the RVV optimization on DNN to adapt to clang.

* Modify intrin_rvv: Disable some existing types.

* Modify intrin_rvv: Reinterpret instead of load&cast.

* Modify intrin_rvv: Update load&store without cast.

* Modify intrin_rvv: Rename vfredsum to fredosum.

* Modify intrin_rvv: Rewrite Check all/any by using vpopc.

* Modify intrin_rvv: Use reinterpret instead of c-style casting.

* Remove all macros which is not used in v_reinterpret

* Rename vpopc to vcpop according to spec.
2021-12-03 15:13:24 +00:00
Alexander Alekhin 0835611d3a dnn(test): re-enable tests which works with OpenVINO 2021.4.x 2021-12-03 14:01:30 +00:00
Alexander Alekhin 8b4fa2605e Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-12-03 12:32:49 +00:00
Anna Khakimova c3910807c5 Merge pull request #21177 from anna-khakimova:ak/simd_mulc
* GAPI Fluid: SIMD for MulC kernel.

* Changes for MulDouble kernel.
2021-12-03 12:30:39 +00:00
Sergey Ivanov c5b8b5687f Merge pull request #21041 from sivanov-work:gin_gout_concept
G-API: GAPI introduce compile guard for some types for gin/gout params passing

* Initial for taged solution

* Move out tags to gtags.hpp & add protection for own::Mat

* Add compile guard to proper place

* Fix MACRO concat

* Add unit tests

* Remove class MACRO injection due to Python3

* Revert back unproper changes

* Apply comments: reuse shape from traits

* Throw away unused gtags

* Apply comments

* Handle own::*

* Fix test

* Fix test(1)

* Fix unix build

* Try on type list

* Apply comments

* Apply comments

* Fix warning
2021-12-03 12:30:05 +00:00
Alexander Alekhin f61883b227 Merge pull request #21165 from utibenkei:fix_android_ndk_camera_order_of_u_and_v 2021-12-02 17:16:35 +00:00
Alexander Alekhin 35ff9af6ce Merge pull request #21162 from rogday:softmax_simplification 2021-12-02 17:14:48 +00:00
Alexander Alekhin dad2b9aac8 Merge pull request #21160 from rogday:elu_alpha 2021-12-02 17:13:57 +00:00
rogday 1613d30544 Merge pull request #21159 from rogday:ceil_mode
fix ceil_mode for Average/MaxPooling

* fix ceil_mode

* add a comment
2021-12-02 20:11:11 +03:00
Alexander Alekhin b6df9debaf Merge pull request #21174 from APrigarina:fix_qr_encoder 2021-12-02 16:41:03 +00:00
Alexander Alekhin b9d0dc60b0 Merge pull request #21173 from alalek:3.4_dnn_test_reenable_ov_2021_4 2021-12-02 16:33:15 +00:00
APrigarina 37b1876807 qr encoder: fix memory and unused variables issues 2021-12-02 18:35:33 +03:00
Alexander Alekhin d206350738 Merge pull request #21172 from alalek:dnn_test_drop_non_cpu_int8 2021-12-02 13:50:04 +00:00
Jong Sin Kim 2da1f9181a Merge pull request #21170 from JJJoonngg:4.x
Check buffer size when frameWidth * frameHeight bigger than allocated buffer size
2021-12-02 13:48:11 +00:00
Alexander Alekhin bd396e1fd5 dnn(test): re-enable tests which works with OpenVINO 2021.4.x (3.4) 2021-12-02 11:30:45 +00:00
Alexander Alekhin f55c9ed1ba dnn(test): drop non OCV/CPU cases for Int8
- zero code coverage and up to x3-x8 tests slowdown
- implementation executes OCV/CPU in all cases
- wrong skip conditions
2021-12-02 06:27:10 +00:00
Alexander Alekhin 5da69c0b9a Merge pull request #21164 from rogday:sum_identity 2021-12-01 22:49:02 +00:00
Alexander Alekhin a806e8cc58 Merge pull request #21163 from rogday:transpose_default 2021-12-01 22:47:57 +00:00
Anna Khakimova 369b260e12 Merge pull request #21158 from anna-khakimova:ak/simd_subC
* GAPI Fluid: SIMD for SubC kernel.

* Applied comments
2021-12-01 21:58:30 +00:00
Alexander Alekhin d9e7c1626a Merge pull request #21153 from alalek:build_warnings_msvs2017 2021-12-01 12:49:28 +00:00
Vincent Rabaud 1a1a7bbbfd Merge pull request #21112 from vrabaud:3.4_luv_overflow
* Fix integer overflow in cv::Luv2RGBinteger::process.

For LL=49, uu=205, vv=23, we end up with x=7373056 and y=458
which overflows y*x.

* imgproc(test): adjust test parameters to cover SIMD code
2021-12-01 15:46:03 +03:00
Smirnov Egor 33e97e994d add sum of 1 input 2021-11-30 15:42:20 +03:00
Smirnov Egor 11e6848bb9 add default order to transpose 2021-11-30 15:34:34 +03:00
Smirnov Egor 829410729c add new (Log)SoftMax simplification passes 2021-11-30 15:20:52 +03:00
Smirnov Egor 4995aecd62 add alpha parameter to ELU 2021-11-30 14:43:18 +03:00
Smirnov Egor 0e2a3686c0 add alpha parameter to ELU layer 2021-11-30 12:20:35 +03:00
Alexander Alekhin 66b2140892 build: eliminate C4309 warning from protobuf files with MSVS2017 2021-11-30 04:27:39 +00:00
Alexander Alekhin 0d2857a242 Merge pull request #21152 from rogday:fix_defaults 2021-11-29 22:39:27 +00:00
Alexander Alekhin 17d99e6266 Merge pull request #21142 from alalek:dnn_two_inputs_ocl_fp16_3.4 2021-11-29 21:44:59 +00:00
Andrew Ryrie ea7d4be3f8 Merge pull request #20658 from smbz:lstm_optimisation
* dnn: LSTM optimisation

This uses the AVX-optimised fastGEMM1T for matrix multiplications where available, instead of the standard cv::gemm.

fastGEMM1T is already used by the fully-connected layer.  This commit involves two minor modifications:
 - Use unaligned access.  I don't believe this involves any performance hit in on modern CPUs (Nehalem and Bulldozer onwards) in the case where the address is actually aligned.
 - Allow for weight matrices where the number of columns is not a multiple of 8.

I have not enabled AVX-512 as I don't have an AVX-512 CPU to test on.

* Fix warning about initialisation order

* Remove C++11 syntax

* Fix build when AVX(2) is not available

In this case the CV_TRY_X macros are defined to 0, rather than being undefined.

* Minor changes as requested:

 - Don't check hardware support for AVX(2) when dispatch is disabled for these
 - Add braces

* Fix out-of-bounds access in fully connected layer

The old tail handling in fastGEMM1T implicitly rounded vecsize up to the next multiple of 8, and the fully connected layer implements padding up to the next multiple of 8 to cope with this.  The new tail handling does not round the vecsize upwards like this but it does require that the vecsize is at least 8.  To adapt to the new tail handling, the fully connected layer now rounds vecsize itself at the same time as adding the padding(which makes more sense anyway).

This also means that the fully connected layer always passes a vecsize of at least 8 to fastGEMM1T, which fixes the out-of-bounds access problems.

* Improve tail mask handling

 - Use static array for generating tail masks (as requested)
 - Apply tail mask to the weights as well as the input vectors to prevent spurious propagation of NaNs/Infs

* Revert whitespace change

* Improve readability of conditions for using AVX

* dnn(lstm): minor coding style changes, replaced left aligned load
2021-11-29 21:43:00 +00:00
Smirnov Egor 05db8784ae fix Clip, LeakyReLU, LRN, Split defaults 2021-11-29 20:20:34 +03:00
utibenkei 68667d6057 fix_android_ndk_camera_order_of_u_and_v 2021-11-30 01:44:22 +09:00
Anna Khakimova d58b5ef74b Merge pull request #21119 from anna-khakimova:ak/simd_addc
* GAPI Fluid: SIMD for AddC kernel

* Final version

* Applied comments.
2021-11-29 11:20:53 +00:00
rogday f044037ec5 Merge pull request #20733 from rogday:argmaxnd
Implement ArgMax and ArgMin

* add reduceArgMax and reduceArgMin

* fix review comments

* address review concerns
2021-11-28 16:17:46 +00:00
Suleyman TURKMEN a97f21ba4e Merge pull request #20957 from sturkmen72:update-documentation
Update documentation

* Update DNN-based Face Detection And Recognition tutorial

* samples(dnn/face): update face_detect.cpp

* final changes

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-11-28 12:56:28 +00:00
Supernovae b594ed99b8 Merge pull request #20933 from shubham-shahh:master
Improved overall readability of the code

* grid_nms.cu: minor fix-ups

* Update grid_stride_range.hpp

* Update tf_importer.cpp
2021-11-28 12:54:29 +00:00
Alexander Alekhin 58b06222ff dnn(DataLayer): fix CPU/OpenCL code paths for FP16 handling 2021-11-28 07:44:05 +00:00
Alexander Alekhin 58dc397930 dnn(test): add two_inputs test with FP32/U8 data types
- remove similar test from IE scope under HAVE_INF_ENGINE
2021-11-28 07:44:04 +00:00
Alexander Alekhin 15073d63d9 Merge pull request #21126 from alalek:dnn_test_ie_update_4.x 2021-11-27 19:27:59 +00:00
yuki takehara a6277370ca Merge pull request #21107 from take1014:remove_assert_21038
resolves #21038

* remove C assert

* revert C header

* fix several points in review

* fix test_ds.cpp
2021-11-27 18:34:52 +00:00
Alexander Alekhin 31b2d6be75 dnn(test): update InferenceEngine tests (4.x) 2021-11-27 18:16:52 +00:00
Alexander Alekhin 57ee14d62d Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-11-27 16:50:55 +00:00
Alexander Alekhin d470cfe86e Merge pull request #21134 from alalek:gapi_fix_build_ie_msvs2015 2021-11-27 12:59:46 +00:00
Alexander Alekhin b55d8f46f4 Merge pull request #21133 from alalek:dnn_test_ie_update_3.4 2021-11-26 20:35:58 +00:00
Alexander Alekhin c15218e37a gapi: fix build with MSVS2015 (with IE) 2021-11-26 19:34:52 +00:00
Alexander Alekhin 985aa0423d dnn(test): update InferenceEngine tests 2021-11-26 18:46:26 +00:00
Alexander Alekhin c14a8dce93 Merge pull request #21131 from cclauss:codespell 2021-11-26 18:32:54 +00:00
Alexander Alekhin f5d45221ca Merge pull request #21130 from cclauss:print-function 2021-11-26 18:31:32 +00:00
Christian Clauss d668aa7c24 Merge pull request #21121 from cclauss:patch-2
* GitHub Action to lint Python code

* Move from automatic events to manual ones

* flake8: Do not look for undefined names
2021-11-26 18:18:48 +00:00
Orest Chura e20fe421e7 Merge pull request #21103 from OrestChura:oc/fix_1D_Mat_RMat_View_issue
[G-API] Fix issue of getting 1D Mat out of RMat::View

* Fix issue of getting 1D Mat out of RMat::View
 - added test
 - fixed for standalone too (removed Assert(dims.empty()))

* Fixed asVeiw() function for standalone

* Put more detailed comment
2021-11-26 16:42:12 +00:00
Orest Chura 2deb38d615 Merge pull request #21083 from OrestChura:oc/fix_coverity_vino_issues
[G-API] Fixed Coverity issues

* Fixed Coverity issues
 - VectorRef&OpaqueRef m_kind = CV_UNKNOWN
 - added same-type overload for saturate()
 - sanitized resize value in ByteMemoryInStream::operator>> (std::string& str)
 - handled throws from ~GStreamingExecutor()

* Catching exception by const ref

* Addressing Sergey's comments

* Applied enable_if semanitcs to saturate(x, round) too

* Removed uncaught_exception, made destructor noexcept back

* Split Fluid ConvertTo to multiple functions to avoid ifs; added CV_ALWAYS_INLINE

* Added FIXME to address throwings from stop()

* Fix standalone

* Addressing comments

* Guarded SIMD optimizations properly

* Removed excess parameter from simd_impl functions
2021-11-26 16:40:36 +00:00
Maxim Pashchenkov b95d71af2b Merge pull request #21106 from mpashchenkov:mp/ocv-gapi-clean-samples
G-API: Cleaning samples

* parseSSD + removed render details from gcpukernel

* self-rev

* Applying comment

* Added operators

* warnings
2021-11-26 14:31:15 +03:00
Christian Clauss ebe4ca6b60 Fix typos discovered by codespell 2021-11-26 12:29:56 +01:00
Alexander Alekhin f159ed20c2 Merge pull request #21128 from cclauss:patch-3 2021-11-26 11:11:58 +00:00
Christian Clauss cdbb042ce4 Use print() function in both Python 2 and Python 3 2021-11-26 11:57:54 +01:00
Christian Clauss 23bbe511fe CMakeLists.txt: Fix typo discovered by codespell
https://pypi.org/project/codespell/
2021-11-26 11:07:14 +01:00
Alexander Alekhin 444218e755 Merge pull request #21123 from cclauss:patch-3 2021-11-25 18:06:33 +00:00
Christian Clauss 9cc60c9dd3 Use ==/!= to compare constant literals (str, bytes, int, float, tuple)
Avoid `SyntaxWarning` on Python >= 3.8
```
>>> "convolutional" == "convolutional"
True
>>> "convolutional" is "convolutional"
<stdin>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
True
```
Related to #21121
2021-11-25 15:39:58 +01:00
Alexander Alekhin cc1fbe0956 Merge pull request #21108 from ShuangLiu1992:patch-1 2021-11-24 20:10:37 +00:00
Alexander Alekhin 2c226d597d Merge pull request #21110 from alalek:update_libjpeg-turbo 2021-11-24 20:08:27 +00:00
Alexander Alekhin c6ab32ffb9 3rdparty: libjpeg-turbo 2.1.0 => 2.1.2
https://github.com/libjpeg-turbo/libjpeg-turbo/releases/tag/2.1.2
2021-11-24 04:00:47 +00:00
cudawarped 97c6ec6d49 Merge pull request #20978 from cudawarped:videocapture_read_raw_enchancement
Add capacity to Videocapture to return the extraData from FFmpeg when required

* Update rawMode to append any extra data recieved during the initial negotiation of an RTSP stream or during the parsing of an MPEG4 file header.
For h264[5] RTSP streams this ensures the parameter sets if available are always returned on the first call to grab()/read() and has two purposes:
1) To ensure the parameter sets are available even if they are not transmitted in band.  This is common for axis ip camera's.
2) To allow callers of VideoCapture::grab()[read()] to write to split the raw stream over multiple files by appending the parameter sets to the begining of any new files.
For (1) there is no alternative, for (2) if the parameter sets were provided in band it would be possible to parse the raw bit stream and search for the parameter sets however that would be a lot of work when that information is already provided by FFMPEG.
For MPEG4 files this information is only suplied in the header and is required for decoding.

Two properties are also required to enable the raw encoded bitstream to be written to multiple files, these are;
1) an indicator as to whether the last frame was a key frame or not - each new file needs to start at a key frame to avoid storing unusable frame diffs,
2) the length in bytes of the paramater sets contained in the last frame - required to split the paramater sets from the frame without having to parse the stream.  Any call to VideoCapture::get(CAP_PROP_LF_PARAM_SET_LEN) returning a number greater than zero indicates the presense of a parameter set at the begining of the raw bitstream.

* Adjust test data to account for extraData

* Address warning.

* Change added property names and remove paramater set start code check.

* Output extra data on calls to retrieve instead of appending to the first packet.

* Reverted old test case and added new one to evaluate new functionality.

* Add missing definition.

* Remove flag from legacy api.
Add property to determine if returning extra data is supported.
Always allow extra data to be returned on calls to cap.retrieve()
Update test case.

* Update condition which indicates CAP_PROP_CODEC_EXTRADATA_INDEX is not supported in test case.

* Include compatibility for windows dll if not updated.
Enforce existing return status convention.

* Fix return error and missing test constraints.
2021-11-23 21:18:55 +00:00
Hanxi Guo 1fcf7ba5bc Merge pull request #20406 from MarkGHX:gsoc_2021_webnn
[GSoC] OpenCV.js: Accelerate OpenCV.js DNN via WebNN

* Add WebNN backend for OpenCV DNN Module

Update dnn.cpp

Update dnn.cpp

Update dnn.cpp

Update dnn.cpp

Add WebNN head files into OpenCV 3rd partiy files

Create webnn.hpp

update cmake

Complete README and add OpenCVDetectWebNN.cmake file

add webnn.cpp

Modify webnn.cpp

Can successfully compile the codes for creating a MLContext

Update webnn.cpp

Update README.md

Update README.md

Update README.md

Update README.md

Update cmake files and

update README.md

Update OpenCVDetectWebNN.cmake and README.md

Update OpenCVDetectWebNN.cmake

Fix OpenCVDetectWebNN.cmake and update README.md

Add source webnn_cpp.cpp and libary libwebnn_proc.so

Update dnn.cpp

Update dnn.cpp

Update dnn.cpp

Update dnn.cpp

update dnn.cpp

update op_webnn

update op_webnn

Update op_webnn.hpp

update op_webnn.cpp & hpp

Update op_webnn.hpp

Update op_webnn

update the skeleton

Update op_webnn.cpp

Update op_webnn

Update op_webnn.cpp

Update op_webnn.cpp

Update op_webnn.hpp

update op_webnn

update op_webnn

Solved the problems of released variables.

Fixed the bugs in op_webnn.cpp

Implement op_webnn

Implement Relu by WebNN API

Update dnn.cpp for better test

Update elementwise_layers.cpp

Implement ReLU6

Update elementwise_layers.cpp

Implement SoftMax using WebNN API

Implement Reshape by WebNN API

Implement PermuteLayer by WebNN API

Implement PoolingLayer using WebNN API

Update pooling_layer.cpp

Update pooling_layer.cpp

Update pooling_layer.cpp

Update pooling_layer.cpp

Update pooling_layer.cpp

Update pooling_layer.cpp

Implement poolingLayer by WebNN API and add more detailed logs

Update dnn.cpp

Update dnn.cpp

Remove redundant codes and add more logs for poolingLayer

Add more logs in the pooling layer implementation

Fix the indent issue and resolve the compiling issue

Fix the build problems

Fix the build issue

FIx the build issue

Update dnn.cpp

Update dnn.cpp

* Fix the build issue

* Implement BatchNorm Layer by WebNN API

* Update convolution_layer.cpp

This is a temporary file for Conv2d layer implementation

* Integrate some general functions into op_webnn.cpp&hpp

* Update const_layer.cpp

* Update convolution_layer.cpp

Still have some bugs that should be fixed.

* Update conv2d layer and fc layer

still have some problems to be fixed.

* update constLayer, conv layer, fc layer

There are still some bugs to be fixed.

* Fix the build issue

* Update concat_layer.cpp

Still have some bugs to be fixed.

* Update conv2d layer, fully connected layer and const layer

* Update convolution_layer.cpp

* Add OpenCV.js DNN module WebNN Backend (both using webnn-polyfill and electron)

* Delete bib19450.aux

* Add WebNN backend for OpenCV DNN Module

Update dnn.cpp

Update dnn.cpp

Update dnn.cpp

Update dnn.cpp

Add WebNN head files into OpenCV 3rd partiy files

Create webnn.hpp

update cmake

Complete README and add OpenCVDetectWebNN.cmake file

add webnn.cpp

Modify webnn.cpp

Can successfully compile the codes for creating a MLContext

Update webnn.cpp

Update README.md

Update README.md

Update README.md

Update README.md

Update cmake files and

update README.md

Update OpenCVDetectWebNN.cmake and README.md

Update OpenCVDetectWebNN.cmake

Fix OpenCVDetectWebNN.cmake and update README.md

Add source webnn_cpp.cpp and libary libwebnn_proc.so

Update dnn.cpp

Update dnn.cpp

Update dnn.cpp

Update dnn.cpp

update dnn.cpp

update op_webnn

update op_webnn

Update op_webnn.hpp

update op_webnn.cpp & hpp

Update op_webnn.hpp

Update op_webnn

update the skeleton

Update op_webnn.cpp

Update op_webnn

Update op_webnn.cpp

Update op_webnn.cpp

Update op_webnn.hpp

update op_webnn

update op_webnn

Solved the problems of released variables.

Fixed the bugs in op_webnn.cpp

Implement op_webnn

Implement Relu by WebNN API

Update dnn.cpp for better test

Update elementwise_layers.cpp

Implement ReLU6

Update elementwise_layers.cpp

Implement SoftMax using WebNN API

Implement Reshape by WebNN API

Implement PermuteLayer by WebNN API

Implement PoolingLayer using WebNN API

Update pooling_layer.cpp

Update pooling_layer.cpp

Update pooling_layer.cpp

Update pooling_layer.cpp

Update pooling_layer.cpp

Update pooling_layer.cpp

Implement poolingLayer by WebNN API and add more detailed logs

Update dnn.cpp

Update dnn.cpp

Remove redundant codes and add more logs for poolingLayer

Add more logs in the pooling layer implementation

Fix the indent issue and resolve the compiling issue

Fix the build problems

Fix the build issue

FIx the build issue

Update dnn.cpp

Update dnn.cpp

* Fix the build issue

* Implement BatchNorm Layer by WebNN API

* Update convolution_layer.cpp

This is a temporary file for Conv2d layer implementation

* Integrate some general functions into op_webnn.cpp&hpp

* Update const_layer.cpp

* Update convolution_layer.cpp

Still have some bugs that should be fixed.

* Update conv2d layer and fc layer

still have some problems to be fixed.

* update constLayer, conv layer, fc layer

There are still some bugs to be fixed.

* Update conv2d layer, fully connected layer and const layer

* Update convolution_layer.cpp

* Add OpenCV.js DNN module WebNN Backend (both using webnn-polyfill and electron)

* Update dnn.cpp

* Fix Error in dnn.cpp

* Resolve duplication in conditions in convolution_layer.cpp

* Fixed the issues in the comments

* Fix building issue

* Update tutorial

* Fixed comments

* Address the comments

* Update CMakeLists.txt

* Offer more accurate perf test on native

* Add better perf tests for both native and web

* Modify per tests for better results

* Use more latest version of Electron

* Support latest WebNN Clamp op

* Add definition of HAVE_WEBNN macro

* Support group convolution

* Implement Scale_layer using WebNN

* Add Softmax option for native classification example

* Fix comments

* Fix comments
2021-11-23 21:15:31 +00:00
Alexander Alekhin 12c1e1d149 Merge pull request #21032 from alalek:js_tracker_mil 2021-11-23 19:57:38 +00:00
ShuangLiu1992 fa222b0ea2 Update cap_android_camera.cpp
since u and v Pixel ptr have been swapped the compare condition should be updated too
2021-11-23 15:03:18 +00:00
Alexander Alekhin 101be77d9d Merge pull request #21092 from alalek:core_logger_show_timestamp 2021-11-22 22:44:31 +00:00
Ruan a6dbef89c2 Merge pull request #21094 from Ryyyc:patch-2
* Update how_to_use_OpenCV_parallel_for_new.markdown

Fix an incorrect jump link in the tutorial how_to_use_OpenCV_parallel_for_new.

* Update how_to_use_OpenCV_parallel_for_new.markdown

Update the URL of the tutorial code.
2021-11-22 18:52:08 +00:00
Sergey Ivanov 02f08879a4 Merge pull request #21022 from sivanov-work:async_mfp_demux
G-API: oneVPL Implement asynchronous MFP demux data provider

* Add dummy dmux

* Initial commit for draft versionn

* Demux for low res file works

* Add media source resolver to work over incorrect MIME

* Add MFP Demux logger

* stash changes

* Extend IDataProvider with CodecId, Add troubleshooting info

* Add IDapaProvider dispatcher

* Add ComPtrGuard wrappers

* Add new unit test scope for MFP demux & Add minor changes

* Enhance UTs

* Remove ATL header

* Remove ATL another one

* Fix build

* Add static for some methods

* Initial commit

* Add async demuxing

* Apply tdd idea

* Intro IDataProvider changes: +fetch_bitstream, -fetch_data

* Fix UTs

* Remove IDataProvider::CodecId & Fix EOF hang

* Remove sync demux

* Remove mfp async dependencies

* Remove VPL dependencies from IDataProvider declaration

* Apply comments

* Fix compilation

* Suppress unused warning

* Apply some comments

* Apply some comments

* Apply comments
2021-11-22 14:53:38 +03:00
Alexander Alekhin 61f1ee2d2d core(logger): dump timestamp information with message 2021-11-20 15:34:23 +00:00
Alexander Alekhin ac4b592b4e Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-11-20 05:13:50 +00:00
Alexander Alekhin 93b6e80cd7 Merge pull request #21063 from vrabaud:3.4_h_clamping 2021-11-19 20:28:25 +00:00
zcx f5de714451 Merge pull request #20987 from zcx-xxx:master
* Update drawing.cpp

optimize FillEdgeCollection function

* Update drawing.cpp

optimize FillEdgeCollection,remove sort_flag
2021-11-19 18:57:07 +03:00
Vincent Rabaud d4741eece1 Fix H clamping for very small negative values.
In case of very small negative h (e.g. -1e-40), with the current implementation,
you will go through the first condition and end up with h = 6.f, and will miss
the second condition.
2021-11-19 16:34:09 +01:00
Alexander Alekhin 585484cb06 Merge pull request #21067 from NickJackolson:nickjackolson/imread-warning 2021-11-18 22:48:40 +00:00
nickjackolson b696928a5b add !empty assertion in seamlessClone()
issue #20617 addresses lack of warnings on
seamlessClone() function when src is None.
This commit adds source check using CV_Assert
therefore debugging would be easier.

Signed-off-by: nickjackolson <metedurlu@gmail.com>
2021-11-18 21:19:05 +01:00
nickjackolson 79d4e865fe Add warning message to imread()
Add a warning message using CV_LOG__WARNING().
This way api behaviour is preserved. Outputs are
the same but user gets an extra warning in case
fopen() fails to access image file for some reason.
This would help new users and also debugging
complex apps which use imread()

Signed-off-by: nickjackolson <metedurlu@gmail.com>
2021-11-18 21:19:05 +01:00
Alexander Alekhin 8380879804 Merge pull request #21077 from alalek:js_test_pin_cli_table 2021-11-18 18:34:44 +00:00
Alexander Alekhin 091461cece Merge pull request #21081 from alalek:issue_17261 2021-11-18 18:23:00 +00:00
Alexander Alekhin d228c5459d core: avoid using of 'check' identifier 2021-11-18 16:02:59 +00:00
Alexander Alekhin 3d5d3ea20c js: add TrackerMIL 2021-11-18 12:13:05 +00:00
Alexander Alekhin de7f8eec04 js(test): pin cli-table dependency 2021-11-18 05:40:16 +00:00
Alexander Alekhin 4b6047e746 Merge pull request #21024 from anna-khakimova:ak/simd_mul 2021-11-17 18:41:52 +00:00
Anna Khakimova c47673bf10 Fluid: SIMD multiply kernel 2021-11-17 11:35:32 +03:00
Alexander Alekhin 49432009fe Merge pull request #21064 from alalek:doc_videoio_api_preference_3.4 2021-11-16 20:05:59 +00:00
Maxim Pashchenkov 2f6d2b08aa Merge pull request #20995 from mpashchenkov:mp/ocv-gapi-tdp-skip
G-API: Removing G-API test code that is a reflection of ts module

* gapi: don't hijack testing infrastructure

* Removed initDataPath functionality (ts module exists)

* Removed false for ocv_extra data from findDataFile

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-11-16 18:27:42 +00:00
Alexander Alekhin 473f10877c doc(videoio): fix apiPreference note, replace DSHOW(deprecated)->MSMF 2021-11-16 17:08:11 +00:00
Anatoliy Talamanov c7df82460c Merge pull request #20925 from TolyaTalamanov:at/enable-2d-inputs-giebackend
[G-API] Enable 2D inputs for GIEBackend

* Enable 2D inputs

* Fix typo
2021-11-16 12:52:42 +00:00
Anna Khakimova b19697e3ac Merge pull request #20914 from anna-khakimova:ak/simd_div
GAPI Fluid: SIMD Div kernel.

* HAL implementation for Div kernel

* Removed dbg lines

* Applied comments.

* Reworked

* Final version
2021-11-15 17:16:25 +00:00
Qiushi Zheng 3e51448ef0 Merge pull request #17889 from ZhengQiushi:my_3.4
QR code (encoding process)

* add qrcode encoder

* qr encoder fixes

* qr encoder: fix api and realization

* fixed qr encoder, added eci and kanji modes

* trigger CI

* qr encoder constructor fixes

Co-authored-by: APrigarina <ann73617@gmail.com>
2021-11-15 17:15:39 +00:00
Anatoliy Talamanov 2b2e515a30 Merge pull request #20918 from TolyaTalamanov:at/fix-empty-map-importNetwork
[G-API] Fix bugs in GIEBackend

* Remove inputs/outputs map from IEUnit

* Add test

* Add NV12 test

* Reorganize setBlob function

* Check that backend don't overwrite blob precision

* Stop setting config to global IE::Core

* Replace mutable to const_cast

* Update modules/gapi/test/infer/gapi_infer_ie_test.cpp

* Update modules/gapi/test/infer/gapi_infer_ie_test.cpp

* Make blob parameter as const ref

* Cosmetic fixes

* Fix failed test on inferROI

* Removed double ref for ii

* Disable tests

* Skip tests if device not available

* Use Sync prim under shared_ptr to avoid issue on MAC

* Apply WA for IE::Core

* Apply WA for MAC build

* Try to apply another WA

* Not release IE::Core for apple

* Put comment

* Support PreprocInfo for

* InferROI
* InferList
* InferList2

* Remove empty line

* Fix alignment

Co-authored-by: Maxim Pashchenkov <maxim.pashchenkov@intel.com>
2021-11-15 17:11:53 +00:00
Alexander Alekhin 394e640909 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-11-13 15:11:30 +00:00
Alexander Alekhin b48eb4e88b Merge pull request #21039 from SegaraRai:use-pragma-message 2021-11-12 14:31:03 +00:00
Trutnev Aleksei b525480b25 Merge pull request #20857 from alexgiving:atrutnev/move_API_samples
Move API sample code to tutorial_code location
2021-11-12 14:17:21 +00:00
Alexander Alekhin 45f18eaa52 Merge pull request #21048 from ffontaine:4.x 2021-11-12 12:28:28 +00:00
Fabrice Fontaine 4c92a2869b modules/videoio/src/cap_ffmpeg_impl.hpp: fix build with gcc 4.8
Fix the following build failure with gcc 4.8:

In file included from /home/buildroot/autobuild/instance-3/output-1/build/opencv4-4.5.4/modules/videoio/src/cap_ffmpeg_impl.hpp:100:0,
                 from /home/buildroot/autobuild/instance-3/output-1/build/opencv4-4.5.4/modules/videoio/src/cap_ffmpeg.cpp:50:
/home/buildroot/autobuild/instance-3/output-1/build/opencv4-4.5.4/modules/videoio/src/cap_ffmpeg_hw.hpp: In constructor 'HWAccelIterator::HWAccelIterator(cv::VideoAccelerationType, bool, AVDictionary*)':
/home/buildroot/autobuild/instance-3/output-1/build/opencv4-4.5.4/modules/videoio/src/cap_ffmpeg_hw.hpp:939:23: error: use of deleted function 'std::basic_istringstream<char>& std::basic_istringstream<char>::operator=(const std::basic_istringstream<char>&)'
             s_stream_ = std::istringstream(accel_list);
                       ^
In file included from /home/buildroot/autobuild/instance-3/output-1/host/opt/ext-toolchain/arm-none-linux-gnueabi/include/c++/4.8.3/complex:45:0,
                 from /home/buildroot/autobuild/instance-3/output-1/build/opencv4-4.5.4/modules/core/include/opencv2/core/cvstd.inl.hpp:47,
                 from /home/buildroot/autobuild/instance-3/output-1/build/opencv4-4.5.4/modules/core/include/opencv2/core.hpp:3306,
                 from /home/buildroot/autobuild/instance-3/output-1/build/opencv4-4.5.4/modules/videoio/include/opencv2/videoio.hpp:46,
                 from /home/buildroot/autobuild/instance-3/output-1/build/opencv4-4.5.4/modules/videoio/src/precomp.hpp:57,
                 from /home/buildroot/autobuild/instance-3/output-1/build/opencv4-4.5.4/modules/videoio/src/cap_ffmpeg.cpp:42:
/home/buildroot/autobuild/instance-3/output-1/host/opt/ext-toolchain/arm-none-linux-gnueabi/include/c++/4.8.3/sstream:272:11: note: 'std::basic_istringstream<char>& std::basic_istringstream<char>::operator=(const std::basic_istringstream<char>&)' is implicitly deleted because the default definition would be ill-formed:
     class basic_istringstream : public basic_istream<_CharT, _Traits>
           ^
/home/buildroot/autobuild/instance-3/output-1/host/opt/ext-toolchain/arm-none-linux-gnueabi/include/c++/4.8.3/sstream:272:11: error: use of deleted function 'std::basic_istream<char>& std::basic_istream<char>::operator=(const std::basic_istream<char>&)'

Fixes:
 - http://autobuild.buildroot.org/results/60f8846b435dafda0ced412d59ffe15bdff0810d

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
2021-11-12 09:50:17 +01:00
Alexander Alekhin 8041ab8a61 Merge pull request #21025 from alalek:issue_21004
* dnn(ocl4dnn): fix LRN layer accuracy problems

- FP16 intermediate computation is not accurate and may provide NaN values

* dnn(test): update tolerance for FP16
2021-11-12 01:54:07 +03:00
Alexander Alekhin 8251fc0811 Merge pull request #21028 from AleksandrPanov:fix_markers_parse_in_gen_pattern.py 2021-11-11 22:11:34 +00:00
Alexander Alekhin 827ff80c06 Merge pull request #20977 from JulieBar:remap_overflow 2021-11-11 22:06:16 +00:00
Trutnev Aleksei 18ca998f67 Merge pull request #21040 from alexgiving:atrutnev/rename_RMatAdapter
GAPI: Rename MatAdapter to RMatOnMat
2021-11-11 14:52:38 +03:00
tv3141 cb286a66be Merge pull request #21030 from tv3141:fix_seg_fault_houghlinespointset
Fix seg fault houghlinespointset

* Clarify parameter doc for HoughLinesPointSet

* Fix seg fault.

* Add regression test.

* Fix latex typo
2021-11-10 22:15:38 +03:00
SegaraRai 8444470e3a use #pragma message instead of #warning for non-GCC compilers 2021-11-11 03:14:19 +09:00
Alexander Alekhin f33828a1ca Merge pull request #20870 from pkubaj:master 2021-11-10 16:08:20 +00:00
Piotr Kubaj 68e425f869 Add support for runtime CPU feature check on POWER on FreeBSD.
1. Code uses PPC_FEATURE_HAS_VSX, but it's not checked similarly to
PPC_FEATURE2_ARCH_3_00 and PPC_FEATURE2_ARCH_3_00 for availability. FreeBSD has
those macros in machine/cpu.h, but I went with the way chosen for
PPC_FEATURE2_ARCH_3_00 and PPC_FEATURE2_ARCH_3_00. Other than that, FreeBSD also
has sys/auxv.h and that's where elf_aux_info() is defined.
2. getauxval() is actually Linux-only, but code checked for __unix__. It won't
work on all UNIX, so change it back to __linux__. Add another code variant
strictly for FreeBSD.
3. Update comment. This commit adds code for FreeBSD, but recently there
appeared support for powerpc64 in OpenBSD.
2021-11-10 13:28:09 +00:00
Sergey Ivanov da6344297a Merge pull request #20901 from sivanov-work:merge_source_unite_perf_mod
G-API: oneVPL - Performance: Add async decode pipeline & add cached pool

* Add async decode pipeline & intro cached pool

* Fix performacne test with checking OPENCV_EXTRA

* Add sip perf test with no VPL

* Fix misprint

* Remove empty line..

* Apply some comments

* Apply some comments

* Make perf test fail if no OPENCV_TEST_DATA_PATH declared
2021-11-10 13:21:51 +00:00
Anna Khakimova 3cfca01372 Merge pull request #20664 from anna-khakimova:ak/resize_simd
Fluid: SIMD for Resize Linear 8UC3

* SIMD for fluid::Resize 8U3C

* Rework horizontal pass + add 8U4C case

* Reproduce stackoverflow test

* StackOverflow test

* SSE42 impl

* SSE42 impl improvement

* GAPI:SSE42 simd opt for Resize 8UC3. Final version

* Fix tests

* Conditional compilation fix

* Applied comments

* Applied comments. Step2

* Applied comments. Step2
2021-11-10 13:19:52 +00:00
Alexander Alekhin d934bb15b0 Merge pull request #20998 from alalek:update_protobuf_3.19.1
3rdparty(protobuf): upgrade 3.5.2 => 3.19.1

* 3rdparty(protobuf): upgrade 3.5.2 => 3.19.1

* dnn: update protobuf files (3.19.1)

* 3rdparty(protobuf): re-apply OpenCV patch for custom fields (3.19.1)

* protobuf: suppress new build warnings

* protobuf: remove unused files
2021-11-10 12:03:45 +00:00
AleksandrPanov 0c0a8392e5 fix markers parse in gen_pattern.py 2021-11-10 11:14:06 +03:00
ZaKiiiiiiiii 98b6ce353c Merge pull request #20904 from Crayon-new:fix_bug_in_maxLayer
fix bug: wrong output dimension when "keep_dims" is false in pooling layer.

* fix bug in max layer

* code align

* delete permute layer and add test case

* add name assert

* check other cases

* remove c++11 features

* style:add "const" remove assert

* style:sanitize file names
2021-11-09 19:24:04 +03:00
Alexander Alekhin 58043dac0f Merge pull request #21027 from anonymouss:4.x 2021-11-09 15:12:35 +00:00
jcong d2c1f1131b videoio: drop unnecessary offset for accessing video output buffer
Fix: #21021

NDK API AMediaCodec_getOutputBuffer() returns MediaCodecBuffer::data()
which is actually ABuffer::data(). The returned buffer address is already
adjusted by offset.

More info:
    ABuffer::base() returns base address without offset
    ABuffer::data() returns base + offset

Change-Id: I2936339ce4fa9acf657a5a7d92adc1275d7b28a1
2021-11-09 17:23:34 +08:00
Lukas-Alexander Weber fa5c7a9e75 Merge pull request #21020 from lukasalexanderweber:squash
Created Stitching Tool based on stitching_detailed.py
2021-11-08 11:54:06 +00:00
Alexander Alekhin ceb94d52a1 Merge pull request #21016 from alalek:issue_21002 2021-11-06 22:12:40 +00:00
Alexander Alekhin a2716712ab highgui(win32): fix trackbar setRange 2021-11-06 15:19:22 +00:00
Alexander Alekhin 1ac7baceff Merge pull request #21005 from nikpappas:bug-samples-falsecolor-trackbar 2021-11-06 14:19:58 +00:00
Nikolaos Pappas 968d94d417 Fix trackbar in falsecolor cpp sample 2021-11-06 10:11:58 +00:00
Alexander Alekhin 7842181b47 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-11-05 09:27:46 +00:00
Alexander Alekhin 2ce47fda88 Merge pull request #21011 from vrabaud:3.4 2021-11-05 09:25:50 +00:00
Vincent Rabaud ffd010767f Only use fma functions when CV_FMA3 is set.
In practice, processors offering AVX2/AVX512 also FMA, that is why it got unnoticed.
2021-11-04 23:15:49 +01:00
Alexander Alekhin 635990a5b0 Merge pull request #21009 from alalek:dnn_skip_tests_32bit 2021-11-04 18:15:50 +00:00
Alexander Alekhin 562f2375c5 dnn(test): skip tests with high memory usage
- 32-bit configuration may fail due to memory fragmentation
2021-11-04 13:26:33 +00:00
Alexander Alekhin edf533c83e Merge pull request #21007 from alalek:cmake_dnn_fix_wrong_tengine_order 2021-11-04 12:28:27 +00:00
Alexander Alekhin c1d61c88e9 dnn(cmake): don't hijack OpenCL options with Tengine 2021-11-04 09:59:19 +00:00
Alexander Alekhin 6360b846c6 Merge pull request #21003 from APrigarina:add_test_qrdetect_fix 2021-11-03 22:32:00 +00:00
Alexander Alekhin 57900d07f0 Merge pull request #20882 from flytogcp:flytogcp-patch-1 2021-11-03 20:30:24 +00:00
APrigarina 8e72e1ed88 add test case for QR detect fix 2021-11-03 19:56:54 +00:00
Alexander Alekhin 10c547396d Merge pull request #20990 from alalek:fix_warnings_msvc_clang_dshow_3.4 2021-11-03 19:51:31 +00:00
cpengu 66dd871288 Update qrcode.cpp
Fixed issue #20880, QRDetect::searchHorizontalLines() boundary condition will skip the matched qrcode near the end
2021-11-03 19:45:24 +00:00
Alexander Alekhin d484939c02 Merge pull request #20999 from alalek:dnn_replace_deprecated_calls
dnn(protobuf): replace deprecated calls

* dnn: replace deprecated ByteSize() => ByteSizeLong()

* dnn: replace deprecated calls, use GetRepeatedFieldRef
2021-11-03 15:59:36 +00:00
Alexander Alekhin 85fd8729ce Merge pull request #20970 from s-trinh:update_Bayer_naming 2021-11-02 20:41:17 +00:00
Alexander Alekhin b3e16c6423 videoio(dshow): eliminate build warnings from MSVC-Clang 2021-11-02 19:22:47 +00:00
Souriya Trinh 30d6766db4 Add conventional Bayer naming. 2021-11-02 20:17:57 +01:00
Trutnev Aleksei 17234f82d0 Merge pull request #20836 from alexgiving:atrutnev/rename_Adapter_to_IAdapter
* Rename RMat::Adapter to RMat::IAdapter

* Add comments
2021-11-01 12:43:27 +00:00
Alexander Alekhin 7b57df02a7 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-10-30 14:26:17 +00:00
Alexander Alekhin b65ae3b036 Merge pull request #20982 from alalek:highgui_drop_cvGetWindowImageRect_4.x 2021-10-30 14:01:33 +00:00
Alexander Alekhin bce76a7977 Merge pull request #20980 from alalek:highgui_fix_cvGetWindowImageRect_3.4 2021-10-30 13:59:08 +00:00
Alexander Alekhin 66f3e97457 highgui: drop invalid cvGetWindowImageRect 2021-10-30 12:47:07 +00:00
Alexander Alekhin 0ee61d178f highgui: drop invalid cvGetWindowImageRect
- return type is C++ template
- removal from 'extern "C"' scope broke ABI anyway, so this symbols is removed completelly
2021-10-30 12:40:20 +00:00
Alexander Alekhin 1ceba29f4b Merge pull request #20976 from alalek:issue_20968 2021-10-30 10:27:32 +00:00
Alexander Alekhin 40c748a2ae python: properly handle step for multichannel case 2021-10-29 18:29:19 +00:00
Alexander Alekhin 0e9453a395 Merge pull request #20971 from alalek:cmake_build_type_use_release 2021-10-29 17:45:09 +00:00
Julie Bareeva 69d0bc8fd5 Added overflow handling during conversion from float to int for LinearFilter 2021-10-29 19:46:11 +03:00
Trutnev Aleksei 6a73e5a720 Merge pull request #20922 from alexgiving:atrutnev/align_expect_assert_macros
GAPI: Align EXPECT/ASSERT macros

* Align TEST macros

* restart CI

* Fix ASSERT_GT in gapi_async_test
2021-10-29 16:30:35 +00:00
Alexander Alekhin e70ba29d95 Merge pull request #20972 from Isydmr:correct-db-text-detector-drive-links 2021-10-29 15:19:34 +00:00
Alexander Alekhin e5647cf70d cmake: use CMAKE_BUILD_TYPE=Release by default 2021-10-29 15:15:17 +00:00
Ihsan Soydemir 9637cf0574 Correct drive links for DB_IC15 and DB_TD500 2021-10-29 13:30:51 +03:00
Alexander Alekhin 74cc63ba2f Merge pull request #20969 from alalek:fix_msvc_clang_warning_noreturn 2021-10-28 23:00:49 +00:00
Alexander Alekhin 0b6e360602 Merge pull request #20967 from alalek:fix_msvc_clang_unused_parameter 2021-10-28 22:27:41 +00:00
Alexander Alekhin a49cda6523 core: eliminate Winvalid-noreturn in base.hpp 2021-10-28 21:33:20 +00:00
Alexander Alekhin d612c72405 build: fix MSVC-Clang warnings about unused parameters in stubs 2021-10-28 21:08:36 +00:00
Maxim Pashchenkov eb152d7431 Merge pull request #20937 from mpashchenkov:mp/ocv-gapi-warnings
G-API: Disable Windows warnings with 4996 code

* Windows warnings 4503 and 4996 are disabled with dnn style

* Applying comments to review

* Reproducing

* Added check MSVC_VERSION for both warnings
2021-10-28 18:19:46 +00:00
Alexander Alekhin 6bd143dd25 Merge pull request #20961 from alalek:fix_msvc_clang 2021-10-28 13:54:24 +00:00
Alexander Alekhin 770d3eabc0 Merge pull request #20960 from alalek:fix_icc_support_3.4 2021-10-28 13:54:07 +00:00
Alexander Alekhin 75e2ba5af3 core(simd): fix compilation with MSVC-Clang 2021-10-28 11:25:00 +00:00
Alexander Alekhin 1726bb6c0d build(icc): fix nodiscard attribute handling 2021-10-28 05:52:22 +00:00
Alexander Alekhin 5dfe65d53a cmake: fix popcnt detection with Intel Compiler 2021-10-28 05:37:23 +00:00
Alexander Alekhin 83afd09f13 Merge pull request #20950 from Harvey-Huang:master 2021-10-27 20:09:51 +00:00
Alexander Alekhin d059cc7170 Merge pull request #20958 from noahstier:3.4_tvl1_optimization 2021-10-27 19:59:57 +00:00
Alexander Alekhin 96488c1c74 Merge pull request #20954 from shengyu7697:remove-redundant-semicolon 2021-10-27 19:31:27 +00:00
Noah Stier 84a81579ba tvl1 cuda optflow optimization 2021-10-27 12:01:53 -07:00
Chengrui Wang 244ba1a61a Merge pull request #20935 from crywang:dnn_face
Fix problems in tutorial and python sample of dnn_face.

* Update dnn_face.markdown

* Update face_match.py
2021-10-27 12:23:42 +00:00
shengyu 9dadc06e64 remove redundant semicolons 2021-10-27 20:19:05 +08:00
Alexander Alekhin 60f949e36f Merge pull request #20924 from alexgiving:atrutnev/fix_gkernel_documentation 2021-10-27 09:17:16 +00:00
Harvey af154e3053 fixed bug: opencv read tif file convert Palette color image as grayscale image 2021-10-27 14:10:11 +08:00
Alexander Alekhin 9e6c290696 Merge pull request #20947 from alalek:cmake_find_package_quiet 2021-10-26 16:04:17 +00:00
MaximMilashchenko 0a71063530 Merge pull request #20942 from MaximMilashchenko:AudioPatch
Audio patch

* fixed microphone, audio position

* fixed docs

* changed AudioOpenCheck
2021-10-26 14:33:53 +00:00
Alexander Alekhin 0b1ae11498 cmake: find_package with QUIET 2021-10-26 14:29:57 +00:00
Alexander Alekhin 017a4e7c30 Merge pull request #20940 from alalek:cmake_fix_samples_parallel_backend 2021-10-25 18:17:13 +00:00
Alexander Alekhin 3891f18e71 samples: update parallel_backend examples
- use find_package(TBB)
2021-10-25 16:21:05 +00:00
Alexander Alekhin 6a2077cbd8 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-10-23 15:33:31 +00:00
Alexander Alekhin aa11cc19e8 Merge pull request #20919 from berak:patch-1 2021-10-22 14:08:08 +00:00
Harvey 9267536fee Merge pull request #20875 from Harvey-Huang:master
* bmp specified BI_BITFIELDS should take care RGBA bit mask

* change the name

* support xrgb bmp file

* support xrgb bmp file(add test case)

* update testing code
2021-10-22 17:04:19 +03:00
berak a6f5717567 resolves #20913
imgproc: remove asserts for circles_ in HoughCircles
2021-10-22 15:07:57 +02:00
atrutnev 0a58d6812a fix gkernel Doxygen documentation 2021-10-22 11:06:09 +03:00
Alexander Alekhin 12507aab8a Merge pull request #20912 from AleksandrPanov:fix_findMinEnclosingTriangle 2021-10-21 16:26:53 +00:00
Sergey Ivanov d376fe9e17 Merge pull request #20921 from sivanov-work:atl_patch
G-API: FIX OpenVINO build - Add CComPtr RAII replacement into G-API sample

* Add CComPtr RAII replacement into G-API sample

* Remove completely `atlbase.h'
2021-10-21 16:12:03 +00:00
AleksandrPanov d21622bef4 fix findMinEnclosingTriangle and add tests 2021-10-21 18:12:51 +03:00
Maksim Shabunin 7febec49b2 Merge pull request #20614 from mshabunin:use-onevpl-load
videoio: use oneVPL load mechanism, encoder bitrate estimation

* videoio: updated oneVPL support - use mfxLoad

* videoio: advanced bitrate estimation for MFX encoder

* videoio: improved MediaSDK/oneVPL/libva detection

* videoio(ffmpeg): don't try oneVPL

* videoio(test): tune checks of videoio_mfx.read_write_raw tests

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-10-21 13:56:11 +00:00
Alexander Alekhin 14d5098ca2 Merge pull request #20903 from alalek:samples_fix_nothreads_build 2021-10-21 13:04:01 +00:00
Alexander Alekhin bc8eac2439 Merge pull request #20906 from alalek:backport_20903 2021-10-21 13:03:46 +00:00
Alexander Alekhin 4e65db80e8 Merge pull request #20916 from Harvey-Huang:32bit_rgb 2021-10-21 11:45:48 +00:00
Alexander Alekhin c0c71d6b3a Merge pull request #20920 from alalek:hotfix_clang_abi 2021-10-21 11:35:58 +00:00
Alexander Alekhin bac1c6d12f hotfix: repair Clang ABI 2021-10-21 09:36:25 +00:00
Harvey ce68291d83 32bit rgb bmp file should not copy data as rgba 2021-10-21 16:47:27 +08:00
Alexander Alekhin 4176a0ade3 Merge pull request #20908 from alalek:4.x_drop_legacy 2021-10-21 07:09:14 +00:00
Alexander Alekhin ec10f2e72b Merge pull request #20877 from rogday:simple_layers 2021-10-20 17:00:38 +00:00
MaximMilashchenko f36c268b9e Merge pull request #19721 from MaximMilashchenko:Audio
add audio support in cap_msmf

* audio msmf

* fixed warnings

* minor fix

* fixed SampleTime MSMF

* minor fix, fixed audio test, retrieveAudioFrame

* fixed warnings

* impelemented sync audio and video stream with start offset

* fixed error

* fixed docs

* fixed audio sample

* CAP_PROP_AUDIO_POS, minor fixed

* fixed warnings

* videoio(MSMF): update audio test checks, add debug logging

* fixed

* fixed desynchronization of time positions, warnings

* fixed warnings

* videoio(audio): tune tests checks

* videoio(audio): update properties description

* build warnings

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-10-20 16:18:24 +03:00
Alexander Alekhin 824392a1c2 Merge pull request #20910 from lukasalexanderweber:sift_fix 2021-10-20 09:48:20 +00:00
Sergey Ivanov 1f9a7b8fd3 Merge pull request #20738 from sivanov-work:merge_master_vpl_dev_select
G-API: oneVPL - Implement IDeviceSelector & default cfg_param-based selector

* Initial commit

* Add MACRO undef

* Change IDeviceSelector, Change Inf sample for choose external device

* Fix compilation

* Address some comments

* Fix compilation

* Add missing header

* Add EXPORT to dev selector

* Add guard

* Remove enum type attr

* Fix compilation without VPL

* Add HAVE_INFER guard in sample

* Remove unusable include from tests

* Remove unusable include from sample

* Remove cl_d3d11 header from unit test
2021-10-20 12:43:32 +03:00
Lukas Weber 9379e85e23 changed no longer patented SIFT 2021-10-20 09:07:48 +02:00
Alexander Alekhin 805c2832c1 4.x: drop DISABLE_OPENCV_24_COMPATIBILITY macro
not used in 4.x code
2021-10-20 05:45:40 +00:00
Alexander Alekhin d33a048d89 Merge pull request #20892 from alalek:issue_20888 2021-10-19 19:45:35 +00:00
Alexander Alekhin f77fdc0ce8 samples: fix build without threading support 2021-10-19 13:35:09 +00:00
Zhuo Zhang 7da51787b9 Merge pull request #20900 from zchrissirhcz:3.4-hwfeatures-support-qnx
* fix: correctly check neon flags for QNX platform

* refactor: change __QNXNTO__ to __QNX__
2021-10-19 13:30:27 +00:00
Alexander Alekhin b1f422c1c5 Merge pull request #20894 from alalek:core_simd_int64_ctor_sse 2021-10-19 13:29:52 +00:00
rogday b3f966e2ca Merge pull request #20883 from rogday:eltwise_refactoring
* backport elementwise_layers refactor

* keep NULL
2021-10-19 13:29:22 +00:00
Alexander Alekhin 3f191e1b75 Merge pull request #20897 from ThalesGroup:master 2021-10-19 13:27:54 +00:00
Alexander Alekhin 6d5fdfbf73 samples: fix build without threading support 2021-10-19 09:31:12 +00:00
Michel Promonet 9a9e457dd6 Allow to set av_log_set_level to reduce ffmpeg level below AV_LOG_ERROR 2021-10-19 10:46:41 +02:00
Alexander Alekhin c316dbe2aa Merge pull request #20895 from sergiud:avx-error-immediate 2021-10-18 19:08:50 +00:00
Alexander Alekhin b5fcb06a76 core(SIMD): update int64 SSE constructor 2021-10-18 18:59:40 +00:00
Anatoliy Talamanov b5a9a6793b Merge pull request #20856 from TolyaTalamanov:at/cfg-batch-size
G-API: Extend ie::Params to specify batch size

* Add cfgBatchSize to ie::Params

* Fix comments to review
2021-10-18 19:31:48 +03:00
Sergey Ivanov 0cf79155d4 Merge pull request #20773 from sivanov-work:merge_vpl_source_unite
G-API: oneVPL (simplification) unite components in entire VPL source

* Unify components in VPLSource

* Revert back decode WRN & Add compile guard

* Address come comments

* Add source alias

* Apply comment for exception handling
2021-10-18 19:20:55 +03:00
Sergiu Deitsch f8f9f3c438 fixed AVX compile error
Some older compilers do not allow to pass a `const int` as an immediate. Use an unnamed enum instead.
2021-10-18 14:56:19 +02:00
Alexander Alekhin 1926e919be dnn(int8): fix using of incorrect UMat constructor 2021-10-18 04:46:00 +00:00
Alexander Alekhin e6c68eed51 Merge pull request #20879 from Wehzie:patch-1 2021-10-17 16:50:13 +00:00
Wehzie f9e747dbc6 Fixed typo in CV_Error message
Error was "Input parameters must be a matrices!", but "matrices" is plural and doesn't allow the unspecific article "a".
2021-10-17 15:37:14 +03:00
Alexander Alekhin 0e86e292e4 Merge pull request #20885 from alalek:cmake_fix_python_submodules 2021-10-15 15:34:30 +00:00
Alexander Alekhin a590682764 cmake: update installation of python extra submodules
- support Python standalone builds
- loader installs submodules unconditionally
2021-10-15 14:21:31 +00:00
Alexander Alekhin 31c40fa4cc Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-10-15 13:35:03 +00:00
Smirnov Egor 1feb3838b5 add Ceil, Floor, Log, Round, Sqrt, Not, Equal, Less, Greater 2021-10-15 16:02:46 +03:00
Nicholas Ho bd0732b1d0 Merge pull request #20740 from Nicholas-Ho-arm:3.4_SymmColumnVec_32f8u
* Add SymmColumnVec_32f8u

* Fix double to float warnings
2021-10-15 11:47:53 +00:00
Alexander Alekhin 0b5cbcefdd Merge pull request #20868 from icestraw:fix-type-error-of-slice-indices 2021-10-14 16:11:37 +00:00
icestraw e4a87f2f4f fix type error of slice indices 2021-10-14 11:52:35 +08:00
Alexander Alekhin 3c8cadf7ca Merge pull request #20867 from alalek:fix_CV_POPCNT_U64_msvs 2021-10-13 17:08:58 +00:00
Alexander Alekhin 7c0b26e8a0 Merge pull request #20834 from sthalik:msvc-shared-library-static-crt 2021-10-13 14:21:08 +00:00
Alexander Alekhin 982503e9a8 core: ensure 'int' result from CV_POPCNT_U64(x) 2021-10-13 01:14:37 +00:00
Stanislaw Halik 3d93675ff9 fix link error on shared libs with -MT 2021-10-12 17:50:31 +02:00
Alexander Alekhin 53d6c9b9c0 Merge pull request #20860 from rogday:sum_fix 2021-10-12 15:36:32 +00:00
Alexander Alekhin a02e90d502 Merge pull request #20859 from rogday:sub_const_fix 2021-10-11 18:51:46 +00:00
Smirnov Egor 238dbffb48 change asserts for Sum 2021-10-11 20:59:44 +03:00
Smirnov Egor a9d7b6eab7 fix const - input and remove unimplemented function 2021-10-11 18:58:10 +03:00
Alexander Alekhin 39c3334147 Merge tag '4.5.4' 2021-10-10 00:22:46 +00:00
Alexander Alekhin 4223495e6c release: OpenCV 4.5.4 2021-10-09 15:48:26 +00:00
Alexander Alekhin 023e86d68f Merge pull request #20848 from alalek:reverse_plugins_candidates_order 2021-10-09 15:45:17 +00:00
Yaniv Hollander ac57be91e1 Merge pull request #20721 from YanivHollander:DocFixes
Doc fixes

* Update imgproc.hpp

* Update imgproc.hpp
2021-10-09 15:43:50 +00:00
Alexander Alekhin c2e65bafb5 Merge pull request #20846 from alalek:issue_19947 2021-10-09 06:22:02 +00:00
Alexander Alekhin 74161b2122 Merge pull request #20847 from alalek:fix_build_js_simd_tests 2021-10-09 05:59:24 +00:00
Alexander Alekhin 39ee5c5a46 plugins: reverse candidates order to fetch higher versions first 2021-10-08 20:34:07 +00:00
Alexander Alekhin 788f330d07 js: fix build of SIMD tests 2021-10-08 20:15:41 +00:00
Alexander Alekhin af56151231 highgui(docs): we don't support 32-bit integer images in imshow() 2021-10-08 19:51:18 +00:00
Yuantao Feng 34d359fe03 Merge pull request #20422 from fengyuentau:dnn_face
Add DNN-based face detection and face recognition into modules/objdetect

* Add DNN-based face detector impl and interface

* Add a sample for DNN-based face detector

* add recog

* add notes

* move samples from samples/cpp to samples/dnn

* add documentation for dnn_face

* add set/get methods for input size, nms & score threshold and topk

* remove the DNN prefix from the face detector and face recognizer

* remove default values in the constructor of impl

* regenerate priors after setting input size

* two filenames for readnet

* Update face.hpp

* Update face_recognize.cpp

* Update face_match.cpp

* Update face.hpp

* Update face_recognize.cpp

* Update face_match.cpp

* Update face_recognize.cpp

* Update dnn_face.markdown

* Update dnn_face.markdown

* Update face.hpp

* Update dnn_face.markdown

* add regression test for face detection

* remove underscore prefix; fix warnings

* add reference & acknowledgement for face detection

* Update dnn_face.markdown

* Update dnn_face.markdown

* Update ts.hpp

* Update test_face.cpp

* Update face_match.cpp

* fix a compile error for python interface; add python examples for face detection and recognition

* Major changes for Vadim's comments:

* Replace class name FaceDetector with FaceDetectorYN in related failes

* Declare local mat before loop in modules/objdetect/src/face_detect.cpp

* Make input image and save flag optional in samples/dnn/face_detect(.cpp, .py)

* Add camera support in samples/dnn/face_detect(.cpp, .py)

* correct file paths for regression test

* fix convertion warnings; remove extra spaces

* update face_recog

* Update dnn_face.markdown

* Fix warnings and errors for the default CI reports:

* Remove trailing white spaces and extra new lines.

* Fix convertion warnings for windows and iOS.

* Add braces around initialization of subobjects.

* Fix warnings and errors for the default CI systems:

* Add prefix 'FR_' for each value name in enum DisType to solve the
redefinition error for iOS compilation; Modify other code accordingly

* Add bookmark '#tutorial_dnn_face' to solve warnings from doxygen

* Correct documentations to solve warnings from doxygen

* update FaceRecognizerSF

* Fix the error for CI to find ONNX models correctly

* add suffix f to float assignments

* add backend & target options for initializing face recognizer

* add checkeq for checking input size and preset size

* update test and threshold

* changes in response to alalek's comments:

* fix typos in samples/dnn/face_match.py

* import numpy before importing cv2

* add documentation to .setInputSize()

* remove extra include in face_recognize.cpp

* fix some bugs

* Update dnn_face.markdown

* update thresholds; remove useless code

* add time suffix to YuNet filename in test

* objdetect: update test code
2021-10-08 19:13:49 +00:00
Alexander Alekhin 4672dbda2a Merge pull request #20818 from rogday:yolov4x_mish_cuda 2021-10-08 19:12:43 +00:00
Alexander Alekhin 62252d157e Merge tag '3.4.16' 2021-10-08 19:05:00 +00:00
Alexander Alekhin b1cf550123 release: OpenCV 3.4.16 2021-10-08 18:31:56 +00:00
Smirnov Egor 9c84749e2c backport YOLOv4x-mish new_coords CUDA implementation 2021-10-08 14:14:49 +03:00
Alexander Alekhin cca4c47781 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-10-08 11:05:45 +00:00
Alexander Alekhin 17bd9a1fa1 Merge pull request #20841 from alalek:core_keep_TlsAbstraction_singleton_3.4 2021-10-08 07:01:05 +00:00
Alexander Alekhin 0321644bbd Merge pull request #20842 from alalek:valgrind_suppression 2021-10-08 09:29:41 +03:00
Alexander Alekhin 81e7988eb9 Merge pull request #20840 from alalek:dnn_ocl_cleanup_code 2021-10-08 05:07:51 +00:00
Alexander Alekhin 4985311d46 core(tls): avoid destruction of TlsAbstraction singleton 2021-10-08 03:12:58 +00:00
Alexander Alekhin 05348f3250 Merge pull request #20839 from alalek:issue_20828_netbsd 2021-10-08 02:19:54 +00:00
Alexander Alekhin 003609e565 Merge pull request #20838 from alalek:fix_20833 2021-10-08 02:09:46 +00:00
Alexander Alekhin e0cfaee7aa Merge pull request #20837 from alalek:fixup_20825 2021-10-08 02:08:26 +00:00
Jonas Vautherin 9537a909f7 Merge pull request #20801 from JonasVautherin:fix-gst-error-handling
* Fix gst error handling

* Use the return value instead of the error, which gives no guarantee of being NULL in case of error
* Test err pointer before accessing it
* Remove unreachable code

* videoio(gstreamer): restore check in writer code

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-10-08 02:07:04 +00:00
Alexander Alekhin e75387f029 core: fix compilation of copy ctors/assignment operators with GCC 4.x 2021-10-08 00:49:30 +00:00
Alexander Alekhin 8c2dd5fb9a dnn(ocl4dnn): cleanup dead code, improve logging 2021-10-08 00:39:40 +00:00
Alexander Alekhin 27545dcc86 core: add __NetBSD__ build fix in parallel.cpp 2021-10-07 23:29:28 +00:00
Alexander Alekhin 724e04e979 dnn(ocl4dnn): add extra checks to convolution layer
- prevent running code over unsupported/non-tested configurations
- prevent integer div by zero
2021-10-07 23:18:32 +00:00
Alexander Panov dfc94c58f0 Merge pull request #20823 from AleksandrPanov:fix_orb_integer_overflow
Fix ORB integer overflow

* set size_t step to fix integer overflow in ptr0 offset

* added issue_537 test

* minor fix tags, points

* added size_t_step and offset to remove mixed unsigned and signed operations

* features2d: update ORB checks

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-10-07 22:46:25 +00:00
Alexander Alekhin 4b0f8d76f4 Merge pull request #20835 from sthalik:msvc-no-thread-support 2021-10-07 16:43:19 +00:00
Alexander Alekhin fac895d7ba Merge pull request #20831 from sthalik:fix-msvc-build-3.4 2021-10-07 16:16:59 +00:00
Stanislaw Halik d023f316ac fix OPENCV_DISABLE_THREAD_SUPPORT
Message was,
  CMake Error at CMakeLists.txt:1475 (message):
    Not all parallel frameworks have been disabled (using Concurrency).
2021-10-07 16:43:17 +02:00
Stanislaw Halik 04b40ff221 add new supported MSVC version 2021-10-07 13:46:34 +02:00
Alexander Alekhin 03a08435e2 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-10-07 04:27:22 +00:00
Alexander Alekhin 4dd3ab8f32 Merge pull request #20825 from alalek:issue_20718 2021-10-06 22:50:09 +00:00
Alexander Alekhin 8e0660ad54 Merge pull request #20820 from alalek:issue_20514 2021-10-06 22:47:31 +00:00
Alexander Alekhin 1f42512199 Merge pull request #20819 from alalek:issue_19567 2021-10-06 22:46:58 +00:00
Alexander Alekhin 1a29ea1038 Merge pull request #20829 from alalek:dnn_ocl_skip_int8_tests 2021-10-06 22:46:21 +00:00
Alexander Alekhin eab2b9dc09 core: ensure is_trivially_copyable for simple types 2021-10-06 21:39:53 +00:00
Alexander Alekhin 94e92cd6c0 dnn(ocl): skip int8 tests due to memory access issues 2021-10-06 21:27:18 +00:00
Alexander Alekhin 57cd6d2de1 Merge pull request #20826 from alalek:fix_20824 2021-10-06 20:30:48 +00:00
Alexander Alekhin 822d468232 Merge pull request #20813 from rogday:soft_nms 2021-10-06 20:20:34 +00:00
Alexander Alekhin bdaa6a1910 highgui: repair Qt backend 2021-10-06 19:14:22 +00:00
Smirnov Egor 2221dcc9f2 add SoftNMS implementation 2021-10-06 21:31:45 +03:00
Alexander Alekhin 2eb1ee967c Merge pull request #20817 from komakai:fix_old_xcode_build 2021-10-06 17:32:09 +00:00
Alexander Alekhin c49cfefe88 videoio: fix plugins handling if no filesystem available 2021-10-06 17:29:00 +00:00
Alexander Alekhin c6a6f39d29 android: drop sourceCompatibility/targetCompatibility options 2021-10-06 16:49:02 +00:00
Oliver Kuckertz a3d7811f24 Merge pull request #20725 from mologie:fix-dnn-tf-on-arm
* dnn: fix unaligned memory access crash on armv7

The getTensorContent function would return a Mat pointing to some
member of a Protobuf-encoded message. Protobuf does not make any
alignment guarantees, which results in a crash on armv7 when loading
models while bit 2 is set in /proc/cpu/alignment (or the relevant
kernel feature for alignment compatibility is disabled). Any read
attempt from the previously unaligned data member would send SIGBUS.

As workaround, this commit makes an aligned copy via existing clone
functionality in getTensorContent. The unsafe copy=false option is
removed. Unfortunately, a rather crude hack in PReLUSubgraph in fact
writes(!) to the Protobuf message. We limit ourselves to fixing the
alignment issues in this commit, and add getTensorContentRefUnaligned
to cover the write case with a safe memcpy. A FIXME marks the issue.

* dnn: reduce amount of .clone() calls

* dnn: update FIXME comment

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-10-06 16:41:05 +00:00
Giles Payne eb56ca3b0d Fix build on older Xcode versions 2021-10-06 21:06:30 +09:00
Alexander Alekhin 755e0143fb Merge pull request #20815 from alalek:fix_20649_revert_19859
features2d: repair SimpleBlobDetector

* features2d: revert code change by PR #19859

Reverted commit 76860933f0

* features2d: check SimpleBlobDetector parameters consistency
2021-10-06 15:05:45 +03:00
Alexander Alekhin dfa48094dc Merge pull request #20814 from alalek:dnn_pytest_input_3d 2021-10-06 12:02:34 +00:00
Alexander Alekhin e585192eeb Merge pull request #20802 from alalek:core_tls_init_TlsAbstraction 2021-10-06 12:01:06 +00:00
Alexander Alekhin 646924fce8 dnn(pytest/test_input_3d): reload model between switching targets 2021-10-05 23:23:08 +00:00
Alexander Alekhin 13c6eb42e9 Merge pull request #20731 from komakai:matrix_mult_android_ios 2021-10-05 15:35:58 +00:00
HAN Liutong e5fb50476c Merge pull request #20521 from hanliutong:dev-rvv-multiVLEN
Make the implementation of optimization in DNN adjustable to different vector sizes with RVV intrinsics.

* Update fastGEMM for multi VLEN.

* Update fastGEMM1T for multi VLEN.

* Update fastDepthwiseConv for multi VLEN.

* Update fastConv for multi VLEN.

* Replace malloc with cv::AutoBuffer.
2021-10-05 15:35:00 +00:00
Alexander Alekhin 073c590d0b Merge pull request #20811 from alalek:update_ffmpeg_4.x 2021-10-05 15:06:25 +00:00
Alexander Alekhin c63aa7f085 Merge pull request #20808 from alalek:update_ffmpeg_3.4 2021-10-05 15:06:08 +00:00
Alexander Alekhin c832e62db0 Merge pull request #20771 from smirnov-alexey:as/render_fixture_params 2021-10-05 11:38:10 +00:00
Alexander Alekhin b7a7119b1f ffmpeg/4.x: update FFmpeg wrapper 2021.10
- FFmpeg 4.4 (no changes)
2021-10-05 14:32:39 +03:00
Giles Payne 19a880bb91 Simple matrix multiplication for Mat in iOS/Android 2021-10-05 20:16:06 +09:00
Alexander Alekhin 672399c751 Merge pull request #20788 from alalek:update_version_4.5.4-pre 2021-10-05 10:45:12 +00:00
Alexander Alekhin c54abde1bd ffmpeg/3.4: update FFmpeg wrapper 2021.10
- FFmpeg 3.4.8 (no changes)
2021-10-05 10:09:27 +03:00
Alexander Alekhin 95c1d2a887 Merge pull request #20806 from alalek:update_version_3.4.16-pre 2021-10-04 22:50:26 +00:00
Alexander Alekhin 3e6f27522b pre: OpenCV 4.5.4 (version++) 2021-10-04 22:35:47 +00:00
Alexander Alekhin 1b70f94282 Merge pull request #20782 from YashasSamaga:cuda4dnn-eltwise-broadcast 2021-10-04 22:35:00 +00:00
Alexander Alekhin ebef84e9ea pre: OpenCV 3.4.16 (version++) 2021-10-04 20:47:07 +00:00
Alexander Alekhin 87d4970e8b Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-10-04 19:50:01 +00:00
Alexander Alekhin b1a772d194 Merge pull request #20803 from alalek:core_parallel_workaround_tsan 2021-10-04 19:16:27 +00:00
Shivanshu Tyagi 4938765eb3 Merge pull request #20291 from spazewalker:master
speech recognition sample

* speech recognition sample added.(initial commit)

* fixed typos, removed plt

* trailing whitespaces removed

* masking removed and using opencv for displaying spectrogram

* description added

* requested changes and add opencl fp16 target

* parenthesis and halide removed

* workaround 3d matrix issue

* handle multi channel audio

support for multiple files at once

* suggested changes

fix whitespaces
2021-10-04 18:18:02 +00:00
Jebastin Nadar cce78cc5e2 Merge pull request #20535 from SamFC10:onnx-q
dnn : int8 quantized layers support in onnx importer

* added quantized layers support in onnx importer

* added more cases in eltwise node, some more checks

* added tests for quantized nodes

* relax thresholds for failed tests, address review comments

* refactoring based on review comments

* added support for unsupported cases and pre-quantized resnet50 test

* relax thresholds due to int8 resize layer
2021-10-04 18:07:38 +00:00
keroiber f11f2bfb56 Merge pull request #20743 from keroiber:prefix_js_function_bindings_with_namespace
* Prefix global javascript functions with sub-namespaces

* js: handle 'namespace_prefix_override', update filtering

- avoid functions override with same name but different namespace

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-10-04 16:51:49 +00:00
xhawk18 24f43e7ae9 Merge pull request #20183 from xhawk18:3.4
* improve compatibility for qt 6.

* cmake(highgui): rework Qt dependency support

* cmake(highgui): workaround Qt5Config.cmake "components" bug

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-10-04 16:44:57 +00:00
Zihao Mu 9085b933d8 Merge pull request #20702 from zihaomu:tf_expand_dim_layer
Add ExpandDims layer of tf_importer.cpp

* Add ExpandDims to tf_importer.

* add -1 expand test case.

* Support different dimensions of input.

* Compatible with 5-dimensional NDHWC data

* Code align

* support 3-dim input.

* 3-dim bug fixed.

* fixing error of code format.
2021-10-04 16:37:38 +00:00
Alexander Alekhin d94d469c86 valgrind: update suppressions 2021-10-04 16:27:05 +00:00
Alexander Alekhin 59502594f8 Merge pull request #20772 from shengyu7697:remove-redundant-semicolon 2021-10-04 15:38:49 +00:00
Alexander Alekhin d20c9bde7e core(TLS): force TlsAbstraction initialization before main() 2021-10-04 11:34:09 +00:00
Alexander Alekhin 62414e3073 core(parallel): suppress TSAN warning 2021-10-04 10:46:32 +00:00
YashasSamaga 505dde09de support broadcasting in eltwise ops 2021-10-04 12:38:45 +05:30
Alexander Alekhin 603d623eda Merge pull request #20800 from SamFC10:fix-int8-conv 2021-10-03 18:52:09 +00:00
SamFC10 87ebf2e50b fix illegal memory access in int8 convolution 2021-10-03 15:16:01 +05:30
Alexander Alekhin 37c3f0d8a0 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-10-02 17:57:18 +00:00
Alexander Alekhin 48c985e775 Merge pull request #20797 from sturkmen72:restore_LSD 2021-10-02 17:50:38 +00:00
Alexander Alekhin 7358fffb0f Merge pull request #20796 from JonasVautherin:patch-1 2021-10-02 17:48:23 +00:00
Jonas Vautherin de5b6386e0 Fix gst_initializer
Use the return value of gst_init_check instead of testing the error pointer
2021-10-02 15:42:13 +00:00
Alexander Alekhin 1de2d5c2b6 Merge pull request #20795 from JBamberger:gradle-dynamic-cv-version 2021-10-02 15:35:56 +00:00
Jannik Bamberger ef53a9229f Automatically set the correct OpenCV version in build.gradle
Automatically sets the correct OpenCV version in the CMAKE example contained in the build.gradle
file of the Android SDK.
2021-10-02 16:06:33 +02:00
Suleyman TURKMEN 259c39a63a additional changes 2021-10-02 13:34:56 +03:00
shengyu 4d87f6025e remove redundant semicolons 2021-10-02 09:35:47 +08:00
Alexander Alekhin 327b98eb13 Merge pull request #20794 from alalek:dnn_ocl_fix_conv_dwconv_workgroup 2021-10-01 22:25:47 +00:00
Alexander Alekhin f977d10a19 dnn(ocl): fix conv DWCONV workgroup 2021-10-01 18:52:07 +00:00
Alexander Alekhin a0cf8c322d Merge pull request #20793 from tomoaki0705:fixGaussianOverflow 2021-10-01 15:53:15 +00:00
Alexander Alekhin 627be179c1 Merge pull request #20791 from TolyaTalamanov:at/dangling-media-frames 2021-10-01 14:49:47 +00:00
Tomoaki Teshima 1e74f5850b suppress GaussianBlur to generate empty images
* sharp Gaussian kernel causes over flow and ends up in blank image
2021-10-01 23:17:02 +09:00
Anatoliy Talamanov 6d83a73858 Fix bugs with hanging frames 2021-10-01 16:38:41 +03:00
Suleyman TURKMEN 9b76872708 restore LSD 2021-10-01 16:23:16 +03:00
Alexander Alekhin 9b093c9a12 Merge pull request #20764 from sturkmen72:Update_OpenCVDetectVTK_cmake 2021-09-30 11:58:38 +00:00
Alexander Alekhin 4d587c341b Merge pull request #20774 from alalek:dnn_ocl_fix_conv_basic_workgroup 2021-09-30 10:16:26 +00:00
Suleyman TURKMEN f8f6cd6ef5 Update OpenCVDetectVTK.cmake 2021-09-30 12:02:33 +03:00
Alexander Alekhin cf08eac15e Merge pull request #20776 from alalek:port_20748_4.x 2021-09-29 15:49:06 +00:00
Suleyman TURKMEN 9a8552e8ae Update perf_bgfg_mog2.cpp, perf_bgfg_knn.cpp 2021-09-29 14:57:13 +00:00
Alexander Alekhin 846317ef37 dnn(ocl): fix conv BASIC workgroup 2021-09-29 14:55:46 +00:00
Alexander Alekhin 7e62789edf Merge pull request #20763 from Cavendish-Koo:houghlines_sdiv_bug_fix 2021-09-29 11:04:13 +00:00
Smirnov Alexey 5865af7f6e Add more parameters to render fixture 2021-09-29 12:13:13 +03:00
Alexander Alekhin 852663f6d2 Merge pull request #20748 from sturkmen72:clean_up_test_data 2021-09-28 20:45:39 +03:00
Sergey Ivanov c1148c4ea6 Merge pull request #20739 from sivanov-work:merge_base_decode
G-API: oneVPL (simplification) Add simple decode pipeline

* Add simple decode pipeline & add onevpl namespace

* Address some review comments

* Add compilation guard
2021-09-28 18:02:21 +03:00
Alexander Alekhin 280dc77f8b Merge pull request #20761 from komakai:fix_rect2f 2021-09-28 15:01:00 +00:00
Alexander Alekhin a9b30984a3 Merge pull request #20762 from fishmandev:patch-1 2021-09-28 15:00:13 +00:00
Cavendish-Koo 2f83c3b689 fix the bug of HoughlinesSDIV 2021-09-28 21:18:07 +08:00
Dmitriy Fishman b25ad12f1a Update video_input_psnr_ssim.markdown 2021-09-28 15:29:47 +03:00
Alexander Alekhin d95e43a6a1 Merge pull request #20754 from asmorkalov:as/parser_verbose_print 2021-09-28 11:47:55 +00:00
Giles Payne 27df987211 Fix bug in initializers Rect2f(Point2f,Point2f) and Rect2d(Point2d,Point2d) 2021-09-28 20:31:07 +09:00
Alexander Panov 982745fb83 Merge pull request #20735 from AleksandrPanov:radon_checkerboard
generate radon checkerboard

* added _make_round_rect

* added round rect to make_checkerboard_pattern

* added markers

* update docs

* removed links to findChessboardCornersSB() and added checks to markers
2021-09-28 10:30:07 +03:00
WJJ1995 8fa8d471af Merge pull request #20290 from wjj19950828:add_paddle_humanseg_demo
Add paddle humanseg demo

* fixed onnx resize op bug

* add humanseg demo for PaddlePaddle sample

* update README.md and flake8 format

* update func name

* update README.md for enviroment setup

* update README.md in the way install paddle2onnx

* update README.md

* update README.md

* add paddleseg in requirements.txt

* deal with comments

* replace picture
2021-09-27 21:59:09 +00:00
Alexander Smorkalov 2cc14bd0fb Verbose output for errors found by header parser. 2021-09-27 10:53:23 +03:00
Alexander Alekhin 98ad72b096 Merge pull request #20558 from alalek:python_cv_mat 2021-09-26 17:40:54 +00:00
Suleyman TURKMEN fdc8ed8d05 Update perf_bgfg_mog2.cpp, perf_bgfg_knn.cpp 2021-09-25 23:06:50 +03:00
Alexander Alekhin 24fcb7f813 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-09-25 17:50:00 +00:00
Nicholas Ho 236c64a17d Merge pull request #20712 from Nicholas-Ho-arm:3.4_RowVec_8u32f
* Add RowVec_8u32f

* Fix build errors in Linux x64 Debug and armeabi-v7a

* Reformat code to make it more clean and conventional

* Optimise with vx_load_expand_q()
2021-09-25 17:43:33 +00:00
thezane 9e835e8edb Merge pull request #20636 from thezane:recoverPoseFromDifferentCameras
Recover pose from different cameras (version 2)

* add recoverPose for two different cameras

* Address review comments from original PR

* Address new review comments

* Rename private api

Co-authored-by: tompollok <tom.pollok@gmail.com>
Co-authored-by: Zane <zane.huang@mail.utoronto.ca>
2021-09-25 17:42:12 +00:00
Alexander Alekhin f96569da1e Merge pull request #20746 from easonycwang:easonycwang/inpaint_perf_opt 2021-09-24 17:38:56 +00:00
easonycwang 91ff45fbde Tile:
This submission is used to improve the performance of the inpaint algorithm for 3 channels images(RGB or BGR).

Reason:
The original algorithm implementation did not consider the cache hits.
The loop of channels is outside the core loop, so the perfmance is not very good.
Moving the channel loop inside the core loop can significantly improve cache hits, thereby improving performance.

Performance:
360P, about >= 30% improvement
iphone8P: 5.52ms -> 3.75ms
iphone6s: 14.04ms -> 9.15ms
2021-09-24 21:47:14 +08:00
Alexander Alekhin 1261f250c6 Merge pull request #20747 from rgarnov:rg/desync_rmats_and_media 2021-09-24 13:27:15 +00:00
Ruslan Garnov 3673b45437 Added desync RMats and MediaFrames support 2021-09-24 14:29:27 +03:00
Alexander Alekhin 45aabc5d0d Merge pull request #20742 from UnaNancyOwen:fix_text_detection 2021-09-24 10:56:22 +00:00
Tsukasa Sugiura f9bd83c854 fix cast in text detection sample 2021-09-24 15:56:02 +09:00
Anatoliy Talamanov 499d8adb75 Merge pull request #20705 from TolyaTalamanov:at/handle-reshape-in-gexecutor
G-API: Handle reshape for generic case in GExecutor

* Handle reshape for generic case for GExecutor

* Add initResources

* Add tests

* Refactor reshape method
2021-09-23 22:59:40 +03:00
Sergey Ivanov 54386c82fd Merge pull request #20727 from sivanov-work:merge_vpl_accel_impl
G-API: oneVPL (simplification) added CPU, DX11(fallback CPU) accels & surface pool

* Add CPU, DX11(fallback CPU) accels & surface pool

* Fix build for surface_pool

* Apply some comments

* Fix indentation
2021-09-23 14:34:30 +03:00
Amir Tulegenov 86a51015b1 Merge pull request #19554 from amirtu:OCV-215_cvtColorTwoPlane_wrong_output_when_Y_Plane_Mat_has_step
different paddings in cvtColorTwoPlane() for biplane YUV420

* Different paddings support in cvtColorTwoPlane() for biplane YUV420

* Build fix for dispatch case.

* Resoted old behaviour for y.step==uv.step to exclude perf regressions.

Co-authored-by: amir.tulegenov <amir.tulegenov@xperience.ai>
Co-authored-by: Alexander Smorkalov <alexander.smorkalov@xperience.ai>
2021-09-22 17:42:32 +03:00
rogday 38b9ec7a18 Merge pull request #20682 from rogday:min
* Add Min layer to CPU, OpenCL, Halide, Inference Engine, NGraph and CUDA

* fix indentation

* add min to fusion and halide tests; fix doc
2021-09-22 15:17:37 +03:00
Alexander Alekhin 998406d20e Merge pull request #20729 from MikaelUrankar:3.4 2021-09-21 22:30:49 +00:00
mikael f7b4b750d8 Detect FP16 on FreeBSD aarch64 2021-09-21 19:48:58 +02:00
Alexander Alekhin 2558ab3de7 Merge pull request #20716 from komakai:fix_ios_macos_put_get 2021-09-21 15:31:36 +00:00
Alexander Alekhin a4e2c56317 Merge pull request #20713 from SamFC10:unsqueeze-opset13 2021-09-21 15:27:48 +00:00
Alexander Alekhin 0c10ae1861 python: cv.Mat wrapper over numpy.ndarray 2021-09-21 04:14:15 +00:00
Giles Payne b3cc828995 Fix put/get functions for non-contiguous Mat on iOS/macOS 2021-09-20 22:44:13 +09:00
Sergey Ivanov ba8f9d8620 Merge pull request #20601 from sivanov-work:surf_bk_test
G-API: oneVPL (simplification) added surface & frame adapter

* added surface & frame adapter

* Add FrameAdapter unut tests

* Fix compilation after rebase

* Fix compilation tests

* Apply some review comments

* Fix compile warning

* Revert back CV_Func usage

* Apply some comments
2021-09-20 16:28:32 +03:00
Vadim Levin 3c89a28a06 Merge pull request #20611 from VadimLevin:dev/vlevin/pure-python-modules
* feat: OpenCV extension with pure Python modules

* feat: cv2 is now a Python package instead of extension module

Python package cv2 now can handle both Python and C extension modules
properly without additional "subfolders" like "_extra_py_code".

* feat: can call native function from its reimplementation in Python
2021-09-18 10:02:55 +03:00
SamFC10 9c5d7716e2 fix for unsqueeze opset version 13 2021-09-17 17:40:57 +05:30
Alexander Alekhin 46fd26e366 Merge pull request #20699 from alalek:dnn_perf_update_convolution_tests 2021-09-16 17:11:32 +00:00
Rohit Sutradhar 41a2eb5245 Merge pull request #20361 from r0hit2005:master
Tutorial for parallel_for_ and Universal Intrinsic (GSoC '21)

* New parallel_for tutorial

* Universal Intrinsics Draft Tutorial

* Added draft of universal intrinsic tutorial

* * Added final markdown for parallel_for_new
* Added first half of universal intrinsic tutorial
* Fixed warnings in documentation and sample code for parallel_for_new
tutorial
* Restored original parallel_for_ tutorial and table_of_content_core
* Minor changes

* Added demonstration of 1-D vectorized convolution

* * Added 2-D convolution implementation and tutorial
* Minor changes in vectorized implementation of 1-D and 2-D convolution

* Minor changes to univ_intrin tutorial. Added new tutorials to the table of contents

* Minor changes

* Removed variable sized array initializations

* Fixed conversion warnings

* Added doxygen references, minor fixes

* Added jpg image for parallel_for_ doc
2021-09-15 19:50:49 +03:00
rogday c410d7a97d Merge pull request #20671 from rogday:yolov4x-mish
Add support for YOLOv4x-mish

* backport to 3.4 for supporting yolov4x-mish

* add YOLOv4x-mish test

* address review comments

Co-authored-by: Guo Xu <guoxu@1school.com.cn>
2021-09-14 17:49:49 +00:00
Alexander Alekhin 6fa63dcc0c Merge pull request #20700 from alalek:cmake_fix_handling_ie_version 2021-09-14 17:17:54 +00:00
Alexander Alekhin 3d7670a6ba Merge pull request #20695 from YashasSamaga:cuda4dnn-fix-padding-effrank 2021-09-14 11:46:06 +00:00
Alexander Alekhin 96f25332ea Merge pull request #20692 from sturkmen72:update_convexhull_cpp 2021-09-14 08:59:35 +00:00
Alexander Alekhin 3385d38648 cmake: fix handling of INF_ENGINE_RELEASE
- default value should be handled earlier
2021-09-14 08:56:09 +00:00
Alexander Panov 1618c963e4 Merge pull request #20676 from AleksandrPanov:delete_createConvexHull_convertTo
* deleted dublicated createConvexHull and convertTo

* replaced checkVector(2) with points.empty()
2021-09-13 19:27:00 +03:00
YashasSamaga 50462dcdc6 fix effrank assert to allow input effrank <= output effrank 2021-09-13 20:44:33 +05:30
Alexander Alekhin 1e3be09b3b Merge pull request #20693 from alalek:backport_merge34_fix 2021-09-12 11:09:51 +00:00
Alexander Alekhin 6e66a9222a dnn(onnx): fix format specifier 2021-09-11 22:26:52 +00:00
Alexander Alekhin c3ac834526 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-09-11 21:27:26 +00:00
Suleyman TURKMEN 9d1e8b1e1d Update convexhull.cpp 2021-09-11 23:58:14 +03:00
Alexander Alekhin f605373a2b Merge pull request #20690 from alalek:build_opencv_winpack_dldt_2021.4.1 2021-09-11 16:26:51 +00:00
Alexander Alekhin 56b7622612 Merge pull request #20687 from alalek:core_ocl_fix_intel_gemm 2021-09-11 16:26:25 +00:00
Alexander Alekhin 696a6ccd57 Merge pull request #20686 from zihaomu:tf_biasadd_bug
DNN: BiasAdd tf_importer.cpp could load Const from First Place
2021-09-11 19:25:04 +03:00
Zihao Mu 51b03b87e6 BiasAdd could load Const from second place. 2021-09-11 15:34:41 +00:00
Alexander Alekhin aa7ba0bc1a build: winpack_dldt with dldt 2021.4.1 2021-09-11 06:20:53 +03:00
Alexander Alekhin 07e4076585 Merge pull request #20689 from diablodale:fix20613-selectocldevice 2021-09-10 22:26:36 +00:00
Dale Phurrough de1a459879 fix opencv/opencv#20613
* copy 4.x selectOpenCLDevice() -- it is compatible
* filter platforms rather than trying only first matching
* this works on 3.4 and 4.x master
2021-09-10 21:18:01 +02:00
Alexander Alekhin 1aacb9bb15 dnn(perf): update convolution tests 2021-09-10 13:11:02 +00:00
Alexander Alekhin 9b4ecc96f6 core(ocl): buffer bounds in intelblas_gemm_buffer_NT 2021-09-10 12:10:41 +00:00
Alexander Alekhin e3f4f874c5 Merge pull request #20670 from alalek:core_ocl_fix_intel_gpu_gemm_requirements
core(OpenCL): fix intel_gpu_gemm kernel requirements

* core(ocl): fix intel_gpu_gemm integration

- allow bailout to generic OpenCL kernel

* core(ocl): avoid failures of generic OpenCL gemm kernel

* core(ocl): define alignment requirements of intel_gpu_gemm kernels
2021-09-10 12:00:11 +00:00
Alexander Alekhin 6ace801418 Merge pull request #20661 from alalek:dnn_ocl_fix_gemm_like_kernel 2021-09-10 11:58:52 +00:00
rogday d31b93b513 Merge pull request #20674 from rogday:prelu_slope
Fix PReLU negative slope access pattern

* fix prelu negative slope access pattern

* change begin() to ptr()
2021-09-10 11:07:16 +00:00
Alexander Alekhin ac0fd6aa9a Merge pull request #20675 from diablodale:fix2-20544 2021-09-09 21:35:03 +00:00
fortemSteve c7e0888982 Merge pull request #20591 from fortemSteve:ffmpeg_get_stream_open_time
Add CAP_PROP_STREAM_OPEN_TIME

* Added CAP_PROP_STREAM_OPEN_TIME to videoio module - can be used to query the time at which the stream was opened, in seconds since Jan 1 1970 (midnight, UTC). Useful for RTSP and other live video where absolute timestamps are needed. Only applicable to ffmpeg backends

* use nanoseconds instead of seconds to mark the stream open time, and change the cap prop name to CAP_PROP_STREAM_OPEN_TIME_NSEC

* use microseconds for CAP_PROP_STREAM_OPEN_TIME (nanoseconds rolls over too soon, and milliseconds/seconds requires a division)

* fix whitespace issue
2021-09-09 21:23:49 +00:00
Dale Phurrough 068f33cfdf add nodiscard to features2d clone funcs 2021-09-09 15:20:45 +02:00
rogday 4807cd8a6e Merge pull request #20605 from rogday:split_slice_shenanigans
Add Normalize subgraph, fix Slice, Mul and Expand

* Add Normalize subgraph, support for starts<0 and axis<0 in Slice, Mul broadcasting in the middle and fix Expand's unsqueeze

* remove todos

* remove range-based for loop

* address review comments

* change >> to > > in template

* fix indexation

* fix expand that does nothing
2021-09-09 14:41:40 +03:00
Ilya Lavrenov c703f1eed6 Merge pull request #20673 from ilya-lavrenov:print-openvino-information
* Support of OpenVINO interface libraries

* cmake: rename and move ocv_get_imported_target to OpenCVUtils.cmake
2021-09-09 10:56:34 +03:00
Alexander Alekhin 5ac5da3524 Merge pull request #20667 from rgonzalezfluendo:rgonzalezfluendo-patch-1 2021-09-08 07:26:21 +00:00
Ruben Gonzalez 0c13d34ade imgcodecs(doc): Sync imread_ docuemtation with the implemetation.
Documentation was desynchronized in commit 11eafca3e2
2021-09-07 12:51:34 +02:00
Alexander Alekhin 35e824c287 dnn(ocl): fix out of bound access in GEMM-like kernels
- dropped usage of CreateSubBuffer() - buffers lifetime management issue
- fixed elementwise offset
- avoid out of bounds read access
2021-09-06 18:17:21 +00:00
Alexander Alekhin 1e0d290f2e Merge pull request #20655 from alalek:dnn_ocl_fix_globalsize 2021-09-06 17:20:18 +00:00
Alexander Alekhin 0097a8d097 Merge pull request #20657 from zchrissirhcz:upd-doc-for-py_fast 2021-09-06 11:31:35 +00:00
Zhuo Zhang 36cc43170d docs: fix image path for py_fast doc 2021-09-06 13:05:58 +08:00
Alexander Alekhin 5578ad5e14 dnn(ocl): fix automatic globalsize adjusting
- if kernel code doesn't support that
2021-09-06 03:11:29 +00:00
Alexander Alekhin d11f0a709d Merge pull request #20652 from alalek:ocl_debug 2021-09-04 18:23:09 +00:00
Alexander Alekhin 0a43b23275 Merge pull request #20651 from alalek:issue_18361 2021-09-04 18:22:12 +00:00
Alexander Alekhin 7967683296 Merge pull request #20648 from alalek:issue_20615 2021-09-04 18:21:58 +00:00
Alexander Alekhin 5b2c016834 dnn(ocl): avoid out of buffer access in copyWeightsSwizzled 2021-09-04 15:45:59 +00:00
Alexander Alekhin aaff125608 core(ocl): debug capabilities 2021-09-04 15:37:39 +00:00
Alexander Alekhin 407adc7061 dnn(ocl): fix buffer offsets in IDLF kernel
- drop CreateSubBuffer
- fix FUSED_CONV_ELTWISE mode
2021-09-04 15:28:35 +00:00
rogday d0e612dc36 Merge pull request #20647 from rogday:resize_concat_optimization
Fix resize+concat optimization

* fix resize+concat optimization

* add comment and fix indentation
2021-09-03 12:32:29 +00:00
Alexander Alekhin 5aa7435d25 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-09-02 15:24:04 +00:00
Alexander Alekhin 7c23ec90a9 Merge pull request #20646 from VadimLevin:dev/vlevin/fix-vector-conversion 2021-09-02 09:30:57 +00:00
Vadim Levin 390957fec4 fix: NumPy array allocation error message in vector conversion 2021-09-02 10:32:17 +03:00
Alexander Alekhin 060a76dc3e Merge pull request #20573 from rogday:onnx_scale_fix 2021-09-01 14:09:17 +00:00
Alexander Alekhin 6625810d2a Merge pull request #20618 from VadimLevin:dev/vlevin/fix-vector-conversion 2021-09-01 10:52:37 +00:00
WJJ1995 edc442afdb Merge pull request #20511 from wjj19950828:add_humanseg_support_0806
* support PPSeg model for dnn module

* fixed README for CI

* add test case

* fixed bug

* deal with comments

* rm dnn_model_runner

* update test case

* fixed bug for testcase

* update testcase
2021-09-01 10:10:05 +00:00
Vadim Levin 16b9514543 feat: update conversion logic for std::vector<T> in Python bindings
`PyObject*` to `std::vector<T>` conversion logic:
- If user passed Numpy Array
  - If array is planar and T is a primitive type (doesn't require
    constructor call) that matches with the element type of array, then
    copy element one by one with the respect of the step between array
    elements. If compiler is lucky (or brave enough) copy loop can be
    vectorized.
    For classes that require constructor calls this path is not
    possible, because we can't begin an object lifetime without hacks.
  - Otherwise fall-back to general case
- Otherwise - execute the general case:
  If PyObject* corresponds to Sequence protocol - iterate over the
  sequence elements and invoke the appropriate `pyopencv_to` function.

`std::vector<T>` to `PyObject*` conversion logic:
- If `std::vector<T>` is empty - return empty tuple.
- If `T` has a corresponding `Mat` `DataType` than return
  Numpy array instance of the matching `dtype` e.g.
  `std::vector<cv::Rect>` is returned as `np.ndarray` of shape `Nx4` and
  `dtype=int`.
  This branch helps to optimize further evaluations in user code.
- Otherwise - execute the general case:
  Construct a tuple of length N = `std::vector::size` and insert
  elements one by one.

Unnecessary functions were removed and code was rearranged to allow
compiler select the appropriate conversion function specialization.
2021-09-01 13:00:21 +03:00
Alexander Alekhin 95c7f4a7f0 Merge pull request #20635 from alalek:issue_20559 2021-08-31 14:42:20 +00:00
Alexander Alekhin ae6fabc6fe dnn(ocl): drop CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE check
- it is a hint and it should not block kernel execution
2021-08-30 20:40:14 +00:00
Alexander Alekhin 7eaadf616c Merge pull request #20622 from diablodale:fix20544-nodiscard 2021-08-30 18:09:51 +00:00
Alexander Alekhin 8fed5fc5ae Merge pull request #20633 from alalek:ocl_dumpValue_handle_null 2021-08-30 13:39:44 +00:00
Alexander Alekhin f25951c412 core(ocl): handle NULL in dumpValue() debug call
- NULL is used for allocation of workgroup local variables
2021-08-30 11:47:51 +00:00
Alexander Alekhin c11195d5e3 Merge pull request #20628 from alalek:fix_build_warnings_4.x 2021-08-30 08:26:51 +00:00
Alexander Alekhin 2ed5cba110 build: eliminate build warnings 2021-08-29 09:18:21 +00:00
Alexander Alekhin 4c05a697fa Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-08-28 21:30:28 +00:00
Alexander Alekhin 1259a474ba Merge pull request #20625 from alalek:fix_msvc_warnings 2021-08-28 21:24:03 +00:00
Dale Phurrough 3995deaf76 fix opencv/opencv#20544 nodiscard for msvc/gcc
- includes workaround for preprocessor non-compliance
- enable attribute syntax checking in msvc
2021-08-28 20:22:47 +02:00
Alexander Alekhin 076587425e build: eliminate build warnings 2021-08-28 17:11:26 +00:00
Alexander Alekhin da6aeaca46 Merge pull request #20623 from alalek:fix_java_byte 2021-08-28 13:23:33 +00:00
Alexander Alekhin 8ee33ca551 java(test): avoid deprecation warning
- 'new Byte' => 'Byte.valueOf'
2021-08-28 02:10:05 +00:00
Alexander Alekhin ea7f13922b Merge pull request #20609 from vrabaud:3.4 2021-08-27 23:42:24 +00:00
Vincent Rabaud 38d0063c36 Do not use deprecated ReleaseCleared in protobuf library.
This is to make code work with protobuf arenas for memory
management (ReleaseCleared is incompatible).
The cleaning of the memory is also simpler.
2021-08-26 15:36:22 +02:00
Alexander Alekhin 56d0d5986f Merge pull request #20598 from hanliutong:rvv-fix 2021-08-26 07:28:55 +00:00
Alexander Alekhin df83459721 Merge pull request #20602 from diablodale:fix20594-refcounts-wiith-exceptions 2021-08-25 22:13:43 +00:00
Dale Phurrough 54a9e00970 fix opencv/opencv#20594 - exception handling with refcounts 2021-08-25 14:38:02 +02:00
Dale Phurrough 9bda96d39e add test case 2021-08-25 14:32:40 +02:00
Alexander Alekhin 053470d5a8 Merge pull request #20597 from alalek:issue_20592 2021-08-24 19:30:38 +00:00
Alexander Panov 6f4160c014 Merge pull request #20584 from AleksandrPanov:fix_HoughCircles_ALT_dimensions
Fix hough circles alt dimensions

* fix OutputArray _circles dimensions

* add houghcircles_alt test

* fix warnings

* add shape assert

* change asserts
2021-08-24 19:29:40 +00:00
Sergey Ivanov 65ef82a946 Merge pull request #20570 from sivanov-work:vpl_source_data_adapter
G-API: oneVPL (simplification) Add data adapter & Cfg params

* Add cfg_param & data_provider

* Fix compilation after rebase

* Apply some comments

* Apply default ctor outside class definition comment

* Apply cfg param in source

* Fix compilation: add virtual dtor

* Move cfg_params in regular gapi src list

* Fix compilation: add export.hpp

* Add errno.h

* Add errno.h

* Apply namespace comment

* Add several Doxygen & rename cfg_param

* Fix build

* Update Doxygen docs for onevpl

* Fix typo
2021-08-24 15:41:57 +03:00
Alexander Alekhin b509a7060a Merge pull request #20593 from TolyaTalamanov:at/fix-gexecutor-writeback 2021-08-24 09:41:21 +00:00
Anatoliy Talamanov 5ad6ff239b Merge pull request #20555 from TolyaTalamanov:at/fix-compileStreaming-bug
[G-API] Extend compileStreaming to support different overloads

* Make different overloads

* Order python compileStreaming overloads

* Fix compileStreaming bug

* Replace

gin -> descr_of

* Set error message

* Fix review comments

* Use macros for pyopencv_to GMetaArgs
* Use GAPI_PROP_RW
* Not split Prims python stuff
2021-08-24 12:37:50 +03:00
Nicolai Behmann fdaa6ff9e3 Merge pull request #20475 from nibeh:patch-1
* Added exposure and gain props, maximized pixel clk

* removed pixel clock maximization

pixel clock maximization is not suitable for all use cases, so I removed it from PR.
2021-08-24 12:31:54 +03:00
HAN Liutong 2f31763335 fix v_reduce_sum 2021-08-24 11:42:19 +08:00
Alexander Alekhin 350562919c highgui(win32): avoid using of stalled iterator 2021-08-23 18:16:14 +00:00
Anatoliy Talamanov aa5c4945d6 Fix GExecutor WriteBackExec 2021-08-23 16:52:49 +03:00
Alexander Alekhin 6fbfc58602 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-08-21 17:25:18 +00:00
Alexander Alekhin 77a5c43d50 Merge pull request #20586 from alalek:issue_20585 2021-08-21 17:22:58 +00:00
Alexander Alekhin f28e4b86fb dnn(ocl): fix top initialization in verifyResult 2021-08-21 16:04:13 +00:00
rogday 6801dd043d Merge pull request #20494 from rogday:onnx_diagnostic_fix
fix ONNXImporter diagnostic mode layer registration issue

* fix layer registration, thread unsafe access and align the behavior of DNN_DIAGNOSTICS_RUN between onnx and tf importers

* move skipModelInput

* print all missing layers

* address TF issue
2021-08-20 14:43:47 +00:00
Alexander Alekhin b675e6ab77 Merge pull request #20581 from alalek:issue_20571 2021-08-20 11:36:38 +00:00
Alexander Panov d6306f8ccb Merge pull request #20564 from AleksandrPanov:update_kalman_sample
Update kalman sample

* updated view and comments, fixed dims

* updated view and comments, added statePost
2021-08-20 10:57:05 +00:00
Alexander Alekhin a9817e9127 Merge pull request #20556 from rogday:onnx_split_sum_fix 2021-08-20 08:10:18 +00:00
Alexander Alekhin bb5f33d13c Merge pull request #20572 from TolyaTalamanov:at/check-adapter-in-executor 2021-08-20 07:41:21 +00:00
Alexander Alekhin c08897cd10 cmake: handle empty CVPY_SUFFIX 2021-08-19 20:06:41 +00:00
Alexander Alekhin 384875f4fc Merge pull request #20386 from vrabaud:3.4 2021-08-19 14:54:02 +00:00
Vincent Rabaud 9cfa84313c Use the one argument version of SetTotalBytesLimit.
The two argument versions has been deprecated, cf
https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.io.coded_stream
2021-08-19 14:31:29 +02:00
Vadim Pisarevsky f787c49b53 Merge pull request #20228 from SamFC10:int8 2021-08-19 08:09:01 +00:00
SamFC10 fa90e14b06 int8 layers and 8-bit quantization support 2021-08-19 09:56:47 +05:30
Smirnov Egor fe625a558e fix hasDynamicShapes for batch_size and fix axis selection in Scale layer 2021-08-18 19:22:24 +03:00
Anatoliy Talamanov 03b989251d Check adapter in executor 2021-08-18 18:13:28 +03:00
Anatoliy Talamanov 95919051e0 Merge pull request #20528 from TolyaTalamanov:at/fix-overwrite-blob-precision-bug
[G-API] Prohibit setPrecision & preprocessing for importedNetworks

* Prohibit preprocessing for imported networks

* Fix typo

input_names -> output_names

* Move setBlob logic to separate function

* Change comment
2021-08-18 10:42:32 +03:00
Sergey Ivanov 46fb88c76f Merge pull request #20546 from sivanov-work:initial_vpl_source
G-API: oneVPL (simplification) source base commit

* oneVPL source initial

* Fix compilation

* Fix compilation path

* Fix NO VPL compile

* Fix unused vars

* Fix unused vars in example

* Simplify oneVPL search: no custom path & download

* Fix standalone GAPI

* Apply comments
2021-08-17 20:11:22 +03:00
thezane 210bfaf8d6 Merge pull request #20483 from thezane:support-cumsum-layer-for-onnx
* Support cumsum layer for onnx

* Add unit tests

* Address review comments
2021-08-17 20:09:25 +03:00
rogday a50dec88d5 Merge pull request #20547 from rogday:gdb_pretty_printer
* add gdb rpetty printer for cv::Mat

* address review comments
2021-08-17 18:23:27 +03:00
zyp 8dcec034ed Merge pull request #18694 from zyp:gstreamer_gray16
* videoio/gstreamer: Add support for GRAY16_LE.

* videoio/gstreamer: added BGRA/BGRx support

Co-authored-by: Maksim Shabunin <maksim.shabunin@gmail.com>
2021-08-16 16:20:10 +00:00
Smirnov Egor 9ef41f68fb fix Split partial sum 2021-08-16 15:44:54 +03:00
Alexander Alekhin 05d733e707 Merge pull request #20524 from yichenj:dnn_text_recognition_enhance 2021-08-15 12:30:25 +00:00
Alexander Alekhin 4bbe28bdf0 Merge pull request #20460 from cv3d:flannHeapPool 2021-08-15 10:40:00 +00:00
Alexander Alekhin 0c01cf7c85 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-08-14 18:24:00 +00:00
Iyad Ahmed 917cd13ce2 Merge pull request #20549 from iyadahmed:video_capture_timeout_set_get
* VideoCapture add open/read timeout params to FFMPEG backend

* Fix wrong enum name

* Fix wrong enum name
2021-08-13 23:12:05 +03:00
Julia Bareeva cfb36443fb Merge pull request #20506 from JulieBar:lstm_activations
* Support activations(Sigmoid, Tanh) for LSTM

* fix warning
2021-08-13 15:41:00 +03:00
Alexander Alekhin 9d3826c676 Merge pull request #20525 from SamFC10:fix-prior-variances 2021-08-13 10:06:55 +00:00
Iyad Ahmed 4300bb2e1f Merge pull request #20541 from iyadahmed:video_capture_timeout_prop
* VideoCapture timeout set/get

* Common formatting for enum values

* Fix enum values wrongly in videoio.hpp

* Define timeout enum values in public api and align with master
2021-08-12 19:51:02 +03:00
Alexander Alekhin 6edc438789 Merge pull request #20545 from AleksandrPanov:resize_docummentation 2021-08-12 15:13:21 +00:00
JIANG Yichen 955cf35d5f Implement ctc prefix beam search decode for TextRecognitionModel.
The algorithm is based on Hannun's paper: First-Pass Large Vocabulary
Continuous Speech Recognition using Bi-Directional Recurrent DNNs
2021-08-12 20:33:31 +08:00
AleksandrPanov 25cd7c7c50 add note about Python's dsize to doc 2021-08-12 14:40:40 +03:00
Alexander Alekhin 0f8efb07c7 Merge pull request #20529 from saikatnanda:master 2021-08-12 08:14:42 +00:00
Alexander Alekhin 732cb6c45c Merge pull request #20515 from utibenkei:fix_java_ml_testSaveLoad 2021-08-12 08:12:48 +00:00
Daniel Playfair Cal 4d63a89fa6 Merge pull request #20536 from hedgepigdaniel:fix/ocl-context-create-ownership
docs(core/ocl): clarify ownership of arguments passed into OpenCL related functions

* docs(core/ocl): clarify ownership in OpenCLExecutionContext::create

Although it is technically true that OpenCLExecutionContext::create
calls `clRetainContext` on its context argument, it is misleading
because it does not increase the reference count overall. Clarify that
the ownership of one reference of the passed context and device is
taken.

* docs(core/ocl): document ownership transfer in ocl::Device::fromHandle
2021-08-11 20:58:08 +03:00
Alexander Alekhin 266a868ba9 Merge pull request #20533 from AleksandrPanov:minAreaRect_fix_rotatingCalipers 2021-08-11 17:56:34 +00:00
AleksandrPanov 8199967b31 fix choose minimum angle in rotatingCalipers 2021-08-11 19:08:52 +03:00
utibenkei 9d61c18143 fix testSaveLoad 2021-08-11 21:52:39 +09:00
Hamdi Sahloul 7c73e28a6d Improves FLANN's heap allocations by a memory pool 2021-08-11 17:34:15 +09:00
Alexander Alekhin 221bfa4c67 Merge pull request #20466 from rogday:efficientnet_fix_34 2021-08-10 22:18:17 +00:00
HAN Liutong aaca4987c9 Merge pull request #20287 from hanliutong:dev-rvv-0.10
Optimization of DNN using native RISC-V vector intrinsics.

* Use RVV to optimize fastGEMM (FP32) in DNN.

* Use RVV to optimize fastGEMM1T in DNN.

* Use RVV to optimize fastConv in DNN.

* Use RVV to optimize fastDepthwiseConv in DNN.

* Vectorize tails using vl.

* Use "vl" instead of scalar to handle small block in fastConv.

* Fix memory access out of bound in "fastGEMM1T".

* Remove setvl.

* Remove useless initialization.

* Use loop unrolling to handle tail part instead of switch.
2021-08-11 01:16:03 +03:00
Alexander Alekhin 1a8b7f7513 Merge pull request #20500 from AleksandrPanov:findContours_documentation 2021-08-10 17:21:33 +00:00
AleksandrPanov 992b47b991 add 19769 and 19769_lightweight tests 2021-08-10 18:53:28 +03:00
Saikat Nanda 21d0f40751 Fix YUV indexes + YUV Planner detection condition 2021-08-09 21:41:00 -04:00
Alexander Alekhin 5e7f06397f Merge pull request #20457 from komakai:ios-macos-mat-quicklook 2021-08-09 17:45:52 +00:00
Alexander Alekhin adaace4ab8 Merge pull request #20510 from mpashchenkov:mp/python-ge-update 2021-08-09 15:42:27 +00:00
Smirnov Egor 739ff84732 add Max layer to TFImporter 2021-08-09 14:01:51 +03:00
SamFC10 2a177052de fix bug in prior-box variances 2021-08-09 12:08:55 +05:30
Alexander Alekhin 424eaba4c5 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-08-07 17:25:06 +00:00
Julia Bareeva e1cafa3834 Merge pull request #20442 from JulieBar:gru_layer
* Add initialization and inference for GRU layer

* fix issues found on review
2021-08-07 10:07:37 +03:00
Anatoliy Talamanov ba539eb9aa Merge pull request #20508 from TolyaTalamanov:at/expand-python-pyparams
[G-API] Expand PyParams to support constInput

* Wrap constInputs to python

* Wrap cfgNumRequests

* Fix alignment

* Move macro to the line above
2021-08-06 14:41:56 +03:00
Anatoliy Talamanov 24de676a64 Merge pull request #20476 from TolyaTalamanov:at/support-unet-camvid-0001-segm-sample
[G-API] Support postprocessing for not argmaxed outputs

* Support postprocessing for not argmaxed outputs

* Fix typo

* Add assert

* Remove static cast

* CamelCast to snake_case

* Fix windows warning

* Add static_cast to uint8_t

* Add const to variables
2021-08-06 10:26:49 +00:00
Alexander Alekhin 0c2741f7ad Merge pull request #20503 from asmorkalov:as/riscv_rvv_v_rshr_pack_store 2021-08-06 09:54:05 +00:00
Alexander Alekhin f7c82baee9 Merge pull request #20505 from AleksandrPanov:contours_tutorial_documentation 2021-08-06 07:09:26 +00:00
Alexander Alekhin 2b34e0abdc Merge pull request #20502 from ddacw:3.4 2021-08-06 07:06:51 +00:00
Maxim Pashchenkov 6306bc3ddc Applying of comments 2021-08-06 09:54:40 +03:00
Alexander Alekhin ea068dcc2c Merge pull request #20507 from alalek:cmake_fix_crosscompilation 2021-08-05 15:38:02 +00:00
Julia Bareeva 633fedaa96 Merge pull request #20480 from JulieBar:lstm_pytest
Add Python's test for LSTM layer

* Add Python's test for LSTM layer

* Set different test threshold for FP16 target

* rename test to test_input_3d

Co-authored-by: Julie Bareeva <julia.bareeva@xperience.ai>
2021-08-05 18:13:17 +03:00
Alexander Alekhin 4ff76cad2a cmake: fix cross-compilation problems
- unexpected pkg-config module (we should not use host binary)
- bump cmake_minimum_required to 3.5 in toolchain files
2021-08-05 11:42:58 +00:00
AleksandrPanov 65134c793b add links in python and js contours tutorial 2021-08-05 14:21:34 +03:00
Anatoliy Talamanov 5af09e73f2 Merge pull request #20490 from TolyaTalamanov:at/support-fp16-input-precision
[G-API] Support FP16 input precision for IE backend

* Support fp16 input precision IE backend

* Add support to wrapIE
2021-08-05 11:59:24 +03:00
Abhinav Sharma d5f34cf34c Merge pull request #20493 from abhi-bhatra:patch-1
Fix Broken Link

* Update README.md

Fix broken link

* Update Readme.txt

* Update readme.txt

Add missing link

* Update readme.txt

Fix names
2021-08-04 20:28:59 +03:00
Alexander Smorkalov 6a2e559222 Fixed memory access issue in v_rshr_pack_store intrinsic on RISC-V RVV. 2021-08-04 20:04:03 +03:00
Duong Dac cefa602601 Avoid adding false UMat/GpuMat declaration 2021-08-04 15:17:25 +02:00
AleksandrPanov d773691848 add note about hierarchy in python version 2021-08-04 15:37:20 +03:00
Alexander Alekhin da07ad16c1 Merge pull request #20384 from rogday:find_package_cache 2021-08-03 18:19:28 +00:00
Alexander Alekhin f40707dc68 Merge pull request #20487 from AleksandrPanov:traincascade_documentation 2021-08-03 12:06:46 +00:00
AleksandrPanov 2d8ce500fa add note about using version 3.4 to traincascade documentation 2021-08-02 18:41:53 +03:00
Dmitry Budnikov ba0cea6826 Merge pull request #20474 from dbudniko:dbudniko/mtcnn_graph_without_resizes
Remove explicit PNet resizes from MTCNN graph

* remove PNet resizes

* address comment from Ruslan
2021-08-02 10:58:18 +00:00
Alexander Alekhin ddf1b04cce Merge pull request #20485 from VadimLevin:dev/vlevin/fix-reserved-python-keyword-arguments 2021-08-02 08:09:55 +00:00
Alexander Alekhin ad5b3a4753 Merge pull request #20451 from kumar-mahendra:patch-1 2021-08-01 14:22:09 +00:00
Vadim Levin 531ea5b3a2 fix: convert arguments names that are keywords reserved by Python 2021-08-01 12:02:36 +03:00
Mahendra Kumar b468468e7e Closing brackets missing
In line 94,  closing brackets are added which were missing .
2021-08-01 08:41:03 +00:00
Alexander Alekhin d52e4e5df3 Merge pull request #20446 from alalek:cmake_eliminate_modules_scope 2021-07-31 14:49:03 +00:00
Alexander Alekhin 907743eee7 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-07-30 14:50:36 +00:00
Alexander Alekhin 610e3dccb7 Merge pull request #20478 from rogday:onnx_refactor_master 2021-07-30 14:38:46 +00:00
Smirnov Egor 27392f832d reimplement onnx refactor for master 2021-07-30 13:00:13 +03:00
Alexander Alekhin e9db7fea5b Merge pull request #20472 from zchrissirhcz:fix-typo-in-comment 2021-07-29 13:11:02 +00:00
Zhuo Zhang bdd3930855 Fix typo in comment, OpenMP => TBB 2021-07-29 09:34:09 +08:00
rogday cff0168f3a Merge pull request #20453 from rogday:onnx_importer_fix
Split layer dispatch into functions in ONNXImporter

* split layer dispatch into functions

* fixes

* identation and comment fixes

* fix constness
2021-07-28 18:06:24 +03:00
Alexander Alekhin 70d5c88026 Merge pull request #20445 from dbudniko:dbudniko/G-API_mtcnn_demo_single_transpose 2021-07-26 10:09:04 +00:00
Alexander Alekhin d83901e665 Merge pull request #20459 from xerxesb:bugfix/cuda-cmake-typo 2021-07-26 09:57:44 +00:00
Xerxes Battiwalla 1e1984a586 Fixed typo in error message in OpenCVDetectCUDA.cmake
There was a minor typo in the FATAL error message when the specified CUDA generation does not match any known generation
2021-07-26 14:54:27 +10:00
Giles Payne 2f180cea7f Add Quicklook for Mat on iOS and macOS 2021-07-25 14:23:52 +09:00
Alexander Alekhin f4d6a3ec4e Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-07-24 15:34:58 +00:00
Parsa 7aa922ceac Merge pull request #20440 from parsa-ra:patch-1
* Update config_reference.markdown

Added description for `WITH_CLP` build option.

* Added extra description

Can't cross-reference with anchors to other sections of the markdown file due to the presence of markdown link extension in the form of 
`## Header {#id-of-header}`

* Fixed trailing space issue
2021-07-24 18:29:24 +03:00
Alexander Alekhin 06dcc5a2c6 Merge pull request #20424 from sbajtl:worker-importscript-bugfix 2021-07-24 15:28:01 +00:00
Alexander Alekhin 000f762fb9 Merge pull request #20369 from shreyastaware:master 2021-07-24 13:41:01 +00:00
Alexander Alekhin 3bc3eeb5da Merge pull request #20447 from snoyes:patch-1 2021-07-23 14:34:57 +00:00
Julia Bareeva 4e5699fa71 Merge pull request #20450 from JulieBar:lstm_inside
Support non-zero hidden state for LSTM

* fully support non-zero hidden state for LSTM

* check dims of hidden state for LSTM

* fix failed test Test_Model.TextRecognition

* add new tests for LSTM w/ non-zero hidden params

Co-authored-by: Julie Bareeva <julia.bareeva@xperience.ai>
2021-07-23 17:11:50 +03:00
ZhangYin acc576658a Merge pull request #20412 from joy2myself:rvv-0.10
bug fixes for universal intrinsics of RISC-V back-end

* Align universal intrinsic comparator behaviour with other platforms

Set all bits to one for return value of int and fp comparators.

* fix v_pack_triplets, v_pack_store and v_pack_u_store

* Remove redundant CV_DECL_ALIGNED statements

Co-authored-by: Alexander Smorkalov <alexander.smorkalov@xperience.ai>
2021-07-23 17:08:43 +03:00
Scott Noyes a76274b549 minor grammar edits 2021-07-23 08:54:00 -05:00
Shreyas Taware 803ff8ebb9 Update py_canny.markdown
Fixed a word that was previously written as third argument but it is instead the fourth argument of cv.Canny() function
2021-07-23 05:01:20 +00:00
Alexander Alekhin b42152ffeb Merge pull request #20429 from rogday:tf_importer_asym_pads 2021-07-22 16:44:47 +00:00
Alexander Alekhin 4015a5486c cmake: process modules in the same CMake scope 2021-07-22 15:22:42 +00:00
Smirnov Egor 024b43ca06 implement asymmetric padding for conv2d, max_pool and conv2d_backprop_input 2021-07-22 16:58:40 +03:00
Dmitry Budnikov aae48e6fd7 single transpose MTCNN version 2021-07-22 16:52:11 +03:00
Francesco Petrogalli d29c7e7871 Merge pull request #20392 from fpetrogalli:aarch64-semihosting
AArch64 semihosting

* [ts] Disable filesystem support in the TS module.

Because of this change, all the tests loading data will file, but tat
least the core module can be tested with the following line:

    opencv_test_core --gtest_filter=-"*Core_InputOutput*:*Core_globbing.accuracy*"

* [aarch64] Build OpenCV for AArch64 semihosting.

This patch provide a toolchain file that allows to build the library
for semihosting applications [1]. Minimal changes have been applied to
the code to be able to compile with a baremetal toolchain.

[1] https://developer.arm.com/documentation/100863/latest

The option `CV_SEMIHOSTING` is used to guard the bits in the code that
are specific to the target.

To build the code:

    cmake ../opencv/ \
        -DCMAKE_TOOLCHAIN_FILE=../opencv/platforms/semihosting/aarch64-semihosting.toolchain.cmake \
        -DSEMIHOSTING_TOOLCHAIN_PATH=/path/to/baremetal-toolchain/bin/ \
        -DBUILD_EXAMPLES=ON -GNinja

A barematel toolchain for targeting aarch64 semihosting can be found
at [2], under `aarch64-none-elf`.

[2] https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads

The folder `samples/semihosting` provides two example semihosting
applications.

The two binaries can be executed on the host platform with:

    qemu-aarch64 ./bin/example_semihosting_histogram
    qemu-aarch64 ./bin/example_semihosting_norm

Similarly, the test and perf executables of the modules can be run
with:

    qemu-aarch64 ./bin/opecv_[test|perf]_<module>

Notice that filesystem support is disabled by the toolchain file,
hence some of the test that depend on filesystem support will fail.

* [semihosting] Remove blank like at the end of file. [NFC]

The spurious blankline was reported by
https://pullrequest.opencv.org/buildbot/builders/precommit_docs/builds/31158.

* [semihosting] Make the raw pixel file generation OS independent.

Use the facilities provided by Cmake to generate the header file
instead of a shell script, so that the build doesn't fail on systems
that do not have a unix shell.

* [semihosting] Rename variable for semihosting compilation.

* [semihosting] Move the cmake configuration to a variable file.

* [semihosting] Make the guard macro private for the core module.

* [semihosting] Remove space. [NFC]

* [semihosting] Improve comment with information about semihosting. [NFC]

* [semihosting] Update license statement on top of sourvce file. [NFC]

* [semihosting] Replace BM_SUFFIX with SEMIHOSTING_SUFFIX. [NFC]

* [semihosting] Remove double space. [NFC]

* [semihosting] Add some text output to the sample applications.

* [semihosting] Remove duplicate entry in cmake configuration. [NFCI]

* [semihosting] Replace `long` with `int` in sample apps. [NFCI]

* [semihosting] Use `configure_file` to create the random pixels. [NFCI]

* [semihosting][bugfix] Fix name of cmakedefine variable.

* [semihosting][samples] Use CV_8UC1 for grayscale images. [NFCI]

* [semihosting] Add readme file.

* [semihosting] Remove blank like at the end of README. [NFC]

This fixes the failure at
https://pullrequest.opencv.org/buildbot/builders/precommit_docs/builds/31272.
2021-07-21 18:46:05 +03:00
Alexander Alekhin 9448fe3db4 Merge pull request #20437 from pytianxxiao:fix#20430 2021-07-21 09:47:11 +00:00
Xiaoxiao Tian 3817f3a89b fix: ocv_target_link_libraries could not handle the keyword rightly #20430 2021-07-21 13:32:50 +08:00
Alexander Alekhin 755f4f324b Merge pull request #20431 from lukasalexanderweber:debug-stitching_detailed.py 2021-07-20 16:25:43 +00:00
Lukas-Alexander Weber 863ab0e72e fix TypeError when specifying compose_megapix
without rounding the composed image sizes (variable "sz") they will be odly fractions of a pixel (e.g. (5300.965, 3772.897)) and therefore cause a "TypeError: integer argument expected, got float" in line

456        roi = warper.warpRoi(sz, K, cameras[i].R)
2021-07-20 10:59:15 +02:00
Alexander Alekhin 4ab0377c6e Merge pull request #20143 from rogday:base64_encoding 2021-07-19 20:43:19 +00:00
Saša Bajtl 2062a7ca8f Bugfix on import script with web worker. 2021-07-18 10:12:39 +02:00
Alexander Alekhin b61a55eebf Merge pull request #20402 from rogday:tf_diag_dummy 2021-07-16 15:44:29 +00:00
Smirnov Egor c30078c5a3 add NotImplemented layer 2021-07-16 15:39:54 +03:00
Alexander Alekhin 39b91c97f0 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-07-16 10:35:42 +00:00
Alexander Alekhin 8334ee18e6 Merge pull request #20394 from SamFC10:conv-asymmetric-pads 2021-07-16 10:33:42 +00:00
Alexander Alekhin cc2592f582 Merge pull request #20200 from rmeertens:update_grabcut 2021-07-16 10:19:25 +00:00
SamFC10 96d35f7c54 Fix convolution asymmetric padding bug in onnx importer 2021-07-16 09:39:41 +05:30
Alexander Alekhin 98c5fc6ae2 Merge pull request #20410 from alalek:fix_dnn_dldt_output_layout 2021-07-15 22:43:42 +00:00
Alexander Alekhin fbde0c6c96 dnn(ie): fix handling of 1D and non-32F outputs of InferenceEngine 2021-07-15 21:47:05 +00:00
Alexander Alekhin 602e7c83e2 dnn(test): add extra IR models, more checks in IE testing code 2021-07-15 21:47:05 +00:00
Alexander Alekhin eb9218a86b Merge pull request #20420 from berak:python_fix_trackbar_warning 2021-07-15 20:06:22 +00:00
berak 9f2dcc3f13 python: fix trackbar warning 2021-07-15 17:42:06 +02:00
Alexander Alekhin bc210b292b dnn(test): backport test_ie_models.cpp from 4.5.3 2021-07-15 00:05:02 +00:00
Roland Meertens 2113af9c52 Updated grabcut example to show the background in a transparant way 2021-07-14 22:02:27 +02:00
Pablo Romero 6f417b57c1 Merge pull request #20399 from pablorcum:3.4
Improves support for Unix non-Linux systems, including QNX

* Fixes #20395. Improves support for Unix non-Linux systems. Focus on QNX Neutrino.

Signed-off-by: promero <promero@mathworks.com>

* Update system.cpp
2021-07-13 19:40:15 +00:00
Dmitry Budnikov a7742d7d63 Merge pull request #20383 from dbudniko:dbudniko/mtcnn_1st_pnet_simplification
MTCNN 1st pnet simplification to ensure single graph input

* 1st pnet simplification to ensure single graph input

* address comment from Dmitry M regarding unused variable
2021-07-13 19:33:13 +00:00
Alexey Smirnov 5179e37bd1 Merge pull request #20329 from smirnov-alexey:as/mediaframe_serialization
[G-API]: Add serialization mechanism for cv::MediaFrame

* Stub initial interface

* Fix templates for deserialization

* Fix tests

* Disable a warning on windows

* Address review comments

* Change enable_ifs to other template helpers

* Resolve ambiguous template

* Fix warnings in docs
2021-07-13 19:31:46 +00:00
Alexander Alekhin a7b17bfaf0 Merge pull request #20400 from alalek:cmake_fix_mode_vars 2021-07-13 10:18:43 +00:00
Alexander Alekhin 4af1f31a3f cmake: use relative path for mode vars 2021-07-13 09:15:03 +00:00
Alexander Alekhin 0acd06d13c Merge pull request #20397 from alalek:fix_winpack_dldt_stale_sysroot 2021-07-12 21:14:22 +00:00
Alexander Alekhin fd22e98298 build(winpack_dldt): avoid stale sysroot contents 2021-07-12 19:33:23 +00:00
Alexander Alekhin 9e42e04b4a Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-07-10 13:01:03 +00:00
Alexander Alekhin 9103837228 Merge pull request #20278 from joy2myself:rvv-0.10 2021-07-09 22:42:29 +00:00
Sergey Ivanov 3f3c5de851 Merge pull request #20372 from sivanov-work:serialize
GAPI: Implement ConstValue serialize/deserialize

* Implement ConstValue ser/deser

* Fix MacOs compile issue

* Fix Docs compile

* Change uint32 -> uint64 for serialize tag
2021-07-09 18:46:38 +00:00
César Gouveia 167a12028d Merge pull request #20374 from cesarpgouveia:bugfix/fix_load_onnxModel_debug
* Fix bug while loading onnx model in debug

* dnn: fix other .at using

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-07-09 18:21:56 +00:00
Alexander Alekhin 6af2faebd2 Merge pull request #20381 from berak:dnn_samples_fix_colorization_links 2021-07-09 18:15:10 +00:00
Smirnov Egor 34b65be44a fix find_package cache pollution 2021-07-09 19:15:45 +03:00
berak fd16222613 dnn: update links for the colorization samples 2021-07-09 13:21:44 +02:00
Alexander Alekhin 1ba6cd8423 Merge pull request #20368 from mightbxg:bugfix_imshowqt 2021-07-08 20:54:09 +00:00
Francesco Petrogalli b928ebdd53 Merge pull request #19985 from fpetrogalli:disable_threads
* [build][option] Introduce `OPENCV_DISABLE_THREAD_SUPPORT` option.

The option forces the library to build without thread support.

* update handling of OPENCV_DISABLE_THREAD_SUPPORT

- reduce amount of #if conditions

* [to squash] cmake: apply mode vars in toolchains too

Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
2021-07-08 20:21:21 +00:00
Smirnov Egor b42623ff9d port base64 encoding from 3.4 2021-07-08 10:42:44 +03:00
Alexey Smirnov 59ae0e0013 Merge pull request #20163 from smirnov-alexey:as/gapi_serialization_docs
G-API: add documentation on serialization functionality

* Add documentation on serialization/deserialization

* Add docs on bind() methods

* Fix typo

* Docs refactoring

* Fix s11n docs

* Fix deserialize() docs

* Change deserialize docs

* Fix warning

* Address review comments

* Fix sample

* Fix warnings and errors

* Fix docs warnings

* Fix warnings

* Address review comments

* Add prefixes to snippets and fix indentation

* Address review comments and move snippets to a single file
2021-07-07 19:07:59 +00:00
Alexander Alekhin 4788de784b Merge pull request #20373 from kikaxa:mjpeg-VideoInputStream-alignment-fix 2021-07-07 18:21:57 +00:00
kikaxa 926535469d fix videoio/src/container_avi.cpp VideoInputStream alignment 2021-07-07 18:31:53 +03:00
Sergey Ivanov c0f63eb21f Merge pull request #20039 from sivanov-work:gapi_empty_input
G-API: Implement variant visit()

* Add variant visitor, use visitor for check compile args

* Fix GAPI UT: variant *compiler

* Aling apply_visior with std, fix indentations

* Fix compilation (included compiler_hints.hpp)

* Fix compilation (due gapi standalone)

* Fix compilation2 (Docs)

* Add Lambdas overload, Refactor visit()

* Add ReturnType auto deduction

* Fix comilation

* Fix compilation

* Fix warnings

* Try to fix MSVC14

* Fix docs

* Try fix Win compile

* Fix Docs again

* Revert GAPI empty input fix

* Apply comment for `tuple_element`

* Add std::decay for std::base_of to work arounf armv7 problem

* Apply review comments

* Apply review comments: added comment & removed unused args

* Fix docs compilation
2021-07-07 12:33:40 +00:00
Xinguang Bian 5627a0cbdf fix scale problem in DefaultViewPort::controlImagePosition() 2021-07-07 12:35:11 +08:00
Maxim Pashchenkov ed2a698392 Merge pull request #20359 from mpashchenkov:mp/onnx-tests
G-API: ONNX. Skip tests.

* imread for every test

* Changed name for Yolo function
2021-07-06 21:35:41 +03:00
Alexander Alekhin aaad1791d9 Merge tag '4.5.3' 2021-07-05 21:48:40 +00:00
Alexander Alekhin ad6e82942b release: OpenCV 4.5.3 2021-07-05 12:03:22 +00:00
Alexander Alekhin 9a9954a036 Merge tag '3.4.15' 2021-07-04 21:32:19 +00:00
Alexander Alekhin d60bb57d4b Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-07-04 21:24:40 +00:00
Alexander Alekhin 591708903b release: OpenCV 3.4.15 2021-07-04 21:10:13 +00:00
Alexander Alekhin f9d62fba7a Merge pull request #20350 from alalek:issue_20285 2021-07-04 21:07:02 +00:00
Alexander Alekhin 85dde8a800 Merge pull request #20355 from alalek:issue_20352 2021-07-04 20:54:03 +00:00
Alexander Alekhin 9d039c206b Merge pull request #20354 from alalek:issue_20353 2021-07-04 18:41:34 +00:00
Alexander Alekhin cbff19ff1a highgui: fix win32 backend behavior 2021-07-04 17:37:45 +03:00
Alexander Alekhin 4c3f9b2ef4 cmake: update Halide detection 2021-07-04 13:20:52 +03:00
Alexander Alekhin 167bac23aa Merge pull request #20351 from alalek:issue_20320 2021-07-03 20:42:17 +00:00
Alexander Alekhin 5d0cfa2527 cmake(highgui): don't allow multiple builtin backends 2021-07-03 11:37:08 +00:00
Alexander Alekhin 0e523618a1 cmake: exclude -pthread from Emscripten default build 2021-07-03 11:13:28 +00:00
Alexander Alekhin 821fae0d94 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-07-03 00:30:58 +00:00
Alexander Alekhin 3b26105f68 Merge pull request #20346 from alalek:backport_20026 2021-07-03 00:27:55 +00:00
Alexander Alekhin 0f2f966a91 Merge pull request #20345 from mitruska:update_ngraph_normalizel2 2021-07-02 23:37:03 +00:00
Alexander Alekhin d7d491d445 Merge pull request #20344 from alalek:backport_20343 2021-07-02 23:35:12 +00:00
Alexander Alekhin 41effbe2da Merge pull request #20343 from alalek:issue_19915 2021-07-02 23:33:49 +00:00
Alexander Alekhin 9b0d6862c4 cmake(IE): extract INF_ENGINE_RELEASE from InferenceEngine package 2021-07-02 23:29:35 +00:00
Alexander Alekhin 890fcdf842 Merge pull request #20337 from alalek:build_opencv_winpack_dldt_2021.4.0 2021-07-02 21:47:14 +00:00
mitruska 18dbac203f Use explicit version of ngraph NormalizeL2 2021-07-02 21:33:05 +00:00
Alexander Alekhin 8d1f254dcc java: force using of 'Ptr<>' for OpenCV classes
backport of commit: e5841d3126
2021-07-02 21:20:08 +00:00
Alexander Alekhin e5841d3126 java: force using of 'Ptr<>' for OpenCV classes 2021-07-02 21:13:49 +00:00
Alexander Alekhin 90df3af6cf build: winpack_dldt with dldt 2021.4.0 2021-07-02 09:58:00 +00:00
Alexander Alekhin 11cc36d770 Merge pull request #20341 from alalek:gapi_replace_ie_deprecated 2021-07-01 19:39:13 +00:00
Maxim Pashchenkov 05f1939b02 Merge pull request #20298 from mpashchenkov:mp/python-desync
G-API: Python. Desync.

* Desync. GMat.

* Alignment
2021-07-01 19:06:35 +00:00
Alexander Alekhin 050ea9762f Merge pull request #20326 from APrigarina:fix_samples 2021-07-01 18:30:19 +00:00
APrigarina 0f24d4d2a1 fix samples 2021-07-01 18:26:17 +03:00
Alexander Alekhin fc799191f4 gapi(ie): replace deprecated calls 2021-07-01 13:49:29 +00:00
Alexander Alekhin 8fad85edda Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-07-01 10:52:31 +00:00
Maxim Pashchenkov d70053aba5 Merge pull request #20144 from mpashchenkov:mp/python-ge
G-API: Python. Gaze Estimation sample.

* GE pep8

* Added function description, wrapped copy

* Applying review comments

* One more change

* Added gin

* Rstrt bb
2021-07-01 10:27:28 +00:00
Alexander Alekhin b699fe7a9d Merge pull request #20335 from SamFC10:concat-const-input 2021-07-01 10:25:35 +00:00
Alexander Alekhin 94c67faaea Merge pull request #20336 from JoeHowse:refactor-cl_image-float16-conversions 2021-07-01 09:52:19 +00:00
Alexander Alekhin b2ed5c3070 Merge pull request #20333 from APrigarina:fix_samples_3.4 2021-07-01 09:41:56 +00:00
Anatoliy Talamanov 9fe49497bb Merge pull request #20284 from TolyaTalamanov:at/wrap-render
G-API: Wrap render functionality to python

* Wrap render Rect prim

* Add all primitives and tests

* Cover mosaic and image

* Handle error in pyopencv_to(Prim)

* Move Mosaic and Rect ctors wrappers to shadow file

* Use GAPI_PROP_RW

* Fix indent
2021-07-01 09:36:19 +00:00
SamFC10 5b8c10f2f8 modified onnx importer to concat const input blobs 2021-07-01 10:58:31 +05:30
Alexander Alekhin 24983f62e2 Merge pull request #20325 from alalek:dnn_openvino_2021.4.0 2021-06-30 23:58:26 +00:00
Alexander Alekhin f2057ce1ab dnn(ie): replace deprecated calls 2021-06-30 22:30:15 +00:00
Alexander Alekhin 6797fd65a5 dnn(test): update tests for OpenVINO 2021.4 2021-06-30 22:30:15 +00:00
Rafael H Tibães bf489feef1 Merge pull request #20327 from tibaes:MSMF-Slow-Webcam-Startup
* fixes MSMF slow webcam startup

* add variable to change MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS at runtime
2021-06-30 22:08:24 +00:00
Alexander Alekhin 947e06a860 Merge pull request #20328 from alalek:backport_20321 2021-06-30 20:51:49 +00:00
Joe Howse 6a3d925a47 OpenCL: core support for FP16, more channel orders
* Support cl_image conversion for CL_HALF_FLOAT (float16)

* Support cl_image conversion for additional channel orders:
  CL_A, CL_INTENSITY, CL_LUMINANCE, CL_RG, CL_RA

* Comment on why cl_image conversion is unsupported for CL_RGB

* Predict optimal vector width for float16

* ocl::kernelToStr: support float16

* ocl::Device::halfFPConfig: drop artificial requirement for OpenCL
  version >= 1.2. Even OpenCL 1.0 supports the underlying config
  property, CL_DEVICE_HALF_FP_CONFIG.

* dumpOpenCLInformation: provide info on OpenCL half-float support
  and preferred half-float vector width

* randu: support default range [-1.0, 1.0] for float16

* TestBase::warmup: support float16
2021-06-30 14:14:37 -03:00
Alexander Alekhin 04d5ba266f Merge pull request #20330 from Wovchena:fix-arg-for-calcHist-in-demos 2021-06-30 14:59:22 +00:00
Vladimir 90be83ae99 Fix an arg for calcHist() in demos
`float* histRange = { range };` doesn't make much sense. `histRange` is
an array of array(s), so it should have a type of ptr to ptr. Strangely
some domos are correct as well as the example for the function
https://docs.opencv.org/master/d6/dc7/group__imgproc__hist.html#ga4b2b5fd75503ff9e6844cc4dcdaed35d
2021-06-30 17:22:56 +03:00
APrigarina 5e80bd3cc9 fix samples 3.4 2021-06-30 12:50:21 +03:00
Anatoliy Talamanov fb7ef76e74 Merge pull request #20271 from TolyaTalamanov:at/extend-python-bindings
G-API: Extend python bindings

* Extend G-API bindings

* Wrap timestamp, seqNo, seq_id
* Wrap copy
* Wrap parseSSD, parseYolo

* Rewrap cv.gapi.networks

* Add test for metabackend in pytnon

* Remove int64 pyopencv_to
2021-06-30 09:04:09 +00:00
Alexander Alekhin db4b1e613c core(persistence): fix types format handling
partial backport of 4eac198270
2021-06-29 21:54:52 +00:00
Alexander Alekhin ee39081b11 Merge pull request #20321 from alalek:issue_20279 2021-06-29 21:13:19 +00:00
Alexander Alekhin 7d842f5bcf dnn: use OpenVINO 2021.4 defines 2021-06-29 18:48:21 +00:00
Alexander Alekhin 4eac198270 core(persistence): fix types format handling, fix 16F support 2021-06-29 11:26:57 +00:00
Alexander Alekhin faac32418c Merge pull request #20302 from rogday:tf_import_diag 2021-06-28 20:54:44 +00:00
Alexander Alekhin 42810621df Merge pull request #20318 from komakai:better-unsigned-type-support 2021-06-28 20:52:32 +00:00
Giles Payne 61a5378aeb Improvements/fixes for unsigned type handling in Swift/Kotlin 2021-06-27 21:08:25 +09:00
xzvno 42d644ef91 Merge pull request #20293 from endjkv:fix-mem-leak-when-throw
* fix memory leak when exception is thrown
2021-06-27 00:01:31 +03:00
Alexey Smirnov c95a56450d Merge pull request #20156 from smirnov-alexey:as/gapi_remote_infer
G-API: Support remote inference

* Extend MediaFrame to be able to extract additional info besides access

* Add API for remote inference

* Add default implementation for blobParams()

* Add default implementation for blobParams()

* Address review comments

* Fix any_cast usage

* Add comment on the default blobParams()

* Address review comments

* Add missing rctx

* Minor fix

* Fix indentation and comment

* Address review comments

* Add documentation
2021-06-26 00:09:33 +03:00
Smirnov Egor dc5199feea skipping missing layers and layer failures 2021-06-25 11:26:37 +03:00
Alexander Alekhin f88fdf6a1b Merge pull request #20304 from vrabaud:master 2021-06-24 09:51:36 +00:00
Vincent Rabaud b68057d927 Do not use = 0 for a cv::Mat.
There are several operator= overloads and some compilers can be confused.
2021-06-23 21:30:06 +02:00
Alexander Alekhin e9a860d9cb Merge pull request #20295 from diablodale:umat_factory_usageflags 2021-06-23 18:15:14 +00:00
Dale Phurrough 8be86cbdfd add usageFlags to UMat static factories
- add abi compatible overloads
- add test case
2021-06-23 18:50:33 +02:00
Alexander Alekhin 5091e64a42 Merge pull request #20204 from Developer-Ecosystem-Engineering:improve-sift 2021-06-22 22:58:52 +00:00
Alexander Alekhin 828304d587 Merge pull request #20128 from kikaxa:master 2021-06-21 21:52:17 +00:00
Alexander Alekhin 9d584475f6 Merge pull request #20283 from SamFC10:fix-batchnorm 2021-06-21 11:27:12 +00:00
kikaxa bb60cb0bf9 Reenable filesystem for ios builds 2021-06-20 16:33:25 +00:00
Alexander Alekhin 25f908b320 Merge pull request #20259 from IanMaquignaz:inverseRectification_newUnitTest 2021-06-20 16:27:47 +00:00
Alexander Alekhin 9b7dca2fa1 Merge pull request #20281 from alalek:highgui_win32ui_plugin 2021-06-20 16:25:20 +00:00
SamFC10 55e1dfb778 Fix BatchNorm reinitialization 2021-06-20 13:19:29 +05:30
Alexander Alekhin 735a79ae83 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-06-19 18:44:16 +00:00
Alexander Alekhin ef2b400c61 highgui: win32ui plugin 2021-06-19 13:15:46 +00:00
Alexander Alekhin c2263db7bc Merge pull request #20232 from gasparitiago:drawMatches3.4 2021-06-18 19:47:52 +00:00
Anatoliy Talamanov 53eca2ff5b Merge pull request #20196 from TolyaTalamanov:at/support-vaargs-compile-args
G-API: Support vaargs for cv.compile_args

* Support cv.compile_args to work with variadic number of inputs

* Disable python2.x G-API

* Move compile_args to gapi pkg
2021-06-18 20:16:07 +03:00
Alexander Alekhin 7bbbda71df Merge pull request #20253 from rogday:gtk_modifiers 2021-06-18 15:46:44 +00:00
Zhang Yin 3a15a3821a Update RISC-V back-end to RVV 0.10 2021-06-18 15:44:38 +08:00
Developer-Ecosystem-Engineering 9557b9f70f Improve SIFT for arm64/Apple silicon
- Reduce branch density by collapsing compares.
- Fix windows build errors
- Use OpenCV universal intrinsics
- Use v_check_any and v_signmask as requested
2021-06-17 10:14:48 -07:00
Ian Maquignaz 464441d8c3 Added new unit test for initInverseRectificationMap()
Function is validated. Included an update to DISABLED_Calib3d_InitInverseRectificationMap.

Includes updates per input from @alalek and unit test regression # to reflect PR #
2021-06-17 12:48:16 -04:00
Alexander Alekhin f30f1afd47 Merge pull request #20272 from rogday:pollKey_link 2021-06-17 11:01:37 +00:00
Alexander Alekhin b3db37b99d Merge pull request #20238 from dmatveev:dm/gframe_docs 2021-06-16 15:06:04 +00:00
Smirnov Egor 7a276f39fb reorder defined checks according to cmake file 2021-06-16 11:36:13 +03:00
Dmitry Matveev 415668ecf0 G-API: Documentation updates
1) Document GFrame/MediaFrame (and also other G-API types)
- Added doxygen comments for GMat, GScalar, GArray<T>, GOpaque classes;
- Documented GFrame and its host-side counterpart MediaFrame;
- Added some more notes to the data type classes.

2) Give @brief descriptions to most of the cv::gapi::* namespaces

3) Make some symbols private
- These structures are mainly internal and shouldn't be used directly
2021-06-16 01:01:55 +03:00
Maxim Pashchenkov 651967b95c Merge pull request #19341 from mpashchenkov:mp/ocv-gapi-parsessd-fix
G-API: Removing ParseSSD overload.

* Removed specialization.

* Removed united
2021-06-15 19:02:17 +00:00
Alexander Alekhin 8e0baf257c Merge pull request #20263 from vrabaud:3.4 2021-06-15 18:20:21 +00:00
Vincent Rabaud c8268e65fd Fix potential NaN in cv::norm.
There can be an int overflow.
cv::norm( InputArray _src, int normType, InputArray _mask ) is fine,
not cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask ).
2021-06-15 14:58:11 +02:00
Tiago De Gaspari 3cf4375387 Merge pull request #19842 from gasparitiago:3.4
Update rotatedRectangleIntersection function to calculate near to origin

* Change type used in points function from RotatedRect

In the function that sets the points of a RotatedRect, the types

should be double in order to keep the precision when dealing with
RotatedRects that are defined far from the origin.

This commit solves the problem in some assertions from
rotatedRectangleIntersection when dealing with rectangles far from
origin.

* added proper type casts

* Update rotatedRectangleIntersection function to calculate near to origin

This commit changes the rotatedRectangleIntersection function in order
to calculate the intersection of two rectangles considering that they
are shifted near the coordinates origin (0, 0).

This commit solves the problem in some assertions from
rotatedRectangleIntersection when dealing with rectangles far from
origin.

* Revert type changes in types.cpp and adequate code to c++98

* Revert unnecessary casts on types.cpp

Co-authored-by: Vadim Pisarevsky <vadim.pisarevsky@gmail.com>
2021-06-12 23:28:54 +03:00
Alexander Alekhin 438e2dc228 Merge pull request #20260 from JoeHowse:DirectX-float16-conversions 2021-06-11 20:13:11 +00:00
Alexander Alekhin c1adbe3189 Merge pull request #20190 from rogday:tf_importer_ref 2021-06-11 20:06:09 +00:00
rogday 7ee1816612 split if into map of functions 2021-06-11 13:20:45 +03:00
Joe Howse b4084491e5 DirectX: Support more types, including float16
Support the following type conversions:

* CV_16FC4 --> DXGI_FORMAT_R16G16B16A16_FLOAT

* CV_16FC2 --> DXGI_FORMAT_R16G16_FLOAT

* CV_16FC1 --> DXGI_FORMAT_R16_FLOAT

* CV_32FC2 --> DXGI_FORMAT_R32G32_FLOAT

* CV_32FC1 --> DXGI_FORMAT_D32_FLOAT

* CV_32SC2 --> DXGI_FORMAT_R32G32_UINT

* CV_32SC2 --> DXGI_FORMAT_R32G32_SINT

* CV_8UC4 -->  DXGI_FORMAT_R8G8_B8G8_UNORM

* CV_8UC4 -->  DXGI_FORMAT_G8R8_G8B8_UNORM
2021-06-11 00:55:06 -03:00
Smirnov Egor 8f4f834ce6 applied modifier mask to the state 2021-06-10 10:57:15 +03:00
Tiago De Gaspari 411fd2b761 Add Thickness parameter in drawMatches function
This commit adds the feature of selecting the thickness
of the matches drawn by the drawMatches function.

In larger images, the default thickness of 1 pixel creates images
that are hard to visualize.
2021-06-07 12:52:48 -03:00
Zach Lowry 61d7d67c39 Use argument value for 'mat' in call to format for vector_mat and vector_mat_template
The hard-coded string value "Mat" was used in the two format strings for vector_mat and vector_mat_template, preventing UMat arguments to functions that have these types from working correctly. Notably, #12231 references this issue.
2019-10-23 12:37:14 -05:00
1530 changed files with 235395 additions and 173164 deletions
+7 -7
View File
@@ -34,11 +34,11 @@ This is a template helping you to create an issue which can be processed as quic
- [ ] I report the issue, it's not a question
<!--
OpenCV team works with forum.opencv.org, Stack Overflow and other communities
to discuss problems. Tickets with question without real issue statement will be
to discuss problems. Tickets with questions without a real issue statement will be
closed.
-->
- [ ] I checked the problem with documentation, FAQ, open issues,
forum.opencv.org, Stack Overflow, etc and have not found solution
forum.opencv.org, Stack Overflow, etc and have not found any solution
<!--
Places to check:
* OpenCV documentation: https://docs.opencv.org
@@ -47,11 +47,11 @@ This is a template helping you to create an issue which can be processed as quic
* OpenCV issue tracker: https://github.com/opencv/opencv/issues?q=is%3Aissue
* Stack Overflow branch: https://stackoverflow.com/questions/tagged/opencv
-->
- [ ] I updated to latest OpenCV version and the issue is still there
- [ ] I updated to the latest OpenCV version and the issue is still there
<!--
master branch for OpenCV 4.x and 3.4 branch for OpenCV 3.x releases.
OpenCV team supports only latest release for each branch.
The ticket is closed, if the problem is not reproduced with modern version.
OpenCV team supports only the latest release for each branch.
The ticket is closed if the problem is not reproduced with the modern version.
-->
- [ ] There is reproducer code and related data files: videos, images, onnx, etc
<!--
@@ -61,9 +61,9 @@ This is a template helping you to create an issue which can be processed as quic
to reduce attachment size
* Use PNG for images, if you report some CV related bug, but not image reader
issue
* Attach the image as archive to the ticket, if you report some reader issue.
* Attach the image as an archive to the ticket, if you report some reader issue.
Image hosting services compress images and it breaks the repro code.
* Provide ONNX file for some public model or ONNX file with with random weights,
* Provide ONNX file for some public model or ONNX file with random weights,
if you report ONNX parsing or handling issue. Architecture details diagram
from netron tool can be very useful too. See https://lutzroeder.github.io/netron/
-->
+3 -3
View File
@@ -3,9 +3,9 @@
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [ ] I agree to contribute to the project under Apache 2 License.
- [ ] To the best of my knowledge, the proposed patch is not based on a code under GPL or other license that is incompatible with OpenCV
- [ ] The PR is proposed to proper branch
- [ ] There is reference to original bug report and related work
- [ ] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [ ] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
+19
View File
@@ -0,0 +1,19 @@
name: PR:4.x
on:
pull_request:
branches:
- 4.x
jobs:
ARM64:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-ARM64.yaml@main
U20:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-U20.yaml@main
W10:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-W10.yaml@main
TIM-VX:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-timvx-backend-tests-4.x.yml@main
+25
View File
@@ -0,0 +1,25 @@
name: lint_python
on: workflow_dispatch
jobs:
lint_python:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- run: pip install --upgrade pip wheel
- run: pip install bandit black codespell flake8 flake8-2020 flake8-bugbear
flake8-comprehensions isort mypy pytest pyupgrade safety
- run: bandit --recursive --skip B101 . || true # B101 is assert statements
- run: black --check . || true
- run: codespell || true # --ignore-words-list="" --skip="*.css,*.js,*.lock"
- run: flake8 . --count --select=E9,F63,F7 --show-source --statistics
- run: flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88
--show-source --statistics
- run: isort --check-only --profile black . || true
- run: pip install -r requirements.txt || pip install --editable . || true
- run: mkdir --parents --verbose .mypy_cache
- run: mypy --ignore-missing-imports --install-types --non-interactive . || true
- run: pytest . || true
- run: pytest --doctest-modules . || true
- run: shopt -s globstar && pyupgrade --py36-plus **/*.py || true
- run: safety check
+26 -17
View File
@@ -1778,30 +1778,30 @@ TegraCvtColor_Invoker(bgrx2hsvf, bgrx2hsv, src_data + static_cast<size_t>(range.
: CV_HAL_ERROR_NOT_IMPLEMENTED \
)
#define TEGRA_CVT2PYUVTOBGR(src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx) \
#define TEGRA_CVT2PYUVTOBGR_EX(y_data, y_step, uv_data, uv_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx) \
( \
CAROTENE_NS::isSupportedConfiguration() ? \
dcn == 3 ? \
uIdx == 0 ? \
(swapBlue ? \
CAROTENE_NS::yuv420i2rgb(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step) : \
CAROTENE_NS::yuv420i2bgr(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step)), \
CV_HAL_ERROR_OK : \
uIdx == 1 ? \
(swapBlue ? \
CAROTENE_NS::yuv420sp2rgb(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step) : \
CAROTENE_NS::yuv420sp2bgr(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step)), \
CV_HAL_ERROR_OK : \
CV_HAL_ERROR_NOT_IMPLEMENTED : \
@@ -1809,29 +1809,32 @@ TegraCvtColor_Invoker(bgrx2hsvf, bgrx2hsv, src_data + static_cast<size_t>(range.
uIdx == 0 ? \
(swapBlue ? \
CAROTENE_NS::yuv420i2rgbx(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step) : \
CAROTENE_NS::yuv420i2bgrx(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step)), \
CV_HAL_ERROR_OK : \
uIdx == 1 ? \
(swapBlue ? \
CAROTENE_NS::yuv420sp2rgbx(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step) : \
CAROTENE_NS::yuv420sp2bgrx(CAROTENE_NS::Size2D(dst_width, dst_height), \
src_data, src_step, \
src_data + src_step * dst_height, src_step, \
y_data, y_step, \
uv_data, uv_step, \
dst_data, dst_step)), \
CV_HAL_ERROR_OK : \
CV_HAL_ERROR_NOT_IMPLEMENTED : \
CV_HAL_ERROR_NOT_IMPLEMENTED \
: CV_HAL_ERROR_NOT_IMPLEMENTED \
)
#define TEGRA_CVT2PYUVTOBGR(src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx) \
TEGRA_CVT2PYUVTOBGR_EX(src_data, src_step, src_data + src_step * dst_height, src_step, dst_data, dst_step, \
dst_width, dst_height, dcn, swapBlue, uIdx);
#undef cv_hal_cvtBGRtoBGR
#define cv_hal_cvtBGRtoBGR TEGRA_CVTBGRTOBGR
@@ -1841,12 +1844,18 @@ TegraCvtColor_Invoker(bgrx2hsvf, bgrx2hsv, src_data + static_cast<size_t>(range.
#define cv_hal_cvtBGRtoGray TEGRA_CVTBGRTOGRAY
#undef cv_hal_cvtGraytoBGR
#define cv_hal_cvtGraytoBGR TEGRA_CVTGRAYTOBGR
#if 0 // bit-exact tests are failed
#undef cv_hal_cvtBGRtoYUV
#define cv_hal_cvtBGRtoYUV TEGRA_CVTBGRTOYUV
#endif
#undef cv_hal_cvtBGRtoHSV
#define cv_hal_cvtBGRtoHSV TEGRA_CVTBGRTOHSV
#if 0 // bit-exact tests are failed
#undef cv_hal_cvtTwoPlaneYUVtoBGR
#define cv_hal_cvtTwoPlaneYUVtoBGR TEGRA_CVT2PYUVTOBGR
#undef cv_hal_cvtTwoPlaneYUVtoBGREx
#define cv_hal_cvtTwoPlaneYUVtoBGREx TEGRA_CVT2PYUVTOBGR_EX
#endif
#endif // OPENCV_IMGPROC_HAL_INTERFACE_H
+5 -5
View File
@@ -1,8 +1,8 @@
# Binaries branch name: ffmpeg/master_20210608
# Binaries were created for OpenCV: eaa9228a4fdfb9c2465aea65a50ce2d16b55dce0
ocv_update(FFMPEG_BINARIES_COMMIT "213fcd5d4897319a83207406036c4a5957fba010")
ocv_update(FFMPEG_FILE_HASH_BIN32 "bab661341c30862fa88627130219c0a5")
ocv_update(FFMPEG_FILE_HASH_BIN64 "ac99f9767a83103c31709628af685924")
# Binaries branch name: ffmpeg/4.x_20220524
# Binaries were created for OpenCV: d6e9616256b46bd59be0a93d397f6ab958d39cd2
ocv_update(FFMPEG_BINARIES_COMMIT "65ec04d4573dcdfa4531f0b9e67f35d8ffff873e")
ocv_update(FFMPEG_FILE_HASH_BIN32 "5573e2262ad1298e603122b7759fc2f6")
ocv_update(FFMPEG_FILE_HASH_BIN64 "5f9e2b2e04c15f080f40e844de80c867")
ocv_update(FFMPEG_FILE_HASH_CMAKE "8862c87496e2e8c375965e1277dee1c7")
function(download_win_ffmpeg script_var)
+1
View File
@@ -54,6 +54,7 @@ set_target_properties(${ITT_LIBRARY} PROPERTIES
)
ocv_warnings_disable(CMAKE_C_FLAGS -Wundef -Wsign-compare)
ocv_warnings_disable(CMAKE_C_FLAGS -Wstrict-prototypes) # clang15
if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(${ITT_LIBRARY} PROPERTIES FOLDER "3rdparty")
+2 -2
View File
@@ -4,9 +4,9 @@ ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter -Wsign-compare -Wshorten-6
set(VERSION_MAJOR 2)
set(VERSION_MINOR 1)
set(VERSION_REVISION 0)
set(VERSION_REVISION 2)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION})
set(LIBJPEG_TURBO_VERSION_NUMBER 2001000)
set(LIBJPEG_TURBO_VERSION_NUMBER 2001002)
string(TIMESTAMP BUILD "opencv-${OPENCV_VERSION}-libjpeg-turbo")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+10
View File
@@ -40,3 +40,13 @@
#define HAVE_BITSCANFORWARD
#endif
#endif
#if defined(__has_attribute)
#if __has_attribute(fallthrough)
#define FALLTHROUGH __attribute__((fallthrough));
#else
#define FALLTHROUGH
#endif
#else
#define FALLTHROUGH
#endif
+3 -2
View File
@@ -44,8 +44,9 @@
* flags (this defines __thumb__).
*/
#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || \
defined(_M_ARM64)
/* NOTE: Both GCC and Clang define __GNUC__ */
#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \
defined(_M_ARM) || defined(_M_ARM64)
#if !defined(__thumb__) || defined(__thumb2__)
#define USE_CLZ_INTRINSIC
#endif
+1 -1
View File
@@ -493,7 +493,7 @@ prepare_for_pass(j_compress_ptr cinfo)
master->pass_type = output_pass;
master->pass_number++;
#endif
/*FALLTHROUGH*/
FALLTHROUGH /*FALLTHROUGH*/
case output_pass:
/* Do a data-output pass. */
/* We need not repeat per-scan setup if prior optimization pass did it. */
+6 -4
View File
@@ -7,6 +7,7 @@
* Copyright (C) 2011, 2015, 2018, 2021, D. R. Commander.
* Copyright (C) 2016, 2018, Matthieu Darbois.
* Copyright (C) 2020, Arm Limited.
* Copyright (C) 2021, Alex Richardson.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -52,8 +53,9 @@
* flags (this defines __thumb__).
*/
#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || \
defined(_M_ARM64)
/* NOTE: Both GCC and Clang define __GNUC__ */
#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \
defined(_M_ARM) || defined(_M_ARM64)
#if !defined(__thumb__) || defined(__thumb2__)
#define USE_CLZ_INTRINSIC
#endif
@@ -679,7 +681,7 @@ encode_mcu_AC_first(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
emit_restart(entropy, entropy->next_restart_num);
#ifdef WITH_SIMD
cvalue = values = (JCOEF *)PAD((size_t)values_unaligned, 16);
cvalue = values = (JCOEF *)PAD((JUINTPTR)values_unaligned, 16);
#else
/* Not using SIMD, so alignment is not needed */
cvalue = values = values_unaligned;
@@ -944,7 +946,7 @@ encode_mcu_AC_refine(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
emit_restart(entropy, entropy->next_restart_num);
#ifdef WITH_SIMD
cabsvalue = absvalues = (JCOEF *)PAD((size_t)absvalues_unaligned, 16);
cabsvalue = absvalues = (JCOEF *)PAD((JUINTPTR)absvalues_unaligned, 16);
#else
/* Not using SIMD, so alignment is not needed */
cabsvalue = absvalues = absvalues_unaligned;
+2 -1
View File
@@ -23,6 +23,7 @@
#include "jinclude.h"
#include "jpeglib.h"
#include "jdmaster.h"
#include "jconfigint.h"
/*
@@ -308,7 +309,7 @@ jpeg_consume_input(j_decompress_ptr cinfo)
/* Initialize application's data source module */
(*cinfo->src->init_source) (cinfo);
cinfo->global_state = DSTATE_INHEADER;
/*FALLTHROUGH*/
FALLTHROUGH /*FALLTHROUGH*/
case DSTATE_INHEADER:
retcode = (*cinfo->inputctl->consume_input) (cinfo);
if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */
+10 -1
View File
@@ -584,7 +584,7 @@ decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
* behavior is, to the best of our understanding, innocuous, and it is
* unclear how to work around it without potentially affecting
* performance. Thus, we (hopefully temporarily) suppress UBSan integer
* overflow errors for this function.
* overflow errors for this function and decode_mcu_fast().
*/
s += state.last_dc_val[ci];
state.last_dc_val[ci] = s;
@@ -651,6 +651,12 @@ decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
#if defined(__has_feature)
#if __has_feature(undefined_behavior_sanitizer)
__attribute__((no_sanitize("signed-integer-overflow"),
no_sanitize("unsigned-integer-overflow")))
#endif
#endif
LOCAL(boolean)
decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
@@ -681,6 +687,9 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if (entropy->dc_needed[blkn]) {
int ci = cinfo->MCU_membership[blkn];
/* Refer to the comment in decode_mcu_slow() regarding the supression of
* a UBSan integer overflow error in this line of code.
*/
s += state.last_dc_val[ci];
state.last_dc_val[ci] = s;
if (block)
+3 -2
View File
@@ -18,6 +18,7 @@
#include "jinclude.h"
#include "jdmainct.h"
#include "jconfigint.h"
/*
@@ -360,7 +361,7 @@ process_data_context_main(j_decompress_ptr cinfo, JSAMPARRAY output_buf,
main_ptr->context_state = CTX_PREPARE_FOR_IMCU;
if (*out_row_ctr >= out_rows_avail)
return; /* Postprocessor exactly filled output buf */
/*FALLTHROUGH*/
FALLTHROUGH /*FALLTHROUGH*/
case CTX_PREPARE_FOR_IMCU:
/* Prepare to process first M-1 row groups of this iMCU row */
main_ptr->rowgroup_ctr = 0;
@@ -371,7 +372,7 @@ process_data_context_main(j_decompress_ptr cinfo, JSAMPARRAY output_buf,
if (main_ptr->iMCU_row_ctr == cinfo->total_iMCU_rows)
set_bottom_pointers(cinfo);
main_ptr->context_state = CTX_PROCESS_IMCU;
/*FALLTHROUGH*/
FALLTHROUGH /*FALLTHROUGH*/
case CTX_PROCESS_IMCU:
/* Call postprocessor using previously set pointers */
(*cinfo->post->post_process_data) (cinfo,
+3 -3
View File
@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2016, D. R. Commander.
* Copyright (C) 2016, 2021, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -1032,7 +1032,7 @@ free_pool(j_common_ptr cinfo, int pool_id)
large_pool_ptr next_lhdr_ptr = lhdr_ptr->next;
space_freed = lhdr_ptr->bytes_used +
lhdr_ptr->bytes_left +
sizeof(large_pool_hdr);
sizeof(large_pool_hdr) + ALIGN_SIZE - 1;
jpeg_free_large(cinfo, (void *)lhdr_ptr, space_freed);
mem->total_space_allocated -= space_freed;
lhdr_ptr = next_lhdr_ptr;
@@ -1045,7 +1045,7 @@ free_pool(j_common_ptr cinfo, int pool_id)
while (shdr_ptr != NULL) {
small_pool_ptr next_shdr_ptr = shdr_ptr->next;
space_freed = shdr_ptr->bytes_used + shdr_ptr->bytes_left +
sizeof(small_pool_hdr);
sizeof(small_pool_hdr) + ALIGN_SIZE - 1;
jpeg_free_small(cinfo, (void *)shdr_ptr, space_freed);
mem->total_space_allocated -= space_freed;
shdr_ptr = next_shdr_ptr;
+14 -1
View File
@@ -5,8 +5,9 @@
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 1997-2009 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2015-2016, 2019, D. R. Commander.
* Copyright (C) 2015-2016, 2019, 2021, D. R. Commander.
* Copyright (C) 2015, Google, Inc.
* Copyright (C) 2021, Alex Richardson.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -47,6 +48,18 @@ typedef enum { /* Operating modes for buffer controllers */
/* JLONG must hold at least signed 32-bit values. */
typedef long JLONG;
/* JUINTPTR must hold pointer values. */
#ifdef __UINTPTR_TYPE__
/*
* __UINTPTR_TYPE__ is GNU-specific and available in GCC 4.6+ and Clang 3.0+.
* Fortunately, that is sufficient to support the few architectures for which
* sizeof(void *) != sizeof(size_t). The only other options would require C99
* or Clang-specific builtins.
*/
typedef __UINTPTR_TYPE__ JUINTPTR;
#else
typedef size_t JUINTPTR;
#endif
/*
* Left shift macro that handles a negative operand without causing any
+5 -1
View File
@@ -77,7 +77,11 @@ endif(MSVC)
add_library(${PNG_LIBRARY} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${lib_srcs} ${lib_hdrs})
target_link_libraries(${PNG_LIBRARY} ${ZLIB_LIBRARIES})
ocv_warnings_disable(CMAKE_C_FLAGS -Wundef -Wcast-align -Wimplicit-fallthrough -Wunused-parameter -Wsign-compare)
ocv_warnings_disable(CMAKE_C_FLAGS -Wundef -Wcast-align -Wimplicit-fallthrough -Wunused-parameter -Wsign-compare
-Wmaybe-uninitialized
-Wnull-pointer-subtraction # clang15
-Wunused-but-set-variable # clang15
)
set_target_properties(${PNG_LIBRARY}
PROPERTIES OUTPUT_NAME ${PNG_LIBRARY}
+3 -1
View File
@@ -452,8 +452,10 @@ ocv_warnings_disable(CMAKE_C_FLAGS -Wno-unused-but-set-variable -Wmissing-protot
-Wcast-align -Wshadow -Wno-maybe-uninitialized -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast
-Wmisleading-indentation
-Wimplicit-fallthrough
-Wunused-parameter # clang
-Warray-parameter
-Wstrict-prototypes # clang15
)
ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter) # clang
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-declarations -Wunused-parameter -Wmissing-prototypes
-Wundef # tiffiop.h: #if __clang_major__ >= 4
)
+73
View File
@@ -0,0 +1,73 @@
set(TIMVX_COMMIT_HASH "1d9c7ab941b3d8d9c4d28d80058402725731e3d6")
set(OCV_TIMVX_DIR "${OpenCV_BINARY_DIR}/3rdparty/libtim-vx")
set(OCV_TIMVX_SOURCE_PATH "${OCV_TIMVX_DIR}/TIM-VX-${TIMVX_COMMIT_HASH}")
# Download TIM-VX source code
if(EXISTS "${OCV_TIMVX_SOURCE_PATH}")
message(STATUS "TIM-VX: Use cache of TIM-VX source code at ${OCV_TIMVX_SOURCE_PATH}")
set(TIMVX_FOUND ON)
else()
set(OCV_TIMVX_FILENAME "${TIMVX_COMMIT_HASH}.zip")
set(OCV_TIMVX_URL "https://github.com/VeriSilicon/TIM-VX/archive/")
set(timvx_zip_md5sum 92619cc4498014ac7a09834d5e33ebd5)
ocv_download(FILENAME ${OCV_TIMVX_FILENAME}
HASH ${timvx_zip_md5sum}
URL "${OCV_TIMVX_URL}"
DESTINATION_DIR "${OCV_TIMVX_DIR}"
ID "TIM-VX"
STATUS res
UNPACK RELATIVE_URL)
if(res)
set(TIMVX_FOUND ON)
message(STATUS "TIM-VX: Source code downloaded at ${OCV_TIMVX_SOURCE_PATH}.")
else()
set(TIMVX_FOUND OFF)
message(STATUS "TIM-VX: Failed to download source code from github. Turning off TIMVX_FOUND")
return()
endif()
endif()
# set VIVANTE SDK especially for x86_64 which comes along with TIM-VX source code
if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
set(VIVANTE_SDK_DIR "${OCV_TIMVX_SOURCE_PATH}/prebuilt-sdk/x86_64_linux")
message(STATUS "TIM-VX: Build from source using prebuilt x86_64 VIVANTE SDK.")
endif()
# Verify if requested VIVANTE SDK libraries are all found
find_vivante_sdk_libs(missing ${VIVANTE_SDK_DIR})
if(missing)
message(STATUS "TIM-VX: Failed to find ${missing} in ${VIVANTE_SDK_DIR}/lib. Turning off TIMVX_VIV_FOUND")
set(TIMVX_VIV_FOUND OFF)
else()
message(STATUS "TIM-VX: dependent VIVANTE SDK libraries are found at ${VIVANTE_SDK_DIR}/lib.")
set(TIMVX_VIV_FOUND ON)
endif()
if(TIMVX_VIV_FOUND)
# vars used by TIM-VX CMake scripts
set(EXTERNAL_VIV_SDK "${VIVANTE_SDK_DIR}" CACHE INTERNAL "" FORCE)
set(VIV_SDK_DRIVER_PREFIX "lib" CACHE INTERNAL "" FORCE)
endif()
if(TIMVX_FOUND AND TIMVX_VIV_FOUND)
set(BUILD_TIMVX ON)
else()
return()
endif()
if(BUILD_TIMVX)
set(HAVE_TIMVX 1)
ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter -Wstrict-prototypes -Wundef -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wstrict-aliasing -Wunused-but-set-variable -Wmaybe-uninitialized -Wshadow -Wsuggest-override -Wswitch)
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wunused-parameter -Wstrict-prototypes -Wundef -Wsign-compare -Wunused-but-set-variable -Wshadow -Wsuggest-override -Wmissing-declarations -Wswitch)
set(TIMVX_INC_DIR "${OCV_TIMVX_SOURCE_PATH}/include" CACHE INTERNAL "TIM-VX include directory")
if(EXISTS "${OCV_TIMVX_SOURCE_PATH}/CMakeLists.txt")
add_subdirectory("${OCV_TIMVX_SOURCE_PATH}" "${OCV_TIMVX_DIR}/build")
else()
message(WARNING "TIM-VX: Missing 'CMakeLists.txt' in the source code: ${OCV_TIMVX_SOURCE_PATH}")
endif()
ocv_install_target(tim-vx EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
set(TIMVX_LIB "tim-vx")
endif()
+4 -1
View File
@@ -32,7 +32,9 @@ endif()
# Define the library target:
# ----------------------------------------------------------------------------------
add_definitions(-DWEBP_USE_THREAD)
if(NOT OPENCV_DISABLE_THREAD_SUPPORT)
add_definitions(-DWEBP_USE_THREAD)
endif()
add_library(${WEBP_LIBRARY} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${lib_srcs} ${lib_hdrs})
if(ANDROID)
@@ -43,6 +45,7 @@ ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-variable -Wunused-function -Wshadow
-Wmissing-prototypes # clang
-Wmissing-declarations # gcc
-Wimplicit-fallthrough
-Wunused-but-set-variable # clang15
)
ocv_warnings_disable(CMAKE_C_FLAGS /wd4244 /wd4267) # vs2005
+1
View File
@@ -13,6 +13,7 @@ project(openjpeg C)
ocv_warnings_disable(CMAKE_C_FLAGS
-Wimplicit-const-int-float-conversion # clang
-Wunused-but-set-variable # clang15
)
#-----------------------------------------------------------------------------
+1 -1
View File
@@ -77,7 +77,7 @@ E.g. external ref-counting is implemented for 1.0 version and native OpenVX one
Also there are some **C++ 11** features are used (e.g. rvalue ref-s) when their availability is detected at ***compile time***.
C++ exceptions are used for errors indication instead of return codes. There are two types of exceptions are defined: `RuntimeError` is thrown when OpenVX C call returned unsuccessful result and `WrapperError` is thrown when a problem is occured in the wrappers code. Both exception calsses are derived from `std::exception` (actually from its inheritants).
C++ exceptions are used for errors indication instead of return codes. There are two types of exceptions are defined: `RuntimeError` is thrown when OpenVX C call returned unsuccessful result and `WrapperError` is thrown when a problem is occurred in the wrappers code. Both exception calsses are derived from `std::exception` (actually from its inheritants).
The so called **OpenVX objects** (e.g. `vx_image`) are represented as C++ classes in wrappers.
All these classes use automatic ref-counting that allows development of exception-safe code.
+9 -5
View File
@@ -923,6 +923,11 @@ int ovx_hal_cvtGraytoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep,
}
int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx)
{
return ovx_hal_cvtTwoPlaneYUVtoBGREx(a, astep, a + h * astep, astep, b, bstep, w, h, bcn, swapBlue, uIdx);
}
int ovx_hal_cvtTwoPlaneYUVtoBGREx(const uchar * a, size_t astep, const uchar * b, size_t bstep, uchar * c, size_t cstep, int w, int h, int bcn, bool swapBlue, int uIdx)
{
if (skipSmallImages<VX_KERNEL_COLOR_CONVERT>(w, h))
return CV_HAL_ERROR_NOT_IMPLEMENTED;
@@ -933,8 +938,7 @@ int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t
if (w & 1 || h & 1) // It's not described in spec but sample implementation unable to convert odd sized images
return CV_HAL_ERROR_NOT_IMPLEMENTED;
refineStep(w, h, uIdx ? VX_DF_IMAGE_NV21 : VX_DF_IMAGE_NV12, astep);
refineStep(w, h, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, bstep);
try
{
ivx::Context ctx = getOpenVXHALContext();
@@ -943,8 +947,8 @@ int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t
std::vector<void *> ptrs;
addr.push_back(ivx::Image::createAddressing(w, h, 1, (vx_int32)astep));
ptrs.push_back((void*)a);
addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 2, (vx_int32)astep));
ptrs.push_back((void*)(a + h * astep));
addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 2, (vx_int32)bstep));
ptrs.push_back((void*)b);
vxImage
ia = ivx::Image::createFromHandle(ctx, uIdx ? VX_DF_IMAGE_NV21 : VX_DF_IMAGE_NV12, addr, ptrs);
@@ -952,7 +956,7 @@ int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t
return CV_HAL_ERROR_NOT_IMPLEMENTED; // OpenCV store NV12/NV21 as RANGE_RESTRICTED while OpenVX expect RANGE_FULL
vxImage
ib = ivx::Image::createFromHandle(ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX,
ivx::Image::createAddressing(w, h, bcn, (vx_int32)bstep), b);
ivx::Image::createAddressing(w, h, bcn, (vx_int32)cstep), c);
ivx::IVX_CHECK_STATUS(vxuColorConvert(ctx, ia, ib));
}
catch (ivx::RuntimeError & e)
+3
View File
@@ -49,6 +49,7 @@ int ovx_hal_morph(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *
int ovx_hal_cvtBGRtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int acn, int bcn, bool swapBlue);
int ovx_hal_cvtGraytoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int bcn);
int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx);
int ovx_hal_cvtTwoPlaneYUVtoBGREx(const uchar * a, size_t astep, const uchar * b, size_t bstep, uchar * c, size_t cstep, int w, int h, int bcn, bool swapBlue, int uIdx);
int ovx_hal_cvtThreePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx);
int ovx_hal_cvtBGRtoThreePlaneYUV(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int acn, bool swapBlue, int uIdx);
int ovx_hal_cvtOnePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx, int ycn);
@@ -130,6 +131,8 @@ int ovx_hal_integral(int depth, int sdepth, int, const uchar * a, size_t astep,
#define cv_hal_cvtGraytoBGR ovx_hal_cvtGraytoBGR
#undef cv_hal_cvtTwoPlaneYUVtoBGR
#define cv_hal_cvtTwoPlaneYUVtoBGR ovx_hal_cvtTwoPlaneYUVtoBGR
#undef cv_hal_cvtTwoPlaneYUVtoBGREx
#define cv_hal_cvtTwoPlaneYUVtoBGREx ovx_hal_cvtTwoPlaneYUVtoBGREx
#undef cv_hal_cvtThreePlaneYUVtoBGR
#define cv_hal_cvtThreePlaneYUVtoBGR ovx_hal_cvtThreePlaneYUVtoBGR
#undef cv_hal_cvtBGRtoThreePlaneYUV
+56 -50
View File
@@ -13,6 +13,9 @@ if(MSVC)
/wd4701 /wd4703 # potentially uninitialized local/pointer variable 'value' used
/wd4505 # unreferenced local function has been removed
)
if(MSVC_VERSION LESS 1920) # MSVS 2015/2017
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4309) # 'static_cast': truncation of constant value
endif()
else()
#NOTE: -Wno-invalid-offsetof was used as solution for invalid offset warning on protobuf #3450
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-deprecated -Wmissing-prototypes -Wmissing-declarations -Wshadow
@@ -49,98 +52,101 @@ endfunction()
set(PROTOBUF_ROOT "${CMAKE_CURRENT_LIST_DIR}")
if(MSVC)
set(ATOMICOPS_INTERNALS ${PROTOBUF_ROOT}/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc)
else()
set(ATOMICOPS_INTERNALS ${PROTOBUF_ROOT}/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc)
endif()
append_if_exist(Protobuf_SRCS
# libprotobuf-lite
${PROTOBUF_ROOT}/src/google/protobuf/any_lite.cc
${PROTOBUF_ROOT}/src/google/protobuf/arena.cc
${PROTOBUF_ROOT}/src/google/protobuf/arenastring.cc
${PROTOBUF_ROOT}/src/google/protobuf/extension_set.cc
${PROTOBUF_ROOT}/src/google/protobuf/generated_message_table_driven_lite.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/generated_enum_util.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/generated_message_table_driven_lite.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/generated_message_tctable_lite.cc
${PROTOBUF_ROOT}/src/google/protobuf/generated_message_util.cc
${PROTOBUF_ROOT}/src/google/protobuf/implicit_weak_message.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/inlined_string_field.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/coded_stream.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/io_win32.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/strtod.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/zero_copy_stream.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/zero_copy_stream_impl.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
${PROTOBUF_ROOT}/src/google/protobuf/map.cc
${PROTOBUF_ROOT}/src/google/protobuf/message_lite.cc
${PROTOBUF_ROOT}/src/google/protobuf/parse_context.cc
${PROTOBUF_ROOT}/src/google/protobuf/repeated_field.cc
${ATOMICOPS_INTERNALS}
${PROTOBUF_ROOT}/src/google/protobuf/repeated_ptr_field.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/bytestream.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/common.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/int128.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/io_win32.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/once.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/status.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/statusor.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/stubs/statusor.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/stringpiece.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/stringprintf.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/structurally_valid.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/strutil.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/time.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/stubs/time.cc
${PROTOBUF_ROOT}/src/google/protobuf/wire_format_lite.cc
# libprotobuf
${PROTOBUF_ROOT}/src/google/protobuf/any.cc
${PROTOBUF_ROOT}/src/google/protobuf/any.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/api.pb.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/any.pb.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/api.pb.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/compiler/importer.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/compiler/parser.cc
${PROTOBUF_ROOT}/src/google/protobuf/descriptor.cc
${PROTOBUF_ROOT}/src/google/protobuf/descriptor.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/descriptor_database.cc
${PROTOBUF_ROOT}/src/google/protobuf/duration.pb.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/duration.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/dynamic_message.cc
${PROTOBUF_ROOT}/src/google/protobuf/empty.pb.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/empty.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/extension_set_heavy.cc
${PROTOBUF_ROOT}/src/google/protobuf/field_mask.pb.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/field_mask.pb.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/generated_message_bases.cc
${PROTOBUF_ROOT}/src/google/protobuf/generated_message_reflection.cc
${PROTOBUF_ROOT}/src/google/protobuf/generated_message_table_driven.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/gzip_stream.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/printer.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/strtod.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/generated_message_table_driven.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/generated_message_tctable_full.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/io/gzip_stream.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/io/printer.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/tokenizer.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/zero_copy_stream_impl.cc
${PROTOBUF_ROOT}/src/google/protobuf/map_field.cc
${PROTOBUF_ROOT}/src/google/protobuf/message.cc
${PROTOBUF_ROOT}/src/google/protobuf/reflection_ops.cc
${PROTOBUF_ROOT}/src/google/protobuf/service.cc
${PROTOBUF_ROOT}/src/google/protobuf/source_context.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/struct.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/mathlimits.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/service.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/source_context.pb.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/struct.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/substitute.cc
${PROTOBUF_ROOT}/src/google/protobuf/text_format.cc
${PROTOBUF_ROOT}/src/google/protobuf/timestamp.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/type.pb.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/timestamp.pb.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/type.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/unknown_field_set.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/delimited_message_util.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/field_comparator.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/field_mask_util.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/internal/datapiece.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/internal/default_value_objectwriter.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/delimited_message_util.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/field_comparator.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/field_mask_util.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/datapiece.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/default_value_objectwriter.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/error_listener.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/internal/field_mask_utility.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/internal/json_escaping.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/internal/json_objectwriter.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/internal/json_stream_parser.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/internal/object_writer.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/internal/proto_writer.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/internal/protostream_objectsource.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/internal/protostream_objectwriter.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/internal/type_info.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/type_info_test_helper.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/internal/utility.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/json_util.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/message_differencer.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/time_util.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/type_resolver_util.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/field_mask_utility.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/json_escaping.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/json_objectwriter.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/json_stream_parser.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/object_writer.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/proto_writer.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/protostream_objectsource.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/protostream_objectwriter.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/type_info.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/utility.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/json_util.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/message_differencer.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/time_util.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/util/type_resolver_util.cc
${PROTOBUF_ROOT}/src/google/protobuf/wire_format.cc
${PROTOBUF_ROOT}/src/google/protobuf/wrappers.pb.cc
# ${PROTOBUF_ROOT}/src/google/protobuf/wrappers.pb.cc
)
include_directories(BEFORE "${PROTOBUF_ROOT}/src") # ensure using if own headers: https://github.com/opencv/opencv/issues/13328
include_directories(BEFORE "${PROTOBUF_ROOT}/src") # ensure using of own headers: https://github.com/opencv/opencv/issues/13328
add_library(libprotobuf STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${Protobuf_SRCS})
target_include_directories(libprotobuf SYSTEM PUBLIC $<BUILD_INTERFACE:${PROTOBUF_ROOT}/src>)
set_target_properties(libprotobuf
+1 -11
View File
@@ -1,14 +1,4 @@
This license applies to all parts of Protocol Buffers except the following:
- Atomicops support for generic gcc, located in
src/google/protobuf/stubs/atomicops_internals_generic_gcc.h.
This file is copyrighted by Red Hat Inc.
- Atomicops support for AIX/POWER, located in
src/google/protobuf/stubs/atomicops_internals_power.h.
This file is copyrighted by Bloomberg Finance LP.
Copyright 2014, Google Inc. All rights reserved.
Copyright 2008 Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
+1 -1
View File
@@ -1,3 +1,3 @@
Project: Protocol Buffers - Google's data interchange format
Source code: https://github.com/protocolbuffers/protobuf
Version: 3.5.2
Version: 3.19.1
+28 -59
View File
@@ -30,85 +30,54 @@
#include <google/protobuf/any.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/message.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace internal {
namespace {
string GetTypeUrl(const Descriptor* message,
const string& type_url_prefix) {
if (!type_url_prefix.empty() &&
type_url_prefix[type_url_prefix.size() - 1] == '/') {
return type_url_prefix + message->full_name();
} else {
return type_url_prefix + "/" + message->full_name();
}
}
} // namespace
const char kAnyFullTypeName[] = "google.protobuf.Any";
const char kTypeGoogleApisComPrefix[] = "type.googleapis.com/";
const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/";
AnyMetadata::AnyMetadata(UrlType* type_url, ValueType* value)
: type_url_(type_url), value_(value) {
bool AnyMetadata::PackFrom(Arena* arena, const Message& message) {
return PackFrom(arena, message, kTypeGoogleApisComPrefix);
}
void AnyMetadata::PackFrom(const Message& message) {
PackFrom(message, kTypeGoogleApisComPrefix);
}
void AnyMetadata::PackFrom(const Message& message,
const string& type_url_prefix) {
type_url_->SetNoArena(&::google::protobuf::internal::GetEmptyString(),
GetTypeUrl(message.GetDescriptor(), type_url_prefix));
message.SerializeToString(value_->MutableNoArena(
&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
bool AnyMetadata::PackFrom(Arena* arena, const Message& message,
StringPiece type_url_prefix) {
type_url_->Set(
&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString(),
GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix), arena);
return message.SerializeToString(
value_->Mutable(ArenaStringPtr::EmptyDefault{}, arena));
}
bool AnyMetadata::UnpackTo(Message* message) const {
if (!InternalIs(message->GetDescriptor())) {
if (!InternalIs(message->GetDescriptor()->full_name())) {
return false;
}
return message->ParseFromString(value_->GetNoArena());
return message->ParseFromString(value_->Get());
}
bool AnyMetadata::InternalIs(const Descriptor* descriptor) const {
const string type_url = type_url_->GetNoArena();
string full_name;
if (!ParseAnyTypeUrl(type_url, &full_name)) {
return false;
}
return full_name == descriptor->full_name();
}
bool ParseAnyTypeUrl(const string& type_url, string* full_type_name) {
size_t pos = type_url.find_last_of("/");
if (pos == string::npos || pos + 1 == type_url.size()) {
return false;
}
*full_type_name = type_url.substr(pos + 1);
return true;
}
bool GetAnyFieldDescriptors(const Message& message,
const FieldDescriptor** type_url_field,
const FieldDescriptor** value_field) {
const Descriptor* descriptor = message.GetDescriptor();
if (descriptor->full_name() != kAnyFullTypeName) {
return false;
}
*type_url_field = descriptor->FindFieldByNumber(1);
*value_field = descriptor->FindFieldByNumber(2);
return (*type_url_field != NULL &&
(*type_url_field)->type() == FieldDescriptor::TYPE_STRING &&
*value_field != NULL &&
(*value_field)->type() == FieldDescriptor::TYPE_BYTES);
const Descriptor* descriptor = message.GetDescriptor();
if (descriptor->full_name() != kAnyFullTypeName) {
return false;
}
*type_url_field = descriptor->FindFieldByNumber(1);
*value_field = descriptor->FindFieldByNumber(2);
return (*type_url_field != nullptr &&
(*type_url_field)->type() == FieldDescriptor::TYPE_STRING &&
*value_field != nullptr &&
(*value_field)->type() == FieldDescriptor::TYPE_BYTES);
}
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
+66 -17
View File
@@ -34,49 +34,89 @@
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/message.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
class FieldDescriptor;
class Message;
namespace internal {
extern const char kAnyFullTypeName[]; // "google.protobuf.Any".
extern const char kTypeGoogleApisComPrefix[]; // "type.googleapis.com/".
extern const char kTypeGoogleProdComPrefix[]; // "type.googleprod.com/".
std::string GetTypeUrl(StringPiece message_name,
StringPiece type_url_prefix);
// Helper class used to implement google::protobuf::Any.
class LIBPROTOBUF_EXPORT AnyMetadata {
class PROTOBUF_EXPORT AnyMetadata {
typedef ArenaStringPtr UrlType;
typedef ArenaStringPtr ValueType;
public:
// AnyMetadata does not take ownership of "type_url" and "value".
AnyMetadata(UrlType* type_url, ValueType* value);
constexpr AnyMetadata(UrlType* type_url, ValueType* value)
: type_url_(type_url), value_(value) {}
// Packs a message using the default type URL prefix: "type.googleapis.com".
// The resulted type URL will be "type.googleapis.com/<message_full_name>".
void PackFrom(const Message& message);
// Returns false if serializing the message failed.
template <typename T>
bool PackFrom(Arena* arena, const T& message) {
return InternalPackFrom(arena, message, kTypeGoogleApisComPrefix,
T::FullMessageName());
}
bool PackFrom(Arena* arena, const Message& message);
// Packs a message using the given type URL prefix. The type URL will be
// constructed by concatenating the message type's full name to the prefix
// with an optional "/" separator if the prefix doesn't already end up "/".
// with an optional "/" separator if the prefix doesn't already end with "/".
// For example, both PackFrom(message, "type.googleapis.com") and
// PackFrom(message, "type.googleapis.com/") yield the same result type
// URL: "type.googleapis.com/<message_full_name>".
void PackFrom(const Message& message, const string& type_url_prefix);
// Returns false if serializing the message failed.
template <typename T>
bool PackFrom(Arena* arena, const T& message,
StringPiece type_url_prefix) {
return InternalPackFrom(arena, message, type_url_prefix,
T::FullMessageName());
}
bool PackFrom(Arena* arena, const Message& message,
StringPiece type_url_prefix);
// Unpacks the payload into the given message. Returns false if the message's
// type doesn't match the type specified in the type URL (i.e., the full
// name after the last "/" of the type URL doesn't match the message's actual
// full name) or parsing the payload has failed.
template <typename T>
bool UnpackTo(T* message) const {
return InternalUnpackTo(T::FullMessageName(), message);
}
bool UnpackTo(Message* message) const;
// Checks whether the type specified in the type URL matches the given type.
// A type is consdiered matching if its full name matches the full name after
// A type is considered matching if its full name matches the full name after
// the last "/" in the type URL.
template<typename T>
template <typename T>
bool Is() const {
return InternalIs(T::default_instance().GetDescriptor());
return InternalIs(T::FullMessageName());
}
private:
bool InternalIs(const Descriptor* message) const;
bool InternalPackFrom(Arena* arena, const MessageLite& message,
StringPiece type_url_prefix,
StringPiece type_name);
bool InternalUnpackTo(StringPiece type_name,
MessageLite* message) const;
bool InternalIs(StringPiece type_name) const;
UrlType* type_url_;
ValueType* value_;
@@ -84,15 +124,22 @@ class LIBPROTOBUF_EXPORT AnyMetadata {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AnyMetadata);
};
extern const char kAnyFullTypeName[]; // "google.protobuf.Any".
extern const char kTypeGoogleApisComPrefix[]; // "type.googleapis.com/".
extern const char kTypeGoogleProdComPrefix[]; // "type.googleprod.com/".
// Get the proto type name from Any::type_url value. For example, passing
// "type.googleapis.com/rpc.QueryOrigin" will return "rpc.QueryOrigin" in
// *full_type_name. Returns false if the type_url does not have a "/"
// in the type url separating the full type name.
bool ParseAnyTypeUrl(const string& type_url, string* full_type_name);
//
// NOTE: this function is available publicly as:
// google::protobuf::Any() // static method on the generated message type.
bool ParseAnyTypeUrl(StringPiece type_url, std::string* full_type_name);
// Get the proto type name and prefix from Any::type_url value. For example,
// passing "type.googleapis.com/rpc.QueryOrigin" will return
// "type.googleapis.com/" in *url_prefix and "rpc.QueryOrigin" in
// *full_type_name. Returns false if the type_url does not have a "/" in the
// type url separating the full type name.
bool ParseAnyTypeUrl(StringPiece type_url, std::string* url_prefix,
std::string* full_type_name);
// See if message is of type google.protobuf.Any, if so, return the descriptors
// for "type_url" and "value" fields.
@@ -102,6 +149,8 @@ bool GetAnyFieldDescriptors(const Message& message,
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_ANY_H__
-440
View File
@@ -1,440 +0,0 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/any.proto
#include <google/protobuf/any.pb.h>
#include <algorithm>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// This is a temporary google only hack
#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
#include "third_party/protobuf/version.h"
#endif
// @@protoc_insertion_point(includes)
namespace google {
namespace protobuf {
class AnyDefaultTypeInternal {
public:
::google::protobuf::internal::ExplicitlyConstructed<Any>
_instance;
} _Any_default_instance_;
} // namespace protobuf
} // namespace google
namespace protobuf_google_2fprotobuf_2fany_2eproto {
void InitDefaultsAnyImpl() {
GOOGLE_PROTOBUF_VERIFY_VERSION;
#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
::google::protobuf::internal::InitProtobufDefaultsForceUnique();
#else
::google::protobuf::internal::InitProtobufDefaults();
#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
{
void* ptr = &::google::protobuf::_Any_default_instance_;
new (ptr) ::google::protobuf::Any();
::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
}
::google::protobuf::Any::InitAsDefaultInstance();
}
void InitDefaultsAny() {
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
::google::protobuf::GoogleOnceInit(&once, &InitDefaultsAnyImpl);
}
::google::protobuf::Metadata file_level_metadata[1];
const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
~0u, // no _has_bits_
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Any, _internal_metadata_),
~0u, // no _extensions_
~0u, // no _oneof_case_
~0u, // no _weak_field_map_
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Any, type_url_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Any, value_),
};
static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
{ 0, -1, sizeof(::google::protobuf::Any)},
};
static ::google::protobuf::Message const * const file_default_instances[] = {
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Any_default_instance_),
};
void protobuf_AssignDescriptors() {
AddDescriptors();
::google::protobuf::MessageFactory* factory = NULL;
AssignDescriptors(
"google/protobuf/any.proto", schemas, file_default_instances, TableStruct::offsets, factory,
file_level_metadata, NULL, NULL);
}
void protobuf_AssignDescriptorsOnce() {
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
}
void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
}
void AddDescriptorsImpl() {
InitDefaults();
static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
"\n\031google/protobuf/any.proto\022\017google.prot"
"obuf\"&\n\003Any\022\020\n\010type_url\030\001 \001(\t\022\r\n\005value\030\002"
" \001(\014Bo\n\023com.google.protobufB\010AnyProtoP\001Z"
"%github.com/golang/protobuf/ptypes/any\242\002"
"\003GPB\252\002\036Google.Protobuf.WellKnownTypesb\006p"
"roto3"
};
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
descriptor, 205);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/any.proto", &protobuf_RegisterTypes);
}
void AddDescriptors() {
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
}
// Force AddDescriptors() to be called at dynamic initialization time.
struct StaticDescriptorInitializer {
StaticDescriptorInitializer() {
AddDescriptors();
}
} static_descriptor_initializer;
} // namespace protobuf_google_2fprotobuf_2fany_2eproto
namespace google {
namespace protobuf {
// ===================================================================
void Any::InitAsDefaultInstance() {
}
void Any::PackFrom(const ::google::protobuf::Message& message) {
_any_metadata_.PackFrom(message);
}
void Any::PackFrom(const ::google::protobuf::Message& message,
const ::std::string& type_url_prefix) {
_any_metadata_.PackFrom(message, type_url_prefix);
}
bool Any::UnpackTo(::google::protobuf::Message* message) const {
return _any_metadata_.UnpackTo(message);
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Any::kTypeUrlFieldNumber;
const int Any::kValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Any::Any()
: ::google::protobuf::Message(), _internal_metadata_(NULL), _any_metadata_(&type_url_, &value_) {
if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
::protobuf_google_2fprotobuf_2fany_2eproto::InitDefaultsAny();
}
SharedCtor();
// @@protoc_insertion_point(constructor:google.protobuf.Any)
}
Any::Any(const Any& from)
: ::google::protobuf::Message(),
_internal_metadata_(NULL),
_cached_size_(0),
_any_metadata_(&type_url_, &value_) {
_internal_metadata_.MergeFrom(from._internal_metadata_);
type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (from.type_url().size() > 0) {
type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_url_);
}
value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (from.value().size() > 0) {
value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.value_);
}
// @@protoc_insertion_point(copy_constructor:google.protobuf.Any)
}
void Any::SharedCtor() {
type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
_cached_size_ = 0;
}
Any::~Any() {
// @@protoc_insertion_point(destructor:google.protobuf.Any)
SharedDtor();
}
void Any::SharedDtor() {
type_url_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
void Any::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* Any::descriptor() {
::protobuf_google_2fprotobuf_2fany_2eproto::protobuf_AssignDescriptorsOnce();
return ::protobuf_google_2fprotobuf_2fany_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}
const Any& Any::default_instance() {
::protobuf_google_2fprotobuf_2fany_2eproto::InitDefaultsAny();
return *internal_default_instance();
}
Any* Any::New(::google::protobuf::Arena* arena) const {
Any* n = new Any;
if (arena != NULL) {
arena->Own(n);
}
return n;
}
void Any::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.Any)
::google::protobuf::uint32 cached_has_bits = 0;
// Prevent compiler warnings about cached_has_bits being unused
(void) cached_has_bits;
type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
_internal_metadata_.Clear();
}
bool Any::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Any)
for (;;) {
::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
tag = p.first;
if (!p.second) goto handle_unusual;
switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
// string type_url = 1;
case 1: {
if (static_cast< ::google::protobuf::uint8>(tag) ==
static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_type_url()));
DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->type_url().data(), static_cast<int>(this->type_url().length()),
::google::protobuf::internal::WireFormatLite::PARSE,
"google.protobuf.Any.type_url"));
} else {
goto handle_unusual;
}
break;
}
// bytes value = 2;
case 2: {
if (static_cast< ::google::protobuf::uint8>(tag) ==
static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
input, this->mutable_value()));
} else {
goto handle_unusual;
}
break;
}
default: {
handle_unusual:
if (tag == 0) {
goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, _internal_metadata_.mutable_unknown_fields()));
break;
}
}
}
success:
// @@protoc_insertion_point(parse_success:google.protobuf.Any)
return true;
failure:
// @@protoc_insertion_point(parse_failure:google.protobuf.Any)
return false;
#undef DO_
}
void Any::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// @@protoc_insertion_point(serialize_start:google.protobuf.Any)
::google::protobuf::uint32 cached_has_bits = 0;
(void) cached_has_bits;
// string type_url = 1;
if (this->type_url().size() > 0) {
::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->type_url().data(), static_cast<int>(this->type_url().length()),
::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Any.type_url");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->type_url(), output);
}
// bytes value = 2;
if (this->value().size() > 0) {
::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
2, this->value(), output);
}
if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
(::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output);
}
// @@protoc_insertion_point(serialize_end:google.protobuf.Any)
}
::google::protobuf::uint8* Any::InternalSerializeWithCachedSizesToArray(
bool deterministic, ::google::protobuf::uint8* target) const {
(void)deterministic; // Unused
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Any)
::google::protobuf::uint32 cached_has_bits = 0;
(void) cached_has_bits;
// string type_url = 1;
if (this->type_url().size() > 0) {
::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->type_url().data(), static_cast<int>(this->type_url().length()),
::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Any.type_url");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
1, this->type_url(), target);
}
// bytes value = 2;
if (this->value().size() > 0) {
target =
::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
2, this->value(), target);
}
if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
(::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target);
}
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Any)
return target;
}
size_t Any::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Any)
size_t total_size = 0;
if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
(::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()));
}
// string type_url = 1;
if (this->type_url().size() > 0) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->type_url());
}
// bytes value = 2;
if (this->value().size() > 0) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::BytesSize(
this->value());
}
int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = cached_size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
return total_size;
}
void Any::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Any)
GOOGLE_DCHECK_NE(&from, this);
const Any* source =
::google::protobuf::internal::DynamicCastToGenerated<const Any>(
&from);
if (source == NULL) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Any)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Any)
MergeFrom(*source);
}
}
void Any::MergeFrom(const Any& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom(from._internal_metadata_);
::google::protobuf::uint32 cached_has_bits = 0;
(void) cached_has_bits;
if (from.type_url().size() > 0) {
type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_url_);
}
if (from.value().size() > 0) {
value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.value_);
}
}
void Any::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Any)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Any::CopyFrom(const Any& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Any)
if (&from == this) return;
Clear();
MergeFrom(from);
}
bool Any::IsInitialized() const {
return true;
}
void Any::Swap(Any* other) {
if (other == this) return;
InternalSwap(other);
}
void Any::InternalSwap(Any* other) {
using std::swap;
type_url_.Swap(&other->type_url_);
value_.Swap(&other->value_);
_internal_metadata_.Swap(&other->_internal_metadata_);
swap(_cached_size_, other->_cached_size_);
}
::google::protobuf::Metadata Any::GetMetadata() const {
protobuf_google_2fprotobuf_2fany_2eproto::protobuf_AssignDescriptorsOnce();
return ::protobuf_google_2fprotobuf_2fany_2eproto::file_level_metadata[kIndexInFileMessages];
}
// @@protoc_insertion_point(namespace_scope)
} // namespace protobuf
} // namespace google
// @@protoc_insertion_point(global_scope)
-323
View File
@@ -1,323 +0,0 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/any.proto
#ifndef PROTOBUF_google_2fprotobuf_2fany_2eproto__INCLUDED
#define PROTOBUF_google_2fprotobuf_2fany_2eproto__INCLUDED
#include <string>
#include <google/protobuf/stubs/common.h>
#if GOOGLE_PROTOBUF_VERSION < 3005000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/metadata.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h>
#include <google/protobuf/any.h>
// @@protoc_insertion_point(includes)
namespace protobuf_google_2fprotobuf_2fany_2eproto {
// Internal implementation detail -- do not use these members.
struct LIBPROTOBUF_EXPORT TableStruct {
static const ::google::protobuf::internal::ParseTableField entries[];
static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
static const ::google::protobuf::internal::ParseTable schema[1];
static const ::google::protobuf::internal::FieldMetadata field_metadata[];
static const ::google::protobuf::internal::SerializationTable serialization_table[];
static const ::google::protobuf::uint32 offsets[];
};
void LIBPROTOBUF_EXPORT AddDescriptors();
void LIBPROTOBUF_EXPORT InitDefaultsAnyImpl();
void LIBPROTOBUF_EXPORT InitDefaultsAny();
inline void LIBPROTOBUF_EXPORT InitDefaults() {
InitDefaultsAny();
}
} // namespace protobuf_google_2fprotobuf_2fany_2eproto
namespace google {
namespace protobuf {
class Any;
class AnyDefaultTypeInternal;
LIBPROTOBUF_EXPORT extern AnyDefaultTypeInternal _Any_default_instance_;
} // namespace protobuf
} // namespace google
namespace google {
namespace protobuf {
// ===================================================================
class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Any) */ {
public:
Any();
virtual ~Any();
Any(const Any& from);
inline Any& operator=(const Any& from) {
CopyFrom(from);
return *this;
}
#if LANG_CXX11
Any(Any&& from) noexcept
: Any() {
*this = ::std::move(from);
}
inline Any& operator=(Any&& from) noexcept {
if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
if (this != &from) InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
#endif
static const ::google::protobuf::Descriptor* descriptor();
static const Any& default_instance();
static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY
static inline const Any* internal_default_instance() {
return reinterpret_cast<const Any*>(
&_Any_default_instance_);
}
static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
0;
// implements Any -----------------------------------------------
void PackFrom(const ::google::protobuf::Message& message);
void PackFrom(const ::google::protobuf::Message& message,
const ::std::string& type_url_prefix);
bool UnpackTo(::google::protobuf::Message* message) const;
template<typename T> bool Is() const {
return _any_metadata_.Is<T>();
}
void Swap(Any* other);
friend void swap(Any& a, Any& b) {
a.Swap(&b);
}
// implements Message ----------------------------------------------
inline Any* New() const PROTOBUF_FINAL { return New(NULL); }
Any* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
void CopyFrom(const Any& from);
void MergeFrom(const Any& from);
void Clear() PROTOBUF_FINAL;
bool IsInitialized() const PROTOBUF_FINAL;
size_t ByteSizeLong() const PROTOBUF_FINAL;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const PROTOBUF_FINAL;
void InternalSwap(Any* other);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return NULL;
}
inline void* MaybeArenaPtr() const {
return NULL;
}
public:
::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
// string type_url = 1;
void clear_type_url();
static const int kTypeUrlFieldNumber = 1;
const ::std::string& type_url() const;
void set_type_url(const ::std::string& value);
#if LANG_CXX11
void set_type_url(::std::string&& value);
#endif
void set_type_url(const char* value);
void set_type_url(const char* value, size_t size);
::std::string* mutable_type_url();
::std::string* release_type_url();
void set_allocated_type_url(::std::string* type_url);
// bytes value = 2;
void clear_value();
static const int kValueFieldNumber = 2;
const ::std::string& value() const;
void set_value(const ::std::string& value);
#if LANG_CXX11
void set_value(::std::string&& value);
#endif
void set_value(const char* value);
void set_value(const void* value, size_t size);
::std::string* mutable_value();
::std::string* release_value();
void set_allocated_value(::std::string* value);
// @@protoc_insertion_point(class_scope:google.protobuf.Any)
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
::google::protobuf::internal::ArenaStringPtr type_url_;
::google::protobuf::internal::ArenaStringPtr value_;
mutable int _cached_size_;
::google::protobuf::internal::AnyMetadata _any_metadata_;
friend struct ::protobuf_google_2fprotobuf_2fany_2eproto::TableStruct;
friend void ::protobuf_google_2fprotobuf_2fany_2eproto::InitDefaultsAnyImpl();
};
// ===================================================================
// ===================================================================
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif // __GNUC__
// Any
// string type_url = 1;
inline void Any::clear_type_url() {
type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Any::type_url() const {
// @@protoc_insertion_point(field_get:google.protobuf.Any.type_url)
return type_url_.GetNoArena();
}
inline void Any::set_type_url(const ::std::string& value) {
type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
// @@protoc_insertion_point(field_set:google.protobuf.Any.type_url)
}
#if LANG_CXX11
inline void Any::set_type_url(::std::string&& value) {
type_url_.SetNoArena(
&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
// @@protoc_insertion_point(field_set_rvalue:google.protobuf.Any.type_url)
}
#endif
inline void Any::set_type_url(const char* value) {
GOOGLE_DCHECK(value != NULL);
type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
// @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url)
}
inline void Any::set_type_url(const char* value, size_t size) {
type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
::std::string(reinterpret_cast<const char*>(value), size));
// @@protoc_insertion_point(field_set_pointer:google.protobuf.Any.type_url)
}
inline ::std::string* Any::mutable_type_url() {
// @@protoc_insertion_point(field_mutable:google.protobuf.Any.type_url)
return type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Any::release_type_url() {
// @@protoc_insertion_point(field_release:google.protobuf.Any.type_url)
return type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Any::set_allocated_type_url(::std::string* type_url) {
if (type_url != NULL) {
} else {
}
type_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), type_url);
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.type_url)
}
// bytes value = 2;
inline void Any::clear_value() {
value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Any::value() const {
// @@protoc_insertion_point(field_get:google.protobuf.Any.value)
return value_.GetNoArena();
}
inline void Any::set_value(const ::std::string& value) {
value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
// @@protoc_insertion_point(field_set:google.protobuf.Any.value)
}
#if LANG_CXX11
inline void Any::set_value(::std::string&& value) {
value_.SetNoArena(
&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
// @@protoc_insertion_point(field_set_rvalue:google.protobuf.Any.value)
}
#endif
inline void Any::set_value(const char* value) {
GOOGLE_DCHECK(value != NULL);
value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
// @@protoc_insertion_point(field_set_char:google.protobuf.Any.value)
}
inline void Any::set_value(const void* value, size_t size) {
value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
::std::string(reinterpret_cast<const char*>(value), size));
// @@protoc_insertion_point(field_set_pointer:google.protobuf.Any.value)
}
inline ::std::string* Any::mutable_value() {
// @@protoc_insertion_point(field_mutable:google.protobuf.Any.value)
return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Any::release_value() {
// @@protoc_insertion_point(field_release:google.protobuf.Any.value)
return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Any::set_allocated_value(::std::string* value) {
if (value != NULL) {
} else {
}
value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.value)
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif // __GNUC__
// @@protoc_insertion_point(namespace_scope)
} // namespace protobuf
} // namespace google
// @@protoc_insertion_point(global_scope)
#endif // PROTOBUF_google_2fprotobuf_2fany_2eproto__INCLUDED
+99
View File
@@ -0,0 +1,99 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/any.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
namespace protobuf {
namespace internal {
std::string GetTypeUrl(StringPiece message_name,
StringPiece type_url_prefix) {
if (!type_url_prefix.empty() &&
type_url_prefix[type_url_prefix.size() - 1] == '/') {
return StrCat(type_url_prefix, message_name);
} else {
return StrCat(type_url_prefix, "/", message_name);
}
}
const char kAnyFullTypeName[] = "google.protobuf.Any";
const char kTypeGoogleApisComPrefix[] = "type.googleapis.com/";
const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/";
bool AnyMetadata::InternalPackFrom(Arena* arena, const MessageLite& message,
StringPiece type_url_prefix,
StringPiece type_name) {
type_url_->Set(&::google::protobuf::internal::GetEmptyString(),
GetTypeUrl(type_name, type_url_prefix), arena);
return message.SerializeToString(
value_->Mutable(ArenaStringPtr::EmptyDefault{}, arena));
}
bool AnyMetadata::InternalUnpackTo(StringPiece type_name,
MessageLite* message) const {
if (!InternalIs(type_name)) {
return false;
}
return message->ParseFromString(value_->Get());
}
bool AnyMetadata::InternalIs(StringPiece type_name) const {
StringPiece type_url = type_url_->Get();
return type_url.size() >= type_name.size() + 1 &&
type_url[type_url.size() - type_name.size() - 1] == '/' &&
HasSuffixString(type_url, type_name);
}
bool ParseAnyTypeUrl(StringPiece type_url, std::string* url_prefix,
std::string* full_type_name) {
size_t pos = type_url.find_last_of('/');
if (pos == std::string::npos || pos + 1 == type_url.size()) {
return false;
}
if (url_prefix) {
*url_prefix = std::string(type_url.substr(0, pos + 1));
}
*full_type_name = std::string(type_url.substr(pos + 1));
return true;
}
bool ParseAnyTypeUrl(StringPiece type_url, std::string* full_type_name) {
return ParseAnyTypeUrl(type_url, nullptr, full_type_name);
}
} // namespace internal
} // namespace protobuf
} // namespace google
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+407 -281
View File
@@ -31,355 +31,481 @@
#include <google/protobuf/arena.h>
#include <algorithm>
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <limits>
#include <typeinfo>
#include <google/protobuf/arena_impl.h>
#include <google/protobuf/stubs/mutex.h>
#ifdef ADDRESS_SANITIZER
#include <sanitizer/asan_interface.h>
#endif // ADDRESS_SANITIZER
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/port_def.inc>
namespace google {
static const size_t kMinCleanupListElements = 8;
static const size_t kMaxCleanupListElements = 64; // 1kB on 64-bit.
namespace protobuf {
namespace internal {
static SerialArena::Memory AllocateMemory(const AllocationPolicy* policy_ptr,
size_t last_size, size_t min_bytes) {
AllocationPolicy policy; // default policy
if (policy_ptr) policy = *policy_ptr;
size_t size;
if (last_size != 0) {
// Double the current block size, up to a limit.
auto max_size = policy.max_block_size;
size = std::min(2 * last_size, max_size);
} else {
size = policy.start_block_size;
}
// Verify that min_bytes + kBlockHeaderSize won't overflow.
GOOGLE_CHECK_LE(min_bytes,
std::numeric_limits<size_t>::max() - SerialArena::kBlockHeaderSize);
size = std::max(size, SerialArena::kBlockHeaderSize + min_bytes);
google::protobuf::internal::SequenceNumber ArenaImpl::lifecycle_id_generator_;
void* mem;
if (policy.block_alloc == nullptr) {
mem = ::operator new(size);
} else {
mem = policy.block_alloc(size);
}
return {mem, size};
}
class GetDeallocator {
public:
GetDeallocator(const AllocationPolicy* policy, size_t* space_allocated)
: dealloc_(policy ? policy->block_dealloc : nullptr),
space_allocated_(space_allocated) {}
void operator()(SerialArena::Memory mem) const {
#ifdef ADDRESS_SANITIZER
// This memory was provided by the underlying allocator as unpoisoned,
// so return it in an unpoisoned state.
ASAN_UNPOISON_MEMORY_REGION(mem.ptr, mem.size);
#endif // ADDRESS_SANITIZER
if (dealloc_) {
dealloc_(mem.ptr, mem.size);
} else {
#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
::operator delete(mem.ptr, mem.size);
#else
::operator delete(mem.ptr);
#endif
}
*space_allocated_ += mem.size;
}
private:
void (*dealloc_)(void*, size_t);
size_t* space_allocated_;
};
SerialArena::SerialArena(Block* b, void* owner) : space_allocated_(b->size) {
owner_ = owner;
head_ = b;
ptr_ = b->Pointer(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize);
limit_ = b->Pointer(b->size & static_cast<size_t>(-8));
}
SerialArena* SerialArena::New(Memory mem, void* owner) {
GOOGLE_DCHECK_LE(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize, mem.size);
auto b = new (mem.ptr) Block{nullptr, mem.size};
return new (b->Pointer(kBlockHeaderSize)) SerialArena(b, owner);
}
template <typename Deallocator>
SerialArena::Memory SerialArena::Free(Deallocator deallocator) {
Block* b = head_;
Memory mem = {b, b->size};
while (b->next) {
b = b->next; // We must first advance before deleting this block
deallocator(mem);
mem = {b, b->size};
}
return mem;
}
PROTOBUF_NOINLINE
std::pair<void*, SerialArena::CleanupNode*>
SerialArena::AllocateAlignedWithCleanupFallback(
size_t n, const AllocationPolicy* policy) {
AllocateNewBlock(n + kCleanupSize, policy);
return AllocateFromExistingWithCleanupFallback(n);
}
PROTOBUF_NOINLINE
void* SerialArena::AllocateAlignedFallback(size_t n,
const AllocationPolicy* policy) {
AllocateNewBlock(n, policy);
return AllocateFromExisting(n);
}
void SerialArena::AllocateNewBlock(size_t n, const AllocationPolicy* policy) {
// Sync limit to block
head_->start = reinterpret_cast<CleanupNode*>(limit_);
// Record how much used in this block.
space_used_ += ptr_ - head_->Pointer(kBlockHeaderSize);
auto mem = AllocateMemory(policy, head_->size, n);
// We don't want to emit an expensive RMW instruction that requires
// exclusive access to a cacheline. Hence we write it in terms of a
// regular add.
auto relaxed = std::memory_order_relaxed;
space_allocated_.store(space_allocated_.load(relaxed) + mem.size, relaxed);
head_ = new (mem.ptr) Block{head_, mem.size};
ptr_ = head_->Pointer(kBlockHeaderSize);
limit_ = head_->Pointer(head_->size);
#ifdef ADDRESS_SANITIZER
ASAN_POISON_MEMORY_REGION(ptr_, limit_ - ptr_);
#endif // ADDRESS_SANITIZER
}
uint64_t SerialArena::SpaceUsed() const {
uint64_t space_used = ptr_ - head_->Pointer(kBlockHeaderSize);
space_used += space_used_;
// Remove the overhead of the SerialArena itself.
space_used -= ThreadSafeArena::kSerialArenaSize;
return space_used;
}
void SerialArena::CleanupList() {
Block* b = head_;
b->start = reinterpret_cast<CleanupNode*>(limit_);
do {
auto* limit = reinterpret_cast<CleanupNode*>(
b->Pointer(b->size & static_cast<size_t>(-8)));
auto it = b->start;
auto num = limit - it;
if (num > 0) {
for (; it < limit; it++) {
it->cleanup(it->elem);
}
}
b = b->next;
} while (b);
}
ThreadSafeArena::CacheAlignedLifecycleIdGenerator
ThreadSafeArena::lifecycle_id_generator_;
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
ArenaImpl::ThreadCache& ArenaImpl::thread_cache() {
ThreadSafeArena::ThreadCache& ThreadSafeArena::thread_cache() {
static internal::ThreadLocalStorage<ThreadCache>* thread_cache_ =
new internal::ThreadLocalStorage<ThreadCache>();
return *thread_cache_->Get();
}
#elif defined(PROTOBUF_USE_DLLS)
ArenaImpl::ThreadCache& ArenaImpl::thread_cache() {
static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_ = { -1, NULL };
ThreadSafeArena::ThreadCache& ThreadSafeArena::thread_cache() {
static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_ = {
0, static_cast<LifecycleIdAtomic>(-1), nullptr};
return thread_cache_;
}
#else
GOOGLE_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {-1, NULL};
PROTOBUF_THREAD_LOCAL ThreadSafeArena::ThreadCache
ThreadSafeArena::thread_cache_ = {0, static_cast<LifecycleIdAtomic>(-1),
nullptr};
#endif
void ArenaImpl::Init() {
lifecycle_id_ = lifecycle_id_generator_.GetNext();
google::protobuf::internal::NoBarrier_Store(&hint_, 0);
google::protobuf::internal::NoBarrier_Store(&threads_, 0);
if (initial_block_) {
// Thread which calls Init() owns the first block. This allows the
// single-threaded case to allocate on the first block without having to
// perform atomic operations.
InitBlock(initial_block_, &thread_cache(), options_.initial_block_size);
ThreadInfo* info = NewThreadInfo(initial_block_);
info->next = NULL;
google::protobuf::internal::NoBarrier_Store(&threads_,
reinterpret_cast<google::protobuf::internal::AtomicWord>(info));
google::protobuf::internal::NoBarrier_Store(&space_allocated_,
options_.initial_block_size);
CacheBlock(initial_block_);
} else {
google::protobuf::internal::NoBarrier_Store(&space_allocated_, 0);
}
}
ArenaImpl::~ArenaImpl() {
// Have to do this in a first pass, because some of the destructors might
// refer to memory in other blocks.
CleanupList();
FreeBlocks();
}
uint64 ArenaImpl::Reset() {
// Have to do this in a first pass, because some of the destructors might
// refer to memory in other blocks.
CleanupList();
uint64 space_allocated = FreeBlocks();
void ThreadSafeArena::InitializeFrom(void* mem, size_t size) {
GOOGLE_DCHECK_EQ(reinterpret_cast<uintptr_t>(mem) & 7, 0u);
GOOGLE_DCHECK(!AllocPolicy()); // Reset should call InitializeWithPolicy instead.
Init();
return space_allocated;
// Ignore initial block if it is too small.
if (mem != nullptr && size >= kBlockHeaderSize + kSerialArenaSize) {
alloc_policy_.set_is_user_owned_initial_block(true);
SetInitialBlock(mem, size);
}
}
ArenaImpl::Block* ArenaImpl::NewBlock(void* me, Block* my_last_block,
size_t min_bytes) {
size_t size;
if (my_last_block != NULL) {
// Double the current block size, up to a limit.
size = std::min(2 * my_last_block->size, options_.max_block_size);
void ThreadSafeArena::InitializeWithPolicy(void* mem, size_t size,
AllocationPolicy policy) {
#ifndef NDEBUG
const uint64_t old_alloc_policy = alloc_policy_.get_raw();
// If there was a policy (e.g., in Reset()), make sure flags were preserved.
#define GOOGLE_DCHECK_POLICY_FLAGS_() \
if (old_alloc_policy > 3) \
GOOGLE_CHECK_EQ(old_alloc_policy & 3, alloc_policy_.get_raw() & 3)
#else
#define GOOGLE_DCHECK_POLICY_FLAGS_()
#endif // NDEBUG
if (policy.IsDefault()) {
// Legacy code doesn't use the API above, but provides the initial block
// through ArenaOptions. I suspect most do not touch the allocation
// policy parameters.
InitializeFrom(mem, size);
GOOGLE_DCHECK_POLICY_FLAGS_();
return;
}
GOOGLE_DCHECK_EQ(reinterpret_cast<uintptr_t>(mem) & 7, 0u);
Init();
// Ignore initial block if it is too small. We include an optional
// AllocationPolicy in this check, so that this can be allocated on the
// first block.
constexpr size_t kAPSize = internal::AlignUpTo8(sizeof(AllocationPolicy));
constexpr size_t kMinimumSize = kBlockHeaderSize + kSerialArenaSize + kAPSize;
// The value for alloc_policy_ stores whether or not allocations should be
// recorded.
alloc_policy_.set_should_record_allocs(
policy.metrics_collector != nullptr &&
policy.metrics_collector->RecordAllocs());
// Make sure we have an initial block to store the AllocationPolicy.
if (mem != nullptr && size >= kMinimumSize) {
alloc_policy_.set_is_user_owned_initial_block(true);
} else {
size = options_.start_block_size;
auto tmp = AllocateMemory(&policy, 0, kMinimumSize);
mem = tmp.ptr;
size = tmp.size;
}
// Verify that min_bytes + kHeaderSize won't overflow.
GOOGLE_CHECK_LE(min_bytes, std::numeric_limits<size_t>::max() - kHeaderSize);
size = std::max(size, kHeaderSize + min_bytes);
SetInitialBlock(mem, size);
Block* b = reinterpret_cast<Block*>(options_.block_alloc(size));
InitBlock(b, me, size);
google::protobuf::internal::NoBarrier_AtomicIncrement(&space_allocated_, size);
return b;
}
void ArenaImpl::InitBlock(Block* b, void *me, size_t size) {
b->pos = kHeaderSize;
b->size = size;
b->owner = me;
b->next = NULL;
#ifdef ADDRESS_SANITIZER
// Poison the rest of the block for ASAN. It was unpoisoned by the underlying
// malloc but it's not yet usable until we return it as part of an allocation.
ASAN_POISON_MEMORY_REGION(
reinterpret_cast<char*>(b) + b->pos, b->size - b->pos);
#endif // ADDRESS_SANITIZER
}
ArenaImpl::CleanupChunk* ArenaImpl::ExpandCleanupList(CleanupChunk* cleanup,
Block* b) {
size_t size = cleanup ? cleanup->size * 2 : kMinCleanupListElements;
size = std::min(size, kMaxCleanupListElements);
size_t bytes = internal::AlignUpTo8(CleanupChunk::SizeOf(size));
if (b->avail() < bytes) {
b = GetBlock(bytes);
auto sa = threads_.load(std::memory_order_relaxed);
// We ensured enough space so this cannot fail.
void* p;
if (!sa || !sa->MaybeAllocateAligned(kAPSize, &p)) {
GOOGLE_LOG(FATAL) << "MaybeAllocateAligned cannot fail here.";
return;
}
CleanupChunk* list =
reinterpret_cast<CleanupChunk*>(AllocFromBlock(b, bytes));
list->next = b->thread_info->cleanup;
list->size = size;
list->len = 0;
b->thread_info->cleanup = list;
return list;
new (p) AllocationPolicy{policy};
// Low bits store flags, so they mustn't be overwritten.
GOOGLE_DCHECK_EQ(0, reinterpret_cast<uintptr_t>(p) & 3);
alloc_policy_.set_policy(reinterpret_cast<AllocationPolicy*>(p));
GOOGLE_DCHECK_POLICY_FLAGS_();
#undef GOOGLE_DCHECK_POLICY_FLAGS_
}
inline GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
void ArenaImpl::AddCleanupInBlock(
Block* b, void* elem, void (*func)(void*)) {
CleanupChunk* cleanup = b->thread_info->cleanup;
if (cleanup == NULL || cleanup->len == cleanup->size) {
cleanup = ExpandCleanupList(cleanup, b);
void ThreadSafeArena::Init() {
#ifndef NDEBUG
const bool was_message_owned = IsMessageOwned();
#endif // NDEBUG
ThreadCache& tc = thread_cache();
auto id = tc.next_lifecycle_id;
// We increment lifecycle_id's by multiples of two so we can use bit 0 as
// a tag.
constexpr uint64_t kDelta = 2;
constexpr uint64_t kInc = ThreadCache::kPerThreadIds * kDelta;
if (PROTOBUF_PREDICT_FALSE((id & (kInc - 1)) == 0)) {
constexpr auto relaxed = std::memory_order_relaxed;
// On platforms that don't support uint64_t atomics we can certainly not
// afford to increment by large intervals and expect uniqueness due to
// wrapping, hence we only add by 1.
id = lifecycle_id_generator_.id.fetch_add(1, relaxed) * kInc;
}
tc.next_lifecycle_id = id + kDelta;
// Message ownership is stored in tag_and_id_, and is set in the constructor.
// This flag bit must be preserved, even across calls to Reset().
tag_and_id_ = id | (tag_and_id_ & kMessageOwnedArena);
hint_.store(nullptr, std::memory_order_relaxed);
threads_.store(nullptr, std::memory_order_relaxed);
#ifndef NDEBUG
GOOGLE_CHECK_EQ(was_message_owned, IsMessageOwned());
#endif // NDEBUG
}
void ThreadSafeArena::SetInitialBlock(void* mem, size_t size) {
SerialArena* serial = SerialArena::New({mem, size}, &thread_cache());
serial->set_next(NULL);
threads_.store(serial, std::memory_order_relaxed);
CacheSerialArena(serial);
}
ThreadSafeArena::~ThreadSafeArena() {
// Have to do this in a first pass, because some of the destructors might
// refer to memory in other blocks.
CleanupList();
size_t space_allocated = 0;
auto mem = Free(&space_allocated);
// Policy is about to get deleted.
auto* p = alloc_policy_.get();
ArenaMetricsCollector* collector = p ? p->metrics_collector : nullptr;
if (alloc_policy_.is_user_owned_initial_block()) {
space_allocated += mem.size;
} else {
GetDeallocator(alloc_policy_.get(), &space_allocated)(mem);
}
CleanupNode* node = &cleanup->nodes[cleanup->len++];
node->elem = elem;
node->cleanup = func;
if (collector) collector->OnDestroy(space_allocated);
}
void ArenaImpl::AddCleanup(void* elem, void (*cleanup)(void*)) {
return AddCleanupInBlock(GetBlock(0), elem, cleanup);
}
void* ArenaImpl::AllocateAligned(size_t n) {
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
return AllocFromBlock(GetBlock(n), n);
}
void* ArenaImpl::AllocateAlignedAndAddCleanup(size_t n,
void (*cleanup)(void*)) {
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
Block* b = GetBlock(n);
void* mem = AllocFromBlock(b, n);
AddCleanupInBlock(b, mem, cleanup);
SerialArena::Memory ThreadSafeArena::Free(size_t* space_allocated) {
SerialArena::Memory mem = {nullptr, 0};
auto deallocator = GetDeallocator(alloc_policy_.get(), space_allocated);
PerSerialArena([deallocator, &mem](SerialArena* a) {
if (mem.ptr) deallocator(mem);
mem = a->Free(deallocator);
});
return mem;
}
inline GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
ArenaImpl::Block* ArenaImpl::GetBlock(size_t n) {
Block* my_block = NULL;
uint64_t ThreadSafeArena::Reset() {
// Have to do this in a first pass, because some of the destructors might
// refer to memory in other blocks.
CleanupList();
// If this thread already owns a block in this arena then try to use that.
// This fast path optimizes the case where multiple threads allocate from the
// same arena.
ThreadCache* tc = &thread_cache();
if (tc->last_lifecycle_id_seen == lifecycle_id_) {
my_block = tc->last_block_used_;
if (my_block->avail() >= n) {
return my_block;
// Discard all blocks except the special block (if present).
size_t space_allocated = 0;
auto mem = Free(&space_allocated);
AllocationPolicy* policy = alloc_policy_.get();
if (policy) {
auto saved_policy = *policy;
if (alloc_policy_.is_user_owned_initial_block()) {
space_allocated += mem.size;
} else {
GetDeallocator(alloc_policy_.get(), &space_allocated)(mem);
mem.ptr = nullptr;
mem.size = 0;
}
}
// Check whether we own the last accessed block on this arena.
// This fast path optimizes the case where a single thread uses multiple
// arenas.
Block* b = reinterpret_cast<Block*>(google::protobuf::internal::Acquire_Load(&hint_));
if (b != NULL && b->owner == tc) {
my_block = b;
if (my_block->avail() >= n) {
return my_block;
ArenaMetricsCollector* collector = saved_policy.metrics_collector;
if (collector) collector->OnReset(space_allocated);
InitializeWithPolicy(mem.ptr, mem.size, saved_policy);
} else {
GOOGLE_DCHECK(!alloc_policy_.should_record_allocs());
// Nullptr policy
if (alloc_policy_.is_user_owned_initial_block()) {
space_allocated += mem.size;
InitializeFrom(mem.ptr, mem.size);
} else {
GetDeallocator(alloc_policy_.get(), &space_allocated)(mem);
Init();
}
}
return GetBlockSlow(tc, my_block, n);
}
inline GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
void* ArenaImpl::AllocFromBlock(Block* b, size_t n) {
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(b->pos), b->pos); // Must be already aligned.
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
GOOGLE_DCHECK_GE(b->avail(), n);
size_t p = b->pos;
b->pos = p + n;
#ifdef ADDRESS_SANITIZER
ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast<char*>(b) + p, n);
#endif // ADDRESS_SANITIZER
return reinterpret_cast<char*>(b) + p;
}
ArenaImpl::Block* ArenaImpl::GetBlockSlow(void* me, Block* my_full_block,
size_t n) {
ThreadInfo* info =
my_full_block ? my_full_block->thread_info : GetThreadInfo(me, n);
GOOGLE_DCHECK(info != NULL);
Block* b = info->head;
if (b->avail() < n) {
Block* new_b = NewBlock(me, b, n);
new_b->thread_info = info;
new_b->next = b;
info->head = new_b;
b = new_b;
}
CacheBlock(b);
return b;
}
uint64 ArenaImpl::SpaceAllocated() const {
return google::protobuf::internal::NoBarrier_Load(&space_allocated_);
}
uint64 ArenaImpl::SpaceUsed() const {
ThreadInfo* info =
reinterpret_cast<ThreadInfo*>(google::protobuf::internal::Acquire_Load(&threads_));
uint64 space_used = 0;
for ( ; info; info = info->next) {
// Remove the overhead of the ThreadInfo itself.
space_used -= sizeof(ThreadInfo);
for (Block* b = info->head; b; b = b->next) {
space_used += (b->pos - kHeaderSize);
}
}
return space_used;
}
uint64 ArenaImpl::FreeBlocks() {
uint64 space_allocated = 0;
// By omitting an Acquire barrier we ensure that any user code that doesn't
// properly synchronize Reset() or the destructor will throw a TSAN warning.
ThreadInfo* info =
reinterpret_cast<ThreadInfo*>(google::protobuf::internal::NoBarrier_Load(&threads_));
while (info) {
// This is inside the block we are freeing, so we need to read it now.
ThreadInfo* next_info = info->next;
for (Block* b = info->head; b; ) {
// This is inside the block we are freeing, so we need to read it now.
Block* next_block = b->next;
space_allocated += (b->size);
#ifdef ADDRESS_SANITIZER
// This memory was provided by the underlying allocator as unpoisoned, so
// return it in an unpoisoned state.
ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast<char*>(b), b->size);
#endif // ADDRESS_SANITIZER
if (b != initial_block_) {
options_.block_dealloc(b, b->size);
}
b = next_block;
}
info = next_info;
}
return space_allocated;
}
void ArenaImpl::CleanupList() {
// By omitting an Acquire barrier we ensure that any user code that doesn't
// properly synchronize Reset() or the destructor will throw a TSAN warning.
ThreadInfo* info =
reinterpret_cast<ThreadInfo*>(google::protobuf::internal::NoBarrier_Load(&threads_));
for ( ; info; info = info->next) {
CleanupChunk* list = info->cleanup;
while (list) {
size_t n = list->len;
CleanupNode* node = &list->nodes[list->len - 1];
for (size_t i = 0; i < n; i++, node--) {
node->cleanup(node->elem);
}
list = list->next;
}
std::pair<void*, SerialArena::CleanupNode*>
ThreadSafeArena::AllocateAlignedWithCleanup(size_t n,
const std::type_info* type) {
SerialArena* arena;
if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() &&
GetSerialArenaFast(&arena))) {
return arena->AllocateAlignedWithCleanup(n, alloc_policy_.get());
} else {
return AllocateAlignedWithCleanupFallback(n, type);
}
}
ArenaImpl::ThreadInfo* ArenaImpl::NewThreadInfo(Block* b) {
GOOGLE_DCHECK(FindThreadInfo(b->owner) == NULL);
ThreadInfo* info =
reinterpret_cast<ThreadInfo*>(AllocFromBlock(b, sizeof(ThreadInfo)));
b->thread_info = info;
info->owner = b->owner;
info->head = b;
info->cleanup = NULL;
return info;
void ThreadSafeArena::AddCleanup(void* elem, void (*cleanup)(void*)) {
SerialArena* arena;
if (PROTOBUF_PREDICT_FALSE(!GetSerialArenaFast(&arena))) {
arena = GetSerialArenaFallback(&thread_cache());
}
arena->AddCleanup(elem, cleanup, AllocPolicy());
}
ArenaImpl::ThreadInfo* ArenaImpl::FindThreadInfo(void* me) {
ThreadInfo* info =
reinterpret_cast<ThreadInfo*>(google::protobuf::internal::Acquire_Load(&threads_));
for ( ; info; info = info->next) {
if (info->owner == me) {
return info;
PROTOBUF_NOINLINE
void* ThreadSafeArena::AllocateAlignedFallback(size_t n,
const std::type_info* type) {
if (alloc_policy_.should_record_allocs()) {
alloc_policy_.RecordAlloc(type, n);
SerialArena* arena;
if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) {
return arena->AllocateAligned(n, alloc_policy_.get());
}
}
return GetSerialArenaFallback(&thread_cache())
->AllocateAligned(n, alloc_policy_.get());
}
PROTOBUF_NOINLINE
std::pair<void*, SerialArena::CleanupNode*>
ThreadSafeArena::AllocateAlignedWithCleanupFallback(
size_t n, const std::type_info* type) {
if (alloc_policy_.should_record_allocs()) {
alloc_policy_.RecordAlloc(type, n);
SerialArena* arena;
if (GetSerialArenaFast(&arena)) {
return arena->AllocateAlignedWithCleanup(n, alloc_policy_.get());
}
}
return GetSerialArenaFallback(&thread_cache())
->AllocateAlignedWithCleanup(n, alloc_policy_.get());
}
uint64_t ThreadSafeArena::SpaceAllocated() const {
SerialArena* serial = threads_.load(std::memory_order_acquire);
uint64_t res = 0;
for (; serial; serial = serial->next()) {
res += serial->SpaceAllocated();
}
return res;
}
uint64_t ThreadSafeArena::SpaceUsed() const {
SerialArena* serial = threads_.load(std::memory_order_acquire);
uint64_t space_used = 0;
for (; serial; serial = serial->next()) {
space_used += serial->SpaceUsed();
}
return space_used - (alloc_policy_.get() ? sizeof(AllocationPolicy) : 0);
}
void ThreadSafeArena::CleanupList() {
PerSerialArena([](SerialArena* a) { a->CleanupList(); });
}
PROTOBUF_NOINLINE
SerialArena* ThreadSafeArena::GetSerialArenaFallback(void* me) {
// Look for this SerialArena in our linked list.
SerialArena* serial = threads_.load(std::memory_order_acquire);
for (; serial; serial = serial->next()) {
if (serial->owner() == me) {
break;
}
}
return NULL;
}
if (!serial) {
// This thread doesn't have any SerialArena, which also means it doesn't
// have any blocks yet. So we'll allocate its first block now.
serial = SerialArena::New(
AllocateMemory(alloc_policy_.get(), 0, kSerialArenaSize), me);
ArenaImpl::ThreadInfo* ArenaImpl::GetThreadInfo(void* me, size_t n) {
ThreadInfo* info = FindThreadInfo(me);
if (!info) {
// This thread doesn't have any ThreadInfo, which also means it doesn't have
// any blocks yet. So we'll allocate its first block now.
Block* b = NewBlock(me, NULL, sizeof(ThreadInfo) + n);
info = NewThreadInfo(b);
google::protobuf::internal::AtomicWord head;
SerialArena* head = threads_.load(std::memory_order_relaxed);
do {
head = google::protobuf::internal::NoBarrier_Load(&threads_);
info->next = reinterpret_cast<ThreadInfo*>(head);
} while (google::protobuf::internal::Release_CompareAndSwap(
&threads_, head, reinterpret_cast<google::protobuf::internal::AtomicWord>(info)) != head);
serial->set_next(head);
} while (!threads_.compare_exchange_weak(
head, serial, std::memory_order_release, std::memory_order_relaxed));
}
return info;
CacheSerialArena(serial);
return serial;
}
} // namespace internal
void Arena::CallDestructorHooks() {
uint64 space_allocated = impl_.SpaceAllocated();
// Call the reset hook
if (on_arena_reset_ != NULL) {
on_arena_reset_(this, hooks_cookie_, space_allocated);
}
// Call the destruction hook
if (on_arena_destruction_ != NULL) {
on_arena_destruction_(this, hooks_cookie_, space_allocated);
}
PROTOBUF_FUNC_ALIGN(32)
void* Arena::AllocateAlignedNoHook(size_t n) {
return impl_.AllocateAligned(n, nullptr);
}
void Arena::OnArenaAllocation(const std::type_info* allocated_type,
size_t n) const {
if (on_arena_allocation_ != NULL) {
on_arena_allocation_(allocated_type, n, hooks_cookie_);
}
PROTOBUF_FUNC_ALIGN(32)
void* Arena::AllocateAlignedWithHook(size_t n, const std::type_info* type) {
return impl_.AllocateAligned(n, type);
}
PROTOBUF_FUNC_ALIGN(32)
std::pair<void*, internal::SerialArena::CleanupNode*>
Arena::AllocateAlignedWithCleanup(size_t n, const std::type_info* type) {
return impl_.AllocateAlignedWithCleanup(n, type);
}
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
File diff suppressed because it is too large Load Diff
+457 -137
View File
@@ -33,85 +33,168 @@
#ifndef GOOGLE_PROTOBUF_ARENA_IMPL_H__
#define GOOGLE_PROTOBUF_ARENA_IMPL_H__
#include <atomic>
#include <limits>
#include <typeinfo>
#include <google/protobuf/stubs/atomic_sequence_num.h>
#include <google/protobuf/stubs/atomicops.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/stubs/type_traits.h>
#include <google/protobuf/stubs/port.h>
#ifdef ADDRESS_SANITIZER
#include <sanitizer/asan_interface.h>
#endif // ADDRESS_SANITIZER
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace internal {
inline size_t AlignUpTo8(size_t n) {
inline constexpr size_t AlignUpTo8(size_t n) {
// Align n to next multiple of 8 (from Hacker's Delight, Chapter 3.)
return (n + 7) & -8;
return (n + 7) & static_cast<size_t>(-8);
}
// This class provides the core Arena memory allocation library. Different
// implementations only need to implement the public interface below.
// Arena is not a template type as that would only be useful if all protos
// in turn would be templates, which will/cannot happen. However separating
// the memory allocation part from the cruft of the API users expect we can
// use #ifdef the select the best implementation based on hardware / OS.
class LIBPROTOBUF_EXPORT ArenaImpl {
using LifecycleIdAtomic = uint64_t;
// MetricsCollector collects stats for a particular arena.
class PROTOBUF_EXPORT ArenaMetricsCollector {
public:
struct Options {
size_t start_block_size;
size_t max_block_size;
char* initial_block;
size_t initial_block_size;
void* (*block_alloc)(size_t);
void (*block_dealloc)(void*, size_t);
ArenaMetricsCollector(bool record_allocs) : record_allocs_(record_allocs) {}
template <typename O>
explicit Options(const O& options)
: start_block_size(options.start_block_size),
max_block_size(options.max_block_size),
initial_block(options.initial_block),
initial_block_size(options.initial_block_size),
block_alloc(options.block_alloc),
block_dealloc(options.block_dealloc) {}
};
// Invoked when the arena is about to be destroyed. This method will
// typically finalize any metric collection and delete the collector.
// space_allocated is the space used by the arena.
virtual void OnDestroy(uint64_t space_allocated) = 0;
template <typename O>
explicit ArenaImpl(const O& options) : options_(options) {
if (options_.initial_block != NULL && options_.initial_block_size > 0) {
GOOGLE_CHECK_GE(options_.initial_block_size, sizeof(Block))
<< ": Initial block size too small for header.";
initial_block_ = reinterpret_cast<Block*>(options_.initial_block);
} else {
initial_block_ = NULL;
}
// OnReset() is called when the associated arena is reset.
// space_allocated is the space used by the arena just before the reset.
virtual void OnReset(uint64_t space_allocated) = 0;
Init();
// OnAlloc is called when an allocation happens.
// type_info is promised to be static - its lifetime extends to
// match program's lifetime (It is given by typeid operator).
// Note: typeid(void) will be passed as allocated_type every time we
// intentionally want to avoid monitoring an allocation. (i.e. internal
// allocations for managing the arena)
virtual void OnAlloc(const std::type_info* allocated_type,
uint64_t alloc_size) = 0;
// Does OnAlloc() need to be called? If false, metric collection overhead
// will be reduced since we will not do extra work per allocation.
bool RecordAllocs() { return record_allocs_; }
protected:
// This class is destructed by the call to OnDestroy().
~ArenaMetricsCollector() = default;
const bool record_allocs_;
};
struct AllocationPolicy {
static constexpr size_t kDefaultStartBlockSize = 256;
static constexpr size_t kDefaultMaxBlockSize = 8192;
size_t start_block_size = kDefaultStartBlockSize;
size_t max_block_size = kDefaultMaxBlockSize;
void* (*block_alloc)(size_t) = nullptr;
void (*block_dealloc)(void*, size_t) = nullptr;
ArenaMetricsCollector* metrics_collector = nullptr;
bool IsDefault() const {
return start_block_size == kDefaultMaxBlockSize &&
max_block_size == kDefaultMaxBlockSize && block_alloc == nullptr &&
block_dealloc == nullptr && metrics_collector == nullptr;
}
};
// Tagged pointer to an AllocationPolicy.
class TaggedAllocationPolicyPtr {
public:
constexpr TaggedAllocationPolicyPtr() : policy_(0) {}
explicit TaggedAllocationPolicyPtr(AllocationPolicy* policy)
: policy_(reinterpret_cast<uintptr_t>(policy)) {}
void set_policy(AllocationPolicy* policy) {
auto bits = policy_ & kTagsMask;
policy_ = reinterpret_cast<uintptr_t>(policy) | bits;
}
// Destructor deletes all owned heap allocated objects, and destructs objects
// that have non-trivial destructors, except for proto2 message objects whose
// destructors can be skipped. Also, frees all blocks except the initial block
// if it was passed in.
~ArenaImpl();
AllocationPolicy* get() {
return reinterpret_cast<AllocationPolicy*>(policy_ & kPtrMask);
}
const AllocationPolicy* get() const {
return reinterpret_cast<const AllocationPolicy*>(policy_ & kPtrMask);
}
uint64 Reset();
AllocationPolicy& operator*() { return *get(); }
const AllocationPolicy& operator*() const { return *get(); }
uint64 SpaceAllocated() const;
uint64 SpaceUsed() const;
AllocationPolicy* operator->() { return get(); }
const AllocationPolicy* operator->() const { return get(); }
void* AllocateAligned(size_t n);
bool is_user_owned_initial_block() const {
return static_cast<bool>(get_mask<kUserOwnedInitialBlock>());
}
void set_is_user_owned_initial_block(bool v) {
set_mask<kUserOwnedInitialBlock>(v);
}
void* AllocateAlignedAndAddCleanup(size_t n, void (*cleanup)(void*));
bool should_record_allocs() const {
return static_cast<bool>(get_mask<kRecordAllocs>());
}
void set_should_record_allocs(bool v) { set_mask<kRecordAllocs>(v); }
// Add object pointer and cleanup function pointer to the list.
void AddCleanup(void* elem, void (*cleanup)(void*));
uintptr_t get_raw() const { return policy_; }
inline void RecordAlloc(const std::type_info* allocated_type,
size_t n) const {
get()->metrics_collector->OnAlloc(allocated_type, n);
}
private:
enum : uintptr_t {
kUserOwnedInitialBlock = 1,
kRecordAllocs = 2,
};
static constexpr uintptr_t kTagsMask = 7;
static constexpr uintptr_t kPtrMask = ~kTagsMask;
template <uintptr_t kMask>
uintptr_t get_mask() const {
return policy_ & kMask;
}
template <uintptr_t kMask>
void set_mask(bool v) {
if (v) {
policy_ |= kMask;
} else {
policy_ &= ~kMask;
}
}
uintptr_t policy_;
};
// A simple arena allocator. Calls to allocate functions must be properly
// serialized by the caller, hence this class cannot be used as a general
// purpose allocator in a multi-threaded program. It serves as a building block
// for ThreadSafeArena, which provides a thread-safe arena allocator.
//
// This class manages
// 1) Arena bump allocation + owning memory blocks.
// 2) Maintaining a cleanup list.
// It delagetes the actual memory allocation back to ThreadSafeArena, which
// contains the information on block growth policy and backing memory allocation
// used.
class PROTOBUF_EXPORT SerialArena {
public:
struct Memory {
void* ptr;
size_t size;
};
// Node contains the ptr of the object to be cleaned up and the associated
// cleanup function ptr.
struct CleanupNode {
@@ -119,124 +202,361 @@ class LIBPROTOBUF_EXPORT ArenaImpl {
void (*cleanup)(void*); // Function pointer to the destructor or deleter.
};
// Cleanup uses a chunked linked list, to reduce pointer chasing.
struct CleanupChunk {
static size_t SizeOf(size_t i) {
return sizeof(CleanupChunk) + (sizeof(CleanupNode) * (i - 1));
void CleanupList();
uint64_t SpaceAllocated() const {
return space_allocated_.load(std::memory_order_relaxed);
}
uint64_t SpaceUsed() const;
bool HasSpace(size_t n) { return n <= static_cast<size_t>(limit_ - ptr_); }
void* AllocateAligned(size_t n, const AllocationPolicy* policy) {
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
GOOGLE_DCHECK_GE(limit_, ptr_);
if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) {
return AllocateAlignedFallback(n, policy);
}
size_t len; // Number of elements currently present.
size_t size; // Total elements in the list.
CleanupChunk* next; // Next node in the list.
CleanupNode nodes[1]; // True length is |size|.
};
return AllocateFromExisting(n);
}
struct Block;
private:
void* AllocateFromExisting(size_t n) {
void* ret = ptr_;
ptr_ += n;
#ifdef ADDRESS_SANITIZER
ASAN_UNPOISON_MEMORY_REGION(ret, n);
#endif // ADDRESS_SANITIZER
return ret;
}
// Tracks per-thread info. ThreadInfos are kept in a linked list.
struct ThreadInfo {
void *owner; // &ThreadCache of this thread;
Block* head; // Head of linked list of blocks.
CleanupChunk* cleanup; // Head of cleanup list.
ThreadInfo* next; // Next ThreadInfo in this linked list.
};
public:
// Allocate space if the current region provides enough space.
bool MaybeAllocateAligned(size_t n, void** out) {
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
GOOGLE_DCHECK_GE(limit_, ptr_);
if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) return false;
*out = AllocateFromExisting(n);
return true;
}
std::pair<void*, CleanupNode*> AllocateAlignedWithCleanup(
size_t n, const AllocationPolicy* policy) {
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
if (PROTOBUF_PREDICT_FALSE(!HasSpace(n + kCleanupSize))) {
return AllocateAlignedWithCleanupFallback(n, policy);
}
return AllocateFromExistingWithCleanupFallback(n);
}
private:
std::pair<void*, CleanupNode*> AllocateFromExistingWithCleanupFallback(
size_t n) {
void* ret = ptr_;
ptr_ += n;
limit_ -= kCleanupSize;
#ifdef ADDRESS_SANITIZER
ASAN_UNPOISON_MEMORY_REGION(ret, n);
ASAN_UNPOISON_MEMORY_REGION(limit_, kCleanupSize);
#endif // ADDRESS_SANITIZER
return CreatePair(ret, reinterpret_cast<CleanupNode*>(limit_));
}
public:
void AddCleanup(void* elem, void (*cleanup)(void*),
const AllocationPolicy* policy) {
auto res = AllocateAlignedWithCleanup(0, policy);
res.second->elem = elem;
res.second->cleanup = cleanup;
}
void* owner() const { return owner_; }
SerialArena* next() const { return next_; }
void set_next(SerialArena* next) { next_ = next; }
private:
friend class ThreadSafeArena;
friend class ArenaBenchmark;
// Creates a new SerialArena inside mem using the remaining memory as for
// future allocations.
static SerialArena* New(SerialArena::Memory mem, void* owner);
// Free SerialArena returning the memory passed in to New
template <typename Deallocator>
Memory Free(Deallocator deallocator);
// Blocks are variable length malloc-ed objects. The following structure
// describes the common header for all blocks.
struct Block {
void* owner; // &ThreadCache of thread that owns this block.
ThreadInfo* thread_info; // ThreadInfo of thread that owns this block.
Block* next; // Next block in arena (may have different owner)
// ((char*) &block) + pos is next available byte. It is always
// aligned at a multiple of 8 bytes.
size_t pos;
size_t size; // total size of the block.
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
size_t avail() const { return size - pos; }
Block(Block* next, size_t size) : next(next), size(size), start(nullptr) {}
char* Pointer(size_t n) {
GOOGLE_DCHECK(n <= size);
return reinterpret_cast<char*>(this) + n;
}
Block* const next;
const size_t size;
CleanupNode* start;
// data follows
};
struct ThreadCache {
void* owner_; // &ThreadCache of this thread;
Block* head_; // Head of linked list of blocks.
SerialArena* next_; // Next SerialArena in this linked list.
size_t space_used_ = 0; // Necessary for metrics.
std::atomic<size_t> space_allocated_;
// Next pointer to allocate from. Always 8-byte aligned. Points inside
// head_ (and head_->pos will always be non-canonical). We keep these
// here to reduce indirection.
char* ptr_;
char* limit_;
// Constructor is private as only New() should be used.
inline SerialArena(Block* b, void* owner);
void* AllocateAlignedFallback(size_t n, const AllocationPolicy* policy);
std::pair<void*, CleanupNode*> AllocateAlignedWithCleanupFallback(
size_t n, const AllocationPolicy* policy);
void AllocateNewBlock(size_t n, const AllocationPolicy* policy);
std::pair<void*, CleanupNode*> CreatePair(void* ptr, CleanupNode* node) {
return {ptr, node};
}
public:
static constexpr size_t kBlockHeaderSize = AlignUpTo8(sizeof(Block));
static constexpr size_t kCleanupSize = AlignUpTo8(sizeof(CleanupNode));
};
// Tag type used to invoke the constructor of message-owned arena.
// Only message-owned arenas use this constructor for creation.
// Such constructors are internal implementation details of the library.
struct MessageOwned {
explicit MessageOwned() = default;
};
// This class provides the core Arena memory allocation library. Different
// implementations only need to implement the public interface below.
// Arena is not a template type as that would only be useful if all protos
// in turn would be templates, which will/cannot happen. However separating
// the memory allocation part from the cruft of the API users expect we can
// use #ifdef the select the best implementation based on hardware / OS.
class PROTOBUF_EXPORT ThreadSafeArena {
public:
ThreadSafeArena() { Init(); }
// Constructor solely used by message-owned arena.
ThreadSafeArena(internal::MessageOwned) : tag_and_id_(kMessageOwnedArena) {
Init();
}
ThreadSafeArena(char* mem, size_t size) { InitializeFrom(mem, size); }
explicit ThreadSafeArena(void* mem, size_t size,
const AllocationPolicy& policy) {
InitializeWithPolicy(mem, size, policy);
}
// Destructor deletes all owned heap allocated objects, and destructs objects
// that have non-trivial destructors, except for proto2 message objects whose
// destructors can be skipped. Also, frees all blocks except the initial block
// if it was passed in.
~ThreadSafeArena();
uint64_t Reset();
uint64_t SpaceAllocated() const;
uint64_t SpaceUsed() const;
void* AllocateAligned(size_t n, const std::type_info* type) {
SerialArena* arena;
if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() &&
GetSerialArenaFast(&arena))) {
return arena->AllocateAligned(n, AllocPolicy());
} else {
return AllocateAlignedFallback(n, type);
}
}
// This function allocates n bytes if the common happy case is true and
// returns true. Otherwise does nothing and returns false. This strange
// semantics is necessary to allow callers to program functions that only
// have fallback function calls in tail position. This substantially improves
// code for the happy path.
PROTOBUF_NDEBUG_INLINE bool MaybeAllocateAligned(size_t n, void** out) {
SerialArena* a;
if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() &&
GetSerialArenaFromThreadCache(&a))) {
return a->MaybeAllocateAligned(n, out);
}
return false;
}
std::pair<void*, SerialArena::CleanupNode*> AllocateAlignedWithCleanup(
size_t n, const std::type_info* type);
// Add object pointer and cleanup function pointer to the list.
void AddCleanup(void* elem, void (*cleanup)(void*));
// Checks whether this arena is message-owned.
PROTOBUF_ALWAYS_INLINE bool IsMessageOwned() const {
return tag_and_id_ & kMessageOwnedArena;
}
private:
// Unique for each arena. Changes on Reset().
uint64_t tag_and_id_ = 0;
// The LSB of tag_and_id_ indicates if the arena is message-owned.
enum : uint64_t { kMessageOwnedArena = 1 };
TaggedAllocationPolicyPtr alloc_policy_; // Tagged pointer to AllocPolicy.
// Pointer to a linked list of SerialArena.
std::atomic<SerialArena*> threads_;
std::atomic<SerialArena*> hint_; // Fast thread-local block access
const AllocationPolicy* AllocPolicy() const { return alloc_policy_.get(); }
void InitializeFrom(void* mem, size_t size);
void InitializeWithPolicy(void* mem, size_t size, AllocationPolicy policy);
void* AllocateAlignedFallback(size_t n, const std::type_info* type);
std::pair<void*, SerialArena::CleanupNode*>
AllocateAlignedWithCleanupFallback(size_t n, const std::type_info* type);
void Init();
void SetInitialBlock(void* mem, size_t size);
// Delete or Destruct all objects owned by the arena.
void CleanupList();
inline uint64_t LifeCycleId() const {
return tag_and_id_ & ~kMessageOwnedArena;
}
inline void CacheSerialArena(SerialArena* serial) {
thread_cache().last_serial_arena = serial;
thread_cache().last_lifecycle_id_seen = tag_and_id_;
// TODO(haberman): evaluate whether we would gain efficiency by getting rid
// of hint_. It's the only write we do to ThreadSafeArena in the allocation
// path, which will dirty the cache line.
hint_.store(serial, std::memory_order_release);
}
PROTOBUF_NDEBUG_INLINE bool GetSerialArenaFast(SerialArena** arena) {
if (GetSerialArenaFromThreadCache(arena)) return true;
// Check whether we own the last accessed SerialArena on this arena. This
// fast path optimizes the case where a single thread uses multiple arenas.
ThreadCache* tc = &thread_cache();
SerialArena* serial = hint_.load(std::memory_order_acquire);
if (PROTOBUF_PREDICT_TRUE(serial != NULL && serial->owner() == tc)) {
*arena = serial;
return true;
}
return false;
}
PROTOBUF_NDEBUG_INLINE bool GetSerialArenaFromThreadCache(
SerialArena** arena) {
// If this thread already owns a block in this arena then try to use that.
// This fast path optimizes the case where multiple threads allocate from
// the same arena.
ThreadCache* tc = &thread_cache();
if (PROTOBUF_PREDICT_TRUE(tc->last_lifecycle_id_seen == tag_and_id_)) {
*arena = tc->last_serial_arena;
return true;
}
return false;
}
SerialArena* GetSerialArenaFallback(void* me);
template <typename Functor>
void PerSerialArena(Functor fn) {
// By omitting an Acquire barrier we ensure that any user code that doesn't
// properly synchronize Reset() or the destructor will throw a TSAN warning.
SerialArena* serial = threads_.load(std::memory_order_relaxed);
for (; serial; serial = serial->next()) fn(serial);
}
// Releases all memory except the first block which it returns. The first
// block might be owned by the user and thus need some extra checks before
// deleting.
SerialArena::Memory Free(size_t* space_allocated);
#ifdef _MSC_VER
#pragma warning(disable : 4324)
#endif
struct alignas(64) ThreadCache {
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
// If we are using the ThreadLocalStorage class to store the ThreadCache,
// then the ThreadCache's default constructor has to be responsible for
// initializing it.
ThreadCache() : last_lifecycle_id_seen(-1), last_block_used_(NULL) {}
ThreadCache()
: next_lifecycle_id(0),
last_lifecycle_id_seen(-1),
last_serial_arena(NULL) {}
#endif
// Number of per-thread lifecycle IDs to reserve. Must be power of two.
// To reduce contention on a global atomic, each thread reserves a batch of
// IDs. The following number is calculated based on a stress test with
// ~6500 threads all frequently allocating a new arena.
static constexpr size_t kPerThreadIds = 256;
// Next lifecycle ID available to this thread. We need to reserve a new
// batch, if `next_lifecycle_id & (kPerThreadIds - 1) == 0`.
uint64_t next_lifecycle_id;
// The ThreadCache is considered valid as long as this matches the
// lifecycle_id of the arena being used.
int64 last_lifecycle_id_seen;
Block* last_block_used_;
uint64_t last_lifecycle_id_seen;
SerialArena* last_serial_arena;
};
static google::protobuf::internal::SequenceNumber lifecycle_id_generator_;
// Lifecycle_id can be highly contended variable in a situation of lots of
// arena creation. Make sure that other global variables are not sharing the
// cacheline.
#ifdef _MSC_VER
#pragma warning(disable : 4324)
#endif
struct alignas(64) CacheAlignedLifecycleIdGenerator {
std::atomic<LifecycleIdAtomic> id;
};
static CacheAlignedLifecycleIdGenerator lifecycle_id_generator_;
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
// Android ndk does not support GOOGLE_THREAD_LOCAL keyword so we use a custom thread
// local storage class we implemented.
// iOS also does not support the GOOGLE_THREAD_LOCAL keyword.
// iOS does not support __thread keyword so we use a custom thread local
// storage class we implemented.
static ThreadCache& thread_cache();
#elif defined(PROTOBUF_USE_DLLS)
// Thread local variables cannot be exposed through DLL interface but we can
// wrap them in static functions.
static ThreadCache& thread_cache();
#else
static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_;
static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_;
static ThreadCache& thread_cache() { return thread_cache_; }
#endif
void Init();
// Free all blocks and return the total space used which is the sums of sizes
// of the all the allocated blocks.
uint64 FreeBlocks();
void AddCleanupInBlock(Block* b, void* elem, void (*func)(void*));
CleanupChunk* ExpandCleanupList(CleanupChunk* cleanup, Block* b);
// Delete or Destruct all objects owned by the arena.
void CleanupList();
inline void CacheBlock(Block* block) {
thread_cache().last_block_used_ = block;
thread_cache().last_lifecycle_id_seen = lifecycle_id_;
// TODO(haberman): evaluate whether we would gain efficiency by getting rid
// of hint_. It's the only write we do to ArenaImpl in the allocation path,
// which will dirty the cache line.
google::protobuf::internal::Release_Store(&hint_, reinterpret_cast<google::protobuf::internal::AtomicWord>(block));
}
google::protobuf::internal::AtomicWord threads_; // Pointer to a linked list of ThreadInfo.
google::protobuf::internal::AtomicWord hint_; // Fast thread-local block access
google::protobuf::internal::AtomicWord space_allocated_; // Sum of sizes of all allocated blocks.
Block *initial_block_; // If non-NULL, points to the block that came from
// user data.
// Returns a block owned by this thread.
Block* GetBlock(size_t n);
Block* GetBlockSlow(void* me, Block* my_full_block, size_t n);
Block* NewBlock(void* me, Block* my_last_block, size_t min_bytes);
void InitBlock(Block* b, void *me, size_t size);
static void* AllocFromBlock(Block* b, size_t n);
ThreadInfo* NewThreadInfo(Block* b);
ThreadInfo* FindThreadInfo(void* me);
ThreadInfo* GetThreadInfo(void* me, size_t n);
int64 lifecycle_id_; // Unique for each arena. Changes on Reset().
Options options_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArenaImpl);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadSafeArena);
// All protos have pointers back to the arena hence Arena must have
// pointer stability.
ThreadSafeArena(ThreadSafeArena&&) = delete;
ThreadSafeArena& operator=(ThreadSafeArena&&) = delete;
public:
// kHeaderSize is sizeof(Block), aligned up to the nearest multiple of 8 to
// protect the invariant that pos is always at a multiple of 8.
static const size_t kHeaderSize = (sizeof(Block) + 7) & -8;
#if LANG_CXX11
static_assert(kHeaderSize % 8 == 0, "kHeaderSize must be a multiple of 8.");
#endif
// kBlockHeaderSize is sizeof(Block), aligned up to the nearest multiple of 8
// to protect the invariant that pos is always at a multiple of 8.
static constexpr size_t kBlockHeaderSize = SerialArena::kBlockHeaderSize;
static constexpr size_t kSerialArenaSize =
(sizeof(SerialArena) + 7) & static_cast<size_t>(-8);
static_assert(kBlockHeaderSize % 8 == 0,
"kBlockHeaderSize must be a multiple of 8.");
static_assert(kSerialArenaSize % 8 == 0,
"kSerialArenaSize must be a multiple of 8.");
};
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_ARENA_IMPL_H__
+246 -3
View File
@@ -28,16 +28,259 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The ArenaString implementation is not included in the open-source release. Do
// not include this file in the distribution.
#include <google/protobuf/arenastring.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/parse_context.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/stl_util.h>
// clang-format off
#include <google/protobuf/port_def.inc>
// clang-format on
namespace google {
namespace protobuf {
namespace internal {
const std::string& LazyString::Init() const {
static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED};
mu.Lock();
const std::string* res = inited_.load(std::memory_order_acquire);
if (res == nullptr) {
auto init_value = init_value_;
res = ::new (static_cast<void*>(string_buf_))
std::string(init_value.ptr, init_value.size);
inited_.store(res, std::memory_order_release);
}
mu.Unlock();
return *res;
}
std::string* ArenaStringPtr::SetAndReturnNewString() {
std::string* new_string = new std::string();
tagged_ptr_.Set(new_string);
return new_string;
}
void ArenaStringPtr::DestroyNoArenaSlowPath() { delete UnsafeMutablePointer(); }
void ArenaStringPtr::Set(const std::string* default_value,
ConstStringParam value, ::google::protobuf::Arena* arena) {
if (IsDefault(default_value)) {
tagged_ptr_.Set(Arena::Create<std::string>(arena, value));
} else {
UnsafeMutablePointer()->assign(value.data(), value.length());
}
}
void ArenaStringPtr::Set(const std::string* default_value, std::string&& value,
::google::protobuf::Arena* arena) {
if (IsDefault(default_value)) {
if (arena == nullptr) {
tagged_ptr_.Set(new std::string(std::move(value)));
} else {
tagged_ptr_.Set(Arena::Create<std::string>(arena, std::move(value)));
}
} else if (IsDonatedString()) {
std::string* current = tagged_ptr_.Get();
auto* s = new (current) std::string(std::move(value));
arena->OwnDestructor(s);
tagged_ptr_.Set(s);
} else /* !IsDonatedString() */ {
*UnsafeMutablePointer() = std::move(value);
}
}
void ArenaStringPtr::Set(EmptyDefault, ConstStringParam value,
::google::protobuf::Arena* arena) {
Set(&GetEmptyStringAlreadyInited(), value, arena);
}
void ArenaStringPtr::Set(EmptyDefault, std::string&& value,
::google::protobuf::Arena* arena) {
Set(&GetEmptyStringAlreadyInited(), std::move(value), arena);
}
void ArenaStringPtr::Set(NonEmptyDefault, ConstStringParam value,
::google::protobuf::Arena* arena) {
Set(nullptr, value, arena);
}
void ArenaStringPtr::Set(NonEmptyDefault, std::string&& value,
::google::protobuf::Arena* arena) {
Set(nullptr, std::move(value), arena);
}
std::string* ArenaStringPtr::Mutable(EmptyDefault, ::google::protobuf::Arena* arena) {
if (!IsDonatedString() && !IsDefault(&GetEmptyStringAlreadyInited())) {
return UnsafeMutablePointer();
} else {
return MutableSlow(arena);
}
}
std::string* ArenaStringPtr::Mutable(const LazyString& default_value,
::google::protobuf::Arena* arena) {
if (!IsDonatedString() && !IsDefault(nullptr)) {
return UnsafeMutablePointer();
} else {
return MutableSlow(arena, default_value);
}
}
std::string* ArenaStringPtr::MutableNoCopy(const std::string* default_value,
::google::protobuf::Arena* arena) {
if (!IsDonatedString() && !IsDefault(default_value)) {
return UnsafeMutablePointer();
} else {
GOOGLE_DCHECK(IsDefault(default_value));
// Allocate empty. The contents are not relevant.
std::string* new_string = Arena::Create<std::string>(arena);
tagged_ptr_.Set(new_string);
return new_string;
}
}
template <typename... Lazy>
std::string* ArenaStringPtr::MutableSlow(::google::protobuf::Arena* arena,
const Lazy&... lazy_default) {
const std::string* const default_value =
sizeof...(Lazy) == 0 ? &GetEmptyStringAlreadyInited() : nullptr;
GOOGLE_DCHECK(IsDefault(default_value));
std::string* new_string =
Arena::Create<std::string>(arena, lazy_default.get()...);
tagged_ptr_.Set(new_string);
return new_string;
}
std::string* ArenaStringPtr::Release(const std::string* default_value,
::google::protobuf::Arena* arena) {
if (IsDefault(default_value)) {
return nullptr;
} else {
return ReleaseNonDefault(default_value, arena);
}
}
std::string* ArenaStringPtr::ReleaseNonDefault(const std::string* default_value,
::google::protobuf::Arena* arena) {
GOOGLE_DCHECK(!IsDefault(default_value));
if (!IsDonatedString()) {
std::string* released;
if (arena != nullptr) {
released = new std::string;
released->swap(*UnsafeMutablePointer());
} else {
released = UnsafeMutablePointer();
}
tagged_ptr_.Set(const_cast<std::string*>(default_value));
return released;
} else /* IsDonatedString() */ {
GOOGLE_DCHECK(arena != nullptr);
std::string* released = new std::string(Get());
tagged_ptr_.Set(const_cast<std::string*>(default_value));
return released;
}
}
void ArenaStringPtr::SetAllocated(const std::string* default_value,
std::string* value, ::google::protobuf::Arena* arena) {
// Release what we have first.
if (arena == nullptr && !IsDefault(default_value)) {
delete UnsafeMutablePointer();
}
if (value == nullptr) {
tagged_ptr_.Set(const_cast<std::string*>(default_value));
} else {
#ifdef NDEBUG
tagged_ptr_.Set(value);
if (arena != nullptr) {
arena->Own(value);
}
#else
// On debug builds, copy the string so the address differs. delete will
// fail if value was a stack-allocated temporary/etc., which would have
// failed when arena ran its cleanup list.
std::string* new_value = Arena::Create<std::string>(arena, *value);
delete value;
tagged_ptr_.Set(new_value);
#endif
}
}
void ArenaStringPtr::Destroy(const std::string* default_value,
::google::protobuf::Arena* arena) {
if (arena == nullptr) {
GOOGLE_DCHECK(!IsDonatedString());
if (!IsDefault(default_value)) {
delete UnsafeMutablePointer();
}
}
}
void ArenaStringPtr::Destroy(EmptyDefault, ::google::protobuf::Arena* arena) {
Destroy(&GetEmptyStringAlreadyInited(), arena);
}
void ArenaStringPtr::Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena) {
Destroy(nullptr, arena);
}
void ArenaStringPtr::ClearToEmpty() {
if (IsDefault(&GetEmptyStringAlreadyInited())) {
// Already set to default -- do nothing.
} else {
// Unconditionally mask away the tag.
//
// UpdateDonatedString uses assign when capacity is larger than the new
// value, which is trivially true in the donated string case.
// const_cast<std::string*>(PtrValue<std::string>())->clear();
tagged_ptr_.Get()->clear();
}
}
void ArenaStringPtr::ClearToDefault(const LazyString& default_value,
::google::protobuf::Arena* arena) {
(void)arena;
if (IsDefault(nullptr)) {
// Already set to default -- do nothing.
} else if (!IsDonatedString()) {
UnsafeMutablePointer()->assign(default_value.get());
}
}
inline void SetStrWithHeapBuffer(std::string* str, ArenaStringPtr* s) {
TaggedPtr<std::string> res;
res.Set(str);
s->UnsafeSetTaggedPointer(res);
}
const char* EpsCopyInputStream::ReadArenaString(const char* ptr,
ArenaStringPtr* s,
Arena* arena) {
GOOGLE_DCHECK(arena != nullptr);
int size = ReadSize(&ptr);
if (!ptr) return nullptr;
auto* str = Arena::Create<std::string>(arena);
ptr = ReadString(ptr, size, str);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
SetStrWithHeapBuffer(str, s);
return ptr;
}
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
+339 -257
View File
@@ -32,307 +32,389 @@
#define GOOGLE_PROTOBUF_ARENASTRING_H__
#include <string>
#include <type_traits>
#include <utility>
#include <google/protobuf/arena.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/fastmem.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/port.h>
#include <google/protobuf/port_def.inc>
#ifdef SWIG
#error "You cannot SWIG proto headers"
#endif
// This is the implementation of arena string fields written for the open-source
// release. The ArenaStringPtr struct below is an internal implementation class
// and *should not be used* by user code. It is used to collect string
// operations together into one place and abstract away the underlying
// string-field pointer representation, so that (for example) an alternate
// implementation that knew more about ::std::string's internals could integrate more
// closely with the arena allocator.
namespace google {
namespace protobuf {
namespace internal {
struct LIBPROTOBUF_EXPORT ArenaStringPtr {
inline void Set(const ::std::string* default_value,
const ::std::string& value, ::google::protobuf::Arena* arena) {
if (ptr_ == default_value) {
CreateInstance(arena, &value);
} else {
*ptr_ = value;
}
template <typename T>
class ExplicitlyConstructed;
class SwapFieldHelper;
// Lazy string instance to support string fields with non-empty default.
// These are initialized on the first call to .get().
class PROTOBUF_EXPORT LazyString {
public:
// We explicitly make LazyString an aggregate so that MSVC can do constant
// initialization on it without marking it `constexpr`.
// We do not want to use `constexpr` because it makes it harder to have extern
// storage for it and causes library bloat.
struct InitValue {
const char* ptr;
size_t size;
};
// We keep a union of the initialization value and the std::string to save on
// space. We don't need the string array after Init() is done.
union {
mutable InitValue init_value_;
alignas(std::string) mutable char string_buf_[sizeof(std::string)];
};
mutable std::atomic<const std::string*> inited_;
const std::string& get() const {
// This check generates less code than a call-once invocation.
auto* res = inited_.load(std::memory_order_acquire);
if (PROTOBUF_PREDICT_FALSE(res == nullptr)) return Init();
return *res;
}
inline void SetLite(const ::std::string* default_value,
const ::std::string& value,
::google::protobuf::Arena* arena) {
Set(default_value, value, arena);
private:
// Initialize the string in `string_buf_`, update `inited_` and return it.
// We return it here to avoid having to read it again in the inlined code.
const std::string& Init() const;
};
template <typename T>
class TaggedPtr {
public:
TaggedPtr() = default;
explicit constexpr TaggedPtr(const ExplicitlyConstructed<std::string>* ptr)
: ptr_(const_cast<ExplicitlyConstructed<std::string>*>(ptr)) {}
void SetTagged(T* p) {
Set(p);
ptr_ = reinterpret_cast<void*>(as_int() | 1);
}
void Set(T* p) { ptr_ = p; }
T* Get() const { return reinterpret_cast<T*>(as_int() & -2); }
bool IsTagged() const { return as_int() & 1; }
// Returned value is only safe to dereference if IsTagged() == false.
// It is safe to compare.
T* UnsafeGet() const { return static_cast<T*>(ptr_); }
bool IsNull() { return ptr_ == nullptr; }
private:
uintptr_t as_int() const { return reinterpret_cast<uintptr_t>(ptr_); }
void* ptr_;
};
static_assert(std::is_trivial<TaggedPtr<std::string>>::value,
"TaggedPtr must be trivial");
// This class encapsulates a pointer to a std::string with or without a donated
// buffer, tagged by bottom bit. It is a high-level wrapper that almost directly
// corresponds to the interface required by string fields in generated
// code. It replaces the old std::string* pointer in such cases.
//
// The object has different but similar code paths for when the default value is
// the empty string and when it is a non-empty string.
// The empty string is handled different throughout the library and there is a
// single global instance of it we can share.
//
// For fields with an empty string default value, there are three distinct
// states:
//
// - Pointer set to 'String' tag (LSB is 0), equal to
// &GetEmptyStringAlreadyInited(): field is set to its default value. Points
// to a true std::string*, but we do not own that std::string* (it's a
// globally shared instance).
//
// - Pointer set to 'String' tag (LSB is 0), but not equal to the global empty
// string: field points to a true std::string* instance that we own. This
// instance is either on the heap or on the arena (i.e. registered on
// free()/destructor-call list) as appropriate.
//
// - Pointer set to 'DonatedString' tag (LSB is 1): points to a std::string
// instance with a buffer on the arena (arena is never nullptr in this case).
//
// For fields with a non-empty string default value, there are three distinct
// states:
//
// - Pointer set to 'String' tag (LSB is 0), equal to `nullptr`:
// Field is in "default" mode and does not point to any actual instance.
// Methods that might need to create an instance of the object will pass a
// `const LazyString&` for it.
//
// - Pointer set to 'String' tag (LSB is 0), but not equal to `nullptr`:
// field points to a true std::string* instance that we own. This instance is
// either on the heap or on the arena (i.e. registered on
// free()/destructor-call list) as appropriate.
//
// - Pointer set to 'DonatedString' tag (LSB is 1): points to a std::string
// instance with a buffer on the arena (arena is never nullptr in this case).
//
// Generated code and reflection code both ensure that ptr_ is never null for
// fields with an empty default.
// Because ArenaStringPtr is used in oneof unions, its constructor is a NOP and
// so the field is always manually initialized via method calls.
//
// Side-note: why pass information about the default on every API call? Because
// we don't want to hold it in a member variable, or else this would go into
// every proto message instance. This would be a huge waste of space, since the
// default instance pointer is typically a global (static class field). We want
// the generated code to be as efficient as possible, and if we take
// the default value information as a parameter that's in practice taken from a
// static class field, and compare ptr_ to the default value, we end up with a
// single "cmp %reg, GLOBAL" in the resulting machine code. (Note that this also
// requires the String tag to be 0 so we can avoid the mask before comparing.)
struct PROTOBUF_EXPORT ArenaStringPtr {
ArenaStringPtr() = default;
explicit constexpr ArenaStringPtr(
const ExplicitlyConstructed<std::string>* default_value)
: tagged_ptr_(default_value) {}
// Some methods below are overloaded on a `default_value` and on tags.
// The tagged overloads help reduce code size in the callers in generated
// code, while the `default_value` overloads are useful from reflection.
// By-value empty struct arguments are elided in the ABI.
struct EmptyDefault {};
struct NonEmptyDefault {};
void Set(const std::string* default_value, ConstStringParam value,
::google::protobuf::Arena* arena);
void Set(const std::string* default_value, std::string&& value,
::google::protobuf::Arena* arena);
void Set(EmptyDefault, ConstStringParam value, ::google::protobuf::Arena* arena);
void Set(EmptyDefault, std::string&& value, ::google::protobuf::Arena* arena);
void Set(NonEmptyDefault, ConstStringParam value, ::google::protobuf::Arena* arena);
void Set(NonEmptyDefault, std::string&& value, ::google::protobuf::Arena* arena);
template <typename FirstParam>
void Set(FirstParam p1, const char* str, ::google::protobuf::Arena* arena) {
Set(p1, ConstStringParam(str), arena);
}
template <typename FirstParam>
void Set(FirstParam p1, const char* str, size_t size,
::google::protobuf::Arena* arena) {
ConstStringParam sp{str, size}; // for string_view and `const string &`
Set(p1, sp, arena);
}
template <typename FirstParam, typename RefWrappedType>
void Set(FirstParam p1,
std::reference_wrapper<RefWrappedType> const_string_ref,
::google::protobuf::Arena* arena) {
Set(p1, const_string_ref.get(), arena);
}
template <typename FirstParam, typename SecondParam>
void SetBytes(FirstParam p1, SecondParam&& p2, ::google::protobuf::Arena* arena) {
Set(p1, static_cast<SecondParam&&>(p2), arena);
}
template <typename FirstParam>
void SetBytes(FirstParam p1, const void* str, size_t size,
::google::protobuf::Arena* arena) {
// must work whether ConstStringParam is string_view or `const string &`
ConstStringParam sp{static_cast<const char*>(str), size};
Set(p1, sp, arena);
}
// Basic accessors.
inline const ::std::string& Get() const { return *ptr_; }
inline ::std::string* Mutable(const ::std::string* default_value,
::google::protobuf::Arena* arena) {
if (ptr_ == default_value) {
CreateInstance(arena, default_value);
}
return ptr_;
PROTOBUF_NDEBUG_INLINE const std::string& Get() const {
// Unconditionally mask away the tag.
return *tagged_ptr_.Get();
}
PROTOBUF_NDEBUG_INLINE const std::string* GetPointer() const {
// Unconditionally mask away the tag.
return tagged_ptr_.Get();
}
// Release returns a ::std::string* instance that is heap-allocated and is not
// Own()'d by any arena. If the field was not set, it returns NULL. The caller
// retains ownership. Clears this field back to NULL state. Used to implement
// release_<field>() methods on generated classes.
inline ::std::string* Release(const ::std::string* default_value,
::google::protobuf::Arena* arena) {
if (ptr_ == default_value) {
return NULL;
}
::std::string* released = NULL;
if (arena != NULL) {
// ptr_ is owned by the arena.
released = new ::std::string;
released->swap(*ptr_);
} else {
released = ptr_;
}
ptr_ = const_cast< ::std::string* >(default_value);
return released;
}
// For fields with an empty default value.
std::string* Mutable(EmptyDefault, ::google::protobuf::Arena* arena);
// For fields with a non-empty default value.
std::string* Mutable(const LazyString& default_value, ::google::protobuf::Arena* arena);
// UnsafeArenaRelease returns a ::std::string*, but it may be arena-owned (i.e.
// have its destructor already registered) if arena != NULL. If the field was
// not set, this returns NULL. This method clears this field back to NULL
// state. Used to implement unsafe_arena_release_<field>() methods on
// generated classes.
inline ::std::string* UnsafeArenaRelease(const ::std::string* default_value,
::google::protobuf::Arena* /* arena */) {
if (ptr_ == default_value) {
return NULL;
}
::std::string* released = ptr_;
ptr_ = const_cast< ::std::string* >(default_value);
return released;
}
// Release returns a std::string* instance that is heap-allocated and is not
// Own()'d by any arena. If the field is not set, this returns nullptr. The
// caller retains ownership. Clears this field back to nullptr state. Used to
// implement release_<field>() methods on generated classes.
PROTOBUF_NODISCARD std::string* Release(const std::string* default_value,
::google::protobuf::Arena* arena);
PROTOBUF_NODISCARD std::string* ReleaseNonDefault(
const std::string* default_value, ::google::protobuf::Arena* arena);
// Takes a string that is heap-allocated, and takes ownership. The string's
// destructor is registered with the arena. Used to implement
// Takes a std::string that is heap-allocated, and takes ownership. The
// std::string's destructor is registered with the arena. Used to implement
// set_allocated_<field> in generated classes.
inline void SetAllocated(const ::std::string* default_value,
::std::string* value, ::google::protobuf::Arena* arena) {
if (arena == NULL && ptr_ != default_value) {
Destroy(default_value, arena);
}
if (value != NULL) {
ptr_ = value;
if (arena != NULL) {
arena->Own(value);
}
} else {
ptr_ = const_cast< ::std::string* >(default_value);
}
}
// Takes a string that has lifetime equal to the arena's lifetime. The arena
// must be non-null. It is safe only to pass this method a value returned by
// UnsafeArenaRelease() on another field of a message in the same arena. Used
// to implement unsafe_arena_set_allocated_<field> in generated classes.
inline void UnsafeArenaSetAllocated(const ::std::string* default_value,
::std::string* value,
::google::protobuf::Arena* /* arena */) {
if (value != NULL) {
ptr_ = value;
} else {
ptr_ = const_cast< ::std::string* >(default_value);
}
}
void SetAllocated(const std::string* default_value, std::string* value,
::google::protobuf::Arena* arena);
// Swaps internal pointers. Arena-safety semantics: this is guarded by the
// logic in Swap()/UnsafeArenaSwap() at the message level, so this method is
// 'unsafe' if called directly.
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void Swap(ArenaStringPtr* other) {
std::swap(ptr_, other->ptr_);
}
inline PROTOBUF_NDEBUG_INLINE static void InternalSwap(
const std::string* default_value, ArenaStringPtr* rhs, Arena* rhs_arena,
ArenaStringPtr* lhs, Arena* lhs_arena);
// Frees storage (if not on an arena).
inline void Destroy(const ::std::string* default_value,
::google::protobuf::Arena* arena) {
if (arena == NULL && ptr_ != default_value) {
delete ptr_;
}
}
void Destroy(const std::string* default_value, ::google::protobuf::Arena* arena);
void Destroy(EmptyDefault, ::google::protobuf::Arena* arena);
void Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena);
// Clears content, but keeps allocated string if arena != NULL, to avoid the
// overhead of heap operations. After this returns, the content (as seen by
// the user) will always be the empty string. Assumes that |default_value|
// is an empty string.
inline void ClearToEmpty(const ::std::string* default_value,
::google::protobuf::Arena* /* arena */) {
if (ptr_ == default_value) {
// Already set to default (which is empty) -- do nothing.
} else {
ptr_->clear();
}
}
// Clears content, but keeps allocated std::string, to avoid the overhead of
// heap operations. After this returns, the content (as seen by the user) will
// always be the empty std::string. Assumes that |default_value| is an empty
// std::string.
void ClearToEmpty();
// Clears content, but keeps allocated string if arena != NULL, to avoid the
// overhead of heap operations. After this returns, the content (as seen by
// the user) will always be equal to |default_value|.
inline void ClearToDefault(const ::std::string* default_value,
::google::protobuf::Arena* /* arena */) {
if (ptr_ == default_value) {
// Already set to default -- do nothing.
} else {
// Have another allocated string -- rather than throwing this away and
// resetting ptr_ to the canonical default string instance, we just reuse
// this instance.
*ptr_ = *default_value;
}
}
// Clears content, assuming that the current value is not the empty
// string default.
void ClearNonDefaultToEmpty();
// Clears content, but keeps allocated std::string if arena != nullptr, to
// avoid the overhead of heap operations. After this returns, the content
// (as seen by the user) will always be equal to |default_value|.
void ClearToDefault(const LazyString& default_value, ::google::protobuf::Arena* arena);
// Called from generated code / reflection runtime only. Resets value to point
// to a default string pointer, with the semantics that this ArenaStringPtr
// does not own the pointed-to memory. Disregards initial value of ptr_ (so
// this is the *ONLY* safe method to call after construction or when
// reinitializing after becoming the active field in a oneof union).
inline void UnsafeSetDefault(const ::std::string* default_value) {
// Casting away 'const' is safe here: accessors ensure that ptr_ is only
// returned as a const if it is equal to default_value.
ptr_ = const_cast< ::std::string* >(default_value);
// to a default string pointer, with the semantics that this
// ArenaStringPtr does not own the pointed-to memory. Disregards initial value
// of ptr_ (so this is the *ONLY* safe method to call after construction or
// when reinitializing after becoming the active field in a oneof union).
inline void UnsafeSetDefault(const std::string* default_value);
// Returns a mutable pointer, but doesn't initialize the string to the
// default value.
std::string* MutableNoArenaNoDefault(const std::string* default_value);
// Get a mutable pointer with unspecified contents.
// Similar to `MutableNoArenaNoDefault`, but also handles the arena case.
// If the value was donated, the contents are discarded.
std::string* MutableNoCopy(const std::string* default_value,
::google::protobuf::Arena* arena);
// Destroy the string. Assumes `arena == nullptr`.
void DestroyNoArena(const std::string* default_value);
// Internal setter used only at parse time to directly set a donated string
// value.
void UnsafeSetTaggedPointer(TaggedPtr<std::string> value) {
tagged_ptr_ = value;
}
// Generated code only! An optimization, in certain cases the generated
// code is certain we can obtain a std::string with no default checks and
// tag tests.
std::string* UnsafeMutablePointer() PROTOBUF_RETURNS_NONNULL;
// The 'NoArena' variants of methods below assume arena == NULL and are
// optimized to provide very little overhead relative to a raw string pointer
// (while still being in-memory compatible with other code that assumes
// ArenaStringPtr). Note the invariant that a class instance that has only
// ever been mutated by NoArena methods must *only* be in the String state
// (i.e., tag bits are not used), *NEVER* ArenaString. This allows all
// tagged-pointer manipulations to be avoided.
inline void SetNoArena(const ::std::string* default_value,
const ::std::string& value) {
if (ptr_ == default_value) {
CreateInstanceNoArena(&value);
} else {
*ptr_ = value;
}
}
#if LANG_CXX11
void SetNoArena(const ::std::string* default_value, ::std::string&& value) {
if (IsDefault(default_value)) {
ptr_ = new ::std::string(std::move(value));
} else {
*ptr_ = std::move(value);
}
}
#endif
void AssignWithDefault(const ::std::string* default_value, ArenaStringPtr value);
inline const ::std::string& GetNoArena() const { return *ptr_; }
inline ::std::string* MutableNoArena(const ::std::string* default_value) {
if (ptr_ == default_value) {
CreateInstanceNoArena(default_value);
}
return ptr_;
}
inline ::std::string* ReleaseNoArena(const ::std::string* default_value) {
if (ptr_ == default_value) {
return NULL;
} else {
::std::string* released = ptr_;
ptr_ = const_cast< ::std::string* >(default_value);
return released;
}
}
inline void SetAllocatedNoArena(const ::std::string* default_value,
::std::string* value) {
if (ptr_ != default_value) {
delete ptr_;
}
if (value != NULL) {
ptr_ = value;
} else {
ptr_ = const_cast< ::std::string* >(default_value);
}
}
inline void DestroyNoArena(const ::std::string* default_value) {
if (ptr_ != default_value) {
delete ptr_;
}
}
inline void ClearToEmptyNoArena(const ::std::string* default_value) {
if (ptr_ == default_value) {
// Nothing: already equal to default (which is the empty string).
} else {
ptr_->clear();
}
}
inline void ClearToDefaultNoArena(const ::std::string* default_value) {
if (ptr_ == default_value) {
// Nothing: already set to default.
} else {
// Reuse existing allocated instance.
*ptr_ = *default_value;
}
}
// Internal accessor used only at parse time to provide direct access to the
// raw pointer from the shared parse routine (in the non-arenas case). The
// parse routine does the string allocation in order to save code size in the
// generated parsing code.
inline ::std::string** UnsafeRawStringPointer() {
return &ptr_;
}
inline bool IsDefault(const ::std::string* default_value) const {
return ptr_ == default_value;
inline bool IsDefault(const std::string* default_value) const {
// Relies on the fact that kPtrTagString == 0, so if IsString(), ptr_ is the
// actual std::string pointer (and if !IsString(), ptr_ will never be equal
// to any aligned |default_value| pointer). The key is that we want to avoid
// masking in the fastpath const-pointer Get() case for non-arena code.
return tagged_ptr_.UnsafeGet() == default_value;
}
private:
::std::string* ptr_;
TaggedPtr<std::string> tagged_ptr_;
GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
void CreateInstance(::google::protobuf::Arena* arena,
const ::std::string* initial_value) {
GOOGLE_DCHECK(initial_value != NULL);
ptr_ = new ::std::string(*initial_value);
if (arena != NULL) {
arena->Own(ptr_);
}
}
GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
void CreateInstanceNoArena(const ::std::string* initial_value) {
GOOGLE_DCHECK(initial_value != NULL);
ptr_ = new ::std::string(*initial_value);
bool IsDonatedString() const { return false; }
// Swaps tagged pointer without debug hardening. This is to allow python
// protobuf to maintain pointer stability even in DEBUG builds.
inline PROTOBUF_NDEBUG_INLINE static void UnsafeShallowSwap(
ArenaStringPtr* rhs, ArenaStringPtr* lhs) {
std::swap(lhs->tagged_ptr_, rhs->tagged_ptr_);
}
friend class ::google::protobuf::internal::SwapFieldHelper;
// Slow paths.
// MutableSlow requires that !IsString() || IsDefault
// Variadic to support 0 args for EmptyDefault and 1 arg for LazyString.
template <typename... Lazy>
std::string* MutableSlow(::google::protobuf::Arena* arena, const Lazy&... lazy_default);
// Sets value to a newly allocated string and returns it
std::string* SetAndReturnNewString();
// Destroys the non-default string value out-of-line
void DestroyNoArenaSlowPath();
};
} // namespace internal
} // namespace protobuf
inline void ArenaStringPtr::UnsafeSetDefault(const std::string* value) {
tagged_ptr_.Set(const_cast<std::string*>(value));
}
// Make sure rhs_arena allocated rhs, and lhs_arena allocated lhs.
inline PROTOBUF_NDEBUG_INLINE void ArenaStringPtr::InternalSwap( //
const std::string* default_value, //
ArenaStringPtr* rhs, Arena* rhs_arena, //
ArenaStringPtr* lhs, Arena* lhs_arena) {
// Silence unused variable warnings in release buildls.
(void)default_value;
(void)rhs_arena;
(void)lhs_arena;
std::swap(lhs->tagged_ptr_, rhs->tagged_ptr_);
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
auto force_realloc = [default_value](ArenaStringPtr* p, Arena* arena) {
if (p->IsDefault(default_value)) return;
std::string* old_value = p->tagged_ptr_.Get();
std::string* new_value =
p->IsDonatedString()
? Arena::Create<std::string>(arena, *old_value)
: Arena::Create<std::string>(arena, std::move(*old_value));
if (arena == nullptr) delete old_value;
p->tagged_ptr_.Set(new_value);
};
// Because, at this point, tagged_ptr_ has been swapped, arena should also be
// swapped.
force_realloc(lhs, rhs_arena);
force_realloc(rhs, lhs_arena);
#endif // PROTOBUF_FORCE_COPY_IN_SWAP
}
inline void ArenaStringPtr::ClearNonDefaultToEmpty() {
// Unconditionally mask away the tag.
tagged_ptr_.Get()->clear();
}
namespace protobuf {
namespace internal {
inline void ArenaStringPtr::AssignWithDefault(const ::std::string* default_value,
ArenaStringPtr value) {
const ::std::string* me = *UnsafeRawStringPointer();
const ::std::string* other = *value.UnsafeRawStringPointer();
// If the pointers are the same then do nothing.
if (me != other) {
SetNoArena(default_value, value.GetNoArena());
inline std::string* ArenaStringPtr::MutableNoArenaNoDefault(
const std::string* default_value) {
// VERY IMPORTANT for performance and code size: this will reduce to a member
// variable load, a pointer check (against |default_value|, in practice a
// static global) and a branch to the slowpath (which calls operator new and
// the ctor). DO NOT add any tagged-pointer operations here.
if (IsDefault(default_value)) {
return SetAndReturnNewString();
} else {
return UnsafeMutablePointer();
}
}
inline void ArenaStringPtr::DestroyNoArena(const std::string* default_value) {
if (!IsDefault(default_value)) {
DestroyNoArenaSlowPath();
}
}
inline std::string* ArenaStringPtr::UnsafeMutablePointer() {
GOOGLE_DCHECK(!tagged_ptr_.IsTagged());
GOOGLE_DCHECK(tagged_ptr_.UnsafeGet() != nullptr);
return tagged_ptr_.UnsafeGet();
}
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_ARENASTRING_H__
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+98 -90
View File
@@ -44,6 +44,12 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/port_def.inc>
#ifdef SWIG
#error "You cannot SWIG proto headers"
#endif
namespace google {
namespace protobuf {
@@ -62,27 +68,27 @@ class MergedDescriptorDatabase;
// calling DescriptorPool::BuildFile() for each one. Instead, a DescriptorPool
// can be created which wraps a DescriptorDatabase and only builds particular
// descriptors when they are needed.
class LIBPROTOBUF_EXPORT DescriptorDatabase {
class PROTOBUF_EXPORT DescriptorDatabase {
public:
inline DescriptorDatabase() {}
virtual ~DescriptorDatabase();
// Find a file by file name. Fills in in *output and returns true if found.
// Otherwise, returns false, leaving the contents of *output undefined.
virtual bool FindFileByName(const string& filename,
virtual bool FindFileByName(const std::string& filename,
FileDescriptorProto* output) = 0;
// Find the file that declares the given fully-qualified symbol name.
// If found, fills in *output and returns true, otherwise returns false
// and leaves *output undefined.
virtual bool FindFileContainingSymbol(const string& symbol_name,
virtual bool FindFileContainingSymbol(const std::string& symbol_name,
FileDescriptorProto* output) = 0;
// Find the file which defines an extension extending the given message type
// with the given field number. If found, fills in *output and returns true,
// otherwise returns false and leaves *output undefined. containing_type
// must be a fully-qualified type name.
virtual bool FindFileContainingExtension(const string& containing_type,
virtual bool FindFileContainingExtension(const std::string& containing_type,
int field_number,
FileDescriptorProto* output) = 0;
@@ -96,7 +102,7 @@ class LIBPROTOBUF_EXPORT DescriptorDatabase {
//
// This method has a default implementation that always returns
// false.
virtual bool FindAllExtensionNumbers(const string& /* extendee_type */,
virtual bool FindAllExtensionNumbers(const std::string& /* extendee_type */,
std::vector<int>* /* output */) {
return false;
}
@@ -110,10 +116,24 @@ class LIBPROTOBUF_EXPORT DescriptorDatabase {
//
// This method has a default implementation that always returns
// false.
virtual bool FindAllFileNames(std::vector<string>* output) {
virtual bool FindAllFileNames(std::vector<std::string>* /*output*/) {
return false;
}
// Finds the package names and appends them to the output in an
// undefined order. This method is best-effort: it's not guaranteed that the
// database will find all packages. Returns true if the database supports
// searching all package names, otherwise returns false and leaves output
// unchanged.
bool FindAllPackageNames(std::vector<std::string>* output);
// Finds the message names and appends them to the output in an
// undefined order. This method is best-effort: it's not guaranteed that the
// database will find all messages. Returns true if the database supports
// searching all message names, otherwise returns false and leaves output
// unchanged.
bool FindAllMessageNames(std::vector<std::string>* output);
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase);
};
@@ -139,10 +159,10 @@ class LIBPROTOBUF_EXPORT DescriptorDatabase {
// FileDescriptor::CopyTo()) will always use fully-qualified names for all
// types. You only need to worry if you are constructing FileDescriptorProtos
// yourself, or are calling compiler::Parser directly.
class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
class PROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
public:
SimpleDescriptorDatabase();
~SimpleDescriptorDatabase();
~SimpleDescriptorDatabase() override;
// Adds the FileDescriptorProto to the database, making a copy. The object
// can be deleted after Add() returns. Returns false if the file conflicted
@@ -154,20 +174,19 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
bool AddAndOwn(const FileDescriptorProto* file);
// implements DescriptorDatabase -----------------------------------
bool FindFileByName(const string& filename,
FileDescriptorProto* output);
bool FindFileContainingSymbol(const string& symbol_name,
FileDescriptorProto* output);
bool FindFileContainingExtension(const string& containing_type,
bool FindFileByName(const std::string& filename,
FileDescriptorProto* output) override;
bool FindFileContainingSymbol(const std::string& symbol_name,
FileDescriptorProto* output) override;
bool FindFileContainingExtension(const std::string& containing_type,
int field_number,
FileDescriptorProto* output);
bool FindAllExtensionNumbers(const string& extendee_type,
std::vector<int>* output);
FileDescriptorProto* output) override;
bool FindAllExtensionNumbers(const std::string& extendee_type,
std::vector<int>* output) override;
bool FindAllFileNames(std::vector<std::string>* output) override;
private:
// So that it can use DescriptorIndex.
friend class EncodedDescriptorDatabase;
// An index mapping file names, symbol names, and extension numbers to
// some sort of values.
template <typename Value>
@@ -175,24 +194,24 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
public:
// Helpers to recursively add particular descriptors and all their contents
// to the index.
bool AddFile(const FileDescriptorProto& file,
Value value);
bool AddSymbol(const string& name, Value value);
bool AddNestedExtensions(const DescriptorProto& message_type,
Value value);
bool AddExtension(const FieldDescriptorProto& field,
Value value);
bool AddFile(const FileDescriptorProto& file, Value value);
bool AddSymbol(const std::string& name, Value value);
bool AddNestedExtensions(const std::string& filename,
const DescriptorProto& message_type, Value value);
bool AddExtension(const std::string& filename,
const FieldDescriptorProto& field, Value value);
Value FindFile(const string& filename);
Value FindSymbol(const string& name);
Value FindExtension(const string& containing_type, int field_number);
bool FindAllExtensionNumbers(const string& containing_type,
Value FindFile(const std::string& filename);
Value FindSymbol(const std::string& name);
Value FindExtension(const std::string& containing_type, int field_number);
bool FindAllExtensionNumbers(const std::string& containing_type,
std::vector<int>* output);
void FindAllFileNames(std::vector<std::string>* output);
private:
std::map<string, Value> by_name_;
std::map<string, Value> by_symbol_;
std::map<std::pair<string, int>, Value> by_extension_;
std::map<std::string, Value> by_name_;
std::map<std::string, Value> by_symbol_;
std::map<std::pair<std::string, int>, Value> by_extension_;
// Invariant: The by_symbol_ map does not contain any symbols which are
// prefixes of other symbols in the map. For example, "foo.bar" is a
@@ -214,7 +233,7 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
// will find it. Proof:
// 1) Define the "search key" to be the key we are looking for, the "found
// key" to be the key found in step (1), and the "match key" to be the
// key which actually matches the serach key (i.e. the key we're trying
// key which actually matches the search key (i.e. the key we're trying
// to find).
// 2) The found key must be less than or equal to the search key by
// definition.
@@ -244,30 +263,14 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
// That symbol cannot be a super-symbol of the search key since if it were,
// then it would be a match, and we're assuming the match key doesn't exist.
// Therefore, step 2 will correctly return no match.
// Find the last entry in the by_symbol_ map whose key is less than or
// equal to the given name.
typename std::map<string, Value>::iterator FindLastLessOrEqual(
const string& name);
// True if either the arguments are equal or super_symbol identifies a
// parent symbol of sub_symbol (e.g. "foo.bar" is a parent of
// "foo.bar.baz", but not a parent of "foo.barbaz").
bool IsSubSymbol(const string& sub_symbol, const string& super_symbol);
// Returns true if and only if all characters in the name are alphanumerics,
// underscores, or periods.
bool ValidateSymbolName(const string& name);
};
DescriptorIndex<const FileDescriptorProto*> index_;
std::vector<const FileDescriptorProto*> files_to_delete_;
std::vector<std::unique_ptr<const FileDescriptorProto>> files_to_delete_;
// If file is non-NULL, copy it into *output and return true, otherwise
// If file is non-nullptr, copy it into *output and return true, otherwise
// return false.
bool MaybeCopy(const FileDescriptorProto* file,
FileDescriptorProto* output);
bool MaybeCopy(const FileDescriptorProto* file, FileDescriptorProto* output);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SimpleDescriptorDatabase);
};
@@ -277,10 +280,10 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
//
// The same caveats regarding FindFileContainingExtension() apply as with
// SimpleDescriptorDatabase.
class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase {
class PROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase {
public:
EncodedDescriptorDatabase();
~EncodedDescriptorDatabase();
~EncodedDescriptorDatabase() override;
// Adds the FileDescriptorProto to the database. The descriptor is provided
// in encoded form. The database does not make a copy of the bytes, nor
@@ -295,27 +298,30 @@ class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase {
bool AddCopy(const void* encoded_file_descriptor, int size);
// Like FindFileContainingSymbol but returns only the name of the file.
bool FindNameOfFileContainingSymbol(const string& symbol_name,
string* output);
bool FindNameOfFileContainingSymbol(const std::string& symbol_name,
std::string* output);
// implements DescriptorDatabase -----------------------------------
bool FindFileByName(const string& filename,
FileDescriptorProto* output);
bool FindFileContainingSymbol(const string& symbol_name,
FileDescriptorProto* output);
bool FindFileContainingExtension(const string& containing_type,
bool FindFileByName(const std::string& filename,
FileDescriptorProto* output) override;
bool FindFileContainingSymbol(const std::string& symbol_name,
FileDescriptorProto* output) override;
bool FindFileContainingExtension(const std::string& containing_type,
int field_number,
FileDescriptorProto* output);
bool FindAllExtensionNumbers(const string& extendee_type,
std::vector<int>* output);
FileDescriptorProto* output) override;
bool FindAllExtensionNumbers(const std::string& extendee_type,
std::vector<int>* output) override;
bool FindAllFileNames(std::vector<std::string>* output) override;
private:
SimpleDescriptorDatabase::DescriptorIndex<std::pair<const void*, int> >
index_;
class DescriptorIndex;
// Keep DescriptorIndex by pointer to hide the implementation to keep a
// cleaner header.
std::unique_ptr<DescriptorIndex> index_;
std::vector<void*> files_to_delete_;
// If encoded_file.first is non-NULL, parse the data into *output and return
// true, otherwise return false.
// If encoded_file.first is non-nullptr, parse the data into *output and
// return true, otherwise return false.
bool MaybeParse(std::pair<const void*, int> encoded_file,
FileDescriptorProto* output);
@@ -323,21 +329,21 @@ class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase {
};
// A DescriptorDatabase that fetches files from a given pool.
class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase {
class PROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase {
public:
explicit DescriptorPoolDatabase(const DescriptorPool& pool);
~DescriptorPoolDatabase();
~DescriptorPoolDatabase() override;
// implements DescriptorDatabase -----------------------------------
bool FindFileByName(const string& filename,
FileDescriptorProto* output);
bool FindFileContainingSymbol(const string& symbol_name,
FileDescriptorProto* output);
bool FindFileContainingExtension(const string& containing_type,
bool FindFileByName(const std::string& filename,
FileDescriptorProto* output) override;
bool FindFileContainingSymbol(const std::string& symbol_name,
FileDescriptorProto* output) override;
bool FindFileContainingExtension(const std::string& containing_type,
int field_number,
FileDescriptorProto* output);
bool FindAllExtensionNumbers(const string& extendee_type,
std::vector<int>* output);
FileDescriptorProto* output) override;
bool FindAllExtensionNumbers(const std::string& extendee_type,
std::vector<int>* output) override;
private:
const DescriptorPool& pool_;
@@ -346,7 +352,7 @@ class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase {
// A DescriptorDatabase that wraps two or more others. It first searches the
// first database and, if that fails, tries the second, and so on.
class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase {
class PROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase {
public:
// Merge just two databases. The sources remain property of the caller.
MergedDescriptorDatabase(DescriptorDatabase* source1,
@@ -356,20 +362,20 @@ class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase {
// DescriptorDatabases need to stick around.
explicit MergedDescriptorDatabase(
const std::vector<DescriptorDatabase*>& sources);
~MergedDescriptorDatabase();
~MergedDescriptorDatabase() override;
// implements DescriptorDatabase -----------------------------------
bool FindFileByName(const string& filename,
FileDescriptorProto* output);
bool FindFileContainingSymbol(const string& symbol_name,
FileDescriptorProto* output);
bool FindFileContainingExtension(const string& containing_type,
bool FindFileByName(const std::string& filename,
FileDescriptorProto* output) override;
bool FindFileContainingSymbol(const std::string& symbol_name,
FileDescriptorProto* output) override;
bool FindFileContainingExtension(const std::string& containing_type,
int field_number,
FileDescriptorProto* output);
FileDescriptorProto* output) override;
// Merges the results of calling all databases. Returns true iff any
// of the databases returned true.
bool FindAllExtensionNumbers(const string& extendee_type,
std::vector<int>* output);
bool FindAllExtensionNumbers(const std::string& extendee_type,
std::vector<int>* output) override;
private:
@@ -378,6 +384,8 @@ class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase {
};
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
-431
View File
@@ -1,431 +0,0 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/duration.proto
#include <google/protobuf/duration.pb.h>
#include <algorithm>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// This is a temporary google only hack
#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
#include "third_party/protobuf/version.h"
#endif
// @@protoc_insertion_point(includes)
namespace google {
namespace protobuf {
class DurationDefaultTypeInternal {
public:
::google::protobuf::internal::ExplicitlyConstructed<Duration>
_instance;
} _Duration_default_instance_;
} // namespace protobuf
} // namespace google
namespace protobuf_google_2fprotobuf_2fduration_2eproto {
void InitDefaultsDurationImpl() {
GOOGLE_PROTOBUF_VERIFY_VERSION;
#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
::google::protobuf::internal::InitProtobufDefaultsForceUnique();
#else
::google::protobuf::internal::InitProtobufDefaults();
#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
{
void* ptr = &::google::protobuf::_Duration_default_instance_;
new (ptr) ::google::protobuf::Duration();
::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
}
::google::protobuf::Duration::InitAsDefaultInstance();
}
void InitDefaultsDuration() {
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
::google::protobuf::GoogleOnceInit(&once, &InitDefaultsDurationImpl);
}
::google::protobuf::Metadata file_level_metadata[1];
const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
~0u, // no _has_bits_
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Duration, _internal_metadata_),
~0u, // no _extensions_
~0u, // no _oneof_case_
~0u, // no _weak_field_map_
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Duration, seconds_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Duration, nanos_),
};
static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
{ 0, -1, sizeof(::google::protobuf::Duration)},
};
static ::google::protobuf::Message const * const file_default_instances[] = {
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Duration_default_instance_),
};
void protobuf_AssignDescriptors() {
AddDescriptors();
::google::protobuf::MessageFactory* factory = NULL;
AssignDescriptors(
"google/protobuf/duration.proto", schemas, file_default_instances, TableStruct::offsets, factory,
file_level_metadata, NULL, NULL);
}
void protobuf_AssignDescriptorsOnce() {
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
}
void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
}
void AddDescriptorsImpl() {
InitDefaults();
static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
"\n\036google/protobuf/duration.proto\022\017google"
".protobuf\"*\n\010Duration\022\017\n\007seconds\030\001 \001(\003\022\r"
"\n\005nanos\030\002 \001(\005B|\n\023com.google.protobufB\rDu"
"rationProtoP\001Z*github.com/golang/protobu"
"f/ptypes/duration\370\001\001\242\002\003GPB\252\002\036Google.Prot"
"obuf.WellKnownTypesb\006proto3"
};
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
descriptor, 227);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/duration.proto", &protobuf_RegisterTypes);
}
void AddDescriptors() {
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
}
// Force AddDescriptors() to be called at dynamic initialization time.
struct StaticDescriptorInitializer {
StaticDescriptorInitializer() {
AddDescriptors();
}
} static_descriptor_initializer;
} // namespace protobuf_google_2fprotobuf_2fduration_2eproto
namespace google {
namespace protobuf {
// ===================================================================
void Duration::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Duration::kSecondsFieldNumber;
const int Duration::kNanosFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Duration::Duration()
: ::google::protobuf::Message(), _internal_metadata_(NULL) {
if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
::protobuf_google_2fprotobuf_2fduration_2eproto::InitDefaultsDuration();
}
SharedCtor();
// @@protoc_insertion_point(constructor:google.protobuf.Duration)
}
Duration::Duration(::google::protobuf::Arena* arena)
: ::google::protobuf::Message(),
_internal_metadata_(arena) {
::protobuf_google_2fprotobuf_2fduration_2eproto::InitDefaultsDuration();
SharedCtor();
RegisterArenaDtor(arena);
// @@protoc_insertion_point(arena_constructor:google.protobuf.Duration)
}
Duration::Duration(const Duration& from)
: ::google::protobuf::Message(),
_internal_metadata_(NULL),
_cached_size_(0) {
_internal_metadata_.MergeFrom(from._internal_metadata_);
::memcpy(&seconds_, &from.seconds_,
static_cast<size_t>(reinterpret_cast<char*>(&nanos_) -
reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
// @@protoc_insertion_point(copy_constructor:google.protobuf.Duration)
}
void Duration::SharedCtor() {
::memset(&seconds_, 0, static_cast<size_t>(
reinterpret_cast<char*>(&nanos_) -
reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
_cached_size_ = 0;
}
Duration::~Duration() {
// @@protoc_insertion_point(destructor:google.protobuf.Duration)
SharedDtor();
}
void Duration::SharedDtor() {
GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}
void Duration::ArenaDtor(void* object) {
Duration* _this = reinterpret_cast< Duration* >(object);
(void)_this;
}
void Duration::RegisterArenaDtor(::google::protobuf::Arena* arena) {
}
void Duration::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* Duration::descriptor() {
::protobuf_google_2fprotobuf_2fduration_2eproto::protobuf_AssignDescriptorsOnce();
return ::protobuf_google_2fprotobuf_2fduration_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}
const Duration& Duration::default_instance() {
::protobuf_google_2fprotobuf_2fduration_2eproto::InitDefaultsDuration();
return *internal_default_instance();
}
Duration* Duration::New(::google::protobuf::Arena* arena) const {
return ::google::protobuf::Arena::CreateMessage<Duration>(arena);
}
void Duration::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.Duration)
::google::protobuf::uint32 cached_has_bits = 0;
// Prevent compiler warnings about cached_has_bits being unused
(void) cached_has_bits;
::memset(&seconds_, 0, static_cast<size_t>(
reinterpret_cast<char*>(&nanos_) -
reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
_internal_metadata_.Clear();
}
bool Duration::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Duration)
for (;;) {
::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
tag = p.first;
if (!p.second) goto handle_unusual;
switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
// int64 seconds = 1;
case 1: {
if (static_cast< ::google::protobuf::uint8>(tag) ==
static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
input, &seconds_)));
} else {
goto handle_unusual;
}
break;
}
// int32 nanos = 2;
case 2: {
if (static_cast< ::google::protobuf::uint8>(tag) ==
static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
input, &nanos_)));
} else {
goto handle_unusual;
}
break;
}
default: {
handle_unusual:
if (tag == 0) {
goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, _internal_metadata_.mutable_unknown_fields()));
break;
}
}
}
success:
// @@protoc_insertion_point(parse_success:google.protobuf.Duration)
return true;
failure:
// @@protoc_insertion_point(parse_failure:google.protobuf.Duration)
return false;
#undef DO_
}
void Duration::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// @@protoc_insertion_point(serialize_start:google.protobuf.Duration)
::google::protobuf::uint32 cached_has_bits = 0;
(void) cached_has_bits;
// int64 seconds = 1;
if (this->seconds() != 0) {
::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->seconds(), output);
}
// int32 nanos = 2;
if (this->nanos() != 0) {
::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->nanos(), output);
}
if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
(::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output);
}
// @@protoc_insertion_point(serialize_end:google.protobuf.Duration)
}
::google::protobuf::uint8* Duration::InternalSerializeWithCachedSizesToArray(
bool deterministic, ::google::protobuf::uint8* target) const {
(void)deterministic; // Unused
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Duration)
::google::protobuf::uint32 cached_has_bits = 0;
(void) cached_has_bits;
// int64 seconds = 1;
if (this->seconds() != 0) {
target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->seconds(), target);
}
// int32 nanos = 2;
if (this->nanos() != 0) {
target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->nanos(), target);
}
if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
(::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target);
}
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Duration)
return target;
}
size_t Duration::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Duration)
size_t total_size = 0;
if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
(::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()));
}
// int64 seconds = 1;
if (this->seconds() != 0) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::Int64Size(
this->seconds());
}
// int32 nanos = 2;
if (this->nanos() != 0) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::Int32Size(
this->nanos());
}
int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = cached_size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
return total_size;
}
void Duration::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Duration)
GOOGLE_DCHECK_NE(&from, this);
const Duration* source =
::google::protobuf::internal::DynamicCastToGenerated<const Duration>(
&from);
if (source == NULL) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Duration)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Duration)
MergeFrom(*source);
}
}
void Duration::MergeFrom(const Duration& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Duration)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom(from._internal_metadata_);
::google::protobuf::uint32 cached_has_bits = 0;
(void) cached_has_bits;
if (from.seconds() != 0) {
set_seconds(from.seconds());
}
if (from.nanos() != 0) {
set_nanos(from.nanos());
}
}
void Duration::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Duration)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Duration::CopyFrom(const Duration& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Duration)
if (&from == this) return;
Clear();
MergeFrom(from);
}
bool Duration::IsInitialized() const {
return true;
}
void Duration::Swap(Duration* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
Duration* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == NULL) {
delete temp;
}
}
}
void Duration::UnsafeArenaSwap(Duration* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Duration::InternalSwap(Duration* other) {
using std::swap;
swap(seconds_, other->seconds_);
swap(nanos_, other->nanos_);
_internal_metadata_.Swap(&other->_internal_metadata_);
swap(_cached_size_, other->_cached_size_);
}
::google::protobuf::Metadata Duration::GetMetadata() const {
protobuf_google_2fprotobuf_2fduration_2eproto::protobuf_AssignDescriptorsOnce();
return ::protobuf_google_2fprotobuf_2fduration_2eproto::file_level_metadata[kIndexInFileMessages];
}
// @@protoc_insertion_point(namespace_scope)
} // namespace protobuf
} // namespace google
// @@protoc_insertion_point(global_scope)
-232
View File
@@ -1,232 +0,0 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/duration.proto
#ifndef PROTOBUF_google_2fprotobuf_2fduration_2eproto__INCLUDED
#define PROTOBUF_google_2fprotobuf_2fduration_2eproto__INCLUDED
#include <string>
#include <google/protobuf/stubs/common.h>
#if GOOGLE_PROTOBUF_VERSION < 3005000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/metadata.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h>
// @@protoc_insertion_point(includes)
namespace protobuf_google_2fprotobuf_2fduration_2eproto {
// Internal implementation detail -- do not use these members.
struct LIBPROTOBUF_EXPORT TableStruct {
static const ::google::protobuf::internal::ParseTableField entries[];
static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
static const ::google::protobuf::internal::ParseTable schema[1];
static const ::google::protobuf::internal::FieldMetadata field_metadata[];
static const ::google::protobuf::internal::SerializationTable serialization_table[];
static const ::google::protobuf::uint32 offsets[];
};
void LIBPROTOBUF_EXPORT AddDescriptors();
void LIBPROTOBUF_EXPORT InitDefaultsDurationImpl();
void LIBPROTOBUF_EXPORT InitDefaultsDuration();
inline void LIBPROTOBUF_EXPORT InitDefaults() {
InitDefaultsDuration();
}
} // namespace protobuf_google_2fprotobuf_2fduration_2eproto
namespace google {
namespace protobuf {
class Duration;
class DurationDefaultTypeInternal;
LIBPROTOBUF_EXPORT extern DurationDefaultTypeInternal _Duration_default_instance_;
} // namespace protobuf
} // namespace google
namespace google {
namespace protobuf {
// ===================================================================
class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Duration) */ {
public:
Duration();
virtual ~Duration();
Duration(const Duration& from);
inline Duration& operator=(const Duration& from) {
CopyFrom(from);
return *this;
}
#if LANG_CXX11
Duration(Duration&& from) noexcept
: Duration() {
*this = ::std::move(from);
}
inline Duration& operator=(Duration&& from) noexcept {
if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
if (this != &from) InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
#endif
inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL {
return GetArenaNoVirtual();
}
inline void* GetMaybeArenaPointer() const PROTOBUF_FINAL {
return MaybeArenaPtr();
}
static const ::google::protobuf::Descriptor* descriptor();
static const Duration& default_instance();
static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY
static inline const Duration* internal_default_instance() {
return reinterpret_cast<const Duration*>(
&_Duration_default_instance_);
}
static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
0;
void UnsafeArenaSwap(Duration* other);
void Swap(Duration* other);
friend void swap(Duration& a, Duration& b) {
a.Swap(&b);
}
// implements Message ----------------------------------------------
inline Duration* New() const PROTOBUF_FINAL { return New(NULL); }
Duration* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
void CopyFrom(const Duration& from);
void MergeFrom(const Duration& from);
void Clear() PROTOBUF_FINAL;
bool IsInitialized() const PROTOBUF_FINAL;
size_t ByteSizeLong() const PROTOBUF_FINAL;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const PROTOBUF_FINAL;
void InternalSwap(Duration* other);
protected:
explicit Duration(::google::protobuf::Arena* arena);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
}
inline void* MaybeArenaPtr() const {
return _internal_metadata_.raw_arena_ptr();
}
public:
::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
// int64 seconds = 1;
void clear_seconds();
static const int kSecondsFieldNumber = 1;
::google::protobuf::int64 seconds() const;
void set_seconds(::google::protobuf::int64 value);
// int32 nanos = 2;
void clear_nanos();
static const int kNanosFieldNumber = 2;
::google::protobuf::int32 nanos() const;
void set_nanos(::google::protobuf::int32 value);
// @@protoc_insertion_point(class_scope:google.protobuf.Duration)
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
typedef void InternalArenaConstructable_;
typedef void DestructorSkippable_;
::google::protobuf::int64 seconds_;
::google::protobuf::int32 nanos_;
mutable int _cached_size_;
friend struct ::protobuf_google_2fprotobuf_2fduration_2eproto::TableStruct;
friend void ::protobuf_google_2fprotobuf_2fduration_2eproto::InitDefaultsDurationImpl();
};
// ===================================================================
// ===================================================================
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif // __GNUC__
// Duration
// int64 seconds = 1;
inline void Duration::clear_seconds() {
seconds_ = GOOGLE_LONGLONG(0);
}
inline ::google::protobuf::int64 Duration::seconds() const {
// @@protoc_insertion_point(field_get:google.protobuf.Duration.seconds)
return seconds_;
}
inline void Duration::set_seconds(::google::protobuf::int64 value) {
seconds_ = value;
// @@protoc_insertion_point(field_set:google.protobuf.Duration.seconds)
}
// int32 nanos = 2;
inline void Duration::clear_nanos() {
nanos_ = 0;
}
inline ::google::protobuf::int32 Duration::nanos() const {
// @@protoc_insertion_point(field_get:google.protobuf.Duration.nanos)
return nanos_;
}
inline void Duration::set_nanos(::google::protobuf::int32 value) {
nanos_ = value;
// @@protoc_insertion_point(field_set:google.protobuf.Duration.nanos)
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif // __GNUC__
// @@protoc_insertion_point(namespace_scope)
} // namespace protobuf
} // namespace google
// @@protoc_insertion_point(global_scope)
#endif // PROTOBUF_google_2fprotobuf_2fduration_2eproto__INCLUDED
File diff suppressed because it is too large Load Diff
+42 -53
View File
@@ -40,22 +40,27 @@
#include <algorithm>
#include <memory>
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
#endif
#include <unordered_map>
#include <vector>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/message.h>
#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/reflection.h>
#include <google/protobuf/repeated_field.h>
#ifdef SWIG
#error "You cannot SWIG proto headers"
#endif
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
// Defined in other files.
class Descriptor; // descriptor.h
class DescriptorPool; // descriptor.h
class Descriptor; // descriptor.h
class DescriptorPool; // descriptor.h
// Constructs implementations of Message which can emulate types which are not
// known at compile-time.
@@ -74,7 +79,7 @@ class DescriptorPool; // descriptor.h
// encapsulates this "cache". All DynamicMessages of the same type created
// from the same factory will share the same support data. Any Descriptors
// used with a particular factory must outlive the factory.
class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory {
class PROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory {
public:
// Construct a DynamicMessageFactory that will search for extensions in
// the DescriptorPool in which the extendee is defined.
@@ -118,62 +123,44 @@ class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory {
// outlive the DynamicMessageFactory.
//
// The method is thread-safe.
const Message* GetPrototype(const Descriptor* type);
const Message* GetPrototype(const Descriptor* type) override;
private:
const DescriptorPool* pool_;
bool delegate_to_generated_factory_;
// This struct just contains a hash_map. We can't #include <google/protobuf/stubs/hash.h> from
// this header due to hacks needed for hash_map portability in the open source
// release. Namely, stubs/hash.h, which defines hash_map portably, is not a
// public header (for good reason), but dynamic_message.h is, and public
// headers may only #include other public headers.
struct PrototypeMap;
google::protobuf::scoped_ptr<PrototypeMap> prototypes_;
mutable Mutex prototypes_mutex_;
struct TypeInfo;
std::unordered_map<const Descriptor*, const TypeInfo*> prototypes_;
mutable internal::WrappedMutex prototypes_mutex_;
friend class DynamicMessage;
const Message* GetPrototypeNoLock(const Descriptor* type);
// Construct default oneof instance for reflection usage if oneof
// is defined.
static void ConstructDefaultOneofInstance(const Descriptor* type,
const uint32 offsets[],
void* default_oneof_instance);
// Delete default oneof instance. Called by ~DynamicMessageFactory.
static void DeleteDefaultOneofInstance(const Descriptor* type,
const uint32 offsets[],
const void* default_oneof_instance);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory);
};
// Helper for computing a sorted list of map entries via reflection.
class LIBPROTOBUF_EXPORT DynamicMapSorter {
class PROTOBUF_EXPORT DynamicMapSorter {
public:
static std::vector<const Message*> Sort(const Message& message,
int map_size,
static std::vector<const Message*> Sort(const Message& message, int map_size,
const Reflection* reflection,
const FieldDescriptor* field) {
std::vector<const Message*> result(static_cast<size_t>(map_size));
const RepeatedPtrField<Message>& map_field =
reflection->GetRepeatedPtrField<Message>(message, field);
size_t i = 0;
for (RepeatedPtrField<Message>::const_pointer_iterator it =
map_field.pointer_begin(); it != map_field.pointer_end(); ) {
result[i++] = *it++;
std::vector<const Message*> result;
result.reserve(map_size);
RepeatedFieldRef<Message> map_field =
reflection->GetRepeatedFieldRef<Message>(message, field);
for (auto it = map_field.begin(); it != map_field.end(); ++it) {
result.push_back(&*it);
}
GOOGLE_DCHECK_EQ(result.size(), i);
MapEntryMessageComparator comparator(field->message_type());
std::stable_sort(result.begin(), result.end(), comparator);
// Complain if the keys aren't in ascending order.
#ifndef NDEBUG
for (size_t j = 1; j < static_cast<size_t>(map_size); j++) {
if (!comparator(result[j - 1], result[j])) {
GOOGLE_LOG(ERROR) << (comparator(result[j], result[j - 1]) ?
"internal error in map key sorting" :
"map keys are not unique");
GOOGLE_LOG(ERROR) << (comparator(result[j], result[j - 1])
? "internal error in map key sorting"
: "map keys are not unique");
}
}
#endif
@@ -181,7 +168,7 @@ class LIBPROTOBUF_EXPORT DynamicMapSorter {
}
private:
class LIBPROTOBUF_EXPORT MapEntryMessageComparator {
class PROTOBUF_EXPORT MapEntryMessageComparator {
public:
explicit MapEntryMessageComparator(const Descriptor* descriptor)
: field_(descriptor->field(0)) {}
@@ -195,28 +182,28 @@ class LIBPROTOBUF_EXPORT DynamicMapSorter {
return first < second;
}
case FieldDescriptor::CPPTYPE_INT32: {
int32 first = reflection->GetInt32(*a, field_);
int32 second = reflection->GetInt32(*b, field_);
int32_t first = reflection->GetInt32(*a, field_);
int32_t second = reflection->GetInt32(*b, field_);
return first < second;
}
case FieldDescriptor::CPPTYPE_INT64: {
int64 first = reflection->GetInt64(*a, field_);
int64 second = reflection->GetInt64(*b, field_);
int64_t first = reflection->GetInt64(*a, field_);
int64_t second = reflection->GetInt64(*b, field_);
return first < second;
}
case FieldDescriptor::CPPTYPE_UINT32: {
uint32 first = reflection->GetUInt32(*a, field_);
uint32 second = reflection->GetUInt32(*b, field_);
uint32_t first = reflection->GetUInt32(*a, field_);
uint32_t second = reflection->GetUInt32(*b, field_);
return first < second;
}
case FieldDescriptor::CPPTYPE_UINT64: {
uint64 first = reflection->GetUInt64(*a, field_);
uint64 second = reflection->GetUInt64(*b, field_);
uint64_t first = reflection->GetUInt64(*a, field_);
uint64_t second = reflection->GetUInt64(*b, field_);
return first < second;
}
case FieldDescriptor::CPPTYPE_STRING: {
string first = reflection->GetString(*a, field_);
string second = reflection->GetString(*b, field_);
std::string first = reflection->GetString(*a, field_);
std::string second = reflection->GetString(*b, field_);
return first < second;
}
default:
@@ -231,6 +218,8 @@ class LIBPROTOBUF_EXPORT DynamicMapSorter {
};
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
-342
View File
@@ -1,342 +0,0 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/empty.proto
#include <google/protobuf/empty.pb.h>
#include <algorithm>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// This is a temporary google only hack
#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
#include "third_party/protobuf/version.h"
#endif
// @@protoc_insertion_point(includes)
namespace google {
namespace protobuf {
class EmptyDefaultTypeInternal {
public:
::google::protobuf::internal::ExplicitlyConstructed<Empty>
_instance;
} _Empty_default_instance_;
} // namespace protobuf
} // namespace google
namespace protobuf_google_2fprotobuf_2fempty_2eproto {
void InitDefaultsEmptyImpl() {
GOOGLE_PROTOBUF_VERIFY_VERSION;
#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
::google::protobuf::internal::InitProtobufDefaultsForceUnique();
#else
::google::protobuf::internal::InitProtobufDefaults();
#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
{
void* ptr = &::google::protobuf::_Empty_default_instance_;
new (ptr) ::google::protobuf::Empty();
::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
}
::google::protobuf::Empty::InitAsDefaultInstance();
}
void InitDefaultsEmpty() {
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
::google::protobuf::GoogleOnceInit(&once, &InitDefaultsEmptyImpl);
}
::google::protobuf::Metadata file_level_metadata[1];
const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
~0u, // no _has_bits_
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Empty, _internal_metadata_),
~0u, // no _extensions_
~0u, // no _oneof_case_
~0u, // no _weak_field_map_
};
static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
{ 0, -1, sizeof(::google::protobuf::Empty)},
};
static ::google::protobuf::Message const * const file_default_instances[] = {
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Empty_default_instance_),
};
void protobuf_AssignDescriptors() {
AddDescriptors();
::google::protobuf::MessageFactory* factory = NULL;
AssignDescriptors(
"google/protobuf/empty.proto", schemas, file_default_instances, TableStruct::offsets, factory,
file_level_metadata, NULL, NULL);
}
void protobuf_AssignDescriptorsOnce() {
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
}
void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
}
void AddDescriptorsImpl() {
InitDefaults();
static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
"\n\033google/protobuf/empty.proto\022\017google.pr"
"otobuf\"\007\n\005EmptyBv\n\023com.google.protobufB\n"
"EmptyProtoP\001Z\'github.com/golang/protobuf"
"/ptypes/empty\370\001\001\242\002\003GPB\252\002\036Google.Protobuf"
".WellKnownTypesb\006proto3"
};
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
descriptor, 183);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/empty.proto", &protobuf_RegisterTypes);
}
void AddDescriptors() {
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
}
// Force AddDescriptors() to be called at dynamic initialization time.
struct StaticDescriptorInitializer {
StaticDescriptorInitializer() {
AddDescriptors();
}
} static_descriptor_initializer;
} // namespace protobuf_google_2fprotobuf_2fempty_2eproto
namespace google {
namespace protobuf {
// ===================================================================
void Empty::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Empty::Empty()
: ::google::protobuf::Message(), _internal_metadata_(NULL) {
if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
::protobuf_google_2fprotobuf_2fempty_2eproto::InitDefaultsEmpty();
}
SharedCtor();
// @@protoc_insertion_point(constructor:google.protobuf.Empty)
}
Empty::Empty(::google::protobuf::Arena* arena)
: ::google::protobuf::Message(),
_internal_metadata_(arena) {
::protobuf_google_2fprotobuf_2fempty_2eproto::InitDefaultsEmpty();
SharedCtor();
RegisterArenaDtor(arena);
// @@protoc_insertion_point(arena_constructor:google.protobuf.Empty)
}
Empty::Empty(const Empty& from)
: ::google::protobuf::Message(),
_internal_metadata_(NULL),
_cached_size_(0) {
_internal_metadata_.MergeFrom(from._internal_metadata_);
// @@protoc_insertion_point(copy_constructor:google.protobuf.Empty)
}
void Empty::SharedCtor() {
_cached_size_ = 0;
}
Empty::~Empty() {
// @@protoc_insertion_point(destructor:google.protobuf.Empty)
SharedDtor();
}
void Empty::SharedDtor() {
GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}
void Empty::ArenaDtor(void* object) {
Empty* _this = reinterpret_cast< Empty* >(object);
(void)_this;
}
void Empty::RegisterArenaDtor(::google::protobuf::Arena* arena) {
}
void Empty::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* Empty::descriptor() {
::protobuf_google_2fprotobuf_2fempty_2eproto::protobuf_AssignDescriptorsOnce();
return ::protobuf_google_2fprotobuf_2fempty_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}
const Empty& Empty::default_instance() {
::protobuf_google_2fprotobuf_2fempty_2eproto::InitDefaultsEmpty();
return *internal_default_instance();
}
Empty* Empty::New(::google::protobuf::Arena* arena) const {
return ::google::protobuf::Arena::CreateMessage<Empty>(arena);
}
void Empty::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.Empty)
::google::protobuf::uint32 cached_has_bits = 0;
// Prevent compiler warnings about cached_has_bits being unused
(void) cached_has_bits;
_internal_metadata_.Clear();
}
bool Empty::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Empty)
for (;;) {
::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
tag = p.first;
if (!p.second) goto handle_unusual;
handle_unusual:
if (tag == 0) {
goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, _internal_metadata_.mutable_unknown_fields()));
}
success:
// @@protoc_insertion_point(parse_success:google.protobuf.Empty)
return true;
failure:
// @@protoc_insertion_point(parse_failure:google.protobuf.Empty)
return false;
#undef DO_
}
void Empty::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// @@protoc_insertion_point(serialize_start:google.protobuf.Empty)
::google::protobuf::uint32 cached_has_bits = 0;
(void) cached_has_bits;
if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
(::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output);
}
// @@protoc_insertion_point(serialize_end:google.protobuf.Empty)
}
::google::protobuf::uint8* Empty::InternalSerializeWithCachedSizesToArray(
bool deterministic, ::google::protobuf::uint8* target) const {
(void)deterministic; // Unused
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Empty)
::google::protobuf::uint32 cached_has_bits = 0;
(void) cached_has_bits;
if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
(::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target);
}
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Empty)
return target;
}
size_t Empty::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Empty)
size_t total_size = 0;
if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
(::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()));
}
int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = cached_size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
return total_size;
}
void Empty::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Empty)
GOOGLE_DCHECK_NE(&from, this);
const Empty* source =
::google::protobuf::internal::DynamicCastToGenerated<const Empty>(
&from);
if (source == NULL) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Empty)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Empty)
MergeFrom(*source);
}
}
void Empty::MergeFrom(const Empty& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Empty)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom(from._internal_metadata_);
::google::protobuf::uint32 cached_has_bits = 0;
(void) cached_has_bits;
}
void Empty::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Empty)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Empty::CopyFrom(const Empty& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Empty)
if (&from == this) return;
Clear();
MergeFrom(from);
}
bool Empty::IsInitialized() const {
return true;
}
void Empty::Swap(Empty* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
Empty* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == NULL) {
delete temp;
}
}
}
void Empty::UnsafeArenaSwap(Empty* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Empty::InternalSwap(Empty* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
swap(_cached_size_, other->_cached_size_);
}
::google::protobuf::Metadata Empty::GetMetadata() const {
protobuf_google_2fprotobuf_2fempty_2eproto::protobuf_AssignDescriptorsOnce();
return ::protobuf_google_2fprotobuf_2fempty_2eproto::file_level_metadata[kIndexInFileMessages];
}
// @@protoc_insertion_point(namespace_scope)
} // namespace protobuf
} // namespace google
// @@protoc_insertion_point(global_scope)
-190
View File
@@ -1,190 +0,0 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/empty.proto
#ifndef PROTOBUF_google_2fprotobuf_2fempty_2eproto__INCLUDED
#define PROTOBUF_google_2fprotobuf_2fempty_2eproto__INCLUDED
#include <string>
#include <google/protobuf/stubs/common.h>
#if GOOGLE_PROTOBUF_VERSION < 3005000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/metadata.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h>
// @@protoc_insertion_point(includes)
namespace protobuf_google_2fprotobuf_2fempty_2eproto {
// Internal implementation detail -- do not use these members.
struct LIBPROTOBUF_EXPORT TableStruct {
static const ::google::protobuf::internal::ParseTableField entries[];
static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
static const ::google::protobuf::internal::ParseTable schema[1];
static const ::google::protobuf::internal::FieldMetadata field_metadata[];
static const ::google::protobuf::internal::SerializationTable serialization_table[];
static const ::google::protobuf::uint32 offsets[];
};
void LIBPROTOBUF_EXPORT AddDescriptors();
void LIBPROTOBUF_EXPORT InitDefaultsEmptyImpl();
void LIBPROTOBUF_EXPORT InitDefaultsEmpty();
inline void LIBPROTOBUF_EXPORT InitDefaults() {
InitDefaultsEmpty();
}
} // namespace protobuf_google_2fprotobuf_2fempty_2eproto
namespace google {
namespace protobuf {
class Empty;
class EmptyDefaultTypeInternal;
LIBPROTOBUF_EXPORT extern EmptyDefaultTypeInternal _Empty_default_instance_;
} // namespace protobuf
} // namespace google
namespace google {
namespace protobuf {
// ===================================================================
class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Empty) */ {
public:
Empty();
virtual ~Empty();
Empty(const Empty& from);
inline Empty& operator=(const Empty& from) {
CopyFrom(from);
return *this;
}
#if LANG_CXX11
Empty(Empty&& from) noexcept
: Empty() {
*this = ::std::move(from);
}
inline Empty& operator=(Empty&& from) noexcept {
if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
if (this != &from) InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
#endif
inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL {
return GetArenaNoVirtual();
}
inline void* GetMaybeArenaPointer() const PROTOBUF_FINAL {
return MaybeArenaPtr();
}
static const ::google::protobuf::Descriptor* descriptor();
static const Empty& default_instance();
static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY
static inline const Empty* internal_default_instance() {
return reinterpret_cast<const Empty*>(
&_Empty_default_instance_);
}
static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
0;
void UnsafeArenaSwap(Empty* other);
void Swap(Empty* other);
friend void swap(Empty& a, Empty& b) {
a.Swap(&b);
}
// implements Message ----------------------------------------------
inline Empty* New() const PROTOBUF_FINAL { return New(NULL); }
Empty* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
void CopyFrom(const Empty& from);
void MergeFrom(const Empty& from);
void Clear() PROTOBUF_FINAL;
bool IsInitialized() const PROTOBUF_FINAL;
size_t ByteSizeLong() const PROTOBUF_FINAL;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const PROTOBUF_FINAL;
void InternalSwap(Empty* other);
protected:
explicit Empty(::google::protobuf::Arena* arena);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
}
inline void* MaybeArenaPtr() const {
return _internal_metadata_.raw_arena_ptr();
}
public:
::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
// @@protoc_insertion_point(class_scope:google.protobuf.Empty)
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
typedef void InternalArenaConstructable_;
typedef void DestructorSkippable_;
mutable int _cached_size_;
friend struct ::protobuf_google_2fprotobuf_2fempty_2eproto::TableStruct;
friend void ::protobuf_google_2fprotobuf_2fempty_2eproto::InitDefaultsEmptyImpl();
};
// ===================================================================
// ===================================================================
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif // __GNUC__
// Empty
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif // __GNUC__
// @@protoc_insertion_point(namespace_scope)
} // namespace protobuf
} // namespace google
// @@protoc_insertion_point(global_scope)
#endif // PROTOBUF_google_2fprotobuf_2fempty_2eproto__INCLUDED
@@ -27,49 +27,65 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_STUBS_TIME_H_
#define GOOGLE_PROTOBUF_STUBS_TIME_H_
#ifndef GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__
#define GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__
#include <stdint.h>
#include <utility>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
// clang-format off
#include <google/protobuf/port_def.inc>
// clang-format on
namespace google {
namespace protobuf {
namespace internal {
struct DateTime {
int year;
int month;
int day;
int hour;
int minute;
int second;
// Wraps a variable whose constructor and destructor are explicitly
// called. It is particularly useful for a global variable, without its
// constructor and destructor run on start and end of the program lifetime.
// This circumvents the initial construction order fiasco, while keeping
// the address of the empty string a compile time constant.
//
// Pay special attention to the initialization state of the object.
// 1. The object is "uninitialized" to begin with.
// 2. Call Construct() or DefaultConstruct() only if the object is
// uninitialized. After the call, the object becomes "initialized".
// 3. Call get() and get_mutable() only if the object is initialized.
// 4. Call Destruct() only if the object is initialized.
// After the call, the object becomes uninitialized.
template <typename T>
class ExplicitlyConstructed {
public:
void DefaultConstruct() { new (&union_) T(); }
template <typename... Args>
void Construct(Args&&... args) {
new (&union_) T(std::forward<Args>(args)...);
}
void Destruct() { get_mutable()->~T(); }
constexpr const T& get() const { return reinterpret_cast<const T&>(union_); }
T* get_mutable() { return reinterpret_cast<T*>(&union_); }
private:
union AlignedUnion {
alignas(T) char space[sizeof(T)];
int64_t align_to_int64;
void* align_to_ptr;
} union_;
};
// Converts a timestamp (seconds elapsed since 1970-01-01T00:00:00, could be
// negative to represent time before 1970-01-01) to DateTime. Returns false
// if the timestamp is not in the range between 0001-01-01T00:00:00 and
// 9999-12-31T23:59:59.
bool LIBPROTOBUF_EXPORT SecondsToDateTime(int64 seconds, DateTime* time);
// Converts DateTime to a timestamp (seconds since 1970-01-01T00:00:00).
// Returns false if the DateTime is not valid or is not in the valid range.
bool LIBPROTOBUF_EXPORT DateTimeToSeconds(const DateTime& time, int64* seconds);
void LIBPROTOBUF_EXPORT GetCurrentTime(int64* seconds, int32* nanos);
// Formats a time string in RFC3339 fromat.
//
// For example, "2015-05-20T13:29:35.120Z". For nanos, 0, 3, 6 or 9 fractional
// digits will be used depending on how many are required to represent the exact
// value.
//
// Note that "nanos" must in the range of [0, 999999999].
string LIBPROTOBUF_EXPORT FormatTime(int64 seconds, int32 nanos);
// Parses a time string. This method accepts RFC3339 date/time string with UTC
// offset. For example, "2015-05-20T13:29:35.120-08:00".
bool LIBPROTOBUF_EXPORT ParseTime(const string& value, int64* seconds, int32* nanos);
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_TIME_H_
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+194 -462
View File
@@ -35,42 +35,47 @@
// Contains methods defined in extension_set.h which cannot be part of the
// lite library because they use descriptors or reflection.
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/stubs/casts.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/extension_set_inl.h>
#include <google/protobuf/parse_context.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/message.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/unknown_field_set.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace internal {
// A FieldSkipper used to store unknown MessageSet fields into UnknownFieldSet.
class MessageSetFieldSkipper
: public UnknownFieldSetFieldSkipper {
class MessageSetFieldSkipper : public UnknownFieldSetFieldSkipper {
public:
explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields)
: UnknownFieldSetFieldSkipper(unknown_fields) {}
virtual ~MessageSetFieldSkipper() {}
~MessageSetFieldSkipper() override {}
virtual bool SkipMessageSetField(io::CodedInputStream* input,
int field_number);
};
bool MessageSetFieldSkipper::SkipMessageSetField(
io::CodedInputStream* input, int field_number) {
uint32 length;
bool MessageSetFieldSkipper::SkipMessageSetField(io::CodedInputStream* input,
int field_number) {
uint32_t length;
if (!input->ReadVarint32(&length)) return false;
if (unknown_fields_ == NULL) {
if (unknown_fields_ == nullptr) {
return input->Skip(length);
} else {
return input->ReadString(
unknown_fields_->AddLengthDelimited(field_number), length);
return input->ReadString(unknown_fields_->AddLengthDelimited(field_number),
length);
}
}
@@ -84,9 +89,9 @@ class DescriptorPoolExtensionFinder : public ExtensionFinder {
MessageFactory* factory,
const Descriptor* containing_type)
: pool_(pool), factory_(factory), containing_type_(containing_type) {}
virtual ~DescriptorPoolExtensionFinder() {}
~DescriptorPoolExtensionFinder() override {}
virtual bool Find(int number, ExtensionInfo* output);
bool Find(int number, ExtensionInfo* output) override;
private:
const DescriptorPool* pool_;
@@ -95,16 +100,14 @@ class DescriptorPoolExtensionFinder : public ExtensionFinder {
};
void ExtensionSet::AppendToList(
const Descriptor* containing_type,
const DescriptorPool* pool,
const Descriptor* containing_type, const DescriptorPool* pool,
std::vector<const FieldDescriptor*>* output) const {
for (ExtensionMap::const_iterator iter = extensions_.begin();
iter != extensions_.end(); ++iter) {
ForEach([containing_type, pool, &output](int number, const Extension& ext) {
bool has = false;
if (iter->second.is_repeated) {
has = iter->second.GetSize() > 0;
if (ext.is_repeated) {
has = ext.GetSize() > 0;
} else {
has = !iter->second.is_cleared;
has = !ext.is_cleared;
}
if (has) {
@@ -113,14 +116,13 @@ void ExtensionSet::AppendToList(
// initialized, so they might not even be constructed until
// AppendToList() is called.
if (iter->second.descriptor == NULL) {
output->push_back(pool->FindExtensionByNumber(
containing_type, iter->first));
if (ext.descriptor == nullptr) {
output->push_back(pool->FindExtensionByNumber(containing_type, number));
} else {
output->push_back(iter->second.descriptor);
output->push_back(ext.descriptor);
}
}
}
});
}
inline FieldDescriptor::Type real_type(FieldType type) {
@@ -138,26 +140,26 @@ inline WireFormatLite::FieldType field_type(FieldType type) {
return static_cast<WireFormatLite::FieldType>(type);
}
#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \
: FieldDescriptor::LABEL_OPTIONAL, \
FieldDescriptor::LABEL_##LABEL); \
#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \
: FieldDescriptor::LABEL_OPTIONAL, \
FieldDescriptor::LABEL_##LABEL); \
GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE)
const MessageLite& ExtensionSet::GetMessage(int number,
const Descriptor* message_type,
MessageFactory* factory) const {
ExtensionMap::const_iterator iter = extensions_.find(number);
if (iter == extensions_.end() || iter->second.is_cleared) {
const Extension* extension = FindOrNull(number);
if (extension == nullptr || extension->is_cleared) {
// Not present. Return the default value.
return *factory->GetPrototype(message_type);
} else {
GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
if (iter->second.is_lazy) {
return iter->second.lazymessage_value->GetMessage(
*factory->GetPrototype(message_type));
GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
if (extension->is_lazy) {
return extension->lazymessage_value->GetMessage(
*factory->GetPrototype(message_type), arena_);
} else {
return *iter->second.message_value;
return *extension->message_value;
}
}
}
@@ -181,7 +183,7 @@ MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
extension->is_cleared = false;
if (extension->is_lazy) {
return extension->lazymessage_value->MutableMessage(
*factory->GetPrototype(descriptor->message_type()));
*factory->GetPrototype(descriptor->message_type()), arena_);
} else {
return extension->message_value;
}
@@ -190,63 +192,64 @@ MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
MessageFactory* factory) {
ExtensionMap::iterator iter = extensions_.find(descriptor->number());
if (iter == extensions_.end()) {
// Not present. Return NULL.
return NULL;
Extension* extension = FindOrNull(descriptor->number());
if (extension == nullptr) {
// Not present. Return nullptr.
return nullptr;
} else {
GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
MessageLite* ret = NULL;
if (iter->second.is_lazy) {
ret = iter->second.lazymessage_value->ReleaseMessage(
*factory->GetPrototype(descriptor->message_type()));
if (arena_ == NULL) {
delete iter->second.lazymessage_value;
GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
MessageLite* ret = nullptr;
if (extension->is_lazy) {
ret = extension->lazymessage_value->ReleaseMessage(
*factory->GetPrototype(descriptor->message_type()), arena_);
if (arena_ == nullptr) {
delete extension->lazymessage_value;
}
} else {
if (arena_ != NULL) {
ret = (iter->second.message_value)->New();
ret->CheckTypeAndMergeFrom(*(iter->second.message_value));
if (arena_ != nullptr) {
ret = extension->message_value->New();
ret->CheckTypeAndMergeFrom(*extension->message_value);
} else {
ret = iter->second.message_value;
ret = extension->message_value;
}
}
extensions_.erase(descriptor->number());
Erase(descriptor->number());
return ret;
}
}
MessageLite* ExtensionSet::UnsafeArenaReleaseMessage(
const FieldDescriptor* descriptor, MessageFactory* factory) {
ExtensionMap::iterator iter = extensions_.find(descriptor->number());
if (iter == extensions_.end()) {
// Not present. Return NULL.
return NULL;
Extension* extension = FindOrNull(descriptor->number());
if (extension == nullptr) {
// Not present. Return nullptr.
return nullptr;
} else {
GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
MessageLite* ret = NULL;
if (iter->second.is_lazy) {
ret = iter->second.lazymessage_value->UnsafeArenaReleaseMessage(
*factory->GetPrototype(descriptor->message_type()));
if (arena_ == NULL) {
delete iter->second.lazymessage_value;
GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
MessageLite* ret = nullptr;
if (extension->is_lazy) {
ret = extension->lazymessage_value->UnsafeArenaReleaseMessage(
*factory->GetPrototype(descriptor->message_type()), arena_);
if (arena_ == nullptr) {
delete extension->lazymessage_value;
}
} else {
ret = iter->second.message_value;
ret = extension->message_value;
}
extensions_.erase(descriptor->number());
Erase(descriptor->number());
return ret;
}
}
ExtensionSet::Extension* ExtensionSet::MaybeNewRepeatedExtension(const FieldDescriptor* descriptor) {
ExtensionSet::Extension* ExtensionSet::MaybeNewRepeatedExtension(
const FieldDescriptor* descriptor) {
Extension* extension;
if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
extension->type = descriptor->type();
GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
extension->is_repeated = true;
extension->repeated_message_value =
::google::protobuf::Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
} else {
GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
}
@@ -259,13 +262,15 @@ MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
// RepeatedPtrField<Message> does not know how to Add() since it cannot
// allocate an abstract object, so we have to be tricky.
MessageLite* result = extension->repeated_message_value
->AddFromCleared<GenericTypeHandler<MessageLite> >();
if (result == NULL) {
MessageLite* result =
reinterpret_cast<internal::RepeatedPtrFieldBase*>(
extension->repeated_message_value)
->AddFromCleared<GenericTypeHandler<MessageLite> >();
if (result == nullptr) {
const MessageLite* prototype;
if (extension->repeated_message_value->size() == 0) {
if (extension->repeated_message_value->empty()) {
prototype = factory->GetPrototype(descriptor->message_type());
GOOGLE_CHECK(prototype != NULL);
GOOGLE_CHECK(prototype != nullptr);
} else {
prototype = &extension->repeated_message_value->Get(0);
}
@@ -282,15 +287,22 @@ void ExtensionSet::AddAllocatedMessage(const FieldDescriptor* descriptor,
extension->repeated_message_value->AddAllocated(new_entry);
}
void ExtensionSet::UnsafeArenaAddAllocatedMessage(
const FieldDescriptor* descriptor, MessageLite* new_entry) {
Extension* extension = MaybeNewRepeatedExtension(descriptor);
extension->repeated_message_value->UnsafeArenaAddAllocated(new_entry);
}
static bool ValidateEnumUsingDescriptor(const void* arg, int number) {
return reinterpret_cast<const EnumDescriptor*>(arg)
->FindValueByNumber(number) != NULL;
return reinterpret_cast<const EnumDescriptor*>(arg)->FindValueByNumber(
number) != nullptr;
}
bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
const FieldDescriptor* extension =
pool_->FindExtensionByNumber(containing_type_, number);
if (extension == NULL) {
if (extension == nullptr) {
return false;
} else {
output->type = extension->type();
@@ -298,10 +310,10 @@ bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
output->is_packed = extension->options().packed();
output->descriptor = extension;
if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
output->message_prototype =
output->message_info.prototype =
factory_->GetPrototype(extension->message_type());
GOOGLE_CHECK(output->message_prototype != NULL)
<< "Extension factory's GetPrototype() returned NULL for extension: "
GOOGLE_CHECK(output->message_info.prototype != nullptr)
<< "Extension factory's GetPrototype() returned nullptr; extension: "
<< extension->full_name();
} else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
output->enum_validity_check.func = ValidateEnumUsingDescriptor;
@@ -312,11 +324,63 @@ bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
}
}
bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
bool ExtensionSet::FindExtension(int wire_type, uint32_t field,
const Message* containing_type,
const internal::ParseContext* ctx,
ExtensionInfo* extension,
bool* was_packed_on_wire) {
if (ctx->data().pool == nullptr) {
GeneratedExtensionFinder finder(containing_type);
if (!FindExtensionInfoFromFieldNumber(wire_type, field, &finder, extension,
was_packed_on_wire)) {
return false;
}
} else {
DescriptorPoolExtensionFinder finder(ctx->data().pool, ctx->data().factory,
containing_type->GetDescriptor());
if (!FindExtensionInfoFromFieldNumber(wire_type, field, &finder, extension,
was_packed_on_wire)) {
return false;
}
}
return true;
}
const char* ExtensionSet::ParseField(uint64_t tag, const char* ptr,
const Message* containing_type,
internal::InternalMetadata* metadata,
internal::ParseContext* ctx) {
int number = tag >> 3;
bool was_packed_on_wire;
ExtensionInfo extension;
if (!FindExtension(tag & 7, number, containing_type, ctx, &extension,
&was_packed_on_wire)) {
return UnknownFieldParse(
tag, metadata->mutable_unknown_fields<UnknownFieldSet>(), ptr, ctx);
}
return ParseFieldWithExtensionInfo<UnknownFieldSet>(
number, was_packed_on_wire, extension, metadata, ptr, ctx);
}
const char* ExtensionSet::ParseFieldMaybeLazily(
uint64_t tag, const char* ptr, const Message* containing_type,
internal::InternalMetadata* metadata, internal::ParseContext* ctx) {
return ParseField(tag, ptr, containing_type, metadata, ctx);
}
const char* ExtensionSet::ParseMessageSetItem(
const char* ptr, const Message* containing_type,
internal::InternalMetadata* metadata, internal::ParseContext* ctx) {
return ParseMessageSetItemTmpl<Message, UnknownFieldSet>(ptr, containing_type,
metadata, ctx);
}
bool ExtensionSet::ParseField(uint32_t tag, io::CodedInputStream* input,
const Message* containing_type,
UnknownFieldSet* unknown_fields) {
UnknownFieldSetFieldSkipper skipper(unknown_fields);
if (input->GetExtensionPool() == NULL) {
if (input->GetExtensionPool() == nullptr) {
GeneratedExtensionFinder finder(containing_type);
return ParseField(tag, input, &finder, &skipper);
} else {
@@ -331,7 +395,7 @@ bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
const Message* containing_type,
UnknownFieldSet* unknown_fields) {
MessageSetFieldSkipper skipper(unknown_fields);
if (input->GetExtensionPool() == NULL) {
if (input->GetExtensionPool() == nullptr) {
GeneratedExtensionFinder finder(containing_type);
return ParseMessageSet(input, &finder, &skipper);
} else {
@@ -347,14 +411,10 @@ int ExtensionSet::SpaceUsedExcludingSelf() const {
}
size_t ExtensionSet::SpaceUsedExcludingSelfLong() const {
size_t total_size =
extensions_.size() * sizeof(ExtensionMap::value_type);
for (ExtensionMap::const_iterator iter = extensions_.begin(),
end = extensions_.end();
iter != end;
++iter) {
total_size += iter->second.SpaceUsedExcludingSelfLong();
}
size_t total_size = Size() * sizeof(KeyValue);
ForEach([&total_size](int /* number */, const Extension& ext) {
total_size += ext.SpaceUsedExcludingSelfLong();
});
return total_size;
}
@@ -373,15 +433,15 @@ size_t ExtensionSet::Extension::SpaceUsedExcludingSelfLong() const {
repeated_##LOWERCASE##_value->SpaceUsedExcludingSelfLong(); \
break
HANDLE_TYPE( INT32, int32);
HANDLE_TYPE( INT64, int64);
HANDLE_TYPE( UINT32, uint32);
HANDLE_TYPE( UINT64, uint64);
HANDLE_TYPE( FLOAT, float);
HANDLE_TYPE( DOUBLE, double);
HANDLE_TYPE( BOOL, bool);
HANDLE_TYPE( ENUM, enum);
HANDLE_TYPE( STRING, string);
HANDLE_TYPE(INT32, int32_t);
HANDLE_TYPE(INT64, int64_t);
HANDLE_TYPE(UINT32, uint32_t);
HANDLE_TYPE(UINT64, uint64_t);
HANDLE_TYPE(FLOAT, float);
HANDLE_TYPE(DOUBLE, double);
HANDLE_TYPE(BOOL, bool);
HANDLE_TYPE(ENUM, enum);
HANDLE_TYPE(STRING, string);
#undef HANDLE_TYPE
case FieldDescriptor::CPPTYPE_MESSAGE:
@@ -389,9 +449,10 @@ size_t ExtensionSet::Extension::SpaceUsedExcludingSelfLong() const {
// but MessageLite has no SpaceUsedLong(), so we must directly call
// RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong() with a different
// type handler.
total_size +=
sizeof(*repeated_message_value) +
RepeatedMessage_SpaceUsedExcludingSelfLong(repeated_message_value);
total_size += sizeof(*repeated_message_value) +
RepeatedMessage_SpaceUsedExcludingSelfLong(
reinterpret_cast<internal::RepeatedPtrFieldBase*>(
repeated_message_value));
break;
}
} else {
@@ -415,218 +476,29 @@ size_t ExtensionSet::Extension::SpaceUsedExcludingSelfLong() const {
return total_size;
}
// The Serialize*ToArray methods are only needed in the heavy library, as
// the lite library only generates SerializeWithCachedSizes.
uint8* ExtensionSet::SerializeWithCachedSizesToArray(int start_field_number,
int end_field_number,
uint8* target) const {
return InternalSerializeWithCachedSizesToArray(
start_field_number, end_field_number,
google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(),
target);
uint8_t* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
const MessageLite* extendee, uint8_t* target) const {
io::EpsCopyOutputStream stream(
target, MessageSetByteSize(),
io::CodedOutputStream::IsDefaultSerializationDeterministic());
return InternalSerializeMessageSetWithCachedSizesToArray(extendee, target,
&stream);
}
uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
uint8* target) const {
return InternalSerializeMessageSetWithCachedSizesToArray(
google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(),
target);
}
uint8* ExtensionSet::InternalSerializeWithCachedSizesToArray(
int start_field_number, int end_field_number,
bool deterministic, uint8* target) const {
ExtensionMap::const_iterator iter;
for (iter = extensions_.lower_bound(start_field_number);
iter != extensions_.end() && iter->first < end_field_number;
++iter) {
target = iter->second.InternalSerializeFieldWithCachedSizesToArray(
iter->first, deterministic, target);
}
return target;
}
uint8* ExtensionSet::InternalSerializeMessageSetWithCachedSizesToArray(
bool deterministic, uint8* target) const {
ExtensionMap::const_iterator iter;
for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
target = iter->second.InternalSerializeMessageSetItemWithCachedSizesToArray(
iter->first, deterministic, target);
}
return target;
}
uint8* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray(
int number, bool deterministic, uint8* target) const {
if (is_repeated) {
if (is_packed) {
if (cached_size == 0) return target;
target = WireFormatLite::WriteTagToArray(number,
WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target);
switch (real_type(type)) {
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
case FieldDescriptor::TYPE_##UPPERCASE: \
for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
target = WireFormatLite::Write##CAMELCASE##NoTagToArray( \
repeated_##LOWERCASE##_value->Get(i), target); \
} \
break
HANDLE_TYPE( INT32, Int32, int32);
HANDLE_TYPE( INT64, Int64, int64);
HANDLE_TYPE( UINT32, UInt32, uint32);
HANDLE_TYPE( UINT64, UInt64, uint64);
HANDLE_TYPE( SINT32, SInt32, int32);
HANDLE_TYPE( SINT64, SInt64, int64);
HANDLE_TYPE( FIXED32, Fixed32, uint32);
HANDLE_TYPE( FIXED64, Fixed64, uint64);
HANDLE_TYPE(SFIXED32, SFixed32, int32);
HANDLE_TYPE(SFIXED64, SFixed64, int64);
HANDLE_TYPE( FLOAT, Float, float);
HANDLE_TYPE( DOUBLE, Double, double);
HANDLE_TYPE( BOOL, Bool, bool);
HANDLE_TYPE( ENUM, Enum, enum);
#undef HANDLE_TYPE
case FieldDescriptor::TYPE_STRING:
case FieldDescriptor::TYPE_BYTES:
case FieldDescriptor::TYPE_GROUP:
case FieldDescriptor::TYPE_MESSAGE:
GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
break;
}
} else {
switch (real_type(type)) {
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
case FieldDescriptor::TYPE_##UPPERCASE: \
for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
target = WireFormatLite::Write##CAMELCASE##ToArray(number, \
repeated_##LOWERCASE##_value->Get(i), target); \
} \
break
HANDLE_TYPE( INT32, Int32, int32);
HANDLE_TYPE( INT64, Int64, int64);
HANDLE_TYPE( UINT32, UInt32, uint32);
HANDLE_TYPE( UINT64, UInt64, uint64);
HANDLE_TYPE( SINT32, SInt32, int32);
HANDLE_TYPE( SINT64, SInt64, int64);
HANDLE_TYPE( FIXED32, Fixed32, uint32);
HANDLE_TYPE( FIXED64, Fixed64, uint64);
HANDLE_TYPE(SFIXED32, SFixed32, int32);
HANDLE_TYPE(SFIXED64, SFixed64, int64);
HANDLE_TYPE( FLOAT, Float, float);
HANDLE_TYPE( DOUBLE, Double, double);
HANDLE_TYPE( BOOL, Bool, bool);
HANDLE_TYPE( STRING, String, string);
HANDLE_TYPE( BYTES, Bytes, string);
HANDLE_TYPE( ENUM, Enum, enum);
#undef HANDLE_TYPE
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
case FieldDescriptor::TYPE_##UPPERCASE: \
for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
target = WireFormatLite::InternalWrite##CAMELCASE##ToArray( \
number, repeated_##LOWERCASE##_value->Get(i), \
deterministic, target); \
} \
break
HANDLE_TYPE( GROUP, Group, message);
HANDLE_TYPE( MESSAGE, Message, message);
#undef HANDLE_TYPE
}
}
} else if (!is_cleared) {
switch (real_type(type)) {
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
case FieldDescriptor::TYPE_##UPPERCASE: \
target = WireFormatLite::Write##CAMELCASE##ToArray( \
number, VALUE, target); \
break
HANDLE_TYPE( INT32, Int32, int32_value);
HANDLE_TYPE( INT64, Int64, int64_value);
HANDLE_TYPE( UINT32, UInt32, uint32_value);
HANDLE_TYPE( UINT64, UInt64, uint64_value);
HANDLE_TYPE( SINT32, SInt32, int32_value);
HANDLE_TYPE( SINT64, SInt64, int64_value);
HANDLE_TYPE( FIXED32, Fixed32, uint32_value);
HANDLE_TYPE( FIXED64, Fixed64, uint64_value);
HANDLE_TYPE(SFIXED32, SFixed32, int32_value);
HANDLE_TYPE(SFIXED64, SFixed64, int64_value);
HANDLE_TYPE( FLOAT, Float, float_value);
HANDLE_TYPE( DOUBLE, Double, double_value);
HANDLE_TYPE( BOOL, Bool, bool_value);
HANDLE_TYPE( STRING, String, *string_value);
HANDLE_TYPE( BYTES, Bytes, *string_value);
HANDLE_TYPE( ENUM, Enum, enum_value);
HANDLE_TYPE( GROUP, Group, *message_value);
#undef HANDLE_TYPE
case FieldDescriptor::TYPE_MESSAGE:
if (is_lazy) {
target = lazymessage_value->InternalWriteMessageToArray(
number, deterministic, target);
} else {
target = WireFormatLite::InternalWriteMessageToArray(
number, *message_value, deterministic, target);
}
break;
}
}
return target;
}
uint8*
ExtensionSet::Extension::InternalSerializeMessageSetItemWithCachedSizesToArray(
int number, bool deterministic, uint8* target) const {
if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
// Not a valid MessageSet extension, but serialize it the normal way.
GOOGLE_LOG(WARNING) << "Invalid message set extension.";
return InternalSerializeFieldWithCachedSizesToArray(number, deterministic,
target);
}
if (is_cleared) return target;
// Start group.
target = io::CodedOutputStream::WriteTagToArray(
WireFormatLite::kMessageSetItemStartTag, target);
// Write type ID.
target = WireFormatLite::WriteUInt32ToArray(
WireFormatLite::kMessageSetTypeIdNumber, number, target);
// Write message.
if (is_lazy) {
target = lazymessage_value->InternalWriteMessageToArray(
WireFormatLite::kMessageSetMessageNumber, deterministic, target);
} else {
target = WireFormatLite::InternalWriteMessageToArray(
WireFormatLite::kMessageSetMessageNumber, *message_value, deterministic,
target);
}
// End group.
target = io::CodedOutputStream::WriteTagToArray(
WireFormatLite::kMessageSetItemEndTag, target);
return target;
}
bool ExtensionSet::ParseFieldMaybeLazily(
int wire_type, int field_number, io::CodedInputStream* input,
ExtensionFinder* extension_finder,
MessageSetFieldSkipper* field_skipper) {
return ParseField(WireFormatLite::MakeTag(
field_number, static_cast<WireFormatLite::WireType>(wire_type)),
input, extension_finder, field_skipper);
ExtensionFinder* extension_finder, MessageSetFieldSkipper* field_skipper) {
return ParseField(
WireFormatLite::MakeTag(field_number,
static_cast<WireFormatLite::WireType>(wire_type)),
input, extension_finder, field_skipper);
}
bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
ExtensionFinder* extension_finder,
MessageSetFieldSkipper* field_skipper) {
while (true) {
const uint32 tag = input->ReadTag();
const uint32_t tag = input->ReadTag();
switch (tag) {
case 0:
return true;
@@ -644,171 +516,31 @@ bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
}
}
bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
const MessageLite* containing_type) {
MessageSetFieldSkipper skipper(NULL);
GeneratedExtensionFinder finder(containing_type);
return ParseMessageSet(input, &finder, &skipper);
}
bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
ExtensionFinder* extension_finder,
MessageSetFieldSkipper* field_skipper) {
// TODO(kenton): It would be nice to share code between this and
// WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
// differences would be hard to factor out.
// This method parses a group which should contain two fields:
// required int32 type_id = 2;
// required data message = 3;
uint32 last_type_id = 0;
// If we see message data before the type_id, we'll append it to this so
// we can parse it later.
string message_data;
while (true) {
const uint32 tag = input->ReadTagNoLastTag();
if (tag == 0) return false;
switch (tag) {
case WireFormatLite::kMessageSetTypeIdTag: {
uint32 type_id;
if (!input->ReadVarint32(&type_id)) return false;
last_type_id = type_id;
if (!message_data.empty()) {
// We saw some message data before the type_id. Have to parse it
// now.
io::CodedInputStream sub_input(
reinterpret_cast<const uint8*>(message_data.data()),
message_data.size());
if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
last_type_id, &sub_input,
extension_finder, field_skipper)) {
return false;
}
message_data.clear();
}
break;
}
case WireFormatLite::kMessageSetMessageTag: {
if (last_type_id == 0) {
// We haven't seen a type_id yet. Append this data to message_data.
string temp;
uint32 length;
if (!input->ReadVarint32(&length)) return false;
if (!input->ReadString(&temp, length)) return false;
io::StringOutputStream output_stream(&message_data);
io::CodedOutputStream coded_output(&output_stream);
coded_output.WriteVarint32(length);
coded_output.WriteString(temp);
} else {
// Already saw type_id, so we can parse this directly.
if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
last_type_id, input,
extension_finder, field_skipper)) {
return false;
}
}
break;
}
case WireFormatLite::kMessageSetItemEndTag: {
return true;
}
default: {
if (!field_skipper->SkipField(input, tag)) return false;
}
struct MSFull {
bool ParseField(int type_id, io::CodedInputStream* input) {
return me->ParseFieldMaybeLazily(
WireFormatLite::WIRETYPE_LENGTH_DELIMITED, type_id, input,
extension_finder, field_skipper);
}
}
}
void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
int number,
io::CodedOutputStream* output) const {
if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
// Not a valid MessageSet extension, but serialize it the normal way.
SerializeFieldWithCachedSizes(number, output);
return;
}
bool SkipField(uint32_t tag, io::CodedInputStream* input) {
return field_skipper->SkipField(input, tag);
}
if (is_cleared) return;
ExtensionSet* me;
ExtensionFinder* extension_finder;
MessageSetFieldSkipper* field_skipper;
};
// Start group.
output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
// Write type ID.
WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
number,
output);
// Write message.
if (is_lazy) {
lazymessage_value->WriteMessage(
WireFormatLite::kMessageSetMessageNumber, output);
} else {
WireFormatLite::WriteMessageMaybeToArray(
WireFormatLite::kMessageSetMessageNumber,
*message_value,
output);
}
// End group.
output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
}
size_t ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
// Not a valid MessageSet extension, but compute the byte size for it the
// normal way.
return ByteSize(number);
}
if (is_cleared) return 0;
size_t our_size = WireFormatLite::kMessageSetItemTagsSize;
// type_id
our_size += io::CodedOutputStream::VarintSize32(number);
// message
size_t message_size = 0;
if (is_lazy) {
message_size = lazymessage_value->ByteSize();
} else {
message_size = message_value->ByteSize();
}
our_size += io::CodedOutputStream::VarintSize32(message_size);
our_size += message_size;
return our_size;
}
void ExtensionSet::SerializeMessageSetWithCachedSizes(
io::CodedOutputStream* output) const {
for (ExtensionMap::const_iterator iter = extensions_.begin();
iter != extensions_.end(); ++iter) {
iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
}
}
size_t ExtensionSet::MessageSetByteSize() const {
size_t total_size = 0;
for (ExtensionMap::const_iterator iter = extensions_.begin();
iter != extensions_.end(); ++iter) {
total_size += iter->second.MessageSetItemByteSize(iter->first);
}
return total_size;
return ParseMessageSetItemImpl(input,
MSFull{this, extension_finder, field_skipper});
}
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
@@ -0,0 +1,276 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__
#define GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__
#include <google/protobuf/parse_context.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/metadata_lite.h>
namespace google {
namespace protobuf {
namespace internal {
template <typename T>
const char* ExtensionSet::ParseFieldWithExtensionInfo(
int number, bool was_packed_on_wire, const ExtensionInfo& extension,
InternalMetadata* metadata, const char* ptr, internal::ParseContext* ctx) {
if (was_packed_on_wire) {
switch (extension.type) {
#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE) \
case WireFormatLite::TYPE_##UPPERCASE: \
return internal::Packed##CPP_CAMELCASE##Parser( \
MutableRawRepeatedField(number, extension.type, extension.is_packed, \
extension.descriptor), \
ptr, ctx);
HANDLE_TYPE(INT32, Int32);
HANDLE_TYPE(INT64, Int64);
HANDLE_TYPE(UINT32, UInt32);
HANDLE_TYPE(UINT64, UInt64);
HANDLE_TYPE(SINT32, SInt32);
HANDLE_TYPE(SINT64, SInt64);
HANDLE_TYPE(FIXED32, Fixed32);
HANDLE_TYPE(FIXED64, Fixed64);
HANDLE_TYPE(SFIXED32, SFixed32);
HANDLE_TYPE(SFIXED64, SFixed64);
HANDLE_TYPE(FLOAT, Float);
HANDLE_TYPE(DOUBLE, Double);
HANDLE_TYPE(BOOL, Bool);
#undef HANDLE_TYPE
case WireFormatLite::TYPE_ENUM:
return internal::PackedEnumParserArg<T>(
MutableRawRepeatedField(number, extension.type, extension.is_packed,
extension.descriptor),
ptr, ctx, extension.enum_validity_check.func,
extension.enum_validity_check.arg, metadata, number);
case WireFormatLite::TYPE_STRING:
case WireFormatLite::TYPE_BYTES:
case WireFormatLite::TYPE_GROUP:
case WireFormatLite::TYPE_MESSAGE:
GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
break;
}
} else {
switch (extension.type) {
#define HANDLE_VARINT_TYPE(UPPERCASE, CPP_CAMELCASE) \
case WireFormatLite::TYPE_##UPPERCASE: { \
uint64_t value; \
ptr = VarintParse(ptr, &value); \
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); \
if (extension.is_repeated) { \
Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
extension.is_packed, value, extension.descriptor); \
} else { \
Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
extension.descriptor); \
} \
} break
HANDLE_VARINT_TYPE(INT32, Int32);
HANDLE_VARINT_TYPE(INT64, Int64);
HANDLE_VARINT_TYPE(UINT32, UInt32);
HANDLE_VARINT_TYPE(UINT64, UInt64);
HANDLE_VARINT_TYPE(BOOL, Bool);
#undef HANDLE_VARINT_TYPE
#define HANDLE_SVARINT_TYPE(UPPERCASE, CPP_CAMELCASE, SIZE) \
case WireFormatLite::TYPE_##UPPERCASE: { \
uint64_t val; \
ptr = VarintParse(ptr, &val); \
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); \
auto value = WireFormatLite::ZigZagDecode##SIZE(val); \
if (extension.is_repeated) { \
Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
extension.is_packed, value, extension.descriptor); \
} else { \
Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
extension.descriptor); \
} \
} break
HANDLE_SVARINT_TYPE(SINT32, Int32, 32);
HANDLE_SVARINT_TYPE(SINT64, Int64, 64);
#undef HANDLE_SVARINT_TYPE
#define HANDLE_FIXED_TYPE(UPPERCASE, CPP_CAMELCASE, CPPTYPE) \
case WireFormatLite::TYPE_##UPPERCASE: { \
auto value = UnalignedLoad<CPPTYPE>(ptr); \
ptr += sizeof(CPPTYPE); \
if (extension.is_repeated) { \
Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
extension.is_packed, value, extension.descriptor); \
} else { \
Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
extension.descriptor); \
} \
} break
HANDLE_FIXED_TYPE(FIXED32, UInt32, uint32_t);
HANDLE_FIXED_TYPE(FIXED64, UInt64, uint64_t);
HANDLE_FIXED_TYPE(SFIXED32, Int32, int32_t);
HANDLE_FIXED_TYPE(SFIXED64, Int64, int64_t);
HANDLE_FIXED_TYPE(FLOAT, Float, float);
HANDLE_FIXED_TYPE(DOUBLE, Double, double);
#undef HANDLE_FIXED_TYPE
case WireFormatLite::TYPE_ENUM: {
uint64_t val;
ptr = VarintParse(ptr, &val);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
int value = val;
if (!extension.enum_validity_check.func(
extension.enum_validity_check.arg, value)) {
WriteVarint(number, val, metadata->mutable_unknown_fields<T>());
} else if (extension.is_repeated) {
AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
extension.descriptor);
} else {
SetEnum(number, WireFormatLite::TYPE_ENUM, value,
extension.descriptor);
}
break;
}
case WireFormatLite::TYPE_BYTES:
case WireFormatLite::TYPE_STRING: {
std::string* value =
extension.is_repeated
? AddString(number, WireFormatLite::TYPE_STRING,
extension.descriptor)
: MutableString(number, WireFormatLite::TYPE_STRING,
extension.descriptor);
int size = ReadSize(&ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
return ctx->ReadString(ptr, size, value);
}
case WireFormatLite::TYPE_GROUP: {
MessageLite* value =
extension.is_repeated
? AddMessage(number, WireFormatLite::TYPE_GROUP,
*extension.message_info.prototype,
extension.descriptor)
: MutableMessage(number, WireFormatLite::TYPE_GROUP,
*extension.message_info.prototype,
extension.descriptor);
uint32_t tag = (number << 3) + WireFormatLite::WIRETYPE_START_GROUP;
return ctx->ParseGroup(value, ptr, tag);
}
case WireFormatLite::TYPE_MESSAGE: {
MessageLite* value =
extension.is_repeated
? AddMessage(number, WireFormatLite::TYPE_MESSAGE,
*extension.message_info.prototype,
extension.descriptor)
: MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
*extension.message_info.prototype,
extension.descriptor);
return ctx->ParseMessage(value, ptr);
}
}
}
return ptr;
}
template <typename Msg, typename T>
const char* ExtensionSet::ParseMessageSetItemTmpl(
const char* ptr, const Msg* extendee, internal::InternalMetadata* metadata,
internal::ParseContext* ctx) {
std::string payload;
uint32_t type_id = 0;
bool payload_read = false;
while (!ctx->Done(&ptr)) {
uint32_t tag = static_cast<uint8_t>(*ptr++);
if (tag == WireFormatLite::kMessageSetTypeIdTag) {
uint64_t tmp;
ptr = ParseBigVarint(ptr, &tmp);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
type_id = tmp;
if (payload_read) {
ExtensionInfo extension;
bool was_packed_on_wire;
if (!FindExtension(2, type_id, extendee, ctx, &extension,
&was_packed_on_wire)) {
WriteLengthDelimited(type_id, payload,
metadata->mutable_unknown_fields<T>());
} else {
MessageLite* value =
extension.is_repeated
? AddMessage(type_id, WireFormatLite::TYPE_MESSAGE,
*extension.message_info.prototype,
extension.descriptor)
: MutableMessage(type_id, WireFormatLite::TYPE_MESSAGE,
*extension.message_info.prototype,
extension.descriptor);
const char* p;
// We can't use regular parse from string as we have to track
// proper recursion depth and descriptor pools.
ParseContext tmp_ctx(ctx->depth(), false, &p, payload);
tmp_ctx.data().pool = ctx->data().pool;
tmp_ctx.data().factory = ctx->data().factory;
GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) &&
tmp_ctx.EndedAtLimit());
}
type_id = 0;
}
} else if (tag == WireFormatLite::kMessageSetMessageTag) {
if (type_id != 0) {
ptr = ParseFieldMaybeLazily(static_cast<uint64_t>(type_id) * 8 + 2, ptr,
extendee, metadata, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
type_id = 0;
} else {
int32_t size = ReadSize(&ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
ptr = ctx->ReadString(ptr, size, &payload);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
payload_read = true;
}
} else {
ptr = ReadTag(ptr - 1, &tag);
if (tag == 0 || (tag & 7) == 4) {
ctx->SetLastTag(tag);
return ptr;
}
ptr = ParseField(tag, ptr, extendee, metadata, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
}
}
return ptr;
}
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__
@@ -0,0 +1,172 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_FIELD_ACCESS_LISTENER_H__
#define GOOGLE_PROTOBUF_FIELD_ACCESS_LISTENER_H__
#include <cstddef>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/message_lite.h>
namespace google {
namespace protobuf {
// A default/no-op implementation of message hooks.
//
// See go/statically-dispatched-message-hooks for details.
template <typename Proto>
struct NoOpAccessListener {
// Number of fields are provided at compile time for the trackers to be able
// to have stack allocated bitmaps for the fields. This is useful for
// performance critical trackers. This is also to avoid cyclic dependencies
// if the number of fields is needed.
static constexpr int kFields = Proto::_kInternalFieldNumber;
// Default constructor is called during the static global initialization of
// the program.
// We provide a pointer to extract the name of the proto not to get cyclic
// dependencies on GetDescriptor() and OnGetMetadata() calls. If you want
// to differentiate the protos during the runtime before the start of the
// program, use this functor to get its name. We either way need it for
// LITE_RUNTIME protos as they don't have descriptors at all.
explicit NoOpAccessListener(StringPiece (*name_extractor)()) {}
// called repeatedly during serialization/deserialization/ByteSize of
// Reflection as:
// AccessListener<MessageT>::OnSerialize(this);
static void OnSerialize(const MessageLite* msg) {}
static void OnDeserialize(const MessageLite* msg) {}
static void OnByteSize(const MessageLite* msg) {}
static void OnMergeFrom(const MessageLite* to, const MessageLite* from) {}
// NOTE: This function can be called pre-main. Make sure it does not make
// the state of the listener invalid.
static void OnGetMetadata() {}
// called from accessors as:
// AccessListener<MessageT>::On$operation(this, &field_storage_);
// If you need to override this with type, in your hook implementation
// introduce
// template <int kFieldNum, typename T>
// static void On$operation(const MessageLite* msg,
// const T* field) {}
// And overloads for std::nullptr_t for incomplete types such as Messages,
// Maps. Extract them using reflection if you need. Consequently, second
// argument can be null pointer.
// For an example, see proto_hooks/testing/memory_test_field_listener.h
// And argument template deduction will deduce the type itself without
// changing the generated code.
// add_<field>(f)
template <int kFieldNum>
static void OnAdd(const MessageLite* msg, const void* field) {}
// add_<field>()
template <int kFieldNum>
static void OnAddMutable(const MessageLite* msg, const void* field) {}
// <field>() and <repeated_field>(i)
template <int kFieldNum>
static void OnGet(const MessageLite* msg, const void* field) {}
// clear_<field>()
template <int kFieldNum>
static void OnClear(const MessageLite* msg, const void* field) {}
// has_<field>()
template <int kFieldNum>
static void OnHas(const MessageLite* msg, const void* field) {}
// <repeated_field>()
template <int kFieldNum>
static void OnList(const MessageLite* msg, const void* field) {}
// mutable_<field>()
template <int kFieldNum>
static void OnMutable(const MessageLite* msg, const void* field) {}
// mutable_<repeated_field>()
template <int kFieldNum>
static void OnMutableList(const MessageLite* msg, const void* field) {}
// release_<field>()
template <int kFieldNum>
static void OnRelease(const MessageLite* msg, const void* field) {}
// set_<field>() and set_<repeated_field>(i)
template <int kFieldNum>
static void OnSet(const MessageLite* msg, const void* field) {}
// <repeated_field>_size()
template <int kFieldNum>
static void OnSize(const MessageLite* msg, const void* field) {}
static void OnHasExtension(const MessageLite* msg, int extension_tag,
const void* field) {}
// TODO(b/190614678): Support clear in the proto compiler.
static void OnClearExtension(const MessageLite* msg, int extension_tag,
const void* field) {}
static void OnExtensionSize(const MessageLite* msg, int extension_tag,
const void* field) {}
static void OnGetExtension(const MessageLite* msg, int extension_tag,
const void* field) {}
static void OnMutableExtension(const MessageLite* msg, int extension_tag,
const void* field) {}
static void OnSetExtension(const MessageLite* msg, int extension_tag,
const void* field) {}
static void OnReleaseExtension(const MessageLite* msg, int extension_tag,
const void* field) {}
static void OnAddExtension(const MessageLite* msg, int extension_tag,
const void* field) {}
static void OnAddMutableExtension(const MessageLite* msg, int extension_tag,
const void* field) {}
static void OnListExtension(const MessageLite* msg, int extension_tag,
const void* field) {}
static void OnMutableListExtension(const MessageLite* msg, int extension_tag,
const void* field) {}
};
} // namespace protobuf
} // namespace google
#ifndef REPLACE_PROTO_LISTENER_IMPL
namespace google {
namespace protobuf {
template <class T>
using AccessListener = NoOpAccessListener<T>;
} // namespace protobuf
} // namespace google
#else
// You can put your implementations of hooks/listeners here.
// All hooks are subject to approval by protobuf-team@.
#endif // !REPLACE_PROTO_LISTENER_IMPL
#endif // GOOGLE_PROTOBUF_FIELD_ACCESS_LISTENER_H__
-373
View File
@@ -1,373 +0,0 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/field_mask.proto
#include <google/protobuf/field_mask.pb.h>
#include <algorithm>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// This is a temporary google only hack
#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
#include "third_party/protobuf/version.h"
#endif
// @@protoc_insertion_point(includes)
namespace google {
namespace protobuf {
class FieldMaskDefaultTypeInternal {
public:
::google::protobuf::internal::ExplicitlyConstructed<FieldMask>
_instance;
} _FieldMask_default_instance_;
} // namespace protobuf
} // namespace google
namespace protobuf_google_2fprotobuf_2ffield_5fmask_2eproto {
void InitDefaultsFieldMaskImpl() {
GOOGLE_PROTOBUF_VERIFY_VERSION;
#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
::google::protobuf::internal::InitProtobufDefaultsForceUnique();
#else
::google::protobuf::internal::InitProtobufDefaults();
#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
{
void* ptr = &::google::protobuf::_FieldMask_default_instance_;
new (ptr) ::google::protobuf::FieldMask();
::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
}
::google::protobuf::FieldMask::InitAsDefaultInstance();
}
void InitDefaultsFieldMask() {
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
::google::protobuf::GoogleOnceInit(&once, &InitDefaultsFieldMaskImpl);
}
::google::protobuf::Metadata file_level_metadata[1];
const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
~0u, // no _has_bits_
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldMask, _internal_metadata_),
~0u, // no _extensions_
~0u, // no _oneof_case_
~0u, // no _weak_field_map_
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldMask, paths_),
};
static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
{ 0, -1, sizeof(::google::protobuf::FieldMask)},
};
static ::google::protobuf::Message const * const file_default_instances[] = {
reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_FieldMask_default_instance_),
};
void protobuf_AssignDescriptors() {
AddDescriptors();
::google::protobuf::MessageFactory* factory = NULL;
AssignDescriptors(
"google/protobuf/field_mask.proto", schemas, file_default_instances, TableStruct::offsets, factory,
file_level_metadata, NULL, NULL);
}
void protobuf_AssignDescriptorsOnce() {
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
}
void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
}
void AddDescriptorsImpl() {
InitDefaults();
static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
"\n google/protobuf/field_mask.proto\022\017goog"
"le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB"
"\211\001\n\023com.google.protobufB\016FieldMaskProtoP"
"\001Z9google.golang.org/genproto/protobuf/f"
"ield_mask;field_mask\242\002\003GPB\252\002\036Google.Prot"
"obuf.WellKnownTypesb\006proto3"
};
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
descriptor, 227);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/field_mask.proto", &protobuf_RegisterTypes);
}
void AddDescriptors() {
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
}
// Force AddDescriptors() to be called at dynamic initialization time.
struct StaticDescriptorInitializer {
StaticDescriptorInitializer() {
AddDescriptors();
}
} static_descriptor_initializer;
} // namespace protobuf_google_2fprotobuf_2ffield_5fmask_2eproto
namespace google {
namespace protobuf {
// ===================================================================
void FieldMask::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int FieldMask::kPathsFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
FieldMask::FieldMask()
: ::google::protobuf::Message(), _internal_metadata_(NULL) {
if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
::protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::InitDefaultsFieldMask();
}
SharedCtor();
// @@protoc_insertion_point(constructor:google.protobuf.FieldMask)
}
FieldMask::FieldMask(const FieldMask& from)
: ::google::protobuf::Message(),
_internal_metadata_(NULL),
paths_(from.paths_),
_cached_size_(0) {
_internal_metadata_.MergeFrom(from._internal_metadata_);
// @@protoc_insertion_point(copy_constructor:google.protobuf.FieldMask)
}
void FieldMask::SharedCtor() {
_cached_size_ = 0;
}
FieldMask::~FieldMask() {
// @@protoc_insertion_point(destructor:google.protobuf.FieldMask)
SharedDtor();
}
void FieldMask::SharedDtor() {
}
void FieldMask::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* FieldMask::descriptor() {
::protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::protobuf_AssignDescriptorsOnce();
return ::protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}
const FieldMask& FieldMask::default_instance() {
::protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::InitDefaultsFieldMask();
return *internal_default_instance();
}
FieldMask* FieldMask::New(::google::protobuf::Arena* arena) const {
FieldMask* n = new FieldMask;
if (arena != NULL) {
arena->Own(n);
}
return n;
}
void FieldMask::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldMask)
::google::protobuf::uint32 cached_has_bits = 0;
// Prevent compiler warnings about cached_has_bits being unused
(void) cached_has_bits;
paths_.Clear();
_internal_metadata_.Clear();
}
bool FieldMask::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.FieldMask)
for (;;) {
::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
tag = p.first;
if (!p.second) goto handle_unusual;
switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
// repeated string paths = 1;
case 1: {
if (static_cast< ::google::protobuf::uint8>(tag) ==
static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->add_paths()));
DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->paths(this->paths_size() - 1).data(),
static_cast<int>(this->paths(this->paths_size() - 1).length()),
::google::protobuf::internal::WireFormatLite::PARSE,
"google.protobuf.FieldMask.paths"));
} else {
goto handle_unusual;
}
break;
}
default: {
handle_unusual:
if (tag == 0) {
goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, _internal_metadata_.mutable_unknown_fields()));
break;
}
}
}
success:
// @@protoc_insertion_point(parse_success:google.protobuf.FieldMask)
return true;
failure:
// @@protoc_insertion_point(parse_failure:google.protobuf.FieldMask)
return false;
#undef DO_
}
void FieldMask::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// @@protoc_insertion_point(serialize_start:google.protobuf.FieldMask)
::google::protobuf::uint32 cached_has_bits = 0;
(void) cached_has_bits;
// repeated string paths = 1;
for (int i = 0, n = this->paths_size(); i < n; i++) {
::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->paths(i).data(), static_cast<int>(this->paths(i).length()),
::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.FieldMask.paths");
::google::protobuf::internal::WireFormatLite::WriteString(
1, this->paths(i), output);
}
if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
(::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output);
}
// @@protoc_insertion_point(serialize_end:google.protobuf.FieldMask)
}
::google::protobuf::uint8* FieldMask::InternalSerializeWithCachedSizesToArray(
bool deterministic, ::google::protobuf::uint8* target) const {
(void)deterministic; // Unused
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldMask)
::google::protobuf::uint32 cached_has_bits = 0;
(void) cached_has_bits;
// repeated string paths = 1;
for (int i = 0, n = this->paths_size(); i < n; i++) {
::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->paths(i).data(), static_cast<int>(this->paths(i).length()),
::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.FieldMask.paths");
target = ::google::protobuf::internal::WireFormatLite::
WriteStringToArray(1, this->paths(i), target);
}
if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
(::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target);
}
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldMask)
return target;
}
size_t FieldMask::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FieldMask)
size_t total_size = 0;
if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
(::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()));
}
// repeated string paths = 1;
total_size += 1 *
::google::protobuf::internal::FromIntSize(this->paths_size());
for (int i = 0, n = this->paths_size(); i < n; i++) {
total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
this->paths(i));
}
int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = cached_size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
return total_size;
}
void FieldMask::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FieldMask)
GOOGLE_DCHECK_NE(&from, this);
const FieldMask* source =
::google::protobuf::internal::DynamicCastToGenerated<const FieldMask>(
&from);
if (source == NULL) {
// @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FieldMask)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.FieldMask)
MergeFrom(*source);
}
}
void FieldMask::MergeFrom(const FieldMask& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldMask)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom(from._internal_metadata_);
::google::protobuf::uint32 cached_has_bits = 0;
(void) cached_has_bits;
paths_.MergeFrom(from.paths_);
}
void FieldMask::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.FieldMask)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void FieldMask::CopyFrom(const FieldMask& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FieldMask)
if (&from == this) return;
Clear();
MergeFrom(from);
}
bool FieldMask::IsInitialized() const {
return true;
}
void FieldMask::Swap(FieldMask* other) {
if (other == this) return;
InternalSwap(other);
}
void FieldMask::InternalSwap(FieldMask* other) {
using std::swap;
paths_.InternalSwap(&other->paths_);
_internal_metadata_.Swap(&other->_internal_metadata_);
swap(_cached_size_, other->_cached_size_);
}
::google::protobuf::Metadata FieldMask::GetMetadata() const {
protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::protobuf_AssignDescriptorsOnce();
return ::protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::file_level_metadata[kIndexInFileMessages];
}
// @@protoc_insertion_point(namespace_scope)
} // namespace protobuf
} // namespace google
// @@protoc_insertion_point(global_scope)
+171 -114
View File
@@ -1,177 +1,228 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/field_mask.proto
#ifndef PROTOBUF_google_2fprotobuf_2ffield_5fmask_2eproto__INCLUDED
#define PROTOBUF_google_2fprotobuf_2ffield_5fmask_2eproto__INCLUDED
#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ffield_5fmask_2eproto
#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ffield_5fmask_2eproto
#include <limits>
#include <string>
#include <google/protobuf/stubs/common.h>
#if GOOGLE_PROTOBUF_VERSION < 3005000
#include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3019000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#if 3019001 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif
#include <google/protobuf/port_undef.inc>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/metadata.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h>
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ffield_5fmask_2eproto PROTOBUF_EXPORT
PROTOBUF_NAMESPACE_OPEN
namespace internal {
class AnyMetadata;
} // namespace internal
PROTOBUF_NAMESPACE_CLOSE
namespace protobuf_google_2fprotobuf_2ffield_5fmask_2eproto {
// Internal implementation detail -- do not use these members.
struct LIBPROTOBUF_EXPORT TableStruct {
static const ::google::protobuf::internal::ParseTableField entries[];
static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
static const ::google::protobuf::internal::ParseTable schema[1];
static const ::google::protobuf::internal::FieldMetadata field_metadata[];
static const ::google::protobuf::internal::SerializationTable serialization_table[];
static const ::google::protobuf::uint32 offsets[];
struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto {
static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
PROTOBUF_SECTION_VARIABLE(protodesc_cold);
static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
PROTOBUF_SECTION_VARIABLE(protodesc_cold);
static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1]
PROTOBUF_SECTION_VARIABLE(protodesc_cold);
static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
static const uint32_t offsets[];
};
void LIBPROTOBUF_EXPORT AddDescriptors();
void LIBPROTOBUF_EXPORT InitDefaultsFieldMaskImpl();
void LIBPROTOBUF_EXPORT InitDefaultsFieldMask();
inline void LIBPROTOBUF_EXPORT InitDefaults() {
InitDefaultsFieldMask();
}
} // namespace protobuf_google_2fprotobuf_2ffield_5fmask_2eproto
namespace google {
namespace protobuf {
PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto;
PROTOBUF_NAMESPACE_OPEN
class FieldMask;
class FieldMaskDefaultTypeInternal;
LIBPROTOBUF_EXPORT extern FieldMaskDefaultTypeInternal _FieldMask_default_instance_;
} // namespace protobuf
} // namespace google
namespace google {
namespace protobuf {
struct FieldMaskDefaultTypeInternal;
PROTOBUF_EXPORT extern FieldMaskDefaultTypeInternal _FieldMask_default_instance_;
PROTOBUF_NAMESPACE_CLOSE
PROTOBUF_NAMESPACE_OPEN
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::FieldMask* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FieldMask>(Arena*);
PROTOBUF_NAMESPACE_CLOSE
PROTOBUF_NAMESPACE_OPEN
// ===================================================================
class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldMask) */ {
class PROTOBUF_EXPORT FieldMask final :
public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldMask) */ {
public:
FieldMask();
virtual ~FieldMask();
inline FieldMask() : FieldMask(nullptr) {}
~FieldMask() override;
explicit constexpr FieldMask(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
FieldMask(const FieldMask& from);
inline FieldMask& operator=(const FieldMask& from) {
CopyFrom(from);
return *this;
}
#if LANG_CXX11
FieldMask(FieldMask&& from) noexcept
: FieldMask() {
*this = ::std::move(from);
}
inline FieldMask& operator=(const FieldMask& from) {
CopyFrom(from);
return *this;
}
inline FieldMask& operator=(FieldMask&& from) noexcept {
if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
if (this != &from) InternalSwap(&from);
if (this == &from) return *this;
if (GetOwningArena() == from.GetOwningArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
&& GetOwningArena() != nullptr
#endif // !PROTOBUF_FORCE_COPY_IN_MOVE
) {
InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
#endif
static const ::google::protobuf::Descriptor* descriptor();
static const FieldMask& default_instance();
static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY
static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
return GetDescriptor();
}
static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
return default_instance().GetMetadata().descriptor;
}
static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
return default_instance().GetMetadata().reflection;
}
static const FieldMask& default_instance() {
return *internal_default_instance();
}
static inline const FieldMask* internal_default_instance() {
return reinterpret_cast<const FieldMask*>(
&_FieldMask_default_instance_);
}
static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
static constexpr int kIndexInFileMessages =
0;
void Swap(FieldMask* other);
friend void swap(FieldMask& a, FieldMask& b) {
a.Swap(&b);
}
inline void Swap(FieldMask* other) {
if (other == this) return;
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
if (GetOwningArena() != nullptr &&
GetOwningArena() == other->GetOwningArena()) {
#else // PROTOBUF_FORCE_COPY_IN_SWAP
if (GetOwningArena() == other->GetOwningArena()) {
#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(FieldMask* other) {
if (other == this) return;
GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
InternalSwap(other);
}
// implements Message ----------------------------------------------
inline FieldMask* New() const PROTOBUF_FINAL { return New(NULL); }
FieldMask* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
FieldMask* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
return CreateMaybeMessage<FieldMask>(arena);
}
using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
void CopyFrom(const FieldMask& from);
using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
void MergeFrom(const FieldMask& from);
void Clear() PROTOBUF_FINAL;
bool IsInitialized() const PROTOBUF_FINAL;
private:
static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
size_t ByteSizeLong() const final;
const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
uint8_t* _InternalSerialize(
uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
int GetCachedSize() const final { return _cached_size_.Get(); }
size_t ByteSizeLong() const PROTOBUF_FINAL;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const PROTOBUF_FINAL;
void SetCachedSize(int size) const final;
void InternalSwap(FieldMask* other);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return NULL;
}
inline void* MaybeArenaPtr() const {
return NULL;
friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
return "google.protobuf.FieldMask";
}
protected:
explicit FieldMask(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned = false);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
public:
::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
static const ClassData _class_data_;
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
enum : int {
kPathsFieldNumber = 1,
};
// repeated string paths = 1;
int paths_size() const;
private:
int _internal_paths_size() const;
public:
void clear_paths();
static const int kPathsFieldNumber = 1;
const ::std::string& paths(int index) const;
::std::string* mutable_paths(int index);
void set_paths(int index, const ::std::string& value);
#if LANG_CXX11
void set_paths(int index, ::std::string&& value);
#endif
const std::string& paths(int index) const;
std::string* mutable_paths(int index);
void set_paths(int index, const std::string& value);
void set_paths(int index, std::string&& value);
void set_paths(int index, const char* value);
void set_paths(int index, const char* value, size_t size);
::std::string* add_paths();
void add_paths(const ::std::string& value);
#if LANG_CXX11
void add_paths(::std::string&& value);
#endif
std::string* add_paths();
void add_paths(const std::string& value);
void add_paths(std::string&& value);
void add_paths(const char* value);
void add_paths(const char* value, size_t size);
const ::google::protobuf::RepeatedPtrField< ::std::string>& paths() const;
::google::protobuf::RepeatedPtrField< ::std::string>* mutable_paths();
const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& paths() const;
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_paths();
private:
const std::string& _internal_paths(int index) const;
std::string* _internal_add_paths();
public:
// @@protoc_insertion_point(class_scope:google.protobuf.FieldMask)
private:
class _Internal;
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
::google::protobuf::RepeatedPtrField< ::std::string> paths_;
mutable int _cached_size_;
friend struct ::protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::TableStruct;
friend void ::protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::InitDefaultsFieldMaskImpl();
template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
typedef void InternalArenaConstructable_;
typedef void DestructorSkippable_;
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> paths_;
mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
friend struct ::TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto;
};
// ===================================================================
@@ -185,32 +236,41 @@ class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message /* @@pro
// FieldMask
// repeated string paths = 1;
inline int FieldMask::paths_size() const {
inline int FieldMask::_internal_paths_size() const {
return paths_.size();
}
inline int FieldMask::paths_size() const {
return _internal_paths_size();
}
inline void FieldMask::clear_paths() {
paths_.Clear();
}
inline const ::std::string& FieldMask::paths(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.FieldMask.paths)
inline std::string* FieldMask::add_paths() {
std::string* _s = _internal_add_paths();
// @@protoc_insertion_point(field_add_mutable:google.protobuf.FieldMask.paths)
return _s;
}
inline const std::string& FieldMask::_internal_paths(int index) const {
return paths_.Get(index);
}
inline ::std::string* FieldMask::mutable_paths(int index) {
inline const std::string& FieldMask::paths(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.FieldMask.paths)
return _internal_paths(index);
}
inline std::string* FieldMask::mutable_paths(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.FieldMask.paths)
return paths_.Mutable(index);
}
inline void FieldMask::set_paths(int index, const ::std::string& value) {
// @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths)
inline void FieldMask::set_paths(int index, const std::string& value) {
paths_.Mutable(index)->assign(value);
}
#if LANG_CXX11
inline void FieldMask::set_paths(int index, ::std::string&& value) {
// @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths)
paths_.Mutable(index)->assign(std::move(value));
}
#endif
inline void FieldMask::set_paths(int index, std::string&& value) {
paths_.Mutable(index)->assign(std::move(value));
// @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths)
}
inline void FieldMask::set_paths(int index, const char* value) {
GOOGLE_DCHECK(value != NULL);
GOOGLE_DCHECK(value != nullptr);
paths_.Mutable(index)->assign(value);
// @@protoc_insertion_point(field_set_char:google.protobuf.FieldMask.paths)
}
@@ -219,22 +279,19 @@ inline void FieldMask::set_paths(int index, const char* value, size_t size) {
reinterpret_cast<const char*>(value), size);
// @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldMask.paths)
}
inline ::std::string* FieldMask::add_paths() {
// @@protoc_insertion_point(field_add_mutable:google.protobuf.FieldMask.paths)
inline std::string* FieldMask::_internal_add_paths() {
return paths_.Add();
}
inline void FieldMask::add_paths(const ::std::string& value) {
inline void FieldMask::add_paths(const std::string& value) {
paths_.Add()->assign(value);
// @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths)
}
#if LANG_CXX11
inline void FieldMask::add_paths(::std::string&& value) {
inline void FieldMask::add_paths(std::string&& value) {
paths_.Add(std::move(value));
// @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths)
}
#endif
inline void FieldMask::add_paths(const char* value) {
GOOGLE_DCHECK(value != NULL);
GOOGLE_DCHECK(value != nullptr);
paths_.Add()->assign(value);
// @@protoc_insertion_point(field_add_char:google.protobuf.FieldMask.paths)
}
@@ -242,12 +299,12 @@ inline void FieldMask::add_paths(const char* value, size_t size) {
paths_.Add()->assign(reinterpret_cast<const char*>(value), size);
// @@protoc_insertion_point(field_add_pointer:google.protobuf.FieldMask.paths)
}
inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
FieldMask::paths() const {
// @@protoc_insertion_point(field_list:google.protobuf.FieldMask.paths)
return paths_;
}
inline ::google::protobuf::RepeatedPtrField< ::std::string>*
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
FieldMask::mutable_paths() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldMask.paths)
return &paths_;
@@ -259,9 +316,9 @@ FieldMask::mutable_paths() {
// @@protoc_insertion_point(namespace_scope)
} // namespace protobuf
} // namespace google
PROTOBUF_NAMESPACE_CLOSE
// @@protoc_insertion_point(global_scope)
#endif // PROTOBUF_google_2fprotobuf_2ffield_5fmask_2eproto__INCLUDED
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ffield_5fmask_2eproto
@@ -41,14 +41,23 @@
#include <string>
#include <google/protobuf/stubs/template_util.h>
#include <google/protobuf/generated_enum_util.h>
#include <google/protobuf/port.h>
#include <google/protobuf/stubs/strutil.h>
#ifdef SWIG
#error "You cannot SWIG proto headers"
#endif
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
class EnumDescriptor;
class EnumDescriptor;
} // namespace protobuf
} // namespace google
namespace google {
namespace protobuf {
// Returns the EnumDescriptor for enum type E, which must be a
@@ -59,16 +68,14 @@ const EnumDescriptor* GetEnumDescriptor();
namespace internal {
// Helper for EnumType_Parse functions: try to parse the string 'name' as an
// enum name of the given type, returning true and filling in value on success,
// or returning false and leaving value unchanged on failure.
LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor,
const string& name,
int* value);
// Helper for EnumType_Parse functions: try to parse the string 'name' as
// an enum name of the given type, returning true and filling in value on
// success, or returning false and leaving value unchanged on failure.
PROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor,
ConstStringParam name, int* value);
template<typename EnumType>
bool ParseNamedEnum(const EnumDescriptor* descriptor,
const string& name,
template <typename EnumType>
bool ParseNamedEnum(const EnumDescriptor* descriptor, ConstStringParam name,
EnumType* value) {
int tmp;
if (!ParseNamedEnum(descriptor, name, &tmp)) return false;
@@ -79,10 +86,13 @@ bool ParseNamedEnum(const EnumDescriptor* descriptor,
// Just a wrapper around printing the name of a value. The main point of this
// function is not to be inlined, so that you can do this without including
// descriptor.h.
LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value);
PROTOBUF_EXPORT const std::string& NameOfEnum(const EnumDescriptor* descriptor,
int value);
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
+40 -3
View File
@@ -31,16 +31,53 @@
#ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
#define GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
#include <google/protobuf/stubs/template_util.h>
#include <type_traits>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/port_def.inc>
#ifdef SWIG
#error "You cannot SWIG proto headers"
#endif
namespace google {
namespace protobuf {
// This type trait can be used to cause templates to only match proto2 enum
// types.
template <typename T> struct is_proto_enum : ::google::protobuf::internal::false_type {};
template <typename T>
struct is_proto_enum : ::std::false_type {};
namespace internal {
// The table entry format for storing enum name-to-value mapping used with lite
// protos. This struct and the following related functions should only be used
// by protobuf generated code.
struct EnumEntry {
StringPiece name;
int value;
};
// Looks up a numeric enum value given the string name.
PROTOBUF_EXPORT bool LookUpEnumValue(const EnumEntry* enums, size_t size,
StringPiece name, int* value);
// Looks up an enum name given the numeric value.
PROTOBUF_EXPORT int LookUpEnumName(const EnumEntry* enums,
const int* sorted_indices, size_t size,
int value);
// Initializes the list of enum names in std::string form.
PROTOBUF_EXPORT bool InitializeEnumStrings(
const EnumEntry* enums, const int* sorted_indices, size_t size,
internal::ExplicitlyConstructed<std::string>* enum_strings);
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
@@ -0,0 +1,87 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file contains helpers for generated code.
//
// Nothing in this file should be directly referenced by users of protobufs.
#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_BASES_H__
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_BASES_H__
#include <google/protobuf/parse_context.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/message.h>
// Must come last:
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace internal {
// To save code size, protos without any fields are derived from ZeroFieldsBase
// rather than Message.
class PROTOBUF_EXPORT ZeroFieldsBase : public Message {
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final { return true; }
size_t ByteSizeLong() const final;
int GetCachedSize() const final { return _cached_size_.Get(); }
const char* _InternalParse(const char* ptr,
internal::ParseContext* ctx) final;
::uint8_t* _InternalSerialize(::uint8_t* target,
io::EpsCopyOutputStream* stream) const final;
protected:
constexpr ZeroFieldsBase() {}
explicit ZeroFieldsBase(Arena* arena, bool is_message_owned)
: Message(arena, is_message_owned) {}
ZeroFieldsBase(const ZeroFieldsBase&) = delete;
ZeroFieldsBase& operator=(const ZeroFieldsBase&) = delete;
~ZeroFieldsBase() override;
void SetCachedSize(int size) const final { _cached_size_.Set(size); }
static void MergeImpl(Message* to, const Message& from);
static void CopyImpl(Message* to, const Message& from);
void InternalSwap(ZeroFieldsBase* other);
mutable internal::CachedSize _cached_size_;
};
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_BASES_H__
File diff suppressed because it is too large Load Diff
@@ -42,45 +42,36 @@
#include <vector>
#include <google/protobuf/stubs/casts.h>
#include <google/protobuf/stubs/common.h>
// TODO(jasonh): Remove this once the compiler change to directly include this
// is released to components.
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/message.h>
#include <google/protobuf/metadata.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/port.h>
#include <google/protobuf/unknown_field_set.h>
namespace google {
namespace upb {
namespace google_opensource {
class GMR_Handlers;
} // namespace google_opensource
} // namespace upb
#include <google/protobuf/port_def.inc>
#ifdef SWIG
#error "You cannot SWIG proto headers"
#endif
namespace google {
namespace protobuf {
class DescriptorPool;
class MapKey;
class MapValueRef;
class MessageLayoutInspector;
class Message;
struct Metadata;
} // namespace protobuf
} // namespace google
namespace protobuf {
namespace flat {
class MetadataBuilder;
} // namespace flat
} // namespace protobuf
namespace google {
namespace protobuf {
namespace internal {
class DefaultEmptyOneof;
// Defined in this file.
class GeneratedMessageReflection;
// Defined in other files.
class ExtensionSet; // extension_set.h
class WeakFieldMap; // weak_field_map.h
class ExtensionSet; // extension_set.h
class WeakFieldMap; // weak_field_map.h
// This struct describes the internal layout of the message, hence this is
// used to act on the message reflectively.
@@ -88,17 +79,17 @@ class WeakFieldMap; // weak_field_map.h
// used to obtain pointers to default instances of embedded
// messages, which GetMessage() will return if the particular
// sub-message has not been initialized yet. (Thus, all
// embedded message fields *must* have non-NULL pointers
// embedded message fields *must* have non-null pointers
// in the default instance.)
// offsets: An array of ints giving the byte offsets.
// For each oneof or weak field, the offset is relative to the
// default_instance. These can be computed at compile time
// using the
// GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET()
// PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET()
// macro. For each none oneof field, the offset is related to
// the start of the message object. These can be computed at
// compile time using the
// GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro.
// PROTO2_GENERATED_MESSAGE_FIELD_OFFSET() macro.
// Besides offsets for all fields, this array also contains
// offsets for oneof unions. The offset of the i-th oneof union
// is offsets[descriptor->field_count() + i].
@@ -116,7 +107,7 @@ class WeakFieldMap; // weak_field_map.h
// message, or -1 if the message type has no extension
// ranges.
// oneof_case_offset: Offset in the message of an array of uint32s of
// size descriptor->oneof_decl_count(). Each uint32
// size descriptor->oneof_decl_count(). Each uint32_t
// indicates what field is set for each oneof.
// object_size: The size of a message object of this type, as measured
// by sizeof().
@@ -128,62 +119,88 @@ class WeakFieldMap; // weak_field_map.h
struct ReflectionSchema {
public:
// Size of a google::protobuf::Message object of this type.
uint32 GetObjectSize() const { return static_cast<uint32>(object_size_); }
uint32_t GetObjectSize() const { return static_cast<uint32_t>(object_size_); }
bool InRealOneof(const FieldDescriptor* field) const {
return field->containing_oneof() &&
!field->containing_oneof()->is_synthetic();
}
// Offset of a non-oneof field. Getting a field offset is slightly more
// efficient when we know statically that it is not a oneof field.
uint32 GetFieldOffsetNonOneof(const FieldDescriptor* field) const {
GOOGLE_DCHECK(!field->containing_oneof());
return offsets_[field->index()];
uint32_t GetFieldOffsetNonOneof(const FieldDescriptor* field) const {
GOOGLE_DCHECK(!InRealOneof(field));
return OffsetValue(offsets_[field->index()], field->type());
}
// Offset of any field.
uint32 GetFieldOffset(const FieldDescriptor* field) const {
if (field->containing_oneof()) {
uint32_t GetFieldOffset(const FieldDescriptor* field) const {
if (InRealOneof(field)) {
size_t offset =
static_cast<size_t>(field->containing_type()->field_count() +
field->containing_oneof()->index());
return offsets_[offset];
field->containing_oneof()->index());
return OffsetValue(offsets_[offset], field->type());
} else {
return GetFieldOffsetNonOneof(field);
}
}
uint32 GetOneofCaseOffset(const OneofDescriptor* oneof_descriptor) const {
return static_cast<uint32>(oneof_case_offset_) +
static_cast<uint32>(
static_cast<size_t>(oneof_descriptor->index()) * sizeof(uint32));
bool IsFieldInlined(const FieldDescriptor* field) const {
return Inlined(offsets_[field->index()], field->type());
}
uint32_t GetOneofCaseOffset(const OneofDescriptor* oneof_descriptor) const {
return static_cast<uint32_t>(oneof_case_offset_) +
static_cast<uint32_t>(
static_cast<size_t>(oneof_descriptor->index()) *
sizeof(uint32_t));
}
bool HasHasbits() const { return has_bits_offset_ != -1; }
// Bit index within the bit array of hasbits. Bit order is low-to-high.
uint32 HasBitIndex(const FieldDescriptor* field) const {
uint32_t HasBitIndex(const FieldDescriptor* field) const {
if (has_bits_offset_ == -1) return static_cast<uint32_t>(-1);
GOOGLE_DCHECK(HasHasbits());
return has_bit_indices_[field->index()];
}
// Byte offset of the hasbits array.
uint32 HasBitsOffset() const {
uint32_t HasBitsOffset() const {
GOOGLE_DCHECK(HasHasbits());
return static_cast<uint32>(has_bits_offset_);
return static_cast<uint32_t>(has_bits_offset_);
}
bool HasInlinedString() const { return inlined_string_donated_offset_ != -1; }
// Bit index within the bit array of _inlined_string_donated_. Bit order is
// low-to-high.
uint32_t InlinedStringIndex(const FieldDescriptor* field) const {
GOOGLE_DCHECK(HasInlinedString());
return inlined_string_indices_[field->index()];
}
// Byte offset of the _inlined_string_donated_ array.
uint32_t InlinedStringDonatedOffset() const {
GOOGLE_DCHECK(HasInlinedString());
return static_cast<uint32_t>(inlined_string_donated_offset_);
}
// The offset of the InternalMetadataWithArena member.
// For Lite this will actually be an InternalMetadataWithArenaLite.
// The schema doesn't contain enough information to distinguish between
// these two cases.
uint32 GetMetadataOffset() const {
return static_cast<uint32>(metadata_offset_);
uint32_t GetMetadataOffset() const {
return static_cast<uint32_t>(metadata_offset_);
}
// Whether this message has an ExtensionSet.
bool HasExtensionSet() const { return extensions_offset_ != -1; }
// The offset of the ExtensionSet in this message.
uint32 GetExtensionSetOffset() const {
uint32_t GetExtensionSetOffset() const {
GOOGLE_DCHECK(HasExtensionSet());
return static_cast<uint32>(extensions_offset_);
return static_cast<uint32_t>(extensions_offset_);
}
// The off set of WeakFieldMap when the message contains weak fields.
@@ -196,9 +213,33 @@ struct ReflectionSchema {
// Returns a pointer to the default value for this field. The size and type
// of the underlying data depends on the field's type.
const void *GetFieldDefault(const FieldDescriptor* field) const {
return reinterpret_cast<const uint8*>(default_instance_) +
offsets_[field->index()];
const void* GetFieldDefault(const FieldDescriptor* field) const {
return reinterpret_cast<const uint8_t*>(default_instance_) +
OffsetValue(offsets_[field->index()], field->type());
}
// Returns true if the field is implicitly backed by LazyField.
bool IsEagerlyVerifiedLazyField(const FieldDescriptor* field) const {
GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_MESSAGE);
(void)field;
return false;
}
// Returns true if the field's accessor is called by any external code (aka,
// non proto library code).
bool IsFieldUsed(const FieldDescriptor* field) const {
(void)field;
return true;
}
bool IsFieldStripped(const FieldDescriptor* field) const {
(void)field;
return false;
}
bool IsMessageStripped(const Descriptor* descriptor) const {
(void)descriptor;
return false;
}
@@ -209,16 +250,39 @@ struct ReflectionSchema {
// them, ie.
//
// ReflectionSchema schema = {a, b, c, d, e, ...};
// private:
// private:
const Message* default_instance_;
const uint32* offsets_;
const uint32* has_bit_indices_;
const uint32_t* offsets_;
const uint32_t* has_bit_indices_;
int has_bits_offset_;
int metadata_offset_;
int extensions_offset_;
int oneof_case_offset_;
int object_size_;
int weak_field_map_offset_;
const uint32_t* inlined_string_indices_;
int inlined_string_donated_offset_;
// We tag offset values to provide additional data about fields (such as
// "unused" or "lazy" or "inlined").
static uint32_t OffsetValue(uint32_t v, FieldDescriptor::Type type) {
if (type == FieldDescriptor::TYPE_MESSAGE ||
type == FieldDescriptor::TYPE_STRING ||
type == FieldDescriptor::TYPE_BYTES) {
return v & 0x7FFFFFFEu;
}
return v & 0x7FFFFFFFu;
}
static bool Inlined(uint32_t v, FieldDescriptor::Type type) {
if (type == FieldDescriptor::TYPE_STRING ||
type == FieldDescriptor::TYPE_BYTES) {
return (v & 1u) != 0u;
} else {
// Non string/byte fields are not inlined.
return false;
}
}
};
// Structs that the code generator emits directly to describe a message.
@@ -228,501 +292,71 @@ struct ReflectionSchema {
// EXPERIMENTAL: these are changing rapidly, and may completely disappear
// or merge with ReflectionSchema.
struct MigrationSchema {
int32 offsets_index;
int32 has_bit_indices_index;
int32_t offsets_index;
int32_t has_bit_indices_index;
int32_t inlined_string_indices_index;
int object_size;
};
// THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use
// by generated code. This class is just a big hack that reduces code
// size.
//
// A GeneratedMessageReflection is an implementation of Reflection
// which expects all fields to be backed by simple variables located in
// memory. The locations are given using a base pointer and a set of
// offsets.
//
// It is required that the user represents fields of each type in a standard
// way, so that GeneratedMessageReflection can cast the void* pointer to
// the appropriate type. For primitive fields and string fields, each field
// should be represented using the obvious C++ primitive type. Enums and
// Messages are different:
// - Singular Message fields are stored as a pointer to a Message. These
// should start out NULL, except for in the default instance where they
// should start out pointing to other default instances.
// - Enum fields are stored as an int. This int must always contain
// a valid value, such that EnumDescriptor::FindValueByNumber() would
// not return NULL.
// - Repeated fields are stored as RepeatedFields or RepeatedPtrFields
// of whatever type the individual field would be. Strings and
// Messages use RepeatedPtrFields while everything else uses
// RepeatedFields.
class LIBPROTOBUF_EXPORT GeneratedMessageReflection PROTOBUF_FINAL : public Reflection {
public:
// Constructs a GeneratedMessageReflection.
// Parameters:
// descriptor: The descriptor for the message type being implemented.
// schema: The description of the internal guts of the message.
// pool: DescriptorPool to search for extension definitions. Only
// used by FindKnownExtensionByName() and
// FindKnownExtensionByNumber().
// factory: MessageFactory to use to construct extension messages.
GeneratedMessageReflection(const Descriptor* descriptor,
const ReflectionSchema& schema,
const DescriptorPool* pool,
MessageFactory* factory);
~GeneratedMessageReflection();
// implements Reflection -------------------------------------------
const UnknownFieldSet& GetUnknownFields(const Message& message) const;
UnknownFieldSet* MutableUnknownFields(Message* message) const;
size_t SpaceUsedLong(const Message& message) const;
bool HasField(const Message& message, const FieldDescriptor* field) const;
int FieldSize(const Message& message, const FieldDescriptor* field) const;
void ClearField(Message* message, const FieldDescriptor* field) const;
bool HasOneof(const Message& message,
const OneofDescriptor* oneof_descriptor) const;
void ClearOneof(Message* message, const OneofDescriptor* field) const;
void RemoveLast(Message* message, const FieldDescriptor* field) const;
Message* ReleaseLast(Message* message, const FieldDescriptor* field) const;
void Swap(Message* message1, Message* message2) const;
void SwapFields(Message* message1, Message* message2,
const std::vector<const FieldDescriptor*>& fields) const;
void SwapElements(Message* message, const FieldDescriptor* field,
int index1, int index2) const;
void ListFields(const Message& message,
std::vector<const FieldDescriptor*>* output) const;
int32 GetInt32 (const Message& message,
const FieldDescriptor* field) const;
int64 GetInt64 (const Message& message,
const FieldDescriptor* field) const;
uint32 GetUInt32(const Message& message,
const FieldDescriptor* field) const;
uint64 GetUInt64(const Message& message,
const FieldDescriptor* field) const;
float GetFloat (const Message& message,
const FieldDescriptor* field) const;
double GetDouble(const Message& message,
const FieldDescriptor* field) const;
bool GetBool (const Message& message,
const FieldDescriptor* field) const;
string GetString(const Message& message,
const FieldDescriptor* field) const;
const string& GetStringReference(const Message& message,
const FieldDescriptor* field,
string* scratch) const;
const EnumValueDescriptor* GetEnum(const Message& message,
const FieldDescriptor* field) const;
int GetEnumValue(const Message& message,
const FieldDescriptor* field) const;
const Message& GetMessage(const Message& message,
const FieldDescriptor* field,
MessageFactory* factory = NULL) const;
const FieldDescriptor* GetOneofFieldDescriptor(
const Message& message,
const OneofDescriptor* oneof_descriptor) const;
private:
bool ContainsMapKey(const Message& message,
const FieldDescriptor* field,
const MapKey& key) const;
bool InsertOrLookupMapValue(Message* message,
const FieldDescriptor* field,
const MapKey& key,
MapValueRef* val) const;
bool DeleteMapValue(Message* message,
const FieldDescriptor* field,
const MapKey& key) const;
MapIterator MapBegin(
Message* message,
const FieldDescriptor* field) const;
MapIterator MapEnd(
Message* message,
const FieldDescriptor* field) const;
int MapSize(const Message& message, const FieldDescriptor* field) const;
public:
void SetInt32 (Message* message,
const FieldDescriptor* field, int32 value) const;
void SetInt64 (Message* message,
const FieldDescriptor* field, int64 value) const;
void SetUInt32(Message* message,
const FieldDescriptor* field, uint32 value) const;
void SetUInt64(Message* message,
const FieldDescriptor* field, uint64 value) const;
void SetFloat (Message* message,
const FieldDescriptor* field, float value) const;
void SetDouble(Message* message,
const FieldDescriptor* field, double value) const;
void SetBool (Message* message,
const FieldDescriptor* field, bool value) const;
void SetString(Message* message,
const FieldDescriptor* field,
const string& value) const;
void SetEnum (Message* message, const FieldDescriptor* field,
const EnumValueDescriptor* value) const;
void SetEnumValue(Message* message, const FieldDescriptor* field,
int value) const;
Message* MutableMessage(Message* message, const FieldDescriptor* field,
MessageFactory* factory = NULL) const;
void SetAllocatedMessage(Message* message,
Message* sub_message,
const FieldDescriptor* field) const;
Message* ReleaseMessage(Message* message, const FieldDescriptor* field,
MessageFactory* factory = NULL) const;
int32 GetRepeatedInt32 (const Message& message,
const FieldDescriptor* field, int index) const;
int64 GetRepeatedInt64 (const Message& message,
const FieldDescriptor* field, int index) const;
uint32 GetRepeatedUInt32(const Message& message,
const FieldDescriptor* field, int index) const;
uint64 GetRepeatedUInt64(const Message& message,
const FieldDescriptor* field, int index) const;
float GetRepeatedFloat (const Message& message,
const FieldDescriptor* field, int index) const;
double GetRepeatedDouble(const Message& message,
const FieldDescriptor* field, int index) const;
bool GetRepeatedBool (const Message& message,
const FieldDescriptor* field, int index) const;
string GetRepeatedString(const Message& message,
const FieldDescriptor* field, int index) const;
const string& GetRepeatedStringReference(const Message& message,
const FieldDescriptor* field,
int index, string* scratch) const;
const EnumValueDescriptor* GetRepeatedEnum(const Message& message,
const FieldDescriptor* field,
int index) const;
int GetRepeatedEnumValue(const Message& message,
const FieldDescriptor* field,
int index) const;
const Message& GetRepeatedMessage(const Message& message,
const FieldDescriptor* field,
int index) const;
// Set the value of a field.
void SetRepeatedInt32 (Message* message,
const FieldDescriptor* field, int index, int32 value) const;
void SetRepeatedInt64 (Message* message,
const FieldDescriptor* field, int index, int64 value) const;
void SetRepeatedUInt32(Message* message,
const FieldDescriptor* field, int index, uint32 value) const;
void SetRepeatedUInt64(Message* message,
const FieldDescriptor* field, int index, uint64 value) const;
void SetRepeatedFloat (Message* message,
const FieldDescriptor* field, int index, float value) const;
void SetRepeatedDouble(Message* message,
const FieldDescriptor* field, int index, double value) const;
void SetRepeatedBool (Message* message,
const FieldDescriptor* field, int index, bool value) const;
void SetRepeatedString(Message* message,
const FieldDescriptor* field, int index,
const string& value) const;
void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
int index, const EnumValueDescriptor* value) const;
void SetRepeatedEnumValue(Message* message, const FieldDescriptor* field,
int index, int value) const;
// Get a mutable pointer to a field with a message type.
Message* MutableRepeatedMessage(Message* message,
const FieldDescriptor* field,
int index) const;
void AddInt32 (Message* message,
const FieldDescriptor* field, int32 value) const;
void AddInt64 (Message* message,
const FieldDescriptor* field, int64 value) const;
void AddUInt32(Message* message,
const FieldDescriptor* field, uint32 value) const;
void AddUInt64(Message* message,
const FieldDescriptor* field, uint64 value) const;
void AddFloat (Message* message,
const FieldDescriptor* field, float value) const;
void AddDouble(Message* message,
const FieldDescriptor* field, double value) const;
void AddBool (Message* message,
const FieldDescriptor* field, bool value) const;
void AddString(Message* message,
const FieldDescriptor* field, const string& value) const;
void AddEnum(Message* message,
const FieldDescriptor* field,
const EnumValueDescriptor* value) const;
void AddEnumValue(Message* message,
const FieldDescriptor* field,
int value) const;
Message* AddMessage(Message* message, const FieldDescriptor* field,
MessageFactory* factory = NULL) const;
void AddAllocatedMessage(
Message* message, const FieldDescriptor* field,
Message* new_entry) const;
const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
bool SupportsUnknownEnumValues() const;
// This value for arena_offset_ indicates that there is no arena pointer in
// this message (e.g., old generated code).
static const int kNoArenaPointer = -1;
// This value for unknown_field_offset_ indicates that there is no
// UnknownFieldSet in this message, and that instead, we are using the
// Zero-Overhead Arena Pointer trick. When this is the case, arena_offset_
// actually indexes to an InternalMetadataWithArena instance, which can return
// either an arena pointer or an UnknownFieldSet or both. It is never the case
// that unknown_field_offset_ == kUnknownFieldSetInMetadata && arena_offset_
// == kNoArenaPointer.
static const int kUnknownFieldSetInMetadata = -1;
protected:
void* MutableRawRepeatedField(
Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
int ctype, const Descriptor* desc) const;
const void* GetRawRepeatedField(
const Message& message, const FieldDescriptor* field,
FieldDescriptor::CppType, int ctype,
const Descriptor* desc) const;
virtual MessageFactory* GetMessageFactory() const;
virtual void* RepeatedFieldData(
Message* message, const FieldDescriptor* field,
FieldDescriptor::CppType cpp_type,
const Descriptor* message_type) const;
private:
friend class google::protobuf::flat::MetadataBuilder;
friend class upb::google_opensource::GMR_Handlers;
const Descriptor* const descriptor_;
const ReflectionSchema schema_;
const DescriptorPool* const descriptor_pool_;
MessageFactory* const message_factory_;
// Last non weak field index. This is an optimization when most weak fields
// are at the end of the containing message. If a message proto doesn't
// contain weak fields, then this field equals descriptor_->field_count().
int last_non_weak_field_index_;
template <class T>
const T& GetRawNonOneof(const Message& message,
const FieldDescriptor* field) const;
template <class T>
T* MutableRawNonOneof(Message* message, const FieldDescriptor* field) const;
template <typename Type>
const Type& GetRaw(const Message& message,
const FieldDescriptor* field) const;
template <typename Type>
inline Type* MutableRaw(Message* message,
const FieldDescriptor* field) const;
template <typename Type>
inline const Type& DefaultRaw(const FieldDescriptor* field) const;
inline const uint32* GetHasBits(const Message& message) const;
inline uint32* MutableHasBits(Message* message) const;
inline uint32 GetOneofCase(
const Message& message,
const OneofDescriptor* oneof_descriptor) const;
inline uint32* MutableOneofCase(
Message* message,
const OneofDescriptor* oneof_descriptor) const;
inline const ExtensionSet& GetExtensionSet(const Message& message) const;
inline ExtensionSet* MutableExtensionSet(Message* message) const;
inline Arena* GetArena(Message* message) const;
inline const InternalMetadataWithArena& GetInternalMetadataWithArena(
const Message& message) const;
inline InternalMetadataWithArena*
MutableInternalMetadataWithArena(Message* message) const;
inline bool HasBit(const Message& message,
const FieldDescriptor* field) const;
inline void SetBit(Message* message,
const FieldDescriptor* field) const;
inline void ClearBit(Message* message,
const FieldDescriptor* field) const;
inline void SwapBit(Message* message1,
Message* message2,
const FieldDescriptor* field) const;
// This function only swaps the field. Should swap corresponding has_bit
// before or after using this function.
void SwapField(Message* message1,
Message* message2,
const FieldDescriptor* field) const;
void SwapOneofField(Message* message1,
Message* message2,
const OneofDescriptor* oneof_descriptor) const;
inline bool HasOneofField(const Message& message,
const FieldDescriptor* field) const;
inline void SetOneofCase(Message* message,
const FieldDescriptor* field) const;
inline void ClearOneofField(Message* message,
const FieldDescriptor* field) const;
template <typename Type>
inline const Type& GetField(const Message& message,
const FieldDescriptor* field) const;
template <typename Type>
inline void SetField(Message* message,
const FieldDescriptor* field, const Type& value) const;
template <typename Type>
inline Type* MutableField(Message* message,
const FieldDescriptor* field) const;
template <typename Type>
inline const Type& GetRepeatedField(const Message& message,
const FieldDescriptor* field,
int index) const;
template <typename Type>
inline const Type& GetRepeatedPtrField(const Message& message,
const FieldDescriptor* field,
int index) const;
template <typename Type>
inline void SetRepeatedField(Message* message,
const FieldDescriptor* field, int index,
Type value) const;
template <typename Type>
inline Type* MutableRepeatedField(Message* message,
const FieldDescriptor* field,
int index) const;
template <typename Type>
inline void AddField(Message* message,
const FieldDescriptor* field, const Type& value) const;
template <typename Type>
inline Type* AddField(Message* message,
const FieldDescriptor* field) const;
int GetExtensionNumberOrDie(const Descriptor* type) const;
// Internal versions of EnumValue API perform no checking. Called after checks
// by public methods.
void SetEnumValueInternal(Message* message,
const FieldDescriptor* field,
int value) const;
void SetRepeatedEnumValueInternal(Message* message,
const FieldDescriptor* field,
int index,
int value) const;
void AddEnumValueInternal(Message* message,
const FieldDescriptor* field,
int value) const;
Message* UnsafeArenaReleaseMessage(Message* message,
const FieldDescriptor* field,
MessageFactory* factory = NULL) const;
void UnsafeArenaSetAllocatedMessage(Message* message,
Message* sub_message,
const FieldDescriptor* field) const;
internal::MapFieldBase* MapData(
Message* message, const FieldDescriptor* field) const;
friend inline // inline so nobody can call this function.
void
RegisterAllTypesInternal(const Metadata* file_level_metadata, int size);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection);
// This struct tries to reduce unnecessary padding.
// The num_xxx might not be close to their respective pointer, but this saves
// padding.
struct PROTOBUF_EXPORT DescriptorTable {
mutable bool is_initialized;
bool is_eager;
int size; // of serialized descriptor
const char* descriptor;
const char* filename;
once_flag* once;
const DescriptorTable* const* deps;
int num_deps;
int num_messages;
const MigrationSchema* schemas;
const Message* const* default_instances;
const uint32_t* offsets;
// update the following descriptor arrays.
Metadata* file_level_metadata;
const EnumDescriptor** file_level_enum_descriptors;
const ServiceDescriptor** file_level_service_descriptors;
};
// There are some places in proto2 where dynamic_cast would be useful as an
// optimization. For example, take Message::MergeFrom(const Message& other).
// For a given generated message FooMessage, we generate these two methods:
// void MergeFrom(const FooMessage& other);
// void MergeFrom(const Message& other);
// The former method can be implemented directly in terms of FooMessage's
// inline accessors, but the latter method must work with the reflection
// interface. However, if the parameter to the latter method is actually of
// type FooMessage, then we'd like to be able to just call the other method
// as an optimization. So, we use dynamic_cast to check this.
//
// That said, dynamic_cast requires RTTI, which many people like to disable
// for performance and code size reasons. When RTTI is not available, we
// still need to produce correct results. So, in this case we have to fall
// back to using reflection, which is what we would have done anyway if the
// objects were not of the exact same class.
//
// dynamic_cast_if_available() implements this logic. If RTTI is
// enabled, it does a dynamic_cast. If RTTI is disabled, it just returns
// NULL.
//
// If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI.
// On MSVC, this should be detected automatically.
template<typename To, typename From>
inline To dynamic_cast_if_available(From from) {
#if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI))
// Avoid the compiler warning about unused variables.
(void)from;
return NULL;
#else
return dynamic_cast<To>(from);
#endif
}
enum {
// Tag used on offsets for fields that don't have a real offset.
// For example, weak message fields go into the WeakFieldMap and not in an
// actual field.
kInvalidFieldOffsetTag = 0x40000000u,
};
// Tries to downcast this message to a generated message type.
// Returns NULL if this class is not an instance of T.
//
// This is like dynamic_cast_if_available, except it works even when
// dynamic_cast is not available by using Reflection. However it only works
// with Message objects.
//
// TODO(haberman): can we remove dynamic_cast_if_available in favor of this?
template <typename T>
T* DynamicCastToGenerated(const Message* from) {
// Compile-time assert that T is a generated type that has a
// default_instance() accessor, but avoid actually calling it.
const T&(*get_default_instance)() = &T::default_instance;
(void)get_default_instance;
// AssignDescriptors() pulls the compiled FileDescriptor from the DescriptorPool
// and uses it to populate all of the global variables which store pointers to
// the descriptor objects. It also constructs the reflection objects. It is
// called the first time anyone calls descriptor() or GetReflection() on one of
// the types defined in the file. AssignDescriptors() is thread-safe.
void PROTOBUF_EXPORT AssignDescriptors(const DescriptorTable* table,
bool eager = false);
// Compile-time assert that T is a subclass of google::protobuf::Message.
const Message* unused = static_cast<T*>(NULL);
(void)unused;
#if defined(GOOGLE_PROTOBUF_NO_RTTI) || \
(defined(_MSC_VER) && !defined(_CPPRTTI))
bool ok = &T::default_instance() ==
from->GetReflection()->GetMessageFactory()->GetPrototype(
from->GetDescriptor());
return ok ? down_cast<T*>(from) : NULL;
#else
return dynamic_cast<T*>(from);
#endif
}
template <typename T>
T* DynamicCastToGenerated(Message* from) {
const Message* message_const = from;
return const_cast<T*>(DynamicCastToGenerated<const T>(message_const));
}
LIBPROTOBUF_EXPORT void AssignDescriptors(
const string& filename, const MigrationSchema* schemas,
const Message* const* default_instances_, const uint32* offsets,
MessageFactory* factory,
// update the following descriptor arrays.
Metadata* file_level_metadata,
const EnumDescriptor** file_level_enum_descriptors,
const ServiceDescriptor** file_level_service_descriptors);
LIBPROTOBUF_EXPORT void RegisterAllTypes(const Metadata* file_level_metadata, int size);
// Overload used to implement GetMetadataStatic in the generated code.
// See comments in compiler/cpp/internal/file.cc as to why.
// It takes a `Metadata` and returns it to allow for tail calls and reduce
// binary size.
Metadata PROTOBUF_EXPORT AssignDescriptors(const DescriptorTable* (*table)(),
internal::once_flag* once,
const Metadata& metadata);
// These cannot be in lite so we put them in the reflection.
LIBPROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag,
uint32 has_offset,
::google::protobuf::io::CodedOutputStream* output);
PROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8_t* base,
uint32_t offset, uint32_t tag,
uint32_t has_offset,
io::CodedOutputStream* output);
struct PROTOBUF_EXPORT AddDescriptorsRunner {
explicit AddDescriptorsRunner(const DescriptorTable* table);
};
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
@@ -1,103 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/stubs/type_traits.h>
#include <google/protobuf/generated_message_table_driven_lite.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/metadata.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/wire_format_lite_inl.h>
namespace google {
namespace protobuf {
namespace internal {
namespace {
UnknownFieldSet* MutableUnknownFields(MessageLite* msg, int64 arena_offset) {
return Raw<InternalMetadataWithArena>(msg, arena_offset)
->mutable_unknown_fields();
}
struct UnknownFieldHandler {
static bool Skip(MessageLite* msg, const ParseTable& table,
io::CodedInputStream* input,
int tag) {
GOOGLE_DCHECK(table.unknown_field_set);
return WireFormat::SkipField(input, tag,
MutableUnknownFields(msg, table.arena_offset));
}
static void Varint(MessageLite* msg, const ParseTable& table,
int tag, int value) {
GOOGLE_DCHECK(table.unknown_field_set);
MutableUnknownFields(msg, table.arena_offset)->AddVarint(
WireFormatLite::GetTagFieldNumber(tag), value);
}
static bool ParseExtension(
MessageLite* msg, const ParseTable& table,
io::CodedInputStream* input, int tag) {
ExtensionSet* extensions = GetExtensionSet(msg, table.extension_offset);
if (extensions == NULL) {
return false;
}
const Message* prototype = down_cast<const Message*>(
table.default_instance());
GOOGLE_DCHECK(prototype != NULL);
GOOGLE_DCHECK(table.unknown_field_set);
UnknownFieldSet* unknown_fields =
MutableUnknownFields(msg, table.arena_offset);
return extensions->ParseField(tag, input, prototype, unknown_fields);
}
};
} // namespace
bool MergePartialFromCodedStream(
MessageLite* msg, const ParseTable& table, io::CodedInputStream* input) {
return MergePartialFromCodedStreamImpl<UnknownFieldHandler,
InternalMetadataWithArena>(msg, table,
input);
}
} // namespace internal
} // namespace protobuf
} // namespace google
@@ -36,10 +36,6 @@
#include <google/protobuf/map_field_lite.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/wire_format_lite_inl.h>
#if LANG_CXX11
#define PROTOBUF_CONSTEXPR constexpr
// We require C++11 and Clang to use constexpr for variables, as GCC 4.8
// requires constexpr to be consistent between declarations of variables
@@ -51,37 +47,72 @@
#define PROTOBUF_CONSTEXPR_VAR
#endif // !_clang
#else
#define PROTOBUF_CONSTEXPR
#define PROTOBUF_CONSTEXPR_VAR
#ifdef SWIG
#error "You cannot SWIG proto headers"
#endif
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace internal {
// Processing-type masks.
static PROTOBUF_CONSTEXPR const unsigned char kOneofMask = 0x40;
static PROTOBUF_CONSTEXPR const unsigned char kRepeatedMask = 0x20;
static constexpr const unsigned char kOneofMask = 0x40;
static constexpr const unsigned char kRepeatedMask = 0x20;
// Mask for the raw type: either a WireFormatLite::FieldType or one of the
// ProcessingTypes below, without the oneof or repeated flag.
static PROTOBUF_CONSTEXPR const unsigned char kTypeMask = 0x1f;
static constexpr const unsigned char kTypeMask = 0x1f;
// Wire type masks.
static PROTOBUF_CONSTEXPR const unsigned char kNotPackedMask = 0x10;
static PROTOBUF_CONSTEXPR const unsigned char kInvalidMask = 0x20;
static constexpr const unsigned char kNotPackedMask = 0x10;
static constexpr const unsigned char kInvalidMask = 0x20;
enum ProcessingTypes {
TYPE_STRING_CORD = 19,
TYPE_STRING_STRING_PIECE = 20,
TYPE_BYTES_CORD = 21,
TYPE_BYTES_STRING_PIECE = 22,
TYPE_MAP = 23,
TYPE_STRING_INLINED = 23,
TYPE_BYTES_INLINED = 24,
TYPE_MAP = 25,
};
#if LANG_CXX11
static_assert(TYPE_MAP < kRepeatedMask, "Invalid enum");
#endif
struct PROTOBUF_EXPORT FieldMetadata {
uint32_t offset; // offset of this field in the struct
uint32_t tag; // field * 8 + wire_type
// byte offset * 8 + bit_offset;
// if the high bit is set then this is the byte offset of the oneof_case
// for this field.
uint32_t has_offset;
uint32_t type; // the type of this field.
const void* ptr; // auxiliary data
// From the serializer point of view each fundamental type can occur in
// 4 different ways. For simplicity we treat all combinations as a cartesion
// product although not all combinations are allowed.
enum FieldTypeClass {
kPresence,
kNoPresence,
kRepeated,
kPacked,
kOneOf,
kNumTypeClasses // must be last enum
};
// C++ protobuf has 20 fundamental types, were we added Cord and StringPiece
// and also distinguish the same types if they have different wire format.
enum {
kCordType = 19,
kStringPieceType = 20,
kInlinedType = 21,
kNumTypes = 21,
kSpecial = kNumTypes * kNumTypeClasses,
};
static int CalculateType(int fundamental_type, FieldTypeClass type_class);
};
// TODO(ckennelly): Add a static assertion to ensure that these masks do not
// conflict with wiretypes.
@@ -89,12 +120,12 @@ static_assert(TYPE_MAP < kRepeatedMask, "Invalid enum");
// ParseTableField is kept small to help simplify instructions for computing
// offsets, as we will always need this information to parse a field.
// Additional data, needed for some types, is stored in
// AuxillaryParseTableField.
// AuxiliaryParseTableField.
struct ParseTableField {
uint32 offset;
uint32_t offset;
// The presence_index ordinarily represents a has_bit index, but for fields
// inside a oneof it represents the index in _oneof_case_.
uint32 presence_index;
uint32_t presence_index;
unsigned char normal_wiretype;
unsigned char packed_wiretype;
@@ -107,7 +138,7 @@ struct ParseTableField {
struct ParseTable;
union AuxillaryParseTableField {
union AuxiliaryParseTableField {
typedef bool (*EnumValidator)(int);
// Enums
@@ -124,7 +155,6 @@ union AuxillaryParseTableField {
const MessageLite* default_message() const {
return static_cast<const MessageLite*>(default_message_void);
}
const ParseTable* parse_table;
};
message_aux messages;
// Strings
@@ -139,33 +169,28 @@ union AuxillaryParseTableField {
};
map_aux maps;
#if LANG_CXX11
AuxillaryParseTableField() = default;
#else
AuxillaryParseTableField() { }
#endif
PROTOBUF_CONSTEXPR AuxillaryParseTableField(
AuxillaryParseTableField::enum_aux e) : enums(e) {}
PROTOBUF_CONSTEXPR AuxillaryParseTableField(
AuxillaryParseTableField::message_aux m) : messages(m) {}
PROTOBUF_CONSTEXPR AuxillaryParseTableField(
AuxillaryParseTableField::string_aux s) : strings(s) {}
PROTOBUF_CONSTEXPR AuxillaryParseTableField(
AuxillaryParseTableField::map_aux m)
AuxiliaryParseTableField() = default;
constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::enum_aux e)
: enums(e) {}
constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::message_aux m)
: messages(m) {}
constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::string_aux s)
: strings(s) {}
constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::map_aux m)
: maps(m) {}
};
struct ParseTable {
const ParseTableField* fields;
const AuxillaryParseTableField* aux;
const AuxiliaryParseTableField* aux;
int max_field_number;
// TODO(ckennelly): Do something with this padding.
// TODO(ckennelly): Vet these for sign extension.
int64 has_bits_offset;
int64 oneof_case_offset;
int64 extension_offset;
int64 arena_offset;
int64_t has_bits_offset;
int64_t oneof_case_offset;
int64_t extension_offset;
int64_t arena_offset;
// ExplicitlyInitialized<T> -> T requires a reinterpret_cast, which prevents
// the tables from being constructed as a constexpr. We use void to avoid
@@ -178,42 +203,149 @@ struct ParseTable {
bool unknown_field_set;
};
// TODO(jhen): Remove the __NVCC__ check when we get a version of nvcc that
// supports these checks.
#if LANG_CXX11 && !defined(__NVCC__)
static_assert(sizeof(ParseTableField) <= 16, "ParseTableField is too large");
// The tables must be composed of POD components to ensure link-time
// initialization.
static_assert(std::is_pod<ParseTableField>::value, "");
static_assert(std::is_pod<AuxillaryParseTableField>::value, "");
static_assert(std::is_pod<AuxillaryParseTableField::enum_aux>::value, "");
static_assert(std::is_pod<AuxillaryParseTableField::message_aux>::value, "");
static_assert(std::is_pod<AuxillaryParseTableField::string_aux>::value, "");
static_assert(std::is_pod<ParseTable>::value, "");
#endif
static_assert(std::is_standard_layout<ParseTableField>::value, "");
static_assert(std::is_trivial<ParseTableField>::value, "");
static_assert(std::is_standard_layout<AuxiliaryParseTableField>::value, "");
static_assert(std::is_trivial<AuxiliaryParseTableField>::value, "");
static_assert(
std::is_standard_layout<AuxiliaryParseTableField::enum_aux>::value, "");
static_assert(std::is_trivial<AuxiliaryParseTableField::enum_aux>::value, "");
static_assert(
std::is_standard_layout<AuxiliaryParseTableField::message_aux>::value, "");
static_assert(std::is_trivial<AuxiliaryParseTableField::message_aux>::value,
"");
static_assert(
std::is_standard_layout<AuxiliaryParseTableField::string_aux>::value, "");
static_assert(std::is_trivial<AuxiliaryParseTableField::string_aux>::value, "");
static_assert(std::is_standard_layout<ParseTable>::value, "");
static_assert(std::is_trivial<ParseTable>::value, "");
// TODO(ckennelly): Consolidate these implementations into a single one, using
// dynamic dispatch to the appropriate unknown field handler.
bool MergePartialFromCodedStream(MessageLite* msg, const ParseTable& table,
io::CodedInputStream* input);
bool MergePartialFromCodedStreamLite(MessageLite* msg, const ParseTable& table,
io::CodedInputStream* input);
io::CodedInputStream* input);
template <typename Entry>
bool ParseMap(io::CodedInputStream* input, void* map_field) {
typedef typename MapEntryToMapField<Entry>::MapFieldType MapFieldType;
typedef google::protobuf::Map<typename Entry::EntryKeyType,
typename Entry::EntryValueType>
typedef Map<typename Entry::EntryKeyType, typename Entry::EntryValueType>
MapType;
typedef typename Entry::template Parser<MapFieldType, MapType> ParserType;
ParserType parser(static_cast<MapFieldType*>(map_field));
return ::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(input,
&parser);
return WireFormatLite::ReadMessageNoVirtual(input, &parser);
}
struct SerializationTable {
int num_fields;
const FieldMetadata* field_table;
};
PROTOBUF_EXPORT void SerializeInternal(const uint8_t* base,
const FieldMetadata* table,
int32_t num_fields,
io::CodedOutputStream* output);
inline void TableSerialize(const MessageLite& msg,
const SerializationTable* table,
io::CodedOutputStream* output) {
const FieldMetadata* field_table = table->field_table;
int num_fields = table->num_fields - 1;
const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg);
// TODO(gerbens) This skips the first test if we could use the fast
// array serialization path, we should make this
// int cached_size =
// *reinterpret_cast<const int32_t*>(base + field_table->offset);
// SerializeWithCachedSize(msg, field_table + 1, num_fields, cached_size, ...)
// But we keep conformance with the old way for now.
SerializeInternal(base, field_table + 1, num_fields, output);
}
PROTOBUF_EXPORT uint8_t* SerializeInternalToArray(const uint8_t* base,
const FieldMetadata* table,
int32_t num_fields,
bool is_deterministic,
uint8_t* buffer);
inline uint8_t* TableSerializeToArray(const MessageLite& msg,
const SerializationTable* table,
bool is_deterministic, uint8_t* buffer) {
const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg);
const FieldMetadata* field_table = table->field_table + 1;
int num_fields = table->num_fields - 1;
return SerializeInternalToArray(base, field_table, num_fields,
is_deterministic, buffer);
}
template <typename T>
struct CompareHelper {
bool operator()(const T& a, const T& b) const { return a < b; }
};
template <>
struct CompareHelper<ArenaStringPtr> {
bool operator()(const ArenaStringPtr& a, const ArenaStringPtr& b) const {
return a.Get() < b.Get();
}
};
struct CompareMapKey {
template <typename T>
bool operator()(const MapEntryHelper<T>& a,
const MapEntryHelper<T>& b) const {
return Compare(a.key_, b.key_);
}
template <typename T>
bool Compare(const T& a, const T& b) const {
return CompareHelper<T>()(a, b);
}
};
template <typename MapFieldType, const SerializationTable* table>
void MapFieldSerializer(const uint8_t* base, uint32_t offset, uint32_t tag,
uint32_t has_offset, io::CodedOutputStream* output) {
typedef MapEntryHelper<typename MapFieldType::EntryTypeTrait> Entry;
typedef typename MapFieldType::MapType::const_iterator Iter;
const MapFieldType& map_field =
*reinterpret_cast<const MapFieldType*>(base + offset);
const SerializationTable* t =
table +
has_offset; // has_offset is overloaded for maps to mean table offset
if (!output->IsSerializationDeterministic()) {
for (Iter it = map_field.GetMap().begin(); it != map_field.GetMap().end();
++it) {
Entry map_entry(*it);
output->WriteVarint32(tag);
output->WriteVarint32(map_entry._cached_size_);
SerializeInternal(reinterpret_cast<const uint8_t*>(&map_entry),
t->field_table, t->num_fields, output);
}
} else {
std::vector<Entry> v;
for (Iter it = map_field.GetMap().begin(); it != map_field.GetMap().end();
++it) {
v.push_back(Entry(*it));
}
std::sort(v.begin(), v.end(), CompareMapKey());
for (int i = 0; i < v.size(); i++) {
output->WriteVarint32(tag);
output->WriteVarint32(v[i]._cached_size_);
SerializeInternal(reinterpret_cast<const uint8_t*>(&v[i]), t->field_table,
t->num_fields, output);
}
}
}
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_H__
@@ -1,109 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/generated_message_table_driven_lite.h>
#include <google/protobuf/stubs/type_traits.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/wire_format_lite_inl.h>
namespace google {
namespace protobuf {
namespace internal {
namespace {
string* MutableUnknownFields(MessageLite* msg, int64 arena_offset) {
return Raw<InternalMetadataWithArenaLite>(msg, arena_offset)
->mutable_unknown_fields();
}
struct UnknownFieldHandlerLite {
static bool Skip(MessageLite* msg, const ParseTable& table,
io::CodedInputStream* input,
int tag) {
GOOGLE_DCHECK(!table.unknown_field_set);
::google::protobuf::io::StringOutputStream unknown_fields_string(
MutableUnknownFields(msg, table.arena_offset));
::google::protobuf::io::CodedOutputStream unknown_fields_stream(
&unknown_fields_string, false);
return ::google::protobuf::internal::WireFormatLite::SkipField(
input, tag, &unknown_fields_stream);
}
static void Varint(MessageLite* msg, const ParseTable& table,
int tag, int value) {
GOOGLE_DCHECK(!table.unknown_field_set);
::google::protobuf::io::StringOutputStream unknown_fields_string(
MutableUnknownFields(msg, table.arena_offset));
::google::protobuf::io::CodedOutputStream unknown_fields_stream(
&unknown_fields_string, false);
unknown_fields_stream.WriteVarint32(tag);
unknown_fields_stream.WriteVarint32(value);
}
static bool ParseExtension(
MessageLite* msg, const ParseTable& table,
io::CodedInputStream* input, int tag) {
ExtensionSet* extensions = GetExtensionSet(msg, table.extension_offset);
if (extensions == NULL) {
return false;
}
const MessageLite* prototype = table.default_instance();
GOOGLE_DCHECK(!table.unknown_field_set);
::google::protobuf::io::StringOutputStream unknown_fields_string(
MutableUnknownFields(msg, table.arena_offset));
::google::protobuf::io::CodedOutputStream unknown_fields_stream(
&unknown_fields_string, false);
return extensions->ParseField(
tag, input, prototype, &unknown_fields_stream);
}
};
} // namespace
bool MergePartialFromCodedStreamLite(
MessageLite* msg, const ParseTable& table, io::CodedInputStream* input) {
return MergePartialFromCodedStreamImpl<UnknownFieldHandlerLite,
InternalMetadataWithArenaLite>(
msg, table, input);
}
} // namespace internal
} // namespace protobuf
} // namespace google
@@ -1,823 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/stubs/type_traits.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/wire_format_lite_inl.h>
namespace google {
namespace protobuf {
namespace internal {
enum StringType {
StringType_STRING = 0,
StringType_CORD = 1,
StringType_STRING_PIECE = 2
};
// Logically a superset of StringType, consisting of all field types that
// require special initialization.
enum ProcessingType {
ProcessingType_STRING = 0,
ProcessingType_CORD = 1,
ProcessingType_STRING_PIECE = 2,
ProcessingType_MESSAGE = 3
};
enum Cardinality {
Cardinality_SINGULAR = 0,
Cardinality_REPEATED = 1,
Cardinality_ONEOF = 3
};
template <typename Type>
inline Type* Raw(MessageLite* msg, int64 offset) {
return reinterpret_cast<Type*>(reinterpret_cast<uint8*>(msg) + offset);
}
template <typename Type>
inline const Type* Raw(const MessageLite* msg, int64 offset) {
return reinterpret_cast<const Type*>(reinterpret_cast<const uint8*>(msg) +
offset);
}
template <typename InternalMetadata>
inline Arena* GetArena(MessageLite* msg, int64 arena_offset) {
if (GOOGLE_PREDICT_FALSE(arena_offset == -1)) {
return NULL;
}
return Raw<InternalMetadata>(msg, arena_offset)->arena();
}
inline ExtensionSet* GetExtensionSet(MessageLite* msg, int64 extension_offset) {
if (extension_offset == -1) {
return NULL;
}
return Raw<ExtensionSet>(msg, extension_offset);
}
template <typename Type>
inline Type* AddField(MessageLite* msg, int64 offset) {
#if LANG_CXX11
static_assert(has_trivial_copy<Type>::value,
"Do not assign");
#endif
google::protobuf::RepeatedField<Type>* repeated =
Raw<google::protobuf::RepeatedField<Type> >(msg, offset);
return repeated->Add();
}
template <>
inline string* AddField<string>(MessageLite* msg, int64 offset) {
google::protobuf::RepeatedPtrField<string>* repeated =
Raw<google::protobuf::RepeatedPtrField<string> >(msg, offset);
return repeated->Add();
}
template <typename Type>
inline void AddField(MessageLite* msg, int64 offset, Type value) {
#if LANG_CXX11
static_assert(has_trivial_copy<Type>::value,
"Do not assign");
#endif
*AddField<Type>(msg, offset) = value;
}
inline void SetBit(uint32* has_bits, uint32 has_bit_index) {
GOOGLE_DCHECK(has_bits != NULL);
uint32 mask = static_cast<uint32>(1u) << (has_bit_index % 32);
has_bits[has_bit_index / 32u] |= mask;
}
template <typename Type>
inline Type* MutableField(MessageLite* msg, uint32* has_bits,
uint32 has_bit_index, int64 offset) {
SetBit(has_bits, has_bit_index);
return Raw<Type>(msg, offset);
}
template <typename Type>
inline void SetField(MessageLite* msg, uint32* has_bits, uint32 has_bit_index,
int64 offset, Type value) {
#if LANG_CXX11
static_assert(has_trivial_copy<Type>::value,
"Do not assign");
#endif
*MutableField<Type>(msg, has_bits, has_bit_index, offset) = value;
}
template <typename Type>
inline void SetOneofField(MessageLite* msg, uint32* oneof_case,
uint32 oneof_case_index, int64 offset,
int field_number, Type value) {
oneof_case[oneof_case_index] = field_number;
*Raw<Type>(msg, offset) = value;
}
// Clears a oneof field. The field argument should correspond to the particular
// field that is currently set in the oneof.
inline void ClearOneofField(const ParseTableField& field, Arena* arena,
MessageLite* msg) {
switch (field.processing_type & kTypeMask) {
case WireFormatLite::TYPE_MESSAGE:
if (arena == NULL) {
delete *Raw<MessageLite*>(msg, field.offset);
}
break;
case WireFormatLite::TYPE_STRING:
case WireFormatLite::TYPE_BYTES:
Raw<ArenaStringPtr>(msg, field.offset)
->Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena);
break;
default:
// No cleanup needed.
break;
}
}
// Clears and reinitializes a oneof field as necessary, in preparation for
// parsing a new value with type field_type and field number field_number.
//
// Note: the oneof_case argument should point directly to the _oneof_case_
// element corresponding to this particular oneof, not to the beginning of the
// _oneof_case_ array.
template <ProcessingType field_type>
inline void ResetOneofField(const ParseTable& table, int field_number,
Arena* arena, MessageLite* msg, uint32* oneof_case,
int64 offset, const void* default_ptr) {
if (*oneof_case == field_number) {
// The oneof is already set to the right type, so there is no need to clear
// it.
return;
}
if (*oneof_case != 0) {
ClearOneofField(table.fields[*oneof_case], arena, msg);
}
*oneof_case = field_number;
switch (field_type) {
case ProcessingType_STRING:
Raw<ArenaStringPtr>(msg, offset)
->UnsafeSetDefault(static_cast<const string*>(default_ptr));
break;
case ProcessingType_MESSAGE:
MessageLite** submessage = Raw<MessageLite*>(msg, offset);
const MessageLite* prototype =
table.aux[field_number].messages.default_message();
*submessage = prototype->New(arena);
break;
}
}
template <Cardinality cardinality, bool validate, StringType ctype>
static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg,
Arena* arena, uint32* has_bits,
uint32 has_bit_index, int64 offset,
const void* default_ptr,
const char* field_name) {
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
const char* sdata;
size_t size;
#endif
string* value;
switch (cardinality) {
case Cardinality_SINGULAR:
// TODO(ckennelly): Is this optimal?
value =
MutableField<ArenaStringPtr>(msg, has_bits, has_bit_index, offset)
->Mutable(static_cast<const string*>(default_ptr), arena);
break;
case Cardinality_REPEATED:
value = AddField<string>(msg, offset);
break;
case Cardinality_ONEOF:
value = Raw<ArenaStringPtr>(msg, offset)
->Mutable(static_cast<const string*>(default_ptr), arena);
break;
}
GOOGLE_DCHECK(value != NULL);
if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadString(input, value))) {
return false;
}
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
sdata = value->data();
size = value->size();
#endif
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
if (validate) {
WireFormatLite::VerifyUtf8String(sdata, size, WireFormatLite::PARSE,
field_name);
}
#endif
return true;
}
template <typename UnknownFieldHandler, typename InternalMetadata,
Cardinality cardinality>
inline bool HandleEnum(const ParseTable& table, io::CodedInputStream* input,
MessageLite* msg, uint32* presence,
uint32 presence_index, int64 offset, uint32 tag,
int field_number) {
int value;
if (GOOGLE_PREDICT_FALSE(
(!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
input, &value)))) {
return false;
}
AuxillaryParseTableField::EnumValidator validator =
table.aux[field_number].enums.validator;
if (validator(value)) {
switch (cardinality) {
case Cardinality_SINGULAR:
SetField(msg, presence, presence_index, offset, value);
break;
case Cardinality_REPEATED:
AddField(msg, offset, value);
break;
case Cardinality_ONEOF:
ClearOneofField(table.fields[presence[presence_index]],
GetArena<InternalMetadata>(msg, table.arena_offset),
msg);
SetOneofField(msg, presence, presence_index, offset, field_number,
value);
break;
}
} else {
UnknownFieldHandler::Varint(msg, table, tag, value);
}
return true;
}
// RepeatedMessageTypeHandler allows us to operate on RepeatedPtrField fields
// without instantiating the specific template.
class RepeatedMessageTypeHandler {
public:
typedef MessageLite Type;
static Arena* GetArena(Type* t) { return t->GetArena(); }
static void* GetMaybeArenaPointer(Type* t) {
return t->GetMaybeArenaPointer();
}
static inline Type* NewFromPrototype(const Type* prototype,
Arena* arena = NULL) {
return prototype->New(arena);
}
static void Delete(Type* t, Arena* arena = NULL) {
if (arena == NULL) {
delete t;
}
}
};
inline bool ReadGroup(int field_number, io::CodedInputStream* input,
MessageLite* value) {
if (GOOGLE_PREDICT_FALSE(!input->IncrementRecursionDepth())) {
return false;
}
if (GOOGLE_PREDICT_FALSE(!value->MergePartialFromCodedStream(input))) {
return false;
}
input->DecrementRecursionDepth();
// Make sure the last thing read was an end tag for this group.
if (GOOGLE_PREDICT_FALSE(!input->LastTagWas(WireFormatLite::MakeTag(
field_number, WireFormatLite::WIRETYPE_END_GROUP)))) {
return false;
}
return true;
}
inline bool ReadMessage(io::CodedInputStream* input, MessageLite* value) {
int length;
if (GOOGLE_PREDICT_FALSE(!input->ReadVarintSizeAsInt(&length))) {
return false;
}
std::pair<io::CodedInputStream::Limit, int> p =
input->IncrementRecursionDepthAndPushLimit(length);
if (GOOGLE_PREDICT_FALSE(p.second < 0 ||
!value->MergePartialFromCodedStream(input))) {
return false;
}
// Make sure that parsing stopped when the limit was hit, not at an endgroup
// tag.
return input->DecrementRecursionDepthAndPopLimit(p.first);
}
class MergePartialFromCodedStreamHelper {
public:
static MessageLite* Add(RepeatedPtrFieldBase* field,
const MessageLite* prototype) {
return field->Add<RepeatedMessageTypeHandler>(
const_cast<MessageLite*>(prototype));
}
};
template <typename UnknownFieldHandler, typename InternalMetadata>
bool MergePartialFromCodedStreamImpl(MessageLite* msg, const ParseTable& table,
io::CodedInputStream* input) {
// We require that has_bits are present, as to avoid having to check for them
// for every field.
//
// TODO(ckennelly): Make this a compile-time parameter with templates.
GOOGLE_DCHECK_GE(table.has_bits_offset, 0);
uint32* has_bits = Raw<uint32>(msg, table.has_bits_offset);
GOOGLE_DCHECK(has_bits != NULL);
while (true) {
uint32 tag = input->ReadTag();
const WireFormatLite::WireType wire_type =
WireFormatLite::GetTagWireType(tag);
const int field_number = WireFormatLite::GetTagFieldNumber(tag);
if (field_number > table.max_field_number) {
// check for possible extensions
if (UnknownFieldHandler::ParseExtension(msg, table, input, tag)) {
// successfully parsed
continue;
}
if (GOOGLE_PREDICT_FALSE(!UnknownFieldHandler::Skip(msg, table, input, tag))) {
return false;
}
continue;
}
// We implicitly verify that data points to a valid field as we check the
// wire types. Entries in table.fields[i] that do not correspond to valid
// field numbers have their normal_wiretype and packed_wiretype fields set
// with the kInvalidMask value. As wire_type cannot take on that value, we
// will never match.
const ParseTableField* data = table.fields + field_number;
// TODO(ckennelly): Avoid sign extension
const int64 presence_index = data->presence_index;
const int64 offset = data->offset;
const unsigned char processing_type = data->processing_type;
if (data->normal_wiretype == static_cast<unsigned char>(wire_type)) {
// TODO(ckennelly): Use a computed goto on GCC/LLVM or otherwise eliminate
// the bounds check on processing_type.
switch (processing_type) {
#define HANDLE_TYPE(TYPE, CPPTYPE) \
case (WireFormatLite::TYPE_##TYPE): { \
CPPTYPE value; \
if (GOOGLE_PREDICT_FALSE( \
(!WireFormatLite::ReadPrimitive< \
CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) { \
return false; \
} \
SetField(msg, has_bits, presence_index, offset, value); \
break; \
} \
case (WireFormatLite::TYPE_##TYPE) | kRepeatedMask: { \
google::protobuf::RepeatedField<CPPTYPE>* values = \
Raw<google::protobuf::RepeatedField<CPPTYPE> >(msg, offset); \
if (GOOGLE_PREDICT_FALSE((!WireFormatLite::ReadRepeatedPrimitive< \
CPPTYPE, WireFormatLite::TYPE_##TYPE>( \
data->tag_size, tag, input, values)))) { \
return false; \
} \
break; \
} \
case (WireFormatLite::TYPE_##TYPE) | kOneofMask: { \
uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset); \
CPPTYPE value; \
if (GOOGLE_PREDICT_FALSE( \
(!WireFormatLite::ReadPrimitive< \
CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) { \
return false; \
} \
ClearOneofField(table.fields[oneof_case[presence_index]], \
GetArena<InternalMetadata>(msg, table.arena_offset), msg); \
SetOneofField(msg, oneof_case, presence_index, offset, field_number, \
value); \
break; \
}
HANDLE_TYPE(INT32, int32)
HANDLE_TYPE(INT64, int64)
HANDLE_TYPE(SINT32, int32)
HANDLE_TYPE(SINT64, int64)
HANDLE_TYPE(UINT32, uint32)
HANDLE_TYPE(UINT64, uint64)
HANDLE_TYPE(FIXED32, uint32)
HANDLE_TYPE(FIXED64, uint64)
HANDLE_TYPE(SFIXED32, int32)
HANDLE_TYPE(SFIXED64, int64)
HANDLE_TYPE(FLOAT, float)
HANDLE_TYPE(DOUBLE, double)
HANDLE_TYPE(BOOL, bool)
#undef HANDLE_TYPE
case WireFormatLite::TYPE_BYTES:
#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
case WireFormatLite::TYPE_STRING:
#endif
{
Arena* const arena =
GetArena<InternalMetadata>(msg, table.arena_offset);
const void* default_ptr = table.aux[field_number].strings.default_ptr;
if (GOOGLE_PREDICT_FALSE((
!HandleString<Cardinality_SINGULAR, false, StringType_STRING>(
input, msg, arena, has_bits, presence_index, offset,
default_ptr, NULL)))) {
return false;
}
break;
}
case WireFormatLite::TYPE_BYTES | kOneofMask:
#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
case WireFormatLite::TYPE_STRING | kOneofMask:
#endif
{
Arena* const arena =
GetArena<InternalMetadata>(msg, table.arena_offset);
uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset);
const void* default_ptr = table.aux[field_number].strings.default_ptr;
ResetOneofField<ProcessingType_STRING>(
table, field_number, arena, msg, oneof_case + presence_index,
offset, default_ptr);
if (GOOGLE_PREDICT_FALSE(
(!HandleString<Cardinality_ONEOF, false, StringType_STRING>(
input, msg, arena, has_bits, presence_index, offset,
default_ptr, NULL)))) {
return false;
}
break;
}
case (WireFormatLite::TYPE_BYTES) | kRepeatedMask:
#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
case (WireFormatLite::TYPE_STRING) | kRepeatedMask:
#endif
{
Arena* const arena =
GetArena<InternalMetadata>(msg, table.arena_offset);
const void* default_ptr =
table.aux[field_number].strings.default_ptr;
if (GOOGLE_PREDICT_FALSE((
!HandleString<Cardinality_REPEATED, false, StringType_STRING>(
input, msg, arena, has_bits, presence_index, offset,
default_ptr, NULL)))) {
return false;
}
break;
}
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
case (WireFormatLite::TYPE_STRING): {
Arena* const arena =
GetArena<InternalMetadata>(msg, table.arena_offset);
const void* default_ptr = table.aux[field_number].strings.default_ptr;
const char* field_name = table.aux[field_number].strings.field_name;
if (GOOGLE_PREDICT_FALSE(
(!HandleString<Cardinality_SINGULAR, true, StringType_STRING>(
input, msg, arena, has_bits, presence_index, offset,
default_ptr, field_name)))) {
return false;
}
break;
}
case (WireFormatLite::TYPE_STRING) | kRepeatedMask: {
Arena* const arena =
GetArena<InternalMetadata>(msg, table.arena_offset);
const void* default_ptr = table.aux[field_number].strings.default_ptr;
const char* field_name = table.aux[field_number].strings.field_name;
if (GOOGLE_PREDICT_FALSE(
(!HandleString<Cardinality_REPEATED, true, StringType_STRING>(
input, msg, arena, has_bits, presence_index, offset,
default_ptr, field_name)))) {
return false;
}
break;
}
case (WireFormatLite::TYPE_STRING) | kOneofMask: {
Arena* const arena =
GetArena<InternalMetadata>(msg, table.arena_offset);
uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset);
const void* default_ptr = table.aux[field_number].strings.default_ptr;
const char* field_name = table.aux[field_number].strings.field_name;
ResetOneofField<ProcessingType_STRING>(
table, field_number, arena, msg, oneof_case + presence_index,
offset, default_ptr);
if (GOOGLE_PREDICT_FALSE(
(!HandleString<Cardinality_ONEOF, true, StringType_STRING>(
input, msg, arena, has_bits, presence_index, offset,
default_ptr, field_name)))) {
return false;
}
break;
}
#endif
case WireFormatLite::TYPE_ENUM: {
if (GOOGLE_PREDICT_FALSE((!HandleEnum<UnknownFieldHandler, InternalMetadata,
Cardinality_SINGULAR>(
table, input, msg, has_bits, presence_index, offset, tag,
field_number)))) {
return false;
}
break;
}
case WireFormatLite::TYPE_ENUM | kRepeatedMask: {
if (GOOGLE_PREDICT_FALSE((!HandleEnum<UnknownFieldHandler, InternalMetadata,
Cardinality_REPEATED>(
table, input, msg, has_bits, presence_index, offset, tag,
field_number)))) {
return false;
}
break;
}
case WireFormatLite::TYPE_ENUM | kOneofMask: {
uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset);
if (GOOGLE_PREDICT_FALSE((!HandleEnum<UnknownFieldHandler, InternalMetadata,
Cardinality_ONEOF>(
table, input, msg, oneof_case, presence_index, offset, tag,
field_number)))) {
return false;
}
break;
}
case WireFormatLite::TYPE_GROUP: {
MessageLite** submsg_holder =
MutableField<MessageLite*>(msg, has_bits, presence_index, offset);
MessageLite* submsg = *submsg_holder;
if (submsg == NULL) {
Arena* const arena =
GetArena<InternalMetadata>(msg, table.arena_offset);
const MessageLite* prototype =
table.aux[field_number].messages.default_message();
submsg = prototype->New(arena);
*submsg_holder = submsg;
}
if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadGroup(
field_number, input, submsg))) {
return false;
}
break;
}
case WireFormatLite::TYPE_GROUP | kRepeatedMask: {
RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset);
const MessageLite* prototype =
table.aux[field_number].messages.default_message();
GOOGLE_DCHECK(prototype != NULL);
MessageLite* submsg =
MergePartialFromCodedStreamHelper::Add(field, prototype);
if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadGroup(
field_number, input, submsg))) {
return false;
}
break;
}
case WireFormatLite::TYPE_MESSAGE: {
MessageLite** submsg_holder =
MutableField<MessageLite*>(msg, has_bits, presence_index, offset);
MessageLite* submsg = *submsg_holder;
if (submsg == NULL) {
Arena* const arena =
GetArena<InternalMetadata>(msg, table.arena_offset);
const MessageLite* prototype =
table.aux[field_number].messages.default_message();
submsg = prototype->New(arena);
*submsg_holder = submsg;
}
if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadMessage(input, submsg))) {
return false;
}
break;
}
// TODO(ckennelly): Adapt ReadMessageNoVirtualNoRecursionDepth and
// manage input->IncrementRecursionDepth() here.
case WireFormatLite::TYPE_MESSAGE | kRepeatedMask: {
RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset);
const MessageLite* prototype =
table.aux[field_number].messages.default_message();
GOOGLE_DCHECK(prototype != NULL);
MessageLite* submsg =
MergePartialFromCodedStreamHelper::Add(field, prototype);
if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadMessage(input, submsg))) {
return false;
}
break;
}
case WireFormatLite::TYPE_MESSAGE | kOneofMask: {
Arena* const arena =
GetArena<InternalMetadata>(msg, table.arena_offset);
uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset);
MessageLite** submsg_holder = Raw<MessageLite*>(msg, offset);
ResetOneofField<ProcessingType_MESSAGE>(
table, field_number, arena, msg, oneof_case + presence_index,
offset, NULL);
MessageLite* submsg = *submsg_holder;
if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadMessage(input, submsg))) {
return false;
}
break;
}
case TYPE_MAP: {
if (GOOGLE_PREDICT_FALSE(!(*table.aux[field_number].maps.parse_map)(
input, Raw<void>(msg, offset)))) {
return false;
}
break;
}
case 0: {
// Done.
return true;
}
default:
break;
}
} else if (data->packed_wiretype == static_cast<unsigned char>(wire_type)) {
// Non-packable fields have their packed_wiretype masked with
// kNotPackedMask, which is impossible to match here.
GOOGLE_DCHECK(processing_type & kRepeatedMask);
GOOGLE_DCHECK_NE(processing_type, kRepeatedMask);
GOOGLE_DCHECK_EQ(0, processing_type & kOneofMask);
// TODO(ckennelly): Use a computed goto on GCC/LLVM.
//
// Mask out kRepeatedMask bit, allowing the jump table to be smaller.
switch (static_cast<WireFormatLite::FieldType>(
processing_type ^ kRepeatedMask)) {
#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \
case WireFormatLite::TYPE_##TYPE: { \
google::protobuf::RepeatedField<CPPTYPE>* values = \
Raw<google::protobuf::RepeatedField<CPPTYPE> >(msg, offset); \
if (GOOGLE_PREDICT_FALSE( \
(!WireFormatLite::ReadPackedPrimitive< \
CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, values)))) { \
return false; \
} \
break; \
}
HANDLE_PACKED_TYPE(INT32, int32, Int32)
HANDLE_PACKED_TYPE(INT64, int64, Int64)
HANDLE_PACKED_TYPE(SINT32, int32, Int32)
HANDLE_PACKED_TYPE(SINT64, int64, Int64)
HANDLE_PACKED_TYPE(UINT32, uint32, UInt32)
HANDLE_PACKED_TYPE(UINT64, uint64, UInt64)
HANDLE_PACKED_TYPE(FIXED32, uint32, UInt32)
HANDLE_PACKED_TYPE(FIXED64, uint64, UInt64)
HANDLE_PACKED_TYPE(SFIXED32, int32, Int32)
HANDLE_PACKED_TYPE(SFIXED64, int64, Int64)
HANDLE_PACKED_TYPE(FLOAT, float, Float)
HANDLE_PACKED_TYPE(DOUBLE, double, Double)
HANDLE_PACKED_TYPE(BOOL, bool, Bool)
#undef HANDLE_PACKED_TYPE
case WireFormatLite::TYPE_ENUM: {
// To avoid unnecessarily calling MutableUnknownFields (which mutates
// InternalMetadataWithArena) when all inputs in the repeated series
// are valid, we implement our own parser rather than call
// WireFormat::ReadPackedEnumPreserveUnknowns.
uint32 length;
if (GOOGLE_PREDICT_FALSE(!input->ReadVarint32(&length))) {
return false;
}
AuxillaryParseTableField::EnumValidator validator =
table.aux[field_number].enums.validator;
google::protobuf::RepeatedField<int>* values =
Raw<google::protobuf::RepeatedField<int> >(msg, offset);
io::CodedInputStream::Limit limit = input->PushLimit(length);
while (input->BytesUntilLimit() > 0) {
int value;
if (GOOGLE_PREDICT_FALSE(
(!google::protobuf::internal::WireFormatLite::ReadPrimitive<
int, WireFormatLite::TYPE_ENUM>(input, &value)))) {
return false;
}
if (validator(value)) {
values->Add(value);
} else {
// TODO(ckennelly): Consider caching here.
UnknownFieldHandler::Varint(msg, table, tag, value);
}
}
input->PopLimit(limit);
break;
}
case WireFormatLite::TYPE_STRING:
case WireFormatLite::TYPE_GROUP:
case WireFormatLite::TYPE_MESSAGE:
case WireFormatLite::TYPE_BYTES:
GOOGLE_DCHECK(false);
return false;
default:
break;
}
} else {
if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
// Must be the end of the message.
return true;
}
// check for possible extensions
if (UnknownFieldHandler::ParseExtension(msg, table, input, tag)) {
// successfully parsed
continue;
}
// process unknown field.
if (GOOGLE_PREDICT_FALSE(!UnknownFieldHandler::Skip(msg, table, input, tag))) {
return false;
}
}
}
}
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__
@@ -0,0 +1,139 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file contains declarations needed in generated headers for messages
// that use tail-call table parsing. Everything in this file is for internal
// use only.
#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_DECL_H__
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_DECL_H__
#include <cstdint>
#include <type_traits>
#include <google/protobuf/parse_context.h>
#include <google/protobuf/message_lite.h>
// Must come last:
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace internal {
// Additional information about this field:
struct TcFieldData {
constexpr TcFieldData() : data(0) {}
constexpr TcFieldData(uint16_t coded_tag, uint8_t hasbit_idx, uint16_t offset)
: data(static_cast<uint64_t>(offset) << 48 |
static_cast<uint64_t>(hasbit_idx) << 16 | coded_tag) {}
template <typename TagType = uint16_t>
TagType coded_tag() const {
return static_cast<TagType>(data);
}
uint8_t hasbit_idx() const { return static_cast<uint8_t>(data >> 16); }
uint16_t offset() const { return static_cast<uint16_t>(data >> 48); }
uint64_t data;
};
struct TcParseTableBase;
// TailCallParseFunc is the function pointer type used in the tailcall table.
typedef const char* (*TailCallParseFunc)(PROTOBUF_TC_PARAM_DECL);
#if defined(_MSC_VER) && !defined(_WIN64)
#pragma warning(push)
// TcParseTableBase is intentionally overaligned on 32 bit targets.
#pragma warning(disable : 4324)
#endif
// Base class for message-level table with info for the tail-call parser.
struct alignas(uint64_t) TcParseTableBase {
// Common attributes for message layout:
uint16_t has_bits_offset;
uint16_t extension_offset;
uint32_t extension_range_low;
uint32_t extension_range_high;
uint8_t fast_idx_mask;
uint8_t reserved;
uint16_t num_fields;
const MessageLite* default_instance;
// Handler for fields which are not handled by table dispatch.
TailCallParseFunc fallback;
// Table entry for fast-path tailcall dispatch handling.
struct FastFieldEntry {
// Target function for dispatch:
TailCallParseFunc target;
// Field data used during parse:
TcFieldData bits;
};
// There is always at least one table entry.
const FastFieldEntry* fast_entry(size_t idx) const {
return reinterpret_cast<const FastFieldEntry*>(this + 1) + idx;
}
};
#if defined(_MSC_VER) && !defined(_WIN64)
#pragma warning(pop)
#endif
static_assert(sizeof(TcParseTableBase::FastFieldEntry) <= 16,
"Field entry is too big.");
template <size_t kFastTableSizeLog2>
struct TcParseTable {
TcParseTableBase header;
// Entries for each field.
//
// Fields are indexed by the lowest bits of their field number. The field
// number is masked to fit inside the table. Note that the parsing logic
// generally calls `TailCallParseTableBase::table()` instead of accessing
// this field directly.
TcParseTableBase::FastFieldEntry entries[(1 << kFastTableSizeLog2)];
};
static_assert(std::is_standard_layout<TcParseTable<1>>::value,
"TcParseTable must be standard layout.");
static_assert(offsetof(TcParseTable<1>, entries) == sizeof(TcParseTableBase),
"Table entries must be laid out after TcParseTableBase.");
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_DECL_H__
@@ -0,0 +1,302 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_IMPL_H__
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_IMPL_H__
#include <cstdint>
#include <type_traits>
#include <google/protobuf/parse_context.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/generated_message_tctable_decl.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/port.h>
#include <google/protobuf/wire_format_lite.h>
// Must come last:
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
class Message;
class UnknownFieldSet;
namespace internal {
// PROTOBUF_TC_PARAM_DECL are the parameters for tailcall functions, it is
// defined in port_def.inc.
//
// Note that this is performance sensitive: changing the parameters will change
// the registers used by the ABI calling convention, which subsequently affects
// register selection logic inside the function.
// PROTOBUF_TC_PARAM_PASS passes values to match PROTOBUF_TC_PARAM_DECL.
#define PROTOBUF_TC_PARAM_PASS msg, ptr, ctx, table, hasbits, data
// PROTOBUF_TC_PARSE_* decide which function is used to parse message-typed
// fields. The guard macros are defined in port_def.inc.
#if PROTOBUF_TC_STATIC_PARSE_SINGULAR1
#define PROTOBUF_TC_PARSE_SINGULAR1(MESSAGE) MESSAGE::Tct_ParseS1
#else
#define PROTOBUF_TC_PARSE_SINGULAR1(MESSAGE) \
::google::protobuf::internal::TcParser::SingularParseMessage<MESSAGE, uint8_t>
#endif // PROTOBUF_TC_STATIC_PARSE_SINGULAR1
#if PROTOBUF_TC_STATIC_PARSE_SINGULAR2
#define PROTOBUF_TC_PARSE_SINGULAR2(MESSAGE) MESSAGE::Tct_ParseS2
#else
#define PROTOBUF_TC_PARSE_SINGULAR2(MESSAGE) \
::google::protobuf::internal::TcParser::SingularParseMessage<MESSAGE, uint16_t>
#endif // PROTOBUF_TC_STATIC_PARSE_SINGULAR2
#if PROTOBUF_TC_STATIC_PARSE_REPEATED1
#define PROTOBUF_TC_PARSE_REPEATED1(MESSAGE) MESSAGE::Tct_ParseR1
#else
#define PROTOBUF_TC_PARSE_REPEATED1(MESSAGE) \
::google::protobuf::internal::TcParser::RepeatedParseMessage<MESSAGE, uint8_t>
#endif // PROTOBUF_TC_STATIC_PARSE_REPEATED1
#if PROTOBUF_TC_STATIC_PARSE_REPEATED2
#define PROTOBUF_TC_PARSE_REPEATED2(MESSAGE) MESSAGE::Tct_ParseR2
#else
#define PROTOBUF_TC_PARSE_REPEATED2(MESSAGE) \
::google::protobuf::internal::TcParser::RepeatedParseMessage<MESSAGE, uint16_t>
#endif // PROTOBUF_TC_STATIC_PARSE_REPEATED2
#ifndef NDEBUG
template <size_t align>
#ifndef _MSC_VER
[[noreturn]]
#endif
void AlignFail(uintptr_t address) {
GOOGLE_LOG(FATAL) << "Unaligned (" << align << ") access at " << address;
}
extern template void AlignFail<4>(uintptr_t);
extern template void AlignFail<8>(uintptr_t);
#endif
// TcParser implements most of the parsing logic for tailcall tables.
class TcParser final {
public:
static const char* GenericFallback(PROTOBUF_TC_PARAM_DECL);
static const char* GenericFallbackLite(PROTOBUF_TC_PARAM_DECL);
// Dispatch to the designated parse function
inline PROTOBUF_ALWAYS_INLINE static const char* TagDispatch(
PROTOBUF_TC_PARAM_DECL) {
const auto coded_tag = UnalignedLoad<uint16_t>(ptr);
const size_t idx = coded_tag & table->fast_idx_mask;
PROTOBUF_ASSUME((idx & 7) == 0);
auto* fast_entry = table->fast_entry(idx >> 3);
data = fast_entry->bits;
data.data ^= coded_tag;
PROTOBUF_MUSTTAIL return fast_entry->target(PROTOBUF_TC_PARAM_PASS);
}
// We can only safely call from field to next field if the call is optimized
// to a proper tail call. Otherwise we blow through stack. Clang and gcc
// reliably do this optimization in opt mode, but do not perform this in debug
// mode. Luckily the structure of the algorithm is such that it's always
// possible to just return and use the enclosing parse loop as a trampoline.
static const char* ToTagDispatch(PROTOBUF_TC_PARAM_DECL) {
constexpr bool always_return = !PROTOBUF_TAILCALL;
if (always_return || !ctx->DataAvailable(ptr)) {
PROTOBUF_MUSTTAIL return ToParseLoop(PROTOBUF_TC_PARAM_PASS);
}
PROTOBUF_MUSTTAIL return TagDispatch(PROTOBUF_TC_PARAM_PASS);
}
static const char* ParseLoop(MessageLite* msg, const char* ptr,
ParseContext* ctx,
const TcParseTableBase* table) {
ScopedArenaSwap saved(msg, ctx);
const uint32_t has_bits_offset = table->has_bits_offset;
while (!ctx->Done(&ptr)) {
uint64_t hasbits = 0;
if (has_bits_offset) hasbits = RefAt<uint32_t>(msg, has_bits_offset);
ptr = TagDispatch(msg, ptr, ctx, table, hasbits, {});
if (ptr == nullptr) break;
if (ctx->LastTag() != 1) break; // Ended on terminating tag
}
return ptr;
}
template <typename FieldType, typename TagType>
PROTOBUF_NOINLINE static const char* SingularParseMessage(
PROTOBUF_TC_PARAM_DECL) {
if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
return table->fallback(PROTOBUF_TC_PARAM_PASS);
}
ptr += sizeof(TagType);
hasbits |= (uint64_t{1} << data.hasbit_idx());
auto& field = RefAt<FieldType*>(msg, data.offset());
if (field == nullptr) {
auto arena = ctx->data().arena;
if (Arena::is_arena_constructable<FieldType>::value) {
field = Arena::CreateMessage<FieldType>(arena);
} else {
field = Arena::Create<FieldType>(arena);
}
}
SyncHasbits(msg, hasbits, table);
return ctx->ParseMessage(field, ptr);
}
template <typename FieldType, typename TagType>
PROTOBUF_NOINLINE static const char* RepeatedParseMessage(
PROTOBUF_TC_PARAM_DECL) {
if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
return table->fallback(PROTOBUF_TC_PARAM_PASS);
}
ptr += sizeof(TagType);
auto& field = RefAt<RepeatedPtrField<FieldType>>(msg, data.offset());
SyncHasbits(msg, hasbits, table);
ptr = ctx->ParseMessage(field.Add(), ptr);
return ptr;
}
template <typename LayoutType, typename TagType>
static const char* SingularFixed(PROTOBUF_TC_PARAM_DECL);
template <typename LayoutType, typename TagType>
static const char* RepeatedFixed(PROTOBUF_TC_PARAM_DECL);
template <typename LayoutType, typename TagType>
static const char* PackedFixed(PROTOBUF_TC_PARAM_DECL);
enum VarintDecode { kNoConversion = 0, kZigZag = 1 };
template <typename FieldType, typename TagType, VarintDecode zigzag>
static const char* SingularVarint(PROTOBUF_TC_PARAM_DECL);
template <typename FieldType, typename TagType, VarintDecode zigzag>
static const char* RepeatedVarint(PROTOBUF_TC_PARAM_DECL);
template <typename FieldType, typename TagType, VarintDecode zigzag>
static const char* PackedVarint(PROTOBUF_TC_PARAM_DECL);
enum Utf8Type { kNoUtf8 = 0, kUtf8 = 1, kUtf8ValidateOnly = 2 };
template <typename TagType, Utf8Type utf8>
static const char* SingularString(PROTOBUF_TC_PARAM_DECL);
template <typename TagType, Utf8Type utf8>
static const char* RepeatedString(PROTOBUF_TC_PARAM_DECL);
template <typename T>
static inline T& RefAt(void* x, size_t offset) {
T* target = reinterpret_cast<T*>(static_cast<char*>(x) + offset);
#ifndef NDEBUG
if (PROTOBUF_PREDICT_FALSE(
reinterpret_cast<uintptr_t>(target) % alignof(T) != 0)) {
AlignFail<alignof(T)>(reinterpret_cast<uintptr_t>(target));
}
#endif
return *target;
}
static inline PROTOBUF_ALWAYS_INLINE void SyncHasbits(
MessageLite* msg, uint64_t hasbits, const TcParseTableBase* table) {
const uint32_t has_bits_offset = table->has_bits_offset;
if (has_bits_offset) {
// Only the first 32 has-bits are updated. Nothing above those is stored,
// but e.g. messages without has-bits update the upper bits.
RefAt<uint32_t>(msg, has_bits_offset) = static_cast<uint32_t>(hasbits);
}
}
protected:
static inline PROTOBUF_ALWAYS_INLINE const char* ToParseLoop(
PROTOBUF_TC_PARAM_DECL) {
(void)data;
(void)ctx;
SyncHasbits(msg, hasbits, table);
return ptr;
}
static inline PROTOBUF_ALWAYS_INLINE const char* Error(
PROTOBUF_TC_PARAM_DECL) {
(void)data;
(void)ctx;
(void)ptr;
SyncHasbits(msg, hasbits, table);
return nullptr;
}
class ScopedArenaSwap final {
public:
ScopedArenaSwap(MessageLite* msg, ParseContext* ctx)
: ctx_(ctx), saved_(ctx->data().arena) {
ctx_->data().arena = msg->GetArenaForAllocation();
}
ScopedArenaSwap(const ScopedArenaSwap&) = delete;
~ScopedArenaSwap() { ctx_->data().arena = saved_; }
private:
ParseContext* const ctx_;
Arena* const saved_;
};
template <class MessageBaseT, class UnknownFieldsT>
static const char* GenericFallbackImpl(PROTOBUF_TC_PARAM_DECL) {
#define CHK_(x) \
if (PROTOBUF_PREDICT_FALSE(!(x))) return nullptr /* NOLINT */
SyncHasbits(msg, hasbits, table);
uint32_t tag;
ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
CHK_(ptr);
if ((tag & 7) == WireFormatLite::WIRETYPE_END_GROUP || tag == 0) {
ctx->SetLastTag(tag);
return ptr;
}
(void)data;
uint32_t num = tag >> 3;
if (table->extension_range_low <= num &&
num <= table->extension_range_high) {
return RefAt<ExtensionSet>(msg, table->extension_offset)
.ParseField(tag, ptr,
static_cast<const MessageBaseT*>(table->default_instance),
&msg->_internal_metadata_, ctx);
}
return UnknownFieldParse(
tag, msg->_internal_metadata_.mutable_unknown_fields<UnknownFieldsT>(),
ptr, ctx);
#undef CHK_
}
};
// Declare helper functions:
#include <google/protobuf/generated_message_tctable_impl.inc>
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_IMPL_H__
@@ -0,0 +1,92 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// clang-format off
#ifdef PROTOBUF_TCT_SOURCE
#define PROTOBUF_TCT_EXTERN
#else
#define PROTOBUF_TCT_EXTERN extern
#endif
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::PackedFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::PackedFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoUtf8>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoUtf8>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::PackedFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::PackedFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoUtf8>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoUtf8>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL);
PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL);
#undef PROTOBUF_TCT_EXTERN
// clang-format on
+188 -139
View File
@@ -34,44 +34,63 @@
#include <google/protobuf/generated_message_util.h>
#include <atomic>
#include <limits>
#include <vector>
#include <google/protobuf/io/coded_stream_inl.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/wire_format_lite_inl.h>
// Must be included last
#include <google/protobuf/port_def.inc>
PROTOBUF_PRAGMA_INIT_SEG
namespace google {
namespace protobuf {
namespace internal {
double Infinity() {
return std::numeric_limits<double>::infinity();
void DestroyMessage(const void* message) {
static_cast<const MessageLite*>(message)->~MessageLite();
}
double NaN() {
return std::numeric_limits<double>::quiet_NaN();
void DestroyString(const void* s) {
static_cast<const std::string*>(s)->~basic_string();
}
ExplicitlyConstructed< ::std::string> fixed_address_empty_string;
GOOGLE_PROTOBUF_DECLARE_ONCE(empty_string_once_init_);
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY ExplicitlyConstructed<std::string>
fixed_address_empty_string{}; // NOLINT
void DeleteEmptyString() { fixed_address_empty_string.Destruct(); }
void InitEmptyString() {
PROTOBUF_CONSTINIT std::atomic<bool> init_protobuf_defaults_state{false};
static bool InitProtobufDefaultsImpl() {
fixed_address_empty_string.DefaultConstruct();
OnShutdown(&DeleteEmptyString);
OnShutdownDestroyString(fixed_address_empty_string.get_mutable());
init_protobuf_defaults_state.store(true, std::memory_order_release);
return true;
}
size_t StringSpaceUsedExcludingSelfLong(const string& str) {
void InitProtobufDefaultsSlow() {
static bool is_inited = InitProtobufDefaultsImpl();
(void)is_inited;
}
// Force the initialization of the empty string.
// Normally, registration would do it, but we don't have any guarantee that
// there is any object with reflection.
PROTOBUF_ATTRIBUTE_INIT_PRIORITY static std::true_type init_empty_string =
(InitProtobufDefaultsSlow(), std::true_type{});
size_t StringSpaceUsedExcludingSelfLong(const std::string& str) {
const void* start = &str;
const void* end = &str + 1;
if (start <= str.data() && str.data() < end) {
@@ -82,12 +101,6 @@ size_t StringSpaceUsedExcludingSelfLong(const string& str) {
}
}
void InitProtobufDefaults() {
GetEmptyString();
}
template <typename T>
const T& Get(const void* ptr) {
return *static_cast<const T*>(ptr);
@@ -103,105 +116,96 @@ struct PrimitiveTypeHelper;
template <>
struct PrimitiveTypeHelper<WireFormatLite::TYPE_BOOL> {
typedef bool Type;
static void Serialize(const void* ptr,
::google::protobuf::io::CodedOutputStream* output) {
static void Serialize(const void* ptr, io::CodedOutputStream* output) {
WireFormatLite::WriteBoolNoTag(Get<bool>(ptr), output);
}
static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) {
return WireFormatLite::WriteBoolNoTagToArray(Get<Type>(ptr), buffer);
}
};
template <>
struct PrimitiveTypeHelper<WireFormatLite::TYPE_INT32> {
typedef int32 Type;
static void Serialize(const void* ptr,
::google::protobuf::io::CodedOutputStream* output) {
WireFormatLite::WriteInt32NoTag(Get<int32>(ptr), output);
typedef int32_t Type;
static void Serialize(const void* ptr, io::CodedOutputStream* output) {
WireFormatLite::WriteInt32NoTag(Get<int32_t>(ptr), output);
}
static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) {
return WireFormatLite::WriteInt32NoTagToArray(Get<Type>(ptr), buffer);
}
};
template <>
struct PrimitiveTypeHelper<WireFormatLite::TYPE_SINT32> {
typedef int32 Type;
static void Serialize(const void* ptr,
::google::protobuf::io::CodedOutputStream* output) {
WireFormatLite::WriteSInt32NoTag(Get<int32>(ptr), output);
typedef int32_t Type;
static void Serialize(const void* ptr, io::CodedOutputStream* output) {
WireFormatLite::WriteSInt32NoTag(Get<int32_t>(ptr), output);
}
static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) {
return WireFormatLite::WriteSInt32NoTagToArray(Get<Type>(ptr), buffer);
}
};
template <>
struct PrimitiveTypeHelper<WireFormatLite::TYPE_UINT32> {
typedef uint32 Type;
static void Serialize(const void* ptr,
::google::protobuf::io::CodedOutputStream* output) {
WireFormatLite::WriteUInt32NoTag(Get<uint32>(ptr), output);
typedef uint32_t Type;
static void Serialize(const void* ptr, io::CodedOutputStream* output) {
WireFormatLite::WriteUInt32NoTag(Get<uint32_t>(ptr), output);
}
static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) {
return WireFormatLite::WriteUInt32NoTagToArray(Get<Type>(ptr), buffer);
}
};
template <>
struct PrimitiveTypeHelper<WireFormatLite::TYPE_INT64> {
typedef int64 Type;
static void Serialize(const void* ptr,
::google::protobuf::io::CodedOutputStream* output) {
WireFormatLite::WriteInt64NoTag(Get<int64>(ptr), output);
typedef int64_t Type;
static void Serialize(const void* ptr, io::CodedOutputStream* output) {
WireFormatLite::WriteInt64NoTag(Get<int64_t>(ptr), output);
}
static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) {
return WireFormatLite::WriteInt64NoTagToArray(Get<Type>(ptr), buffer);
}
};
template <>
struct PrimitiveTypeHelper<WireFormatLite::TYPE_SINT64> {
typedef int64 Type;
static void Serialize(const void* ptr,
::google::protobuf::io::CodedOutputStream* output) {
WireFormatLite::WriteSInt64NoTag(Get<int64>(ptr), output);
typedef int64_t Type;
static void Serialize(const void* ptr, io::CodedOutputStream* output) {
WireFormatLite::WriteSInt64NoTag(Get<int64_t>(ptr), output);
}
static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) {
return WireFormatLite::WriteSInt64NoTagToArray(Get<Type>(ptr), buffer);
}
};
template <>
struct PrimitiveTypeHelper<WireFormatLite::TYPE_UINT64> {
typedef uint64 Type;
static void Serialize(const void* ptr,
::google::protobuf::io::CodedOutputStream* output) {
WireFormatLite::WriteUInt64NoTag(Get<uint64>(ptr), output);
typedef uint64_t Type;
static void Serialize(const void* ptr, io::CodedOutputStream* output) {
WireFormatLite::WriteUInt64NoTag(Get<uint64_t>(ptr), output);
}
static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) {
return WireFormatLite::WriteUInt64NoTagToArray(Get<Type>(ptr), buffer);
}
};
template <>
struct PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED32> {
typedef uint32 Type;
static void Serialize(const void* ptr,
::google::protobuf::io::CodedOutputStream* output) {
WireFormatLite::WriteFixed32NoTag(Get<uint32>(ptr), output);
typedef uint32_t Type;
static void Serialize(const void* ptr, io::CodedOutputStream* output) {
WireFormatLite::WriteFixed32NoTag(Get<uint32_t>(ptr), output);
}
static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) {
return WireFormatLite::WriteFixed32NoTagToArray(Get<Type>(ptr), buffer);
}
};
template <>
struct PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED64> {
typedef uint64 Type;
static void Serialize(const void* ptr,
::google::protobuf::io::CodedOutputStream* output) {
WireFormatLite::WriteFixed64NoTag(Get<uint64>(ptr), output);
typedef uint64_t Type;
static void Serialize(const void* ptr, io::CodedOutputStream* output) {
WireFormatLite::WriteFixed64NoTag(Get<uint64_t>(ptr), output);
}
static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) {
return WireFormatLite::WriteFixed64NoTagToArray(Get<Type>(ptr), buffer);
}
};
@@ -213,12 +217,12 @@ struct PrimitiveTypeHelper<WireFormatLite::TYPE_ENUM>
template <>
struct PrimitiveTypeHelper<WireFormatLite::TYPE_SFIXED32>
: PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED32> {
typedef int32 Type;
typedef int32_t Type;
};
template <>
struct PrimitiveTypeHelper<WireFormatLite::TYPE_SFIXED64>
: PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED64> {
typedef int64 Type;
typedef int64_t Type;
};
template <>
struct PrimitiveTypeHelper<WireFormatLite::TYPE_FLOAT>
@@ -233,14 +237,13 @@ struct PrimitiveTypeHelper<WireFormatLite::TYPE_DOUBLE>
template <>
struct PrimitiveTypeHelper<WireFormatLite::TYPE_STRING> {
typedef string Type;
static void Serialize(const void* ptr,
::google::protobuf::io::CodedOutputStream* output) {
typedef std::string Type;
static void Serialize(const void* ptr, io::CodedOutputStream* output) {
const Type& value = *static_cast<const Type*>(ptr);
output->WriteVarint32(value.size());
output->WriteRawMaybeAliased(value.data(), value.size());
}
static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) {
const Type& value = *static_cast<const Type*>(ptr);
return io::CodedOutputStream::WriteStringWithSizeToArray(value, buffer);
}
@@ -251,6 +254,10 @@ struct PrimitiveTypeHelper<WireFormatLite::TYPE_BYTES>
: PrimitiveTypeHelper<WireFormatLite::TYPE_STRING> {};
template <>
struct PrimitiveTypeHelper<FieldMetadata::kInlinedType>
: PrimitiveTypeHelper<WireFormatLite::TYPE_STRING> {};
// We want to serialize to both CodedOutputStream and directly into byte arrays
// without duplicating the code. In fact we might want extra output channels in
// the future.
@@ -263,27 +270,26 @@ void SerializeTo(const void* ptr, O* output) {
}
template <typename O>
void WriteTagTo(uint32 tag, O* output) {
void WriteTagTo(uint32_t tag, O* output) {
SerializeTo<WireFormatLite::TYPE_UINT32>(&tag, output);
}
template <typename O>
void WriteLengthTo(uint32 length, O* output) {
void WriteLengthTo(uint32_t length, O* output) {
SerializeTo<WireFormatLite::TYPE_UINT32>(&length, output);
}
// Specialization for coded output stream
template <int type>
struct OutputHelper< ::google::protobuf::io::CodedOutputStream, type> {
static void Serialize(const void* ptr,
::google::protobuf::io::CodedOutputStream* output) {
struct OutputHelper<io::CodedOutputStream, type> {
static void Serialize(const void* ptr, io::CodedOutputStream* output) {
PrimitiveTypeHelper<type>::Serialize(ptr, output);
}
};
// Specialization for writing into a plain array
struct ArrayOutput {
uint8* ptr;
uint8_t* ptr;
bool is_deterministic;
};
@@ -295,38 +301,32 @@ struct OutputHelper<ArrayOutput, type> {
};
void SerializeMessageNoTable(const MessageLite* msg,
::google::protobuf::io::CodedOutputStream* output) {
io::CodedOutputStream* output) {
msg->SerializeWithCachedSizes(output);
}
void SerializeMessageNoTable(const MessageLite* msg, ArrayOutput* output) {
output->ptr = msg->InternalSerializeWithCachedSizesToArray(
output->is_deterministic, output->ptr);
io::ArrayOutputStream array_stream(output->ptr, INT_MAX);
io::CodedOutputStream o(&array_stream);
o.SetSerializationDeterministic(output->is_deterministic);
msg->SerializeWithCachedSizes(&o);
output->ptr += o.ByteCount();
}
// Helper to branch to fast path if possible
void SerializeMessageDispatch(const ::google::protobuf::MessageLite& msg,
void SerializeMessageDispatch(const MessageLite& msg,
const FieldMetadata* field_table, int num_fields,
int32 cached_size,
::google::protobuf::io::CodedOutputStream* output) {
const uint8* base = reinterpret_cast<const uint8*>(&msg);
// Try the fast path
uint8* ptr = output->GetDirectBufferForNBytesAndAdvance(cached_size);
if (ptr) {
// We use virtual dispatch to enable dedicated generated code for the
// fast path.
msg.InternalSerializeWithCachedSizesToArray(
output->IsSerializationDeterministic(), ptr);
return;
}
int32_t /*cached_size*/,
io::CodedOutputStream* output) {
const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg);
SerializeInternal(base, field_table, num_fields, output);
}
// Helper to branch to fast path if possible
void SerializeMessageDispatch(const ::google::protobuf::MessageLite& msg,
void SerializeMessageDispatch(const MessageLite& msg,
const FieldMetadata* field_table, int num_fields,
int32 cached_size, ArrayOutput* output) {
const uint8* base = reinterpret_cast<const uint8*>(&msg);
int32_t /*cached_size*/, ArrayOutput* output) {
const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg);
output->ptr = SerializeInternalToArray(base, field_table, num_fields,
output->is_deterministic, output->ptr);
}
@@ -345,8 +345,9 @@ void SerializeMessageTo(const MessageLite* msg, const void* table_ptr,
return;
}
const FieldMetadata* field_table = table->field_table;
const uint8* base = reinterpret_cast<const uint8*>(msg);
int cached_size = *reinterpret_cast<const int32*>(base + field_table->offset);
const uint8_t* base = reinterpret_cast<const uint8_t*>(msg);
int cached_size =
*reinterpret_cast<const int32_t*>(base + field_table->offset);
WriteLengthTo(cached_size, output);
int num_fields = table->num_fields - 1;
SerializeMessageDispatch(*msg, field_table + 1, num_fields, cached_size,
@@ -365,8 +366,9 @@ void SerializeGroupTo(const MessageLite* msg, const void* table_ptr,
return;
}
const FieldMetadata* field_table = table->field_table;
const uint8* base = reinterpret_cast<const uint8*>(msg);
int cached_size = *reinterpret_cast<const int32*>(base + field_table->offset);
const uint8_t* base = reinterpret_cast<const uint8_t*>(msg);
int cached_size =
*reinterpret_cast<const int32_t*>(base + field_table->offset);
int num_fields = table->num_fields - 1;
SerializeMessageDispatch(*msg, field_table + 1, num_fields, cached_size,
output);
@@ -416,6 +418,15 @@ struct SingularFieldHelper<WireFormatLite::TYPE_MESSAGE> {
}
};
template <>
struct SingularFieldHelper<FieldMetadata::kInlinedType> {
template <typename O>
static void Serialize(const void* field, const FieldMetadata& md, O* output) {
WriteTagTo(md.tag, output);
SerializeTo<FieldMetadata::kInlinedType>(&Get<std::string>(field), output);
}
};
template <int type>
struct RepeatedFieldHelper {
template <typename O>
@@ -481,13 +492,17 @@ struct RepeatedFieldHelper<WireFormatLite::TYPE_MESSAGE> {
for (int i = 0; i < AccessorHelper::Size(array); i++) {
WriteTagTo(md.tag, output);
SerializeMessageTo(
static_cast<const MessageLite*>(AccessorHelper::Get(array, i)), md.ptr,
output);
static_cast<const MessageLite*>(AccessorHelper::Get(array, i)),
md.ptr, output);
}
}
};
template <>
struct RepeatedFieldHelper<FieldMetadata::kInlinedType>
: RepeatedFieldHelper<WireFormatLite::TYPE_STRING> {};
template <int type>
struct PackedFieldHelper {
template <typename O>
@@ -497,7 +512,7 @@ struct PackedFieldHelper {
if (array.empty()) return;
WriteTagTo(md.tag, output);
int cached_size =
Get<int>(static_cast<const uint8*>(field) + sizeof(RepeatedField<T>));
Get<int>(static_cast<const uint8_t*>(field) + sizeof(RepeatedField<T>));
WriteLengthTo(cached_size, output);
for (int i = 0; i < array.size(); i++) {
SerializeTo<type>(&array[i], output);
@@ -508,7 +523,8 @@ struct PackedFieldHelper {
template <>
struct PackedFieldHelper<WireFormatLite::TYPE_STRING> {
template <typename O>
static void Serialize(const void* field, const FieldMetadata& md, O* output) {
static void Serialize(const void* /*field*/, const FieldMetadata& md,
O* /*output*/) {
GOOGLE_LOG(FATAL) << "Not implemented field number " << md.tag << " with type "
<< md.type;
}
@@ -523,6 +539,9 @@ struct PackedFieldHelper<WireFormatLite::TYPE_GROUP>
template <>
struct PackedFieldHelper<WireFormatLite::TYPE_MESSAGE>
: PackedFieldHelper<WireFormatLite::TYPE_STRING> {};
template <>
struct PackedFieldHelper<FieldMetadata::kInlinedType>
: PackedFieldHelper<WireFormatLite::TYPE_STRING> {};
template <int type>
struct OneOfFieldHelper {
@@ -533,6 +552,15 @@ struct OneOfFieldHelper {
};
template <>
struct OneOfFieldHelper<FieldMetadata::kInlinedType> {
template <typename O>
static void Serialize(const void* field, const FieldMetadata& md, O* output) {
SingularFieldHelper<FieldMetadata::kInlinedType>::Serialize(
Get<const std::string*>(field), md, output);
}
};
void SerializeNotImplemented(int field) {
GOOGLE_LOG(FATAL) << "Not implemented field number " << field;
}
@@ -564,15 +592,20 @@ bool IsNull<WireFormatLite::TYPE_BYTES>(const void* ptr) {
template <>
bool IsNull<WireFormatLite::TYPE_GROUP>(const void* ptr) {
return Get<const MessageLite*>(ptr) == NULL;
return Get<const MessageLite*>(ptr) == nullptr;
}
template <>
bool IsNull<WireFormatLite::TYPE_MESSAGE>(const void* ptr) {
return Get<const MessageLite*>(ptr) == NULL;
return Get<const MessageLite*>(ptr) == nullptr;
}
template <>
bool IsNull<FieldMetadata::kInlinedType>(const void* ptr) {
return static_cast<const std::string*>(ptr)->empty();
}
#define SERIALIZERS_FOR_TYPE(type) \
case SERIALIZE_TABLE_OP(type, FieldMetadata::kPresence): \
if (!IsPresent(base, field_metadata.has_offset)) continue; \
@@ -594,13 +627,13 @@ bool IsNull<WireFormatLite::TYPE_MESSAGE>(const void* ptr) {
OneOfFieldHelper<type>::Serialize(ptr, field_metadata, output); \
break
void SerializeInternal(const uint8* base,
void SerializeInternal(const uint8_t* base,
const FieldMetadata* field_metadata_table,
int32 num_fields,
::google::protobuf::io::CodedOutputStream* output) {
int32_t num_fields, io::CodedOutputStream* output) {
SpecialSerializer func = nullptr;
for (int i = 0; i < num_fields; i++) {
const FieldMetadata& field_metadata = field_metadata_table[i];
const uint8* ptr = base + field_metadata.offset;
const uint8_t* ptr = base + field_metadata.offset;
switch (field_metadata.type) {
SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_DOUBLE);
SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FLOAT);
@@ -620,13 +653,14 @@ void SerializeInternal(const uint8* base,
SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED64);
SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT32);
SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT64);
SERIALIZERS_FOR_TYPE(FieldMetadata::kInlinedType);
// Special cases
case FieldMetadata::kSpecial:
reinterpret_cast<SpecialSerializer>(
const_cast<void*>(field_metadata.ptr))(
base, field_metadata.offset, field_metadata.tag,
field_metadata.has_offset, output);
func = reinterpret_cast<SpecialSerializer>(
const_cast<void*>(field_metadata.ptr));
func(base, field_metadata.offset, field_metadata.tag,
field_metadata.has_offset, output);
break;
default:
// __builtin_unreachable()
@@ -635,15 +669,16 @@ void SerializeInternal(const uint8* base,
}
}
uint8* SerializeInternalToArray(const uint8* base,
const FieldMetadata* field_metadata_table,
int32 num_fields, bool is_deterministic,
uint8* buffer) {
uint8_t* SerializeInternalToArray(const uint8_t* base,
const FieldMetadata* field_metadata_table,
int32_t num_fields, bool is_deterministic,
uint8_t* buffer) {
ArrayOutput array_output = {buffer, is_deterministic};
ArrayOutput* output = &array_output;
SpecialSerializer func = nullptr;
for (int i = 0; i < num_fields; i++) {
const FieldMetadata& field_metadata = field_metadata_table[i];
const uint8* ptr = base + field_metadata.offset;
const uint8_t* ptr = base + field_metadata.offset;
switch (field_metadata.type) {
SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_DOUBLE);
SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FLOAT);
@@ -663,16 +698,17 @@ uint8* SerializeInternalToArray(const uint8* base,
SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED64);
SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT32);
SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT64);
SERIALIZERS_FOR_TYPE(FieldMetadata::kInlinedType);
// Special cases
case FieldMetadata::kSpecial: {
io::ArrayOutputStream array_stream(array_output.ptr, INT_MAX);
io::CodedOutputStream output(&array_stream);
output.SetSerializationDeterministic(is_deterministic);
reinterpret_cast<SpecialSerializer>(
const_cast<void*>(field_metadata.ptr))(
base, field_metadata.offset, field_metadata.tag,
field_metadata.has_offset, &output);
array_output.ptr += output.ByteCount();
io::CodedOutputStream output_stream(&array_stream);
output_stream.SetSerializationDeterministic(is_deterministic);
func = reinterpret_cast<SpecialSerializer>(
const_cast<void*>(field_metadata.ptr));
func(base, field_metadata.offset, field_metadata.tag,
field_metadata.has_offset, &output_stream);
array_output.ptr += output_stream.ByteCount();
} break;
default:
// __builtin_unreachable()
@@ -683,39 +719,50 @@ uint8* SerializeInternalToArray(const uint8* base,
}
#undef SERIALIZERS_FOR_TYPE
void ExtensionSerializer(const uint8* ptr, uint32 offset, uint32 tag,
uint32 has_offset,
::google::protobuf::io::CodedOutputStream* output) {
void ExtensionSerializer(const MessageLite* extendee, const uint8_t* ptr,
uint32_t offset, uint32_t tag, uint32_t has_offset,
io::CodedOutputStream* output) {
reinterpret_cast<const ExtensionSet*>(ptr + offset)
->SerializeWithCachedSizes(tag, has_offset, output);
->SerializeWithCachedSizes(extendee, tag, has_offset, output);
}
void UnknownFieldSerializerLite(const uint8* ptr, uint32 offset, uint32 tag,
uint32 has_offset,
::google::protobuf::io::CodedOutputStream* output) {
void UnknownFieldSerializerLite(const uint8_t* ptr, uint32_t offset,
uint32_t /*tag*/, uint32_t /*has_offset*/,
io::CodedOutputStream* output) {
output->WriteString(
reinterpret_cast<const InternalMetadataWithArenaLite*>(ptr + offset)
->unknown_fields());
reinterpret_cast<const InternalMetadata*>(ptr + offset)
->unknown_fields<std::string>(&internal::GetEmptyString));
}
MessageLite* DuplicateIfNonNullInternal(MessageLite* message, Arena* arena) {
MessageLite* DuplicateIfNonNullInternal(MessageLite* message) {
if (message) {
MessageLite* ret = message->New(arena);
MessageLite* ret = message->New();
ret->CheckTypeAndMergeFrom(*message);
return ret;
} else {
return NULL;
return nullptr;
}
}
void GenericSwap(MessageLite* m1, MessageLite* m2) {
std::unique_ptr<MessageLite> tmp(m1->New());
tmp->CheckTypeAndMergeFrom(*m1);
m1->Clear();
m1->CheckTypeAndMergeFrom(*m2);
m2->Clear();
m2->CheckTypeAndMergeFrom(*tmp);
}
// Returns a message owned by this Arena. This may require Own()ing or
// duplicating the message.
MessageLite* GetOwnedMessageInternal(Arena* message_arena,
MessageLite* submessage,
Arena* submessage_arena) {
GOOGLE_DCHECK(submessage->GetArena() == submessage_arena);
GOOGLE_DCHECK(Arena::InternalHelper<MessageLite>::GetOwningArena(submessage) ==
submessage_arena);
GOOGLE_DCHECK(message_arena != submessage_arena);
if (message_arena != NULL && submessage_arena == NULL) {
GOOGLE_DCHECK_EQ(submessage_arena, nullptr);
if (message_arena != nullptr && submessage_arena == nullptr) {
message_arena->Own(submessage);
return submessage;
} else {
@@ -728,3 +775,5 @@ MessageLite* GetOwnedMessageInternal(Arena* message_arena,
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
+111 -218
View File
@@ -39,73 +39,69 @@
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
#include <assert.h>
#include <atomic>
#include <climits>
#include <string>
#include <vector>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/any.h>
#include <google/protobuf/has_bits.h>
#include <google/protobuf/map_entry_lite.h>
#include <google/protobuf/implicit_weak_message.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/stubs/once.h> // Add direct dep on port for pb.cc
#include <google/protobuf/port.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/casts.h>
#include <google/protobuf/port_def.inc>
#ifdef SWIG
#error "You cannot SWIG proto headers"
#endif
namespace google {
namespace protobuf {
class Arena;
class Message;
namespace io { class CodedInputStream; }
namespace io {
class CodedInputStream;
}
namespace internal {
// Annotation for the compiler to emit a deprecation message if a field marked
// with option 'deprecated=true' is used in the code, or for other things in
// generated code which are deprecated.
//
// For internal use in the pb.cc files, deprecation warnings are suppressed
// there.
#undef DEPRECATED_PROTOBUF_FIELD
#define PROTOBUF_DEPRECATED
#define GOOGLE_PROTOBUF_DEPRECATED_ATTR
template <typename To, typename From>
inline To DownCast(From* f) {
return PROTOBUF_NAMESPACE_ID::internal::down_cast<To>(f);
}
template <typename To, typename From>
inline To DownCast(From& f) {
return PROTOBUF_NAMESPACE_ID::internal::down_cast<To>(f);
}
// Returns the offset of the given field within the given aggregate type.
// This is equivalent to the ANSI C offsetof() macro. However, according
// to the C++ standard, offsetof() only works on POD types, and GCC
// enforces this requirement with a warning. In practice, this rule is
// unnecessarily strict; there is probably no compiler or platform on
// which the offsets of the direct fields of a class are non-constant.
// Fields inherited from superclasses *can* have non-constant offsets,
// but that's not what this macro will be used for.
#if defined(__clang__)
// For Clang we use __builtin_offsetof() and suppress the warning,
// to avoid Control Flow Integrity and UBSan vptr sanitizers from
// crashing while trying to validate the invalid reinterpet_casts.
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
__builtin_offsetof(TYPE, FIELD) \
_Pragma("clang diagnostic pop")
#else
// Note that we calculate relative to the pointer value 16 here since if we
// just use zero, GCC complains about dereferencing a NULL pointer. We
// choose 16 rather than some other number just in case the compiler would
// be confused by an unaligned pointer.
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \
static_cast< ::google::protobuf::uint32>( \
reinterpret_cast<const char*>( \
&reinterpret_cast<const TYPE*>(16)->FIELD) - \
reinterpret_cast<const char*>(16))
#endif
// This fastpath inlines a single branch instead of having to make the
// InitProtobufDefaults function call.
// It also generates less inlined code than a function-scope static initializer.
PROTOBUF_EXPORT extern std::atomic<bool> init_protobuf_defaults_state;
PROTOBUF_EXPORT void InitProtobufDefaultsSlow();
PROTOBUF_EXPORT inline void InitProtobufDefaults() {
if (PROTOBUF_PREDICT_FALSE(
!init_protobuf_defaults_state.load(std::memory_order_acquire))) {
InitProtobufDefaultsSlow();
}
}
// Constants for special floating point values.
LIBPROTOBUF_EXPORT double Infinity();
LIBPROTOBUF_EXPORT double NaN();
// This used by proto1
PROTOBUF_EXPORT inline const std::string& GetEmptyString() {
InitProtobufDefaults();
return GetEmptyStringAlreadyInited();
}
// True if IsInitialized() is true for all elements of t. Type is expected
@@ -113,178 +109,67 @@ LIBPROTOBUF_EXPORT double NaN();
// helper here to keep the protobuf compiler from ever having to emit loops in
// IsInitialized() methods. We want the C++ compiler to inline this or not
// as it sees fit.
template <class Type> bool AllAreInitialized(const Type& t) {
for (int i = t.size(); --i >= 0; ) {
template <typename Msg>
bool AllAreInitialized(const RepeatedPtrField<Msg>& t) {
for (int i = t.size(); --i >= 0;) {
if (!t.Get(i).IsInitialized()) return false;
}
return true;
}
LIBPROTOBUF_EXPORT void InitProtobufDefaults();
struct LIBPROTOBUF_EXPORT FieldMetadata {
uint32 offset; // offset of this field in the struct
uint32 tag; // field * 8 + wire_type
// byte offset * 8 + bit_offset;
// if the high bit is set then this is the byte offset of the oneof_case
// for this field.
uint32 has_offset;
uint32 type; // the type of this field.
const void* ptr; // auxiliary data
// From the serializer point of view each fundamental type can occur in
// 4 different ways. For simplicity we treat all combinations as a cartesion
// product although not all combinations are allowed.
enum FieldTypeClass {
kPresence,
kNoPresence,
kRepeated,
kPacked,
kOneOf,
kNumTypeClasses // must be last enum
};
// C++ protobuf has 20 fundamental types, were we added Cord and StringPiece
// and also distinquish the same types if they have different wire format.
enum {
kCordType = 19,
kStringPieceType = 20,
kNumTypes = 20,
kSpecial = kNumTypes * kNumTypeClasses,
};
static int CalculateType(int fundamental_type, FieldTypeClass type_class);
};
inline bool IsPresent(const void* base, uint32 hasbit) {
const uint32* has_bits_array = static_cast<const uint32*>(base);
return has_bits_array[hasbit / 32] & (1u << (hasbit & 31));
// "Weak" variant of AllAreInitialized, used to implement implicit weak fields.
// This version operates on MessageLite to avoid introducing a dependency on the
// concrete message type.
template <class T>
bool AllAreInitializedWeak(const RepeatedPtrField<T>& t) {
for (int i = t.size(); --i >= 0;) {
if (!reinterpret_cast<const RepeatedPtrFieldBase&>(t)
.Get<ImplicitWeakTypeHandler<T> >(i)
.IsInitialized()) {
return false;
}
}
return true;
}
inline bool IsOneofPresent(const void* base, uint32 offset, uint32 tag) {
const uint32* oneof =
reinterpret_cast<const uint32*>(static_cast<const uint8*>(base) + offset);
inline bool IsPresent(const void* base, uint32_t hasbit) {
const uint32_t* has_bits_array = static_cast<const uint32_t*>(base);
return (has_bits_array[hasbit / 32] & (1u << (hasbit & 31))) != 0;
}
inline bool IsOneofPresent(const void* base, uint32_t offset, uint32_t tag) {
const uint32_t* oneof = reinterpret_cast<const uint32_t*>(
static_cast<const uint8_t*>(base) + offset);
return *oneof == tag >> 3;
}
typedef void (*SpecialSerializer)(const uint8* base, uint32 offset, uint32 tag,
uint32 has_offset,
::google::protobuf::io::CodedOutputStream* output);
typedef void (*SpecialSerializer)(const uint8_t* base, uint32_t offset,
uint32_t tag, uint32_t has_offset,
io::CodedOutputStream* output);
LIBPROTOBUF_EXPORT void ExtensionSerializer(const uint8* base, uint32 offset, uint32 tag,
uint32 has_offset,
::google::protobuf::io::CodedOutputStream* output);
LIBPROTOBUF_EXPORT void UnknownFieldSerializerLite(const uint8* base, uint32 offset, uint32 tag,
uint32 has_offset,
::google::protobuf::io::CodedOutputStream* output);
PROTOBUF_EXPORT void ExtensionSerializer(const MessageLite* extendee,
const uint8_t* ptr, uint32_t offset,
uint32_t tag, uint32_t has_offset,
io::CodedOutputStream* output);
PROTOBUF_EXPORT void UnknownFieldSerializerLite(const uint8_t* base,
uint32_t offset, uint32_t tag,
uint32_t has_offset,
io::CodedOutputStream* output);
struct SerializationTable {
int num_fields;
const FieldMetadata* field_table;
};
LIBPROTOBUF_EXPORT void SerializeInternal(const uint8* base, const FieldMetadata* table,
int num_fields, ::google::protobuf::io::CodedOutputStream* output);
inline void TableSerialize(const ::google::protobuf::MessageLite& msg,
const SerializationTable* table,
::google::protobuf::io::CodedOutputStream* output) {
const FieldMetadata* field_table = table->field_table;
int num_fields = table->num_fields - 1;
const uint8* base = reinterpret_cast<const uint8*>(&msg);
// TODO(gerbens) This skips the first test if we could use the fast
// array serialization path, we should make this
// int cached_size =
// *reinterpret_cast<const int32*>(base + field_table->offset);
// SerializeWithCachedSize(msg, field_table + 1, num_fields, cached_size, ...)
// But we keep conformance with the old way for now.
SerializeInternal(base, field_table + 1, num_fields, output);
}
uint8* SerializeInternalToArray(const uint8* base, const FieldMetadata* table,
int num_fields, bool is_deterministic,
uint8* buffer);
inline uint8* TableSerializeToArray(const ::google::protobuf::MessageLite& msg,
const SerializationTable* table,
bool is_deterministic, uint8* buffer) {
const uint8* base = reinterpret_cast<const uint8*>(&msg);
const FieldMetadata* field_table = table->field_table + 1;
int num_fields = table->num_fields - 1;
return SerializeInternalToArray(base, field_table, num_fields,
is_deterministic, buffer);
}
PROTOBUF_EXPORT MessageLite* DuplicateIfNonNullInternal(MessageLite* message);
PROTOBUF_EXPORT MessageLite* GetOwnedMessageInternal(Arena* message_arena,
MessageLite* submessage,
Arena* submessage_arena);
PROTOBUF_EXPORT void GenericSwap(MessageLite* m1, MessageLite* m2);
// We specialize GenericSwap for non-lite messages to benefit from reflection.
PROTOBUF_EXPORT void GenericSwap(Message* m1, Message* m2);
template <typename T>
struct CompareHelper {
bool operator()(const T& a, const T& b) { return a < b; }
};
template <>
struct CompareHelper<ArenaStringPtr> {
bool operator()(const ArenaStringPtr& a, const ArenaStringPtr& b) {
return a.Get() < b.Get();
}
};
struct CompareMapKey {
template <typename T>
bool operator()(const MapEntryHelper<T>& a, const MapEntryHelper<T>& b) {
return Compare(a.key_, b.key_);
}
template <typename T>
bool Compare(const T& a, const T& b) {
return CompareHelper<T>()(a, b);
}
};
template <typename MapFieldType, const SerializationTable* table>
void MapFieldSerializer(const uint8* base, uint32 offset, uint32 tag,
uint32 has_offset,
::google::protobuf::io::CodedOutputStream* output) {
typedef MapEntryHelper<typename MapFieldType::EntryTypeTrait> Entry;
typedef typename MapFieldType::MapType::const_iterator Iter;
const MapFieldType& map_field =
*reinterpret_cast<const MapFieldType*>(base + offset);
const SerializationTable* t =
table +
has_offset; // has_offset is overloaded for maps to mean table offset
if (!output->IsSerializationDeterministic()) {
for (Iter it = map_field.GetMap().begin(); it != map_field.GetMap().end();
++it) {
Entry map_entry(*it);
output->WriteVarint32(tag);
output->WriteVarint32(map_entry._cached_size_);
SerializeInternal(reinterpret_cast<const uint8*>(&map_entry),
t->field_table, t->num_fields, output);
}
} else {
std::vector<Entry> v;
for (Iter it = map_field.GetMap().begin(); it != map_field.GetMap().end();
++it) {
v.push_back(Entry(*it));
}
std::sort(v.begin(), v.end(), CompareMapKey());
for (int i = 0; i < v.size(); i++) {
output->WriteVarint32(tag);
output->WriteVarint32(v[i]._cached_size_);
SerializeInternal(reinterpret_cast<const uint8*>(&v[i]), t->field_table,
t->num_fields, output);
}
}
}
LIBPROTOBUF_EXPORT MessageLite* DuplicateIfNonNullInternal(MessageLite* message, Arena* arena);
LIBPROTOBUF_EXPORT MessageLite* GetOwnedMessageInternal(Arena* message_arena,
MessageLite* submessage,
Arena* submessage_arena);
template <typename T>
T* DuplicateIfNonNull(T* message, Arena* arena) {
T* DuplicateIfNonNull(T* message) {
// The casts must be reinterpret_cast<> because T might be a forward-declared
// type that the compiler doesn't know is related to MessageLite.
return reinterpret_cast<T*>(DuplicateIfNonNullInternal(
reinterpret_cast<MessageLite*>(message), arena));
return reinterpret_cast<T*>(
DuplicateIfNonNullInternal(reinterpret_cast<MessageLite*>(message)));
}
template <typename T>
@@ -297,24 +182,32 @@ T* GetOwnedMessage(Arena* message_arena, T* submessage,
submessage_arena));
}
// Returns a message owned by this Arena. This may require Own()ing or
// duplicating the message.
template <typename T>
T* GetOwnedMessage(T* message, Arena* arena) {
GOOGLE_DCHECK(message);
Arena* message_arena = google::protobuf::Arena::GetArena(message);
if (message_arena == arena) {
return message;
} else if (arena != NULL && message_arena == NULL) {
arena->Own(message);
return message;
} else {
return DuplicateIfNonNull(message, arena);
}
// Hide atomic from the public header and allow easy change to regular int
// on platforms where the atomic might have a perf impact.
class PROTOBUF_EXPORT CachedSize {
public:
int Get() const { return size_.load(std::memory_order_relaxed); }
void Set(int size) { size_.store(size, std::memory_order_relaxed); }
private:
std::atomic<int> size_{0};
};
PROTOBUF_EXPORT void DestroyMessage(const void* message);
PROTOBUF_EXPORT void DestroyString(const void* s);
// Destroy (not delete) the message
inline void OnShutdownDestroyMessage(const void* ptr) {
OnShutdownRun(DestroyMessage, ptr);
}
// Destroy the string (call std::string destructor)
inline void OnShutdownDestroyString(const std::string* ptr) {
OnShutdownRun(DestroyString, ptr);
}
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
+20 -9
View File
@@ -32,27 +32,32 @@
#define GOOGLE_PROTOBUF_HAS_BITS_H__
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/port.h>
#include <google/protobuf/port_def.inc>
#ifdef SWIG
#error "You cannot SWIG proto headers"
#endif
namespace google {
namespace protobuf {
namespace internal {
template<size_t doublewords>
template <size_t doublewords>
class HasBits {
public:
HasBits() GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE { Clear(); }
PROTOBUF_NDEBUG_INLINE constexpr HasBits() : has_bits_{} {}
void Clear() GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
PROTOBUF_NDEBUG_INLINE void Clear() {
memset(has_bits_, 0, sizeof(has_bits_));
}
::google::protobuf::uint32& operator[](int index) GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
PROTOBUF_NDEBUG_INLINE uint32_t& operator[](int index) {
return has_bits_[index];
}
const ::google::protobuf::uint32& operator[](int index) const
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
PROTOBUF_NDEBUG_INLINE const uint32_t& operator[](int index) const {
return has_bits_[index];
}
@@ -64,10 +69,14 @@ class HasBits {
return !(*this == rhs);
}
void Or(const HasBits<doublewords>& rhs) {
for (size_t i = 0; i < doublewords; i++) has_bits_[i] |= rhs[i];
}
bool empty() const;
private:
::google::protobuf::uint32 has_bits_[doublewords];
uint32_t has_bits_[doublewords];
};
template <>
@@ -100,6 +109,8 @@ inline bool HasBits<doublewords>::empty() const {
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_HAS_BITS_H__
@@ -28,19 +28,40 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/stubs/statusor.h>
#include <google/protobuf/implicit_weak_message.h>
#include <google/protobuf/parse_context.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace util {
namespace internal {
void StatusOrHelper::Crash(const Status& status) {
GOOGLE_LOG(FATAL) << "Attempting to fetch value instead of handling error "
<< status.ToString();
const char* ImplicitWeakMessage::_InternalParse(const char* ptr,
ParseContext* ctx) {
return ctx->AppendString(ptr, &data_);
}
ExplicitlyConstructed<ImplicitWeakMessage>
implicit_weak_message_default_instance;
internal::once_flag implicit_weak_message_once_init_;
void InitImplicitWeakMessageDefaultInstance() {
implicit_weak_message_default_instance.DefaultConstruct();
}
const ImplicitWeakMessage* ImplicitWeakMessage::default_instance() {
internal::call_once(implicit_weak_message_once_init_,
InitImplicitWeakMessageDefaultInstance);
return &implicit_weak_message_default_instance.get();
}
} // namespace internal
} // namespace util
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
@@ -0,0 +1,186 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__
#define GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__
#include <string>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#ifdef SWIG
#error "You cannot SWIG proto headers"
#endif
#include <google/protobuf/port_def.inc>
// This file is logically internal-only and should only be used by protobuf
// generated code.
namespace google {
namespace protobuf {
namespace internal {
// An implementation of MessageLite that treats all data as unknown. This type
// acts as a placeholder for an implicit weak field in the case where the true
// message type does not get linked into the binary.
class PROTOBUF_EXPORT ImplicitWeakMessage : public MessageLite {
public:
ImplicitWeakMessage() {}
explicit ImplicitWeakMessage(Arena* arena) : MessageLite(arena) {}
static const ImplicitWeakMessage* default_instance();
std::string GetTypeName() const override { return ""; }
MessageLite* New(Arena* arena) const override {
return Arena::CreateMessage<ImplicitWeakMessage>(arena);
}
void Clear() override { data_.clear(); }
bool IsInitialized() const override { return true; }
void CheckTypeAndMergeFrom(const MessageLite& other) override {
data_.append(static_cast<const ImplicitWeakMessage&>(other).data_);
}
const char* _InternalParse(const char* ptr, ParseContext* ctx) final;
size_t ByteSizeLong() const override { return data_.size(); }
uint8_t* _InternalSerialize(uint8_t* target,
io::EpsCopyOutputStream* stream) const final {
return stream->WriteRaw(data_.data(), static_cast<int>(data_.size()),
target);
}
int GetCachedSize() const override { return static_cast<int>(data_.size()); }
typedef void InternalArenaConstructable_;
private:
std::string data_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImplicitWeakMessage);
};
// A type handler for use with implicit weak repeated message fields.
template <typename ImplicitWeakType>
class ImplicitWeakTypeHandler {
public:
typedef MessageLite Type;
static constexpr bool Moveable = false;
static inline MessageLite* NewFromPrototype(const MessageLite* prototype,
Arena* arena = nullptr) {
return prototype->New(arena);
}
static inline void Delete(MessageLite* value, Arena* arena) {
if (arena == nullptr) {
delete value;
}
}
static inline Arena* GetArena(MessageLite* value) {
return value->GetArena();
}
static inline void Clear(MessageLite* value) { value->Clear(); }
static void Merge(const MessageLite& from, MessageLite* to) {
to->CheckTypeAndMergeFrom(from);
}
};
} // namespace internal
template <typename T>
struct WeakRepeatedPtrField {
using TypeHandler = internal::ImplicitWeakTypeHandler<T>;
constexpr WeakRepeatedPtrField() : weak() {}
explicit WeakRepeatedPtrField(Arena* arena) : weak(arena) {}
~WeakRepeatedPtrField() { weak.template Destroy<TypeHandler>(); }
typedef internal::RepeatedPtrIterator<MessageLite> iterator;
typedef internal::RepeatedPtrIterator<const MessageLite> const_iterator;
typedef internal::RepeatedPtrOverPtrsIterator<MessageLite*, void*>
pointer_iterator;
typedef internal::RepeatedPtrOverPtrsIterator<const MessageLite* const,
const void* const>
const_pointer_iterator;
iterator begin() { return iterator(base().raw_data()); }
const_iterator begin() const { return iterator(base().raw_data()); }
const_iterator cbegin() const { return begin(); }
iterator end() { return begin() + base().size(); }
const_iterator end() const { return begin() + base().size(); }
const_iterator cend() const { return end(); }
pointer_iterator pointer_begin() {
return pointer_iterator(base().raw_mutable_data());
}
const_pointer_iterator pointer_begin() const {
return const_pointer_iterator(base().raw_mutable_data());
}
pointer_iterator pointer_end() {
return pointer_iterator(base().raw_mutable_data() + base().size());
}
const_pointer_iterator pointer_end() const {
return const_pointer_iterator(base().raw_mutable_data() + base().size());
}
MessageLite* AddWeak(const MessageLite* prototype) {
return base().AddWeak(prototype);
}
T* Add() { return weak.Add(); }
void Clear() { base().template Clear<TypeHandler>(); }
void MergeFrom(const WeakRepeatedPtrField& other) {
base().template MergeFrom<TypeHandler>(other.base());
}
void InternalSwap(WeakRepeatedPtrField* other) {
base().InternalSwap(&other->base());
}
const internal::RepeatedPtrFieldBase& base() const { return weak; }
internal::RepeatedPtrFieldBase& base() { return weak; }
// Union disables running the destructor. Which would create a strong link.
// Instead we explicitly destroy the underlying base through the virtual
// destructor.
union {
RepeatedPtrField<T> weak;
};
};
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__
@@ -0,0 +1,384 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
#define GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
#include <string>
#include <utility>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/port.h>
#include <google/protobuf/stubs/strutil.h>
// Must be included last.
#include <google/protobuf/port_def.inc>
#ifdef SWIG
#error "You cannot SWIG proto headers"
#endif
namespace google {
namespace protobuf {
class Arena;
namespace internal {
// InlinedStringField wraps a std::string instance and exposes an API similar to
// ArenaStringPtr's wrapping of a std::string* instance.
//
// default_value parameters are taken for consistency with ArenaStringPtr, but
// are not used for most methods. With inlining, these should be removed from
// the generated binary.
//
// InlinedStringField has a donating mechanism that allows string buffer
// allocated on arena. A string is donated means both the string container and
// the data buffer are on arena. The donating mechanism here is similar to the
// one in ArenaStringPtr with some differences:
//
// When an InlinedStringField is constructed, the donating state is true. This
// is because the string container is directly stored in the message on the
// arena:
//
// Construction: donated=true
// Arena:
// +-----------------------+
// |Message foo: |
// | +-------------------+ |
// | |InlinedStringField:| |
// | | +-----+ | |
// | | | | | | | |
// | | +-----+ | |
// | +-------------------+ |
// +-----------------------+
//
// When lvalue Set is called, the donating state is still true. String data will
// be allocated on the arena:
//
// Lvalue Set: donated=true
// Arena:
// +-----------------------+
// |Message foo: |
// | +-------------------+ |
// | |InlinedStringField:| |
// | | +-----+ | |
// | | | | | | | |
// | | +|----+ | |
// | +--|----------------+ |
// | V |
// | +----------------+ |
// | |'f','o','o',... | |
// | +----------------+ |
// +-----------------------+
//
// Some operations will undonate a donated string, including: Mutable,
// SetAllocated, Rvalue Set, and Swap with a non-donated string.
//
// For more details of the donating states transitions, go/pd-inlined-string.
class PROTOBUF_EXPORT InlinedStringField {
public:
InlinedStringField() { Init(); }
inline void Init() { new (get_mutable()) std::string(); }
// Add the dummy parameter just to make InlinedStringField(nullptr)
// unambiguous.
constexpr InlinedStringField(
const ExplicitlyConstructed<std::string>* /*default_value*/,
bool /*dummy*/)
: value_{} {}
explicit InlinedStringField(const std::string& default_value);
explicit InlinedStringField(Arena* arena);
~InlinedStringField() { Destruct(); }
// Lvalue Set. To save space, we pack the donating states of multiple
// InlinedStringFields into an uint32_t `donating_states`. The `mask`
// indicates the position of the bit for this InlinedStringField. `donated` is
// whether this field is donated.
//
// The caller should guarantee that:
//
// `donated == ((donating_states & ~mask) != 0)`
//
// This method never changes the `donating_states`.
void Set(const std::string* default_value, ConstStringParam value,
Arena* arena, bool donated, uint32_t* /*donating_states*/,
uint32_t /*mask*/) {
(void)arena;
(void)donated;
SetNoArena(default_value, value);
}
// Rvalue Set. If this field is donated, this method will undonate this field
// by mutating the `donating_states` according to `mask`.
void Set(const std::string* default_value, std::string&& value, Arena* arena,
bool donated, uint32_t* donating_states, uint32_t mask);
template <typename FirstParam>
void Set(FirstParam p1, const char* str, ::google::protobuf::Arena* arena, bool donated,
uint32_t* donating_states, uint32_t mask) {
Set(p1, ConstStringParam(str), arena, donated, donating_states, mask);
}
template <typename FirstParam>
void Set(FirstParam p1, const char* str, size_t size, ::google::protobuf::Arena* arena,
bool donated, uint32_t* donating_states, uint32_t mask) {
ConstStringParam sp{str, size}; // for string_view and `const string &`
Set(p1, sp, arena, donated, donating_states, mask);
}
template <typename FirstParam, typename RefWrappedType>
void Set(FirstParam p1,
std::reference_wrapper<RefWrappedType> const_string_ref,
::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
uint32_t mask) {
Set(p1, const_string_ref.get(), arena, donated, donating_states, mask);
}
template <typename FirstParam, typename SecondParam>
void SetBytes(FirstParam p1, SecondParam&& p2, ::google::protobuf::Arena* arena,
bool donated, uint32_t* donating_states, uint32_t mask) {
Set(p1, static_cast<SecondParam&&>(p2), arena, donated, donating_states,
mask);
}
template <typename FirstParam>
void SetBytes(FirstParam p1, const void* str, size_t size,
::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
uint32_t mask) {
// Must work whether ConstStringParam is string_view or `const string &`
ConstStringParam sp{static_cast<const char*>(str), size};
Set(p1, sp, arena, donated, donating_states, mask);
}
PROTOBUF_NDEBUG_INLINE void SetNoArena(const std::string* default_value,
StringPiece value);
PROTOBUF_NDEBUG_INLINE void SetNoArena(const std::string* default_value,
std::string&& value);
// Basic accessors.
PROTOBUF_NDEBUG_INLINE const std::string& Get() const { return GetNoArena(); }
PROTOBUF_NDEBUG_INLINE const std::string& GetNoArena() const;
// Mutable returns a std::string* instance that is heap-allocated. If this
// field is donated, this method undonates this field by mutating the
// `donating_states` according to `mask`, and copies the content of the
// original string to the returning string.
std::string* Mutable(const LazyString& default_value, Arena* arena,
bool donated, uint32_t* donating_states, uint32_t mask);
std::string* Mutable(ArenaStringPtr::EmptyDefault, Arena* arena, bool donated,
uint32_t* donating_states, uint32_t mask);
// Release returns a std::string* instance that is heap-allocated and is not
// Own()'d by any arena. If the field is not set, this returns nullptr. The
// caller retains ownership. Clears this field back to nullptr state. Used to
// implement release_<field>() methods on generated classes.
PROTOBUF_NODISCARD std::string* Release(const std::string* default_value,
Arena* arena, bool donated);
PROTOBUF_NODISCARD std::string* ReleaseNonDefault(
const std::string* default_value, Arena* arena);
std::string* ReleaseNonDefaultNoArena(const std::string* default_value);
// Takes a std::string that is heap-allocated, and takes ownership. The
// std::string's destructor is registered with the arena. Used to implement
// set_allocated_<field> in generated classes.
//
// If this field is donated, this method undonates this field by mutating the
// `donating_states` according to `mask`.
void SetAllocated(const std::string* default_value, std::string* value,
Arena* arena, bool donated, uint32_t* donating_states,
uint32_t mask);
void SetAllocatedNoArena(const std::string* default_value,
std::string* value);
// When one of `this` and `from` is donated and the other is not donated, this
// method will undonate the donated one and swap the two heap-allocated
// strings.
PROTOBUF_NDEBUG_INLINE void Swap(InlinedStringField* from,
const std::string* default_value,
Arena* arena, bool donated,
bool from_donated, uint32_t* donating_states,
uint32_t* from_donating_states,
uint32_t mask);
// Frees storage (if not on an arena).
PROTOBUF_NDEBUG_INLINE void Destroy(const std::string* default_value,
Arena* arena) {
if (arena == nullptr) {
DestroyNoArena(default_value);
}
}
PROTOBUF_NDEBUG_INLINE void DestroyNoArena(const std::string* default_value);
// Clears content, but keeps allocated std::string, to avoid the overhead of
// heap operations. After this returns, the content (as seen by the user) will
// always be the empty std::string.
PROTOBUF_NDEBUG_INLINE void ClearToEmpty() { ClearNonDefaultToEmpty(); }
PROTOBUF_NDEBUG_INLINE void ClearNonDefaultToEmpty() {
get_mutable()->clear();
}
// Clears content, but keeps allocated std::string if arena != nullptr, to
// avoid the overhead of heap operations. After this returns, the content (as
// seen by the user) will always be equal to |default_value|.
void ClearToDefault(const LazyString& default_value, Arena* arena,
bool donated);
// Returns a mutable pointer, but doesn't initialize the string to the
// default value.
PROTOBUF_NDEBUG_INLINE std::string* MutableNoArenaNoDefault(
const std::string* /*default_value*/);
// Generated code / reflection only! Returns a mutable pointer to the string.
PROTOBUF_NDEBUG_INLINE std::string* UnsafeMutablePointer();
// InlinedStringField doesn't have things like the `default_value` pointer in
// ArenaStringPtr.
bool IsDefault(const std::string* /*default_value*/) const { return false; }
private:
void Destruct() { get_mutable()->~basic_string(); }
PROTOBUF_NDEBUG_INLINE std::string* get_mutable();
PROTOBUF_NDEBUG_INLINE const std::string* get_const() const;
alignas(std::string) char value_[sizeof(std::string)];
std::string* MutableSlow(::google::protobuf::Arena* arena, bool donated,
uint32_t* donating_states, uint32_t mask);
// When constructed in an Arena, we want our destructor to be skipped.
friend class ::google::protobuf::Arena;
typedef void InternalArenaConstructable_;
typedef void DestructorSkippable_;
};
inline std::string* InlinedStringField::get_mutable() {
return reinterpret_cast<std::string*>(&value_);
}
inline const std::string* InlinedStringField::get_const() const {
return reinterpret_cast<const std::string*>(&value_);
}
inline InlinedStringField::InlinedStringField(
const std::string& default_value) {
new (get_mutable()) std::string(default_value);
}
inline InlinedStringField::InlinedStringField(Arena* arena) {
Init();
if (arena != nullptr) {
arena->OwnDestructor(get_mutable());
}
}
inline const std::string& InlinedStringField::GetNoArena() const {
return *get_const();
}
inline void InlinedStringField::SetAllocatedNoArena(
const std::string* /*default_value*/, std::string* value) {
if (value == nullptr) {
// Currently, inlined string field can't have non empty default.
get_mutable()->clear();
} else {
get_mutable()->assign(std::move(*value));
delete value;
}
}
inline void InlinedStringField::DestroyNoArena(const std::string*) {
// This is invoked from the generated message's ArenaDtor, which is used to
// clean up objects not allocated on the Arena.
this->~InlinedStringField();
}
inline std::string* InlinedStringField::ReleaseNonDefaultNoArena(
const std::string* /*default_value*/) {
// Currently, inlined string field can't have non empty default.
auto* released = new std::string();
get_mutable()->swap(*released);
return released;
}
inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/,
StringPiece value) {
get_mutable()->assign(value.data(), value.length());
}
inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/,
std::string&& value) {
get_mutable()->assign(std::move(value));
}
inline void InlinedStringField::Swap(
InlinedStringField* from, const std::string* /*default_value*/,
Arena* arena, bool donated, bool from_donated, uint32_t* donating_states,
uint32_t* from_donating_states, uint32_t mask) {
#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
// If one is donated and the other is not, undonate the donated one.
if (donated && !from_donated) {
MutableSlow(arena, donated, donating_states, mask);
} else if (!donated && from_donated) {
from->MutableSlow(arena, from_donated, from_donating_states, mask);
}
// Then, swap the two undonated strings.
#else
(void)arena;
(void)donated;
(void)from_donated;
(void)donating_states;
(void)from_donating_states;
(void)mask;
#endif
get_mutable()->swap(*from->get_mutable());
}
inline std::string* InlinedStringField::MutableNoArenaNoDefault(
const std::string*) {
return get_mutable();
}
inline std::string* InlinedStringField::UnsafeMutablePointer() {
return get_mutable();
}
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
+460 -273
View File
@@ -38,17 +38,24 @@
// will not cross the end of the buffer, since we can avoid a lot
// of branching in this case.
#include <google/protobuf/io/coded_stream_inl.h>
#include <algorithm>
#include <utility>
#include <google/protobuf/io/coded_stream.h>
#include <limits.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/arena.h>
#include <algorithm>
#include <cstring>
#include <utility>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/stubs/stl_util.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace io {
@@ -59,8 +66,8 @@ static const int kMaxVarintBytes = 10;
static const int kMaxVarint32Bytes = 5;
inline bool NextNonEmpty(ZeroCopyInputStream* input,
const void** data, int* size) {
inline bool NextNonEmpty(ZeroCopyInputStream* input, const void** data,
int* size) {
bool success;
do {
success = input->Next(data, size);
@@ -82,10 +89,6 @@ CodedInputStream::~CodedInputStream() {
int CodedInputStream::default_recursion_limit_ = 100;
void CodedOutputStream::EnableAliasing(bool enabled) {
aliasing_enabled_ = enabled && output_->AllowsAliasing();
}
void CodedInputStream::BackUpInputToCurrentPosition() {
int backup_bytes = BufferSize() + buffer_size_after_limit_ + overflow_bytes_;
if (backup_bytes > 0) {
@@ -121,9 +124,9 @@ CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) {
// security: byte_limit is possibly evil, so check for negative values
// and overflow. Also check that the new requested limit is before the
// previous limit; otherwise we continue to enforce the previous limit.
if GOOGLE_PREDICT_TRUE(byte_limit >= 0 &&
byte_limit <= INT_MAX - current_position &&
byte_limit < current_limit_ - current_position) {
if (PROTOBUF_PREDICT_TRUE(byte_limit >= 0 &&
byte_limit <= INT_MAX - current_position &&
byte_limit < current_limit_ - current_position)) {
current_limit_ = current_position + byte_limit;
RecomputeBufferLimits();
}
@@ -148,7 +151,7 @@ CodedInputStream::IncrementRecursionDepthAndPushLimit(int byte_limit) {
}
CodedInputStream::Limit CodedInputStream::ReadLengthAndPushLimit() {
uint32 length;
uint32_t length;
return PushLimit(ReadVarint32(&length) ? length : 0);
}
@@ -173,10 +176,7 @@ int CodedInputStream::BytesUntilLimit() const {
return current_limit_ - current_position;
}
void CodedInputStream::SetTotalBytesLimit(
int total_bytes_limit, int warning_threshold) {
(void) warning_threshold;
void CodedInputStream::SetTotalBytesLimit(int total_bytes_limit) {
// Make sure the limit isn't already past, since this could confuse other
// code.
int current_position = CurrentPosition();
@@ -190,11 +190,13 @@ int CodedInputStream::BytesUntilTotalBytesLimit() const {
}
void CodedInputStream::PrintTotalBytesLimitError() {
GOOGLE_LOG(ERROR) << "A protocol message was rejected because it was too "
"big (more than " << total_bytes_limit_
<< " bytes). To increase the limit (or to disable these "
"warnings), see CodedInputStream::SetTotalBytesLimit() "
"in google/protobuf/io/coded_stream.h.";
GOOGLE_LOG(ERROR)
<< "A protocol message was rejected because it was too "
"big (more than "
<< total_bytes_limit_
<< " bytes). To increase the limit (or to disable these "
"warnings), see CodedInputStream::SetTotalBytesLimit() "
"in third_party/protobuf/src/google/protobuf/io/coded_stream.h.";
}
bool CodedInputStream::SkipFallback(int count, int original_buffer_size) {
@@ -220,8 +222,12 @@ bool CodedInputStream::SkipFallback(int count, int original_buffer_size) {
return false;
}
if (!input_->Skip(count)) {
total_bytes_read_ = input_->ByteCount();
return false;
}
total_bytes_read_ += count;
return input_->Skip(count);
return true;
}
bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) {
@@ -233,15 +239,42 @@ bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) {
}
bool CodedInputStream::ReadRaw(void* buffer, int size) {
return InternalReadRawInline(buffer, size);
int current_buffer_size;
while ((current_buffer_size = BufferSize()) < size) {
// Reading past end of buffer. Copy what we have, then refresh.
memcpy(buffer, buffer_, current_buffer_size);
buffer = reinterpret_cast<uint8_t*>(buffer) + current_buffer_size;
size -= current_buffer_size;
Advance(current_buffer_size);
if (!Refresh()) return false;
}
memcpy(buffer, buffer_, size);
Advance(size);
return true;
}
bool CodedInputStream::ReadString(string* buffer, int size) {
bool CodedInputStream::ReadString(std::string* buffer, int size) {
if (size < 0) return false; // security: size is often user-supplied
return InternalReadStringInline(buffer, size);
if (BufferSize() >= size) {
STLStringResizeUninitialized(buffer, size);
std::pair<char*, bool> z = as_string_data(buffer);
if (z.second) {
// Oddly enough, memcpy() requires its first two args to be non-NULL even
// if we copy 0 bytes. So, we have ensured that z.first is non-NULL here.
GOOGLE_DCHECK(z.first != NULL);
memcpy(z.first, buffer_, size);
Advance(size);
}
return true;
}
return ReadStringFallback(buffer, size);
}
bool CodedInputStream::ReadStringFallback(string* buffer, int size) {
bool CodedInputStream::ReadStringFallback(std::string* buffer, int size) {
if (!buffer->empty()) {
buffer->clear();
}
@@ -275,11 +308,11 @@ bool CodedInputStream::ReadStringFallback(string* buffer, int size) {
}
bool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) {
uint8 bytes[sizeof(*value)];
bool CodedInputStream::ReadLittleEndian32Fallback(uint32_t* value) {
uint8_t bytes[sizeof(*value)];
const uint8* ptr;
if (BufferSize() >= sizeof(*value)) {
const uint8_t* ptr;
if (BufferSize() >= static_cast<int64_t>(sizeof(*value))) {
// Fast path: Enough bytes in the buffer to read directly.
ptr = buffer_;
Advance(sizeof(*value));
@@ -292,11 +325,11 @@ bool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) {
return true;
}
bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) {
uint8 bytes[sizeof(*value)];
bool CodedInputStream::ReadLittleEndian64Fallback(uint64_t* value) {
uint8_t bytes[sizeof(*value)];
const uint8* ptr;
if (BufferSize() >= sizeof(*value)) {
const uint8_t* ptr;
if (BufferSize() >= static_cast<int64_t>(sizeof(*value))) {
// Fast path: Enough bytes in the buffer to read directly.
ptr = buffer_;
Advance(sizeof(*value));
@@ -311,111 +344,126 @@ bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) {
namespace {
// Decodes varint64 with known size, N, and returns next pointer. Knowing N at
// compile time, compiler can generate optimal code. For example, instead of
// subtracting 0x80 at each iteration, it subtracts properly shifted mask once.
template <size_t N>
const uint8_t* DecodeVarint64KnownSize(const uint8_t* buffer, uint64_t* value) {
GOOGLE_DCHECK_GT(N, 0);
uint64_t result = static_cast<uint64_t>(buffer[N - 1]) << (7 * (N - 1));
for (size_t i = 0, offset = 0; i < N - 1; i++, offset += 7) {
result += static_cast<uint64_t>(buffer[i] - 0x80) << offset;
}
*value = result;
return buffer + N;
}
// Read a varint from the given buffer, write it to *value, and return a pair.
// The first part of the pair is true iff the read was successful. The second
// part is buffer + (number of bytes read). This function is always inlined,
// so returning a pair is costless.
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
::std::pair<bool, const uint8*> ReadVarint32FromArray(
uint32 first_byte, const uint8* buffer,
uint32* value);
inline ::std::pair<bool, const uint8*> ReadVarint32FromArray(
uint32 first_byte, const uint8* buffer, uint32* value) {
PROTOBUF_ALWAYS_INLINE
::std::pair<bool, const uint8_t*> ReadVarint32FromArray(uint32_t first_byte,
const uint8_t* buffer,
uint32_t* value);
inline ::std::pair<bool, const uint8_t*> ReadVarint32FromArray(
uint32_t first_byte, const uint8_t* buffer, uint32_t* value) {
// Fast path: We have enough bytes left in the buffer to guarantee that
// this read won't cross the end, so we can skip the checks.
GOOGLE_DCHECK_EQ(*buffer, first_byte);
GOOGLE_DCHECK_EQ(first_byte & 0x80, 0x80) << first_byte;
const uint8* ptr = buffer;
uint32 b;
uint32 result = first_byte - 0x80;
const uint8_t* ptr = buffer;
uint32_t b;
uint32_t result = first_byte - 0x80;
++ptr; // We just processed the first byte. Move on to the second.
b = *(ptr++); result += b << 7; if (!(b & 0x80)) goto done;
b = *(ptr++);
result += b << 7;
if (!(b & 0x80)) goto done;
result -= 0x80 << 7;
b = *(ptr++); result += b << 14; if (!(b & 0x80)) goto done;
b = *(ptr++);
result += b << 14;
if (!(b & 0x80)) goto done;
result -= 0x80 << 14;
b = *(ptr++); result += b << 21; if (!(b & 0x80)) goto done;
b = *(ptr++);
result += b << 21;
if (!(b & 0x80)) goto done;
result -= 0x80 << 21;
b = *(ptr++); result += b << 28; if (!(b & 0x80)) goto done;
b = *(ptr++);
result += b << 28;
if (!(b & 0x80)) goto done;
// "result -= 0x80 << 28" is irrevelant.
// If the input is larger than 32 bits, we still need to read it all
// and discard the high-order bits.
for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) {
b = *(ptr++); if (!(b & 0x80)) goto done;
b = *(ptr++);
if (!(b & 0x80)) goto done;
}
// We have overrun the maximum size of a varint (10 bytes). Assume
// the data is corrupt.
return std::make_pair(false, ptr);
done:
done:
*value = result;
return std::make_pair(true, ptr);
}
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE::std::pair<bool, const uint8*>
ReadVarint64FromArray(const uint8* buffer, uint64* value);
inline ::std::pair<bool, const uint8*> ReadVarint64FromArray(
const uint8* buffer, uint64* value) {
const uint8* ptr = buffer;
uint32 b;
PROTOBUF_ALWAYS_INLINE::std::pair<bool, const uint8_t*> ReadVarint64FromArray(
const uint8_t* buffer, uint64_t* value);
inline ::std::pair<bool, const uint8_t*> ReadVarint64FromArray(
const uint8_t* buffer, uint64_t* value) {
// Assumes varint64 is at least 2 bytes.
GOOGLE_DCHECK_GE(buffer[0], 128);
// Splitting into 32-bit pieces gives better performance on 32-bit
// processors.
uint32 part0 = 0, part1 = 0, part2 = 0;
const uint8_t* next;
if (buffer[1] < 128) {
next = DecodeVarint64KnownSize<2>(buffer, value);
} else if (buffer[2] < 128) {
next = DecodeVarint64KnownSize<3>(buffer, value);
} else if (buffer[3] < 128) {
next = DecodeVarint64KnownSize<4>(buffer, value);
} else if (buffer[4] < 128) {
next = DecodeVarint64KnownSize<5>(buffer, value);
} else if (buffer[5] < 128) {
next = DecodeVarint64KnownSize<6>(buffer, value);
} else if (buffer[6] < 128) {
next = DecodeVarint64KnownSize<7>(buffer, value);
} else if (buffer[7] < 128) {
next = DecodeVarint64KnownSize<8>(buffer, value);
} else if (buffer[8] < 128) {
next = DecodeVarint64KnownSize<9>(buffer, value);
} else if (buffer[9] < 128) {
next = DecodeVarint64KnownSize<10>(buffer, value);
} else {
// We have overrun the maximum size of a varint (10 bytes). Assume
// the data is corrupt.
return std::make_pair(false, buffer + 11);
}
b = *(ptr++); part0 = b ; if (!(b & 0x80)) goto done;
part0 -= 0x80;
b = *(ptr++); part0 += b << 7; if (!(b & 0x80)) goto done;
part0 -= 0x80 << 7;
b = *(ptr++); part0 += b << 14; if (!(b & 0x80)) goto done;
part0 -= 0x80 << 14;
b = *(ptr++); part0 += b << 21; if (!(b & 0x80)) goto done;
part0 -= 0x80 << 21;
b = *(ptr++); part1 = b ; if (!(b & 0x80)) goto done;
part1 -= 0x80;
b = *(ptr++); part1 += b << 7; if (!(b & 0x80)) goto done;
part1 -= 0x80 << 7;
b = *(ptr++); part1 += b << 14; if (!(b & 0x80)) goto done;
part1 -= 0x80 << 14;
b = *(ptr++); part1 += b << 21; if (!(b & 0x80)) goto done;
part1 -= 0x80 << 21;
b = *(ptr++); part2 = b ; if (!(b & 0x80)) goto done;
part2 -= 0x80;
b = *(ptr++); part2 += b << 7; if (!(b & 0x80)) goto done;
// "part2 -= 0x80 << 7" is irrelevant because (0x80 << 7) << 56 is 0.
// We have overrun the maximum size of a varint (10 bytes). Assume
// the data is corrupt.
return std::make_pair(false, ptr);
done:
*value = (static_cast<uint64>(part0)) |
(static_cast<uint64>(part1) << 28) |
(static_cast<uint64>(part2) << 56);
return std::make_pair(true, ptr);
return std::make_pair(true, next);
}
} // namespace
bool CodedInputStream::ReadVarint32Slow(uint32* value) {
bool CodedInputStream::ReadVarint32Slow(uint32_t* value) {
// Directly invoke ReadVarint64Fallback, since we already tried to optimize
// for one-byte varints.
std::pair<uint64, bool> p = ReadVarint64Fallback();
*value = static_cast<uint32>(p.first);
std::pair<uint64_t, bool> p = ReadVarint64Fallback();
*value = static_cast<uint32_t>(p.first);
return p.second;
}
int64 CodedInputStream::ReadVarint32Fallback(uint32 first_byte_or_zero) {
int64_t CodedInputStream::ReadVarint32Fallback(uint32_t first_byte_or_zero) {
if (BufferSize() >= kMaxVarintBytes ||
// Optimization: We're also safe if the buffer is non-empty and it ends
// with a byte that would terminate a varint.
(buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
GOOGLE_DCHECK_NE(first_byte_or_zero, 0)
<< "Caller should provide us with *buffer_ when buffer is non-empty";
uint32 temp;
::std::pair<bool, const uint8*> p =
ReadVarint32FromArray(first_byte_or_zero, buffer_, &temp);
uint32_t temp;
::std::pair<bool, const uint8_t*> p =
ReadVarint32FromArray(first_byte_or_zero, buffer_, &temp);
if (!p.first) return -1;
buffer_ = p.second;
return temp;
@@ -423,16 +471,16 @@ int64 CodedInputStream::ReadVarint32Fallback(uint32 first_byte_or_zero) {
// Really slow case: we will incur the cost of an extra function call here,
// but moving this out of line reduces the size of this function, which
// improves the common case. In micro benchmarks, this is worth about 10-15%
uint32 temp;
return ReadVarint32Slow(&temp) ? static_cast<int64>(temp) : -1;
uint32_t temp;
return ReadVarint32Slow(&temp) ? static_cast<int64_t>(temp) : -1;
}
}
int CodedInputStream::ReadVarintSizeAsIntSlow() {
// Directly invoke ReadVarint64Fallback, since we already tried to optimize
// for one-byte varints.
std::pair<uint64, bool> p = ReadVarint64Fallback();
if (!p.second || p.first > static_cast<uint64>(INT_MAX)) return -1;
std::pair<uint64_t, bool> p = ReadVarint64Fallback();
if (!p.second || p.first > static_cast<uint64_t>(INT_MAX)) return -1;
return p.first;
}
@@ -441,9 +489,9 @@ int CodedInputStream::ReadVarintSizeAsIntFallback() {
// Optimization: We're also safe if the buffer is non-empty and it ends
// with a byte that would terminate a varint.
(buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
uint64 temp;
::std::pair<bool, const uint8*> p = ReadVarint64FromArray(buffer_, &temp);
if (!p.first || temp > static_cast<uint64>(INT_MAX)) return -1;
uint64_t temp;
::std::pair<bool, const uint8_t*> p = ReadVarint64FromArray(buffer_, &temp);
if (!p.first || temp > static_cast<uint64_t>(INT_MAX)) return -1;
buffer_ = p.second;
return temp;
} else {
@@ -454,7 +502,7 @@ int CodedInputStream::ReadVarintSizeAsIntFallback() {
}
}
uint32 CodedInputStream::ReadTagSlow() {
uint32_t CodedInputStream::ReadTagSlow() {
if (buffer_ == buffer_end_) {
// Call refresh.
if (!Refresh()) {
@@ -475,12 +523,12 @@ uint32 CodedInputStream::ReadTagSlow() {
// For the slow path, just do a 64-bit read. Try to optimize for one-byte tags
// again, since we have now refreshed the buffer.
uint64 result = 0;
uint64_t result = 0;
if (!ReadVarint64(&result)) return 0;
return static_cast<uint32>(result);
return static_cast<uint32_t>(result);
}
uint32 CodedInputStream::ReadTagFallback(uint32 first_byte_or_zero) {
uint32_t CodedInputStream::ReadTagFallback(uint32_t first_byte_or_zero) {
const int buf_size = BufferSize();
if (buf_size >= kMaxVarintBytes ||
// Optimization: We're also safe if the buffer is non-empty and it ends
@@ -491,8 +539,8 @@ uint32 CodedInputStream::ReadTagFallback(uint32 first_byte_or_zero) {
++buffer_;
return 0;
}
uint32 tag;
::std::pair<bool, const uint8*> p =
uint32_t tag;
::std::pair<bool, const uint8_t*> p =
ReadVarint32FromArray(first_byte_or_zero, buffer_, &tag);
if (!p.first) {
return 0;
@@ -517,13 +565,13 @@ uint32 CodedInputStream::ReadTagFallback(uint32 first_byte_or_zero) {
}
}
bool CodedInputStream::ReadVarint64Slow(uint64* value) {
bool CodedInputStream::ReadVarint64Slow(uint64_t* value) {
// Slow path: This read might cross the end of the buffer, so we
// need to check and refresh the buffer if and when it does.
uint64 result = 0;
uint64_t result = 0;
int count = 0;
uint32 b;
uint32_t b;
do {
if (count == kMaxVarintBytes) {
@@ -537,7 +585,7 @@ bool CodedInputStream::ReadVarint64Slow(uint64* value) {
}
}
b = *buffer_;
result |= static_cast<uint64>(b & 0x7F) << (7 * count);
result |= static_cast<uint64_t>(b & 0x7F) << (7 * count);
Advance(1);
++count;
} while (b & 0x80);
@@ -546,20 +594,20 @@ bool CodedInputStream::ReadVarint64Slow(uint64* value) {
return true;
}
std::pair<uint64, bool> CodedInputStream::ReadVarint64Fallback() {
std::pair<uint64_t, bool> CodedInputStream::ReadVarint64Fallback() {
if (BufferSize() >= kMaxVarintBytes ||
// Optimization: We're also safe if the buffer is non-empty and it ends
// with a byte that would terminate a varint.
(buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
uint64 temp;
::std::pair<bool, const uint8*> p = ReadVarint64FromArray(buffer_, &temp);
uint64_t temp;
::std::pair<bool, const uint8_t*> p = ReadVarint64FromArray(buffer_, &temp);
if (!p.first) {
return std::make_pair(0, false);
}
buffer_ = p.second;
return std::make_pair(temp, true);
} else {
uint64 temp;
uint64_t temp;
bool success = ReadVarint64Slow(&temp);
return std::make_pair(temp, success);
}
@@ -585,7 +633,7 @@ bool CodedInputStream::Refresh() {
const void* void_buffer;
int buffer_size;
if (NextNonEmpty(input_, &void_buffer, &buffer_size)) {
buffer_ = reinterpret_cast<const uint8*>(void_buffer);
buffer_ = reinterpret_cast<const uint8_t*>(void_buffer);
buffer_end_ = buffer_ + buffer_size;
GOOGLE_CHECK_GE(buffer_size, 0);
@@ -618,174 +666,313 @@ bool CodedInputStream::Refresh() {
// CodedOutputStream =================================================
google::protobuf::internal::AtomicWord CodedOutputStream::default_serialization_deterministic_ = 0;
CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
: output_(output),
buffer_(NULL),
buffer_size_(0),
total_bytes_(0),
had_error_(false),
aliasing_enabled_(false),
serialization_deterministic_is_overridden_(false) {
// Eagerly Refresh() so buffer space is immediately available.
Refresh();
// The Refresh() may have failed. If the client doesn't write any data,
// though, don't consider this an error. If the client does write data, then
// another Refresh() will be attempted and it will set the error once again.
had_error_ = false;
void EpsCopyOutputStream::EnableAliasing(bool enabled) {
aliasing_enabled_ = enabled && stream_->AllowsAliasing();
}
CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output,
bool do_eager_refresh)
: output_(output),
buffer_(NULL),
buffer_size_(0),
total_bytes_(0),
had_error_(false),
aliasing_enabled_(false),
serialization_deterministic_is_overridden_(false) {
if (do_eager_refresh) {
// Eagerly Refresh() so buffer space is immediately available.
Refresh();
// The Refresh() may have failed. If the client doesn't write any data,
// though, don't consider this an error. If the client does write data, then
// another Refresh() will be attempted and it will set the error once again.
had_error_ = false;
int64_t EpsCopyOutputStream::ByteCount(uint8_t* ptr) const {
// Calculate the current offset relative to the end of the stream buffer.
int delta = (end_ - ptr) + (buffer_end_ ? 0 : kSlopBytes);
return stream_->ByteCount() - delta;
}
// Flushes what's written out to the underlying ZeroCopyOutputStream buffers.
// Returns the size remaining in the buffer and sets buffer_end_ to the start
// of the remaining buffer, ie. [buffer_end_, buffer_end_ + return value)
int EpsCopyOutputStream::Flush(uint8_t* ptr) {
while (buffer_end_ && ptr > end_) {
int overrun = ptr - end_;
GOOGLE_DCHECK(!had_error_);
GOOGLE_DCHECK(overrun <= kSlopBytes); // NOLINT
ptr = Next() + overrun;
if (had_error_) return 0;
}
}
CodedOutputStream::~CodedOutputStream() {
Trim();
}
void CodedOutputStream::Trim() {
if (buffer_size_ > 0) {
output_->BackUp(buffer_size_);
total_bytes_ -= buffer_size_;
buffer_size_ = 0;
buffer_ = NULL;
int s;
if (buffer_end_) {
std::memcpy(buffer_end_, buffer_, ptr - buffer_);
buffer_end_ += ptr - buffer_;
s = end_ - ptr;
} else {
// The stream is writing directly in the ZeroCopyOutputStream buffer.
s = end_ + kSlopBytes - ptr;
buffer_end_ = ptr;
}
GOOGLE_DCHECK(s >= 0); // NOLINT
return s;
}
bool CodedOutputStream::Skip(int count) {
uint8_t* EpsCopyOutputStream::Trim(uint8_t* ptr) {
if (had_error_) return ptr;
int s = Flush(ptr);
if (s) stream_->BackUp(s);
// Reset to initial state (expecting new buffer)
buffer_end_ = end_ = buffer_;
return buffer_;
}
uint8_t* EpsCopyOutputStream::FlushAndResetBuffer(uint8_t* ptr) {
if (had_error_) return buffer_;
int s = Flush(ptr);
if (had_error_) return buffer_;
return SetInitialBuffer(buffer_end_, s);
}
bool EpsCopyOutputStream::Skip(int count, uint8_t** pp) {
if (count < 0) return false;
while (count > buffer_size_) {
count -= buffer_size_;
if (!Refresh()) return false;
}
Advance(count);
return true;
}
bool CodedOutputStream::GetDirectBufferPointer(void** data, int* size) {
if (buffer_size_ == 0 && !Refresh()) return false;
*data = buffer_;
*size = buffer_size_;
return true;
}
void CodedOutputStream::WriteRaw(const void* data, int size) {
while (buffer_size_ < size) {
memcpy(buffer_, data, buffer_size_);
size -= buffer_size_;
data = reinterpret_cast<const uint8*>(data) + buffer_size_;
if (!Refresh()) return;
}
memcpy(buffer_, data, size);
Advance(size);
}
uint8* CodedOutputStream::WriteRawToArray(
const void* data, int size, uint8* target) {
memcpy(target, data, size);
return target + size;
}
void CodedOutputStream::WriteAliasedRaw(const void* data, int size) {
if (size < buffer_size_
) {
WriteRaw(data, size);
} else {
Trim();
total_bytes_ += size;
had_error_ |= !output_->WriteAliasedRaw(data, size);
}
}
void CodedOutputStream::WriteLittleEndian32(uint32 value) {
uint8 bytes[sizeof(value)];
bool use_fast = buffer_size_ >= sizeof(value);
uint8* ptr = use_fast ? buffer_ : bytes;
WriteLittleEndian32ToArray(value, ptr);
if (use_fast) {
Advance(sizeof(value));
} else {
WriteRaw(bytes, sizeof(value));
}
}
void CodedOutputStream::WriteLittleEndian64(uint64 value) {
uint8 bytes[sizeof(value)];
bool use_fast = buffer_size_ >= sizeof(value);
uint8* ptr = use_fast ? buffer_ : bytes;
WriteLittleEndian64ToArray(value, ptr);
if (use_fast) {
Advance(sizeof(value));
} else {
WriteRaw(bytes, sizeof(value));
}
}
void CodedOutputStream::WriteVarint32SlowPath(uint32 value) {
uint8 bytes[kMaxVarint32Bytes];
uint8* target = &bytes[0];
uint8* end = WriteVarint32ToArray(value, target);
int size = end - target;
WriteRaw(bytes, size);
}
void CodedOutputStream::WriteVarint64SlowPath(uint64 value) {
uint8 bytes[kMaxVarintBytes];
uint8* target = &bytes[0];
uint8* end = WriteVarint64ToArray(value, target);
int size = end - target;
WriteRaw(bytes, size);
}
bool CodedOutputStream::Refresh() {
void* void_buffer;
if (output_->Next(&void_buffer, &buffer_size_)) {
buffer_ = reinterpret_cast<uint8*>(void_buffer);
total_bytes_ += buffer_size_;
return true;
} else {
buffer_ = NULL;
buffer_size_ = 0;
had_error_ = true;
if (had_error_) {
*pp = buffer_;
return false;
}
int size = Flush(*pp);
if (had_error_) {
*pp = buffer_;
return false;
}
void* data = buffer_end_;
while (count > size) {
count -= size;
if (!stream_->Next(&data, &size)) {
*pp = Error();
return false;
}
}
*pp = SetInitialBuffer(static_cast<uint8_t*>(data) + count, size - count);
return true;
}
uint8* CodedOutputStream::WriteStringWithSizeToArray(const string& str,
uint8* target) {
GOOGLE_DCHECK_LE(str.size(), kuint32max);
bool EpsCopyOutputStream::GetDirectBufferPointer(void** data, int* size,
uint8_t** pp) {
if (had_error_) {
*pp = buffer_;
return false;
}
*size = Flush(*pp);
if (had_error_) {
*pp = buffer_;
return false;
}
*data = buffer_end_;
while (*size == 0) {
if (!stream_->Next(data, size)) {
*pp = Error();
return false;
}
}
*pp = SetInitialBuffer(*data, *size);
return true;
}
uint8_t* EpsCopyOutputStream::GetDirectBufferForNBytesAndAdvance(int size,
uint8_t** pp) {
if (had_error_) {
*pp = buffer_;
return nullptr;
}
int s = Flush(*pp);
if (had_error_) {
*pp = buffer_;
return nullptr;
}
if (s >= size) {
auto res = buffer_end_;
*pp = SetInitialBuffer(buffer_end_ + size, s - size);
return res;
} else {
*pp = SetInitialBuffer(buffer_end_, s);
return nullptr;
}
}
uint8_t* EpsCopyOutputStream::Next() {
GOOGLE_DCHECK(!had_error_); // NOLINT
if (PROTOBUF_PREDICT_FALSE(stream_ == nullptr)) return Error();
if (buffer_end_) {
// We're in the patch buffer and need to fill up the previous buffer.
std::memcpy(buffer_end_, buffer_, end_ - buffer_);
uint8_t* ptr;
int size;
do {
void* data;
if (PROTOBUF_PREDICT_FALSE(!stream_->Next(&data, &size))) {
// Stream has an error, we use the patch buffer to continue to be
// able to write.
return Error();
}
ptr = static_cast<uint8_t*>(data);
} while (size == 0);
if (PROTOBUF_PREDICT_TRUE(size > kSlopBytes)) {
std::memcpy(ptr, end_, kSlopBytes);
end_ = ptr + size - kSlopBytes;
buffer_end_ = nullptr;
return ptr;
} else {
GOOGLE_DCHECK(size > 0); // NOLINT
// Buffer to small
std::memmove(buffer_, end_, kSlopBytes);
buffer_end_ = ptr;
end_ = buffer_ + size;
return buffer_;
}
} else {
std::memcpy(buffer_, end_, kSlopBytes);
buffer_end_ = end_;
end_ = buffer_ + kSlopBytes;
return buffer_;
}
}
uint8_t* EpsCopyOutputStream::EnsureSpaceFallback(uint8_t* ptr) {
do {
if (PROTOBUF_PREDICT_FALSE(had_error_)) return buffer_;
int overrun = ptr - end_;
GOOGLE_DCHECK(overrun >= 0); // NOLINT
GOOGLE_DCHECK(overrun <= kSlopBytes); // NOLINT
ptr = Next() + overrun;
} while (ptr >= end_);
GOOGLE_DCHECK(ptr < end_); // NOLINT
return ptr;
}
uint8_t* EpsCopyOutputStream::WriteRawFallback(const void* data, int size,
uint8_t* ptr) {
int s = GetSize(ptr);
while (s < size) {
std::memcpy(ptr, data, s);
size -= s;
data = static_cast<const uint8_t*>(data) + s;
ptr = EnsureSpaceFallback(ptr + s);
s = GetSize(ptr);
}
std::memcpy(ptr, data, size);
return ptr + size;
}
uint8_t* EpsCopyOutputStream::WriteAliasedRaw(const void* data, int size,
uint8_t* ptr) {
if (size < GetSize(ptr)
) {
return WriteRaw(data, size, ptr);
} else {
ptr = Trim(ptr);
if (stream_->WriteAliasedRaw(data, size)) return ptr;
return Error();
}
}
#ifndef PROTOBUF_LITTLE_ENDIAN
uint8_t* EpsCopyOutputStream::WriteRawLittleEndian32(const void* data, int size,
uint8_t* ptr) {
auto p = static_cast<const uint8_t*>(data);
auto end = p + size;
while (end - p >= kSlopBytes) {
ptr = EnsureSpace(ptr);
uint32_t buffer[4];
static_assert(sizeof(buffer) == kSlopBytes, "Buffer must be kSlopBytes");
std::memcpy(buffer, p, kSlopBytes);
p += kSlopBytes;
for (auto x : buffer)
ptr = CodedOutputStream::WriteLittleEndian32ToArray(x, ptr);
}
while (p < end) {
ptr = EnsureSpace(ptr);
uint32_t buffer;
std::memcpy(&buffer, p, 4);
p += 4;
ptr = CodedOutputStream::WriteLittleEndian32ToArray(buffer, ptr);
}
return ptr;
}
uint8_t* EpsCopyOutputStream::WriteRawLittleEndian64(const void* data, int size,
uint8_t* ptr) {
auto p = static_cast<const uint8_t*>(data);
auto end = p + size;
while (end - p >= kSlopBytes) {
ptr = EnsureSpace(ptr);
uint64_t buffer[2];
static_assert(sizeof(buffer) == kSlopBytes, "Buffer must be kSlopBytes");
std::memcpy(buffer, p, kSlopBytes);
p += kSlopBytes;
for (auto x : buffer)
ptr = CodedOutputStream::WriteLittleEndian64ToArray(x, ptr);
}
while (p < end) {
ptr = EnsureSpace(ptr);
uint64_t buffer;
std::memcpy(&buffer, p, 8);
p += 8;
ptr = CodedOutputStream::WriteLittleEndian64ToArray(buffer, ptr);
}
return ptr;
}
#endif
uint8_t* EpsCopyOutputStream::WriteStringMaybeAliasedOutline(uint32_t num,
const std::string& s,
uint8_t* ptr) {
ptr = EnsureSpace(ptr);
uint32_t size = s.size();
ptr = WriteLengthDelim(num, size, ptr);
return WriteRawMaybeAliased(s.data(), size, ptr);
}
uint8_t* EpsCopyOutputStream::WriteStringOutline(uint32_t num, const std::string& s,
uint8_t* ptr) {
ptr = EnsureSpace(ptr);
uint32_t size = s.size();
ptr = WriteLengthDelim(num, size, ptr);
return WriteRaw(s.data(), size, ptr);
}
std::atomic<bool> CodedOutputStream::default_serialization_deterministic_{
false};
CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* stream,
bool do_eager_refresh)
: impl_(stream, IsDefaultSerializationDeterministic(), &cur_),
start_count_(stream->ByteCount()) {
if (do_eager_refresh) {
void* data;
int size;
if (!stream->Next(&data, &size) || size == 0) return;
cur_ = impl_.SetInitialBuffer(data, size);
}
}
CodedOutputStream::~CodedOutputStream() { Trim(); }
uint8_t* CodedOutputStream::WriteStringWithSizeToArray(const std::string& str,
uint8_t* target) {
GOOGLE_DCHECK_LE(str.size(), std::numeric_limits<uint32_t>::max());
target = WriteVarint32ToArray(str.size(), target);
return WriteStringToArray(str, target);
}
uint8_t* CodedOutputStream::WriteVarint32ToArrayOutOfLineHelper(uint32_t value,
uint8_t* target) {
GOOGLE_DCHECK_GE(value, 0x80);
target[0] |= static_cast<uint8_t>(0x80);
value >>= 7;
target[1] = static_cast<uint8_t>(value);
if (value < 0x80) {
return target + 2;
}
target += 2;
do {
// Turn on continuation bit in the byte we just wrote.
target[-1] |= static_cast<uint8_t>(0x80);
value >>= 7;
*target = static_cast<uint8_t>(value);
++target;
} while (value >= 0x80);
return target;
}
} // namespace io
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
File diff suppressed because it is too large Load Diff
@@ -1,90 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: jasonh@google.com (Jason Hsueh)
//
// Implements methods of coded_stream.h that need to be inlined for performance
// reasons, but should not be defined in a public header.
#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
#define GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <string>
#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
namespace io {
inline bool CodedInputStream::InternalReadStringInline(string* buffer,
int size) {
if (size < 0) return false; // security: size is often user-supplied
if (BufferSize() >= size) {
STLStringResizeUninitialized(buffer, size);
std::pair<char*, bool> z = as_string_data(buffer);
if (z.second) {
// Oddly enough, memcpy() requires its first two args to be non-NULL even
// if we copy 0 bytes. So, we have ensured that z.first is non-NULL here.
GOOGLE_DCHECK(z.first != NULL);
memcpy(z.first, buffer_, size);
Advance(size);
}
return true;
}
return ReadStringFallback(buffer, size);
}
inline bool CodedInputStream::InternalReadRawInline(void* buffer, int size) {
int current_buffer_size;
while ((current_buffer_size = BufferSize()) < size) {
// Reading past end of buffer. Copy what we have, then refresh.
memcpy(buffer, buffer_, current_buffer_size);
buffer = reinterpret_cast<uint8*>(buffer) + current_buffer_size;
size -= current_buffer_size;
Advance(current_buffer_size);
if (!Refresh()) return false;
}
memcpy(buffer, buffer_, size);
Advance(size);
return true;
}
} // namespace io
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
-330
View File
@@ -1,330 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: brianolson@google.com (Brian Olson)
//
// This file contains the implementation of classes GzipInputStream and
// GzipOutputStream.
#if HAVE_ZLIB
#include <google/protobuf/io/gzip_stream.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
namespace google {
namespace protobuf {
namespace io {
static const int kDefaultBufferSize = 65536;
GzipInputStream::GzipInputStream(
ZeroCopyInputStream* sub_stream, Format format, int buffer_size)
: format_(format), sub_stream_(sub_stream), zerror_(Z_OK), byte_count_(0) {
zcontext_.state = Z_NULL;
zcontext_.zalloc = Z_NULL;
zcontext_.zfree = Z_NULL;
zcontext_.opaque = Z_NULL;
zcontext_.total_out = 0;
zcontext_.next_in = NULL;
zcontext_.avail_in = 0;
zcontext_.total_in = 0;
zcontext_.msg = NULL;
if (buffer_size == -1) {
output_buffer_length_ = kDefaultBufferSize;
} else {
output_buffer_length_ = buffer_size;
}
output_buffer_ = operator new(output_buffer_length_);
GOOGLE_CHECK(output_buffer_ != NULL);
zcontext_.next_out = static_cast<Bytef*>(output_buffer_);
zcontext_.avail_out = output_buffer_length_;
output_position_ = output_buffer_;
}
GzipInputStream::~GzipInputStream() {
operator delete(output_buffer_);
zerror_ = inflateEnd(&zcontext_);
}
static inline int internalInflateInit2(
z_stream* zcontext, GzipInputStream::Format format) {
int windowBitsFormat = 0;
switch (format) {
case GzipInputStream::GZIP: windowBitsFormat = 16; break;
case GzipInputStream::AUTO: windowBitsFormat = 32; break;
case GzipInputStream::ZLIB: windowBitsFormat = 0; break;
}
return inflateInit2(zcontext, /* windowBits */15 | windowBitsFormat);
}
int GzipInputStream::Inflate(int flush) {
if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) {
// previous inflate filled output buffer. don't change input params yet.
} else if (zcontext_.avail_in == 0) {
const void* in;
int in_size;
bool first = zcontext_.next_in == NULL;
bool ok = sub_stream_->Next(&in, &in_size);
if (!ok) {
zcontext_.next_out = NULL;
zcontext_.avail_out = 0;
return Z_STREAM_END;
}
zcontext_.next_in = static_cast<Bytef*>(const_cast<void*>(in));
zcontext_.avail_in = in_size;
if (first) {
int error = internalInflateInit2(&zcontext_, format_);
if (error != Z_OK) {
return error;
}
}
}
zcontext_.next_out = static_cast<Bytef*>(output_buffer_);
zcontext_.avail_out = output_buffer_length_;
output_position_ = output_buffer_;
int error = inflate(&zcontext_, flush);
return error;
}
void GzipInputStream::DoNextOutput(const void** data, int* size) {
*data = output_position_;
*size = ((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_);
output_position_ = zcontext_.next_out;
}
// implements ZeroCopyInputStream ----------------------------------
bool GzipInputStream::Next(const void** data, int* size) {
bool ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END)
|| (zerror_ == Z_BUF_ERROR);
if ((!ok) || (zcontext_.next_out == NULL)) {
return false;
}
if (zcontext_.next_out != output_position_) {
DoNextOutput(data, size);
return true;
}
if (zerror_ == Z_STREAM_END) {
if (zcontext_.next_out != NULL) {
// sub_stream_ may have concatenated streams to follow
zerror_ = inflateEnd(&zcontext_);
byte_count_ += zcontext_.total_out;
if (zerror_ != Z_OK) {
return false;
}
zerror_ = internalInflateInit2(&zcontext_, format_);
if (zerror_ != Z_OK) {
return false;
}
} else {
*data = NULL;
*size = 0;
return false;
}
}
zerror_ = Inflate(Z_NO_FLUSH);
if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out == NULL)) {
// The underlying stream's Next returned false inside Inflate.
return false;
}
ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END)
|| (zerror_ == Z_BUF_ERROR);
if (!ok) {
return false;
}
DoNextOutput(data, size);
return true;
}
void GzipInputStream::BackUp(int count) {
output_position_ = reinterpret_cast<void*>(
reinterpret_cast<uintptr_t>(output_position_) - count);
}
bool GzipInputStream::Skip(int count) {
const void* data;
int size = 0;
bool ok = Next(&data, &size);
while (ok && (size < count)) {
count -= size;
ok = Next(&data, &size);
}
if (size > count) {
BackUp(size - count);
}
return ok;
}
int64 GzipInputStream::ByteCount() const {
int64 ret = byte_count_ + zcontext_.total_out;
if (zcontext_.next_out != NULL && output_position_ != NULL) {
ret += reinterpret_cast<uintptr_t>(zcontext_.next_out) -
reinterpret_cast<uintptr_t>(output_position_);
}
return ret;
}
// =========================================================================
GzipOutputStream::Options::Options()
: format(GZIP),
buffer_size(kDefaultBufferSize),
compression_level(Z_DEFAULT_COMPRESSION),
compression_strategy(Z_DEFAULT_STRATEGY) {}
GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream) {
Init(sub_stream, Options());
}
GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream,
const Options& options) {
Init(sub_stream, options);
}
void GzipOutputStream::Init(ZeroCopyOutputStream* sub_stream,
const Options& options) {
sub_stream_ = sub_stream;
sub_data_ = NULL;
sub_data_size_ = 0;
input_buffer_length_ = options.buffer_size;
input_buffer_ = operator new(input_buffer_length_);
GOOGLE_CHECK(input_buffer_ != NULL);
zcontext_.zalloc = Z_NULL;
zcontext_.zfree = Z_NULL;
zcontext_.opaque = Z_NULL;
zcontext_.next_out = NULL;
zcontext_.avail_out = 0;
zcontext_.total_out = 0;
zcontext_.next_in = NULL;
zcontext_.avail_in = 0;
zcontext_.total_in = 0;
zcontext_.msg = NULL;
// default to GZIP format
int windowBitsFormat = 16;
if (options.format == ZLIB) {
windowBitsFormat = 0;
}
zerror_ = deflateInit2(
&zcontext_,
options.compression_level,
Z_DEFLATED,
/* windowBits */15 | windowBitsFormat,
/* memLevel (default) */8,
options.compression_strategy);
}
GzipOutputStream::~GzipOutputStream() {
Close();
operator delete(input_buffer_);
}
// private
int GzipOutputStream::Deflate(int flush) {
int error = Z_OK;
do {
if ((sub_data_ == NULL) || (zcontext_.avail_out == 0)) {
bool ok = sub_stream_->Next(&sub_data_, &sub_data_size_);
if (!ok) {
sub_data_ = NULL;
sub_data_size_ = 0;
return Z_BUF_ERROR;
}
GOOGLE_CHECK_GT(sub_data_size_, 0);
zcontext_.next_out = static_cast<Bytef*>(sub_data_);
zcontext_.avail_out = sub_data_size_;
}
error = deflate(&zcontext_, flush);
} while (error == Z_OK && zcontext_.avail_out == 0);
if ((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) {
// Notify lower layer of data.
sub_stream_->BackUp(zcontext_.avail_out);
// We don't own the buffer anymore.
sub_data_ = NULL;
sub_data_size_ = 0;
}
return error;
}
// implements ZeroCopyOutputStream ---------------------------------
bool GzipOutputStream::Next(void** data, int* size) {
if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
return false;
}
if (zcontext_.avail_in != 0) {
zerror_ = Deflate(Z_NO_FLUSH);
if (zerror_ != Z_OK) {
return false;
}
}
if (zcontext_.avail_in == 0) {
// all input was consumed. reset the buffer.
zcontext_.next_in = static_cast<Bytef*>(input_buffer_);
zcontext_.avail_in = input_buffer_length_;
*data = input_buffer_;
*size = input_buffer_length_;
} else {
// The loop in Deflate should consume all avail_in
GOOGLE_LOG(DFATAL) << "Deflate left bytes unconsumed";
}
return true;
}
void GzipOutputStream::BackUp(int count) {
GOOGLE_CHECK_GE(zcontext_.avail_in, count);
zcontext_.avail_in -= count;
}
int64 GzipOutputStream::ByteCount() const {
return zcontext_.total_in + zcontext_.avail_in;
}
bool GzipOutputStream::Flush() {
zerror_ = Deflate(Z_FULL_FLUSH);
// Return true if the flush succeeded or if it was a no-op.
return (zerror_ == Z_OK) ||
(zerror_ == Z_BUF_ERROR && zcontext_.avail_in == 0 &&
zcontext_.avail_out != 0);
}
bool GzipOutputStream::Close() {
if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
return false;
}
do {
zerror_ = Deflate(Z_FINISH);
} while (zerror_ == Z_OK);
zerror_ = deflateEnd(&zcontext_);
bool ok = zerror_ == Z_OK;
zerror_ = Z_STREAM_END;
return ok;
}
} // namespace io
} // namespace protobuf
} // namespace google
#endif // HAVE_ZLIB
-209
View File
@@ -1,209 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: brianolson@google.com (Brian Olson)
//
// This file contains the definition for classes GzipInputStream and
// GzipOutputStream.
//
// GzipInputStream decompresses data from an underlying
// ZeroCopyInputStream and provides the decompressed data as a
// ZeroCopyInputStream.
//
// GzipOutputStream is an ZeroCopyOutputStream that compresses data to
// an underlying ZeroCopyOutputStream.
#ifndef GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
#define GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <zlib.h>
namespace google {
namespace protobuf {
namespace io {
// A ZeroCopyInputStream that reads compressed data through zlib
class LIBPROTOBUF_EXPORT GzipInputStream : public ZeroCopyInputStream {
public:
// Format key for constructor
enum Format {
// zlib will autodetect gzip header or deflate stream
AUTO = 0,
// GZIP streams have some extra header data for file attributes.
GZIP = 1,
// Simpler zlib stream format.
ZLIB = 2,
};
// buffer_size and format may be -1 for default of 64kB and GZIP format
explicit GzipInputStream(
ZeroCopyInputStream* sub_stream,
Format format = AUTO,
int buffer_size = -1);
virtual ~GzipInputStream();
// Return last error message or NULL if no error.
inline const char* ZlibErrorMessage() const {
return zcontext_.msg;
}
inline int ZlibErrorCode() const {
return zerror_;
}
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
private:
Format format_;
ZeroCopyInputStream* sub_stream_;
z_stream zcontext_;
int zerror_;
void* output_buffer_;
void* output_position_;
size_t output_buffer_length_;
int64 byte_count_;
int Inflate(int flush);
void DoNextOutput(const void** data, int* size);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipInputStream);
};
class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream {
public:
// Format key for constructor
enum Format {
// GZIP streams have some extra header data for file attributes.
GZIP = 1,
// Simpler zlib stream format.
ZLIB = 2,
};
struct Options {
// Defaults to GZIP.
Format format;
// What size buffer to use internally. Defaults to 64kB.
int buffer_size;
// A number between 0 and 9, where 0 is no compression and 9 is best
// compression. Defaults to Z_DEFAULT_COMPRESSION (see zlib.h).
int compression_level;
// Defaults to Z_DEFAULT_STRATEGY. Can also be set to Z_FILTERED,
// Z_HUFFMAN_ONLY, or Z_RLE. See the documentation for deflateInit2 in
// zlib.h for definitions of these constants.
int compression_strategy;
Options(); // Initializes with default values.
};
// Create a GzipOutputStream with default options.
explicit GzipOutputStream(ZeroCopyOutputStream* sub_stream);
// Create a GzipOutputStream with the given options.
GzipOutputStream(
ZeroCopyOutputStream* sub_stream,
const Options& options);
virtual ~GzipOutputStream();
// Return last error message or NULL if no error.
inline const char* ZlibErrorMessage() const {
return zcontext_.msg;
}
inline int ZlibErrorCode() const {
return zerror_;
}
// Flushes data written so far to zipped data in the underlying stream.
// It is the caller's responsibility to flush the underlying stream if
// necessary.
// Compression may be less efficient stopping and starting around flushes.
// Returns true if no error.
//
// Please ensure that block size is > 6. Here is an excerpt from the zlib
// doc that explains why:
//
// In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out
// is greater than six to avoid repeated flush markers due to
// avail_out == 0 on return.
bool Flush();
// Writes out all data and closes the gzip stream.
// It is the caller's responsibility to close the underlying stream if
// necessary.
// Returns true if no error.
bool Close();
// implements ZeroCopyOutputStream ---------------------------------
bool Next(void** data, int* size);
void BackUp(int count);
int64 ByteCount() const;
private:
ZeroCopyOutputStream* sub_stream_;
// Result from calling Next() on sub_stream_
void* sub_data_;
int sub_data_size_;
z_stream zcontext_;
int zerror_;
void* input_buffer_;
size_t input_buffer_length_;
// Shared constructor code.
void Init(ZeroCopyOutputStream* sub_stream, const Options& options);
// Do some compression.
// Takes zlib flush mode.
// Returns zlib error code.
int Deflate(int flush);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipOutputStream);
};
} // namespace io
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
@@ -29,7 +29,9 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: laszlocsomor@google.com (Laszlo Csomor)
//
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Implementation for long-path-aware open/mkdir/access/etc. on Windows, as well
// as for the supporting utility functions.
//
@@ -40,13 +42,15 @@
//
// This file is only used on Windows, it's empty on other platforms.
#if defined(_WIN32)
#if defined(_WIN32) && !defined(_XBOX_ONE)
// Comment this out to fall back to using the ANSI versions (open, mkdir, ...)
// instead of the Unicode ones (_wopen, _wmkdir, ...). Doing so can be useful to
// debug failing tests if that's caused by the long path support.
#define SUPPORT_LONGPATHS
#include <google/protobuf/io/io_win32.h>
#include <ctype.h>
#include <direct.h>
#include <errno.h>
@@ -55,10 +59,12 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <wctype.h>
#include <windows.h>
#include <google/protobuf/stubs/io_win32.h>
#include <google/protobuf/stubs/scoped_ptr.h>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
#include <memory>
#include <sstream>
@@ -67,7 +73,7 @@
namespace google {
namespace protobuf {
namespace internal {
namespace io {
namespace win32 {
namespace {
@@ -91,7 +97,7 @@ struct CharTraits<wchar_t> {
template <typename char_type>
bool null_or_empty(const char_type* s) {
return s == NULL || *s == 0;
return s == nullptr || *s == 0;
}
// Returns true if the path starts with a drive letter, e.g. "c:".
@@ -151,12 +157,13 @@ wstring normalize(wstring path) {
static const wstring dot(L".");
static const wstring dotdot(L"..");
const WCHAR* p = path.c_str();
std::vector<wstring> segments;
int segment_start = -1;
// Find the path segments in `path` (separated by "/").
for (int i = 0;; ++i) {
if (!is_separator(path[i]) && path[i] != L'\0') {
if (!is_separator(p[i]) && p[i] != L'\0') {
// The current character does not end a segment, so start one unless it's
// already started.
if (segment_start < 0) {
@@ -165,7 +172,7 @@ wstring normalize(wstring path) {
} else if (segment_start >= 0 && i > segment_start) {
// The current character is "/" or "\0", so this ends a segment.
// Add that to `segments` if there's anything to add; handle "." and "..".
wstring segment(path, segment_start, i - segment_start);
wstring segment(p, segment_start, i - segment_start);
segment_start = -1;
if (segment == dotdot) {
if (!segments.empty() &&
@@ -176,7 +183,7 @@ wstring normalize(wstring path) {
segments.push_back(segment);
}
}
if (path[i] == L'\0') {
if (p[i] == L'\0') {
break;
}
}
@@ -199,7 +206,7 @@ wstring normalize(wstring path) {
result << segments[i];
}
// Preserve trailing separator if the input contained it.
if (!path.empty() && is_separator(path[path.size() - 1])) {
if (!path.empty() && is_separator(p[path.size() - 1])) {
result << L'\\';
}
return result.str();
@@ -224,11 +231,11 @@ bool as_windows_path(const char* path, wstring* result) {
if (!is_path_absolute(wpath.c_str())) {
int size = ::GetCurrentDirectoryW(0, NULL);
int size = ::GetCurrentDirectoryW(0, nullptr);
if (size == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
return false;
}
scoped_array<WCHAR> wcwd(new WCHAR[size]);
std::unique_ptr<WCHAR[]> wcwd(new WCHAR[size]);
::GetCurrentDirectoryW(size, wcwd.get());
wpath = join_paths(wcwd.get(), wpath);
}
@@ -259,7 +266,7 @@ int open(const char* path, int flags, int mode) {
#endif
}
int mkdir(const char* path, int _mode) {
int mkdir(const char* path, int /*_mode*/) {
#ifdef SUPPORT_LONGPATHS
wstring wpath;
if (!as_windows_path(path, &wpath)) {
@@ -315,17 +322,17 @@ FILE* fopen(const char* path, const char* mode) {
#ifdef SUPPORT_LONGPATHS
if (null_or_empty(path)) {
errno = EINVAL;
return NULL;
return nullptr;
}
wstring wpath;
if (!as_windows_path(path, &wpath)) {
errno = ENOENT;
return NULL;
return nullptr;
}
wstring wmode;
if (!strings::utf8_to_wcs(mode, &wmode)) {
errno = EINVAL;
return NULL;
return nullptr;
}
return ::_wfopen(wpath.c_str(), wmode.c_str());
#else
@@ -333,7 +340,7 @@ FILE* fopen(const char* path, const char* mode) {
#endif
}
int close(int fd) { return ::close(fd); }
int close(int fd) { return ::_close(fd); }
int dup(int fd) { return ::_dup(fd); }
@@ -354,6 +361,56 @@ wstring testonly_utf8_to_winpath(const char* path) {
return as_windows_path(path, &wpath) ? wpath : wstring();
}
ExpandWildcardsResult ExpandWildcards(
const string& path, std::function<void(const string&)> consume) {
if (path.find_first_of("*?") == string::npos) {
// There are no wildcards in the path, we don't need to expand it.
consume(path);
return ExpandWildcardsResult::kSuccess;
}
wstring wpath;
if (!as_windows_path(path.c_str(), &wpath)) {
return ExpandWildcardsResult::kErrorInputPathConversion;
}
static const wstring kDot = L".";
static const wstring kDotDot = L"..";
WIN32_FIND_DATAW metadata;
HANDLE handle = ::FindFirstFileW(wpath.c_str(), &metadata);
if (handle == INVALID_HANDLE_VALUE) {
// The pattern does not match any files (or directories).
return ExpandWildcardsResult::kErrorNoMatchingFile;
}
string::size_type pos = path.find_last_of("\\/");
string dirname;
if (pos != string::npos) {
dirname = path.substr(0, pos + 1);
}
ExpandWildcardsResult matched = ExpandWildcardsResult::kErrorNoMatchingFile;
do {
// Ignore ".", "..", and directories.
if ((metadata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 &&
kDot != metadata.cFileName && kDotDot != metadata.cFileName) {
matched = ExpandWildcardsResult::kSuccess;
string filename;
if (!strings::wcs_to_utf8(metadata.cFileName, &filename)) {
return ExpandWildcardsResult::kErrorOutputPathConversion;
}
if (dirname.empty()) {
consume(filename);
} else {
consume(dirname + filename);
}
}
} while (::FindNextFileW(handle, &metadata));
FindClose(handle);
return matched;
}
namespace strings {
bool wcs_to_mbs(const WCHAR* s, string* out, bool outUtf8) {
@@ -364,15 +421,15 @@ bool wcs_to_mbs(const WCHAR* s, string* out, bool outUtf8) {
BOOL usedDefaultChar = FALSE;
SetLastError(0);
int size = WideCharToMultiByte(
outUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, NULL, 0, NULL,
outUtf8 ? NULL : &usedDefaultChar);
outUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, nullptr, 0, nullptr,
outUtf8 ? nullptr : &usedDefaultChar);
if ((size == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|| usedDefaultChar) {
return false;
}
scoped_array<CHAR> astr(new CHAR[size]);
std::unique_ptr<CHAR[]> astr(new CHAR[size]);
WideCharToMultiByte(
outUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, astr.get(), size, NULL, NULL);
outUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, astr.get(), size, nullptr, nullptr);
out->assign(astr.get());
return true;
}
@@ -385,11 +442,11 @@ bool mbs_to_wcs(const char* s, wstring* out, bool inUtf8) {
SetLastError(0);
int size =
MultiByteToWideChar(inUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, NULL, 0);
MultiByteToWideChar(inUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, nullptr, 0);
if (size == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
return false;
}
scoped_array<WCHAR> wstr(new WCHAR[size]);
std::unique_ptr<WCHAR[]> wstr(new WCHAR[size]);
MultiByteToWideChar(
inUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, wstr.get(), size + 1);
out->assign(wstr.get());
@@ -406,7 +463,7 @@ bool wcs_to_utf8(const wchar_t* input, string* out) {
} // namespace strings
} // namespace win32
} // namespace internal
} // namespace io
} // namespace protobuf
} // namespace google
@@ -29,68 +29,90 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: laszlocsomor@google.com (Laszlo Csomor)
//
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// This file contains the declarations for Windows implementations of
// commonly used POSIX functions such as open(2) and access(2), as well
// as macro definitions for flags of these functions.
//
// By including this file you'll redefine open/access/etc. to
// ::google::protobuf::internal::win32::{open/access/etc.}.
// ::google::protobuf::io::win32::{open/access/etc.}.
// Make sure you don't include a header that attempts to redeclare or
// redefine these functions, that'll lead to confusing compilation
// errors. It's best to #include this file as the last one to ensure that.
//
// This file is only used on Windows, it's empty on other platforms.
#ifndef GOOGLE_PROTOBUF_STUBS_IO_WIN32_H__
#define GOOGLE_PROTOBUF_STUBS_IO_WIN32_H__
#ifndef GOOGLE_PROTOBUF_IO_IO_WIN32_H__
#define GOOGLE_PROTOBUF_IO_IO_WIN32_H__
#if defined(_WIN32)
#include <functional>
#include <string>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/port.h>
#include <google/protobuf/port_def.inc>
// Compilers on Windows other than MSVC (e.g. Cygwin, MinGW32) define the
// following functions already, except for mkdir.
namespace google {
namespace protobuf {
namespace internal {
namespace io {
namespace win32 {
LIBPROTOBUF_EXPORT FILE* fopen(const char* path, const char* mode);
LIBPROTOBUF_EXPORT int access(const char* path, int mode);
LIBPROTOBUF_EXPORT int chdir(const char* path);
LIBPROTOBUF_EXPORT int close(int fd);
LIBPROTOBUF_EXPORT int dup(int fd);
LIBPROTOBUF_EXPORT int dup2(int fd1, int fd2);
LIBPROTOBUF_EXPORT int mkdir(const char* path, int _mode);
LIBPROTOBUF_EXPORT int open(const char* path, int flags, int mode = 0);
LIBPROTOBUF_EXPORT int read(int fd, void* buffer, size_t size);
LIBPROTOBUF_EXPORT int setmode(int fd, int mode);
LIBPROTOBUF_EXPORT int stat(const char* path, struct _stat* buffer);
LIBPROTOBUF_EXPORT int write(int fd, const void* buffer, size_t size);
LIBPROTOBUF_EXPORT std::wstring testonly_utf8_to_winpath(const char* path);
PROTOBUF_EXPORT FILE* fopen(const char* path, const char* mode);
PROTOBUF_EXPORT int access(const char* path, int mode);
PROTOBUF_EXPORT int chdir(const char* path);
PROTOBUF_EXPORT int close(int fd);
PROTOBUF_EXPORT int dup(int fd);
PROTOBUF_EXPORT int dup2(int fd1, int fd2);
PROTOBUF_EXPORT int mkdir(const char* path, int _mode);
PROTOBUF_EXPORT int open(const char* path, int flags, int mode = 0);
PROTOBUF_EXPORT int read(int fd, void* buffer, size_t size);
PROTOBUF_EXPORT int setmode(int fd, int mode);
PROTOBUF_EXPORT int stat(const char* path, struct _stat* buffer);
PROTOBUF_EXPORT int write(int fd, const void* buffer, size_t size);
PROTOBUF_EXPORT std::wstring testonly_utf8_to_winpath(const char* path);
enum class ExpandWildcardsResult {
kSuccess = 0,
kErrorNoMatchingFile = 1,
kErrorInputPathConversion = 2,
kErrorOutputPathConversion = 3,
};
// Expand wildcards in a path pattern, feed the result to a consumer function.
//
// `path` must be a valid, Windows-style path. It may be absolute, or relative
// to the current working directory, and it may contain wildcards ("*" and "?")
// in the last path segment. This function passes all matching file names to
// `consume`. The resulting paths may not be absolute nor normalized.
//
// The function returns a value from `ExpandWildcardsResult`.
PROTOBUF_EXPORT ExpandWildcardsResult ExpandWildcards(
const std::string& path, std::function<void(const std::string&)> consume);
namespace strings {
// Convert from UTF-16 to Active-Code-Page-encoded or to UTF-8-encoded text.
LIBPROTOBUF_EXPORT bool wcs_to_mbs(
const wchar_t* s, std::string* out, bool outUtf8);
PROTOBUF_EXPORT bool wcs_to_mbs(const wchar_t* s, std::string* out,
bool outUtf8);
// Convert from Active-Code-Page-encoded or UTF-8-encoded text to UTF-16.
LIBPROTOBUF_EXPORT bool mbs_to_wcs(
const char* s, std::wstring* out, bool inUtf8);
PROTOBUF_EXPORT bool mbs_to_wcs(const char* s, std::wstring* out, bool inUtf8);
// Convert from UTF-8-encoded text to UTF-16.
LIBPROTOBUF_EXPORT bool utf8_to_wcs(const char* input, std::wstring* out);
PROTOBUF_EXPORT bool utf8_to_wcs(const char* input, std::wstring* out);
// Convert from UTF-16-encoded text to UTF-8.
LIBPROTOBUF_EXPORT bool wcs_to_utf8(const wchar_t* input, std::string* out);
PROTOBUF_EXPORT bool wcs_to_utf8(const wchar_t* input, std::string* out);
} // namespace strings
} // namespace win32
} // namespace internal
} // namespace io
} // namespace protobuf
} // namespace google
@@ -110,6 +132,8 @@ LIBPROTOBUF_EXPORT bool wcs_to_utf8(const wchar_t* input, std::string* out);
#define STDOUT_FILENO 1
#endif
#include <google/protobuf/port_undef.inc>
#endif // defined(_WIN32)
#endif // GOOGLE_PROTOBUF_STUBS_IO_WIN32_H__
#endif // GOOGLE_PROTOBUF_IO_IO_WIN32_H__
@@ -37,7 +37,6 @@
// documentation generator.
namespace google {
namespace protobuf {
// Auxiliary classes used for I/O.
-372
View File
@@ -1,372 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace io {
Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter)
: variable_delimiter_(variable_delimiter),
output_(output),
buffer_(NULL),
buffer_size_(0),
offset_(0),
at_start_of_line_(true),
failed_(false),
annotation_collector_(NULL) {}
Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter,
AnnotationCollector* annotation_collector)
: variable_delimiter_(variable_delimiter),
output_(output),
buffer_(NULL),
buffer_size_(0),
offset_(0),
at_start_of_line_(true),
failed_(false),
annotation_collector_(annotation_collector) {}
Printer::~Printer() {
// Only BackUp() if we have called Next() at least once and never failed.
if (buffer_size_ > 0 && !failed_) {
output_->BackUp(buffer_size_);
}
}
bool Printer::GetSubstitutionRange(const char* varname,
std::pair<size_t, size_t>* range) {
std::map<string, std::pair<size_t, size_t> >::const_iterator iter =
substitutions_.find(varname);
if (iter == substitutions_.end()) {
GOOGLE_LOG(DFATAL) << " Undefined variable in annotation: " << varname;
return false;
}
if (iter->second.first > iter->second.second) {
GOOGLE_LOG(DFATAL) << " Variable used for annotation used multiple times: "
<< varname;
return false;
}
*range = iter->second;
return true;
}
void Printer::Annotate(const char* begin_varname, const char* end_varname,
const string& file_path, const std::vector<int>& path) {
if (annotation_collector_ == NULL) {
// Can't generate signatures with this Printer.
return;
}
std::pair<size_t, size_t> begin, end;
if (!GetSubstitutionRange(begin_varname, &begin) ||
!GetSubstitutionRange(end_varname, &end)) {
return;
}
if (begin.first > end.second) {
GOOGLE_LOG(DFATAL) << " Annotation has negative length from " << begin_varname
<< " to " << end_varname;
} else {
annotation_collector_->AddAnnotation(begin.first, end.second, file_path,
path);
}
}
void Printer::Print(const std::map<string, string>& variables,
const char* text) {
int size = strlen(text);
int pos = 0; // The number of bytes we've written so far.
substitutions_.clear();
line_start_variables_.clear();
for (int i = 0; i < size; i++) {
if (text[i] == '\n') {
// Saw newline. If there is more text, we may need to insert an indent
// here. So, write what we have so far, including the '\n'.
WriteRaw(text + pos, i - pos + 1);
pos = i + 1;
// Setting this true will cause the next WriteRaw() to insert an indent
// first.
at_start_of_line_ = true;
line_start_variables_.clear();
} else if (text[i] == variable_delimiter_) {
// Saw the start of a variable name.
// Write what we have so far.
WriteRaw(text + pos, i - pos);
pos = i + 1;
// Find closing delimiter.
const char* end = strchr(text + pos, variable_delimiter_);
if (end == NULL) {
GOOGLE_LOG(DFATAL) << " Unclosed variable name.";
end = text + pos;
}
int endpos = end - text;
string varname(text + pos, endpos - pos);
if (varname.empty()) {
// Two delimiters in a row reduce to a literal delimiter character.
WriteRaw(&variable_delimiter_, 1);
} else {
// Replace with the variable's value.
std::map<string, string>::const_iterator iter = variables.find(varname);
if (iter == variables.end()) {
GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname;
} else {
if (at_start_of_line_ && iter->second.empty()) {
line_start_variables_.push_back(varname);
}
WriteRaw(iter->second.data(), iter->second.size());
std::pair<std::map<string, std::pair<size_t, size_t> >::iterator,
bool>
inserted = substitutions_.insert(std::make_pair(
varname,
std::make_pair(offset_ - iter->second.size(), offset_)));
if (!inserted.second) {
// This variable was used multiple times. Make its span have
// negative length so we can detect it if it gets used in an
// annotation.
inserted.first->second = std::make_pair(1, 0);
}
}
}
// Advance past this variable.
i = endpos;
pos = endpos + 1;
}
}
// Write the rest.
WriteRaw(text + pos, size - pos);
}
void Printer::Print(const char* text) {
static std::map<string, string> empty;
Print(empty, text);
}
void Printer::Print(const char* text,
const char* variable, const string& value) {
std::map<string, string> vars;
vars[variable] = value;
Print(vars, text);
}
void Printer::Print(const char* text,
const char* variable1, const string& value1,
const char* variable2, const string& value2) {
std::map<string, string> vars;
vars[variable1] = value1;
vars[variable2] = value2;
Print(vars, text);
}
void Printer::Print(const char* text,
const char* variable1, const string& value1,
const char* variable2, const string& value2,
const char* variable3, const string& value3) {
std::map<string, string> vars;
vars[variable1] = value1;
vars[variable2] = value2;
vars[variable3] = value3;
Print(vars, text);
}
void Printer::Print(const char* text,
const char* variable1, const string& value1,
const char* variable2, const string& value2,
const char* variable3, const string& value3,
const char* variable4, const string& value4) {
std::map<string, string> vars;
vars[variable1] = value1;
vars[variable2] = value2;
vars[variable3] = value3;
vars[variable4] = value4;
Print(vars, text);
}
void Printer::Print(const char* text,
const char* variable1, const string& value1,
const char* variable2, const string& value2,
const char* variable3, const string& value3,
const char* variable4, const string& value4,
const char* variable5, const string& value5) {
std::map<string, string> vars;
vars[variable1] = value1;
vars[variable2] = value2;
vars[variable3] = value3;
vars[variable4] = value4;
vars[variable5] = value5;
Print(vars, text);
}
void Printer::Print(const char* text,
const char* variable1, const string& value1,
const char* variable2, const string& value2,
const char* variable3, const string& value3,
const char* variable4, const string& value4,
const char* variable5, const string& value5,
const char* variable6, const string& value6) {
std::map<string, string> vars;
vars[variable1] = value1;
vars[variable2] = value2;
vars[variable3] = value3;
vars[variable4] = value4;
vars[variable5] = value5;
vars[variable6] = value6;
Print(vars, text);
}
void Printer::Print(const char* text,
const char* variable1, const string& value1,
const char* variable2, const string& value2,
const char* variable3, const string& value3,
const char* variable4, const string& value4,
const char* variable5, const string& value5,
const char* variable6, const string& value6,
const char* variable7, const string& value7) {
std::map<string, string> vars;
vars[variable1] = value1;
vars[variable2] = value2;
vars[variable3] = value3;
vars[variable4] = value4;
vars[variable5] = value5;
vars[variable6] = value6;
vars[variable7] = value7;
Print(vars, text);
}
void Printer::Print(const char* text,
const char* variable1, const string& value1,
const char* variable2, const string& value2,
const char* variable3, const string& value3,
const char* variable4, const string& value4,
const char* variable5, const string& value5,
const char* variable6, const string& value6,
const char* variable7, const string& value7,
const char* variable8, const string& value8) {
std::map<string, string> vars;
vars[variable1] = value1;
vars[variable2] = value2;
vars[variable3] = value3;
vars[variable4] = value4;
vars[variable5] = value5;
vars[variable6] = value6;
vars[variable7] = value7;
vars[variable8] = value8;
Print(vars, text);
}
void Printer::Indent() {
indent_ += " ";
}
void Printer::Outdent() {
if (indent_.empty()) {
GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
return;
}
indent_.resize(indent_.size() - 2);
}
void Printer::PrintRaw(const string& data) {
WriteRaw(data.data(), data.size());
}
void Printer::PrintRaw(const char* data) {
if (failed_) return;
WriteRaw(data, strlen(data));
}
void Printer::WriteRaw(const char* data, int size) {
if (failed_) return;
if (size == 0) return;
if (at_start_of_line_ && (size > 0) && (data[0] != '\n')) {
// Insert an indent.
at_start_of_line_ = false;
CopyToBuffer(indent_.data(), indent_.size());
if (failed_) return;
// Fix up empty variables (e.g., "{") that should be annotated as
// coming after the indent.
for (std::vector<string>::iterator i = line_start_variables_.begin();
i != line_start_variables_.end(); ++i) {
substitutions_[*i].first += indent_.size();
substitutions_[*i].second += indent_.size();
}
}
// If we're going to write any data, clear line_start_variables_, since
// we've either updated them in the block above or they no longer refer to
// the current line.
line_start_variables_.clear();
CopyToBuffer(data, size);
}
void Printer::CopyToBuffer(const char* data, int size) {
if (failed_) return;
if (size == 0) return;
while (size > buffer_size_) {
// Data exceeds space in the buffer. Copy what we can and request a
// new buffer.
memcpy(buffer_, data, buffer_size_);
offset_ += buffer_size_;
data += buffer_size_;
size -= buffer_size_;
void* void_buffer;
failed_ = !output_->Next(&void_buffer, &buffer_size_);
if (failed_) return;
buffer_ = reinterpret_cast<char*>(void_buffer);
}
// Buffer is big enough to receive the data; copy it.
memcpy(buffer_, data, size);
buffer_ += size;
buffer_size_ -= size;
offset_ += size;
}
} // namespace io
} // namespace protobuf
} // namespace google
-363
View File
@@ -1,363 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// Utility class for writing text to a ZeroCopyOutputStream.
#ifndef GOOGLE_PROTOBUF_IO_PRINTER_H__
#define GOOGLE_PROTOBUF_IO_PRINTER_H__
#include <string>
#include <map>
#include <vector>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace io {
class ZeroCopyOutputStream; // zero_copy_stream.h
// Records annotations about a Printer's output.
class LIBPROTOBUF_EXPORT AnnotationCollector {
public:
// Records that the bytes in file_path beginning with begin_offset and ending
// before end_offset are associated with the SourceCodeInfo-style path.
virtual void AddAnnotation(size_t begin_offset, size_t end_offset,
const string& file_path,
const std::vector<int>& path) = 0;
virtual ~AnnotationCollector() {}
};
// Records annotations about a Printer's output to the given protocol buffer,
// assuming that the buffer has an ::Annotation message exposing path,
// source_file, begin and end fields.
template <typename AnnotationProto>
class AnnotationProtoCollector : public AnnotationCollector {
public:
// annotation_proto is the protocol buffer to which new Annotations should be
// added. It is not owned by the AnnotationProtoCollector.
explicit AnnotationProtoCollector(AnnotationProto* annotation_proto)
: annotation_proto_(annotation_proto) {}
// Override for AnnotationCollector::AddAnnotation.
virtual void AddAnnotation(size_t begin_offset, size_t end_offset,
const string& file_path,
const std::vector<int>& path) {
typename AnnotationProto::Annotation* annotation =
annotation_proto_->add_annotation();
for (int i = 0; i < path.size(); ++i) {
annotation->add_path(path[i]);
}
annotation->set_source_file(file_path);
annotation->set_begin(begin_offset);
annotation->set_end(end_offset);
}
private:
// The protocol buffer to which new annotations should be added.
AnnotationProto* const annotation_proto_;
};
// This simple utility class assists in code generation. It basically
// allows the caller to define a set of variables and then output some
// text with variable substitutions. Example usage:
//
// Printer printer(output, '$');
// map<string, string> vars;
// vars["name"] = "Bob";
// printer.Print(vars, "My name is $name$.");
//
// The above writes "My name is Bob." to the output stream.
//
// Printer aggressively enforces correct usage, crashing (with assert failures)
// in the case of undefined variables in debug builds. This helps greatly in
// debugging code which uses it.
//
// If a Printer is constructed with an AnnotationCollector, it will provide it
// with annotations that connect the Printer's output to paths that can identify
// various descriptors. In the above example, if person_ is a descriptor that
// identifies Bob, we can associate the output string "My name is Bob." with
// a source path pointing to that descriptor with:
//
// printer.Annotate("name", person_);
//
// The AnnotationCollector will be sent an annotation linking the output range
// covering "Bob" to the logical path provided by person_. Tools may use
// this association to (for example) link "Bob" in the output back to the
// source file that defined the person_ descriptor identifying Bob.
//
// Annotate can only examine variables substituted during the last call to
// Print. It is invalid to refer to a variable that was used multiple times
// in a single Print call.
//
// In full generality, one may specify a range of output text using a beginning
// substitution variable and an ending variable. The resulting annotation will
// span from the first character of the substituted value for the beginning
// variable to the last character of the substituted value for the ending
// variable. For example, the Annotate call above is equivalent to this one:
//
// printer.Annotate("name", "name", person_);
//
// This is useful if multiple variables combine to form a single span of output
// that should be annotated with the same source path. For example:
//
// Printer printer(output, '$');
// map<string, string> vars;
// vars["first"] = "Alice";
// vars["last"] = "Smith";
// printer.Print(vars, "My name is $first$ $last$.");
// printer.Annotate("first", "last", person_);
//
// This code would associate the span covering "Alice Smith" in the output with
// the person_ descriptor.
//
// Note that the beginning variable must come before (or overlap with, in the
// case of zero-sized substitution values) the ending variable.
//
// It is also sometimes useful to use variables with zero-sized values as
// markers. This avoids issues with multiple references to the same variable
// and also allows annotation ranges to span literal text from the Print
// templates:
//
// Printer printer(output, '$');
// map<string, string> vars;
// vars["foo"] = "bar";
// vars["function"] = "call";
// vars["mark"] = "";
// printer.Print(vars, "$function$($foo$,$foo$)$mark$");
// printer.Annotate("function", "mark", call_);
//
// This code associates the span covering "call(bar,bar)" in the output with the
// call_ descriptor.
class LIBPROTOBUF_EXPORT Printer {
public:
// Create a printer that writes text to the given output stream. Use the
// given character as the delimiter for variables.
Printer(ZeroCopyOutputStream* output, char variable_delimiter);
// Create a printer that writes text to the given output stream. Use the
// given character as the delimiter for variables. If annotation_collector
// is not null, Printer will provide it with annotations about code written
// to the stream. annotation_collector is not owned by Printer.
Printer(ZeroCopyOutputStream* output, char variable_delimiter,
AnnotationCollector* annotation_collector);
~Printer();
// Link a subsitution variable emitted by the last call to Print to the object
// described by descriptor.
template <typename SomeDescriptor>
void Annotate(const char* varname, const SomeDescriptor* descriptor) {
Annotate(varname, varname, descriptor);
}
// Link the output range defined by the substitution variables as emitted by
// the last call to Print to the object described by descriptor. The range
// begins at begin_varname's value and ends after the last character of the
// value substituted for end_varname.
template <typename SomeDescriptor>
void Annotate(const char* begin_varname, const char* end_varname,
const SomeDescriptor* descriptor) {
if (annotation_collector_ == NULL) {
// Annotations aren't turned on for this Printer, so don't pay the cost
// of building the location path.
return;
}
std::vector<int> path;
descriptor->GetLocationPath(&path);
Annotate(begin_varname, end_varname, descriptor->file()->name(), path);
}
// Link a subsitution variable emitted by the last call to Print to the file
// with path file_name.
void Annotate(const char* varname, const string& file_name) {
Annotate(varname, varname, file_name);
}
// Link the output range defined by the substitution variables as emitted by
// the last call to Print to the file with path file_name. The range begins
// at begin_varname's value and ends after the last character of the value
// substituted for end_varname.
void Annotate(const char* begin_varname, const char* end_varname,
const string& file_name) {
if (annotation_collector_ == NULL) {
// Annotations aren't turned on for this Printer.
return;
}
std::vector<int> empty_path;
Annotate(begin_varname, end_varname, file_name, empty_path);
}
// Print some text after applying variable substitutions. If a particular
// variable in the text is not defined, this will crash. Variables to be
// substituted are identified by their names surrounded by delimiter
// characters (as given to the constructor). The variable bindings are
// defined by the given map.
void Print(const std::map<string, string>& variables, const char* text);
// Like the first Print(), except the substitutions are given as parameters.
void Print(const char* text);
// Like the first Print(), except the substitutions are given as parameters.
void Print(const char* text, const char* variable, const string& value);
// Like the first Print(), except the substitutions are given as parameters.
void Print(const char* text, const char* variable1, const string& value1,
const char* variable2, const string& value2);
// Like the first Print(), except the substitutions are given as parameters.
void Print(const char* text, const char* variable1, const string& value1,
const char* variable2, const string& value2,
const char* variable3, const string& value3);
// Like the first Print(), except the substitutions are given as parameters.
void Print(const char* text, const char* variable1, const string& value1,
const char* variable2, const string& value2,
const char* variable3, const string& value3,
const char* variable4, const string& value4);
// Like the first Print(), except the substitutions are given as parameters.
void Print(const char* text, const char* variable1, const string& value1,
const char* variable2, const string& value2,
const char* variable3, const string& value3,
const char* variable4, const string& value4,
const char* variable5, const string& value5);
// Like the first Print(), except the substitutions are given as parameters.
void Print(const char* text, const char* variable1, const string& value1,
const char* variable2, const string& value2,
const char* variable3, const string& value3,
const char* variable4, const string& value4,
const char* variable5, const string& value5,
const char* variable6, const string& value6);
// Like the first Print(), except the substitutions are given as parameters.
void Print(const char* text, const char* variable1, const string& value1,
const char* variable2, const string& value2,
const char* variable3, const string& value3,
const char* variable4, const string& value4,
const char* variable5, const string& value5,
const char* variable6, const string& value6,
const char* variable7, const string& value7);
// Like the first Print(), except the substitutions are given as parameters.
void Print(const char* text, const char* variable1, const string& value1,
const char* variable2, const string& value2,
const char* variable3, const string& value3,
const char* variable4, const string& value4,
const char* variable5, const string& value5,
const char* variable6, const string& value6,
const char* variable7, const string& value7,
const char* variable8, const string& value8);
// Indent text by two spaces. After calling Indent(), two spaces will be
// inserted at the beginning of each line of text. Indent() may be called
// multiple times to produce deeper indents.
void Indent();
// Reduces the current indent level by two spaces, or crashes if the indent
// level is zero.
void Outdent();
// Write a string to the output buffer.
// This method does not look for newlines to add indentation.
void PrintRaw(const string& data);
// Write a zero-delimited string to output buffer.
// This method does not look for newlines to add indentation.
void PrintRaw(const char* data);
// Write some bytes to the output buffer.
// This method does not look for newlines to add indentation.
void WriteRaw(const char* data, int size);
// True if any write to the underlying stream failed. (We don't just
// crash in this case because this is an I/O failure, not a programming
// error.)
bool failed() const { return failed_; }
private:
// Link the output range defined by the substitution variables as emitted by
// the last call to Print to the object found at the SourceCodeInfo-style path
// in a file with path file_path. The range begins at the start of
// begin_varname's value and ends after the last character of the value
// substituted for end_varname. Note that begin_varname and end_varname
// may refer to the same variable.
void Annotate(const char* begin_varname, const char* end_varname,
const string& file_path, const std::vector<int>& path);
// Copy size worth of bytes from data to buffer_.
void CopyToBuffer(const char* data, int size);
const char variable_delimiter_;
ZeroCopyOutputStream* const output_;
char* buffer_;
int buffer_size_;
// The current position, in bytes, in the output stream. This is equivalent
// to the total number of bytes that have been written so far. This value is
// used to calculate annotation ranges in the substitutions_ map below.
size_t offset_;
string indent_;
bool at_start_of_line_;
bool failed_;
// A map from variable name to [start, end) offsets in the output buffer.
// These refer to the offsets used for a variable after the last call to
// Print. If a variable was used more than once, the entry used in
// this map is set to a negative-length span. For singly-used variables, the
// start offset is the beginning of the substitution; the end offset is the
// last byte of the substitution plus one (such that (end - start) is the
// length of the substituted string).
std::map<string, std::pair<size_t, size_t> > substitutions_;
// Keeps track of the keys in substitutions_ that need to be updated when
// indents are inserted. These are keys that refer to the beginning of the
// current line.
std::vector<string> line_start_variables_;
// Returns true and sets range to the substitution range in the output for
// varname if varname was used once in the last call to Print. If varname
// was not used, or if it was used multiple times, returns false (and
// fails a debug assertion).
bool GetSubstitutionRange(const char* varname,
std::pair<size_t, size_t>* range);
// If non-null, annotation_collector_ is used to store annotations about
// generated code.
AnnotationCollector* const annotation_collector_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Printer);
};
} // namespace io
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_IO_PRINTER_H__
+24 -67
View File
@@ -38,88 +38,45 @@
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
namespace protobuf {
namespace io {
// ----------------------------------------------------------------------
// NoLocaleStrtod()
// This code will make you cry.
// ----------------------------------------------------------------------
namespace {
// Returns a string identical to *input except that the character pointed to
// by radix_pos (which should be '.') is replaced with the locale-specific
// radix character.
string LocalizeRadix(const char* input, const char* radix_pos) {
// Determine the locale-specific radix character by calling sprintf() to
// print the number 1.5, then stripping off the digits. As far as I can
// tell, this is the only portable, thread-safe way to get the C library
// to divuldge the locale's radix character. No, localeconv() is NOT
// thread-safe.
char temp[16];
int size = sprintf(temp, "%.1f", 1.5);
GOOGLE_CHECK_EQ(temp[0], '1');
GOOGLE_CHECK_EQ(temp[size-1], '5');
GOOGLE_CHECK_LE(size, 6);
// Now replace the '.' in the input with it.
string result;
result.reserve(strlen(input) + size - 3);
result.append(input, radix_pos);
result.append(temp + 1, size - 2);
result.append(radix_pos + 1);
return result;
}
} // namespace
double NoLocaleStrtod(const char* text, char** original_endptr) {
// We cannot simply set the locale to "C" temporarily with setlocale()
// as this is not thread-safe. Instead, we try to parse in the current
// locale first. If parsing stops at a '.' character, then this is a
// pretty good hint that we're actually in some other locale in which
// '.' is not the radix character.
char* temp_endptr;
double result = strtod(text, &temp_endptr);
if (original_endptr != NULL) *original_endptr = temp_endptr;
if (*temp_endptr != '.') return result;
// Parsing halted on a '.'. Perhaps we're in a different locale? Let's
// try to replace the '.' with a locale-specific radix character and
// try again.
string localized = LocalizeRadix(text, temp_endptr);
const char* localized_cstr = localized.c_str();
char* localized_endptr;
result = strtod(localized_cstr, &localized_endptr);
if ((localized_endptr - localized_cstr) >
(temp_endptr - text)) {
// This attempt got further, so replacing the decimal must have helped.
// Update original_endptr to point at the right location.
if (original_endptr != NULL) {
// size_diff is non-zero if the localized radix has multiple bytes.
int size_diff = localized.size() - strlen(text);
// const_cast is necessary to match the strtod() interface.
*original_endptr = const_cast<char*>(
text + (localized_endptr - localized_cstr - size_diff));
}
}
return result;
}
// This approximately 0x1.ffffffp127, but we don't use 0x1.ffffffp127 because
// it won't compile in MSVC.
const double MAX_FLOAT_AS_DOUBLE_ROUNDED = 3.4028235677973366e+38;
float SafeDoubleToFloat(double value) {
// static_cast<float> on a number larger than float can result in illegal
// instruction error, so we need to manually convert it to infinity or max.
if (value > std::numeric_limits<float>::max()) {
// Max float value is about 3.4028234664E38 when represented as a double.
// However, when printing float as text, it will be rounded as
// 3.4028235e+38. If we parse the value of 3.4028235e+38 from text and
// compare it to 3.4028234664E38, we may think that it is larger, but
// actually, any number between these two numbers could only be represented
// as the same max float number in float, so we should treat them the same
// as max float.
if (value <= MAX_FLOAT_AS_DOUBLE_ROUNDED) {
return std::numeric_limits<float>::max();
}
return std::numeric_limits<float>::infinity();
} else if (value < -std::numeric_limits<float>::max()) {
if (value >= -MAX_FLOAT_AS_DOUBLE_ROUNDED) {
return -std::numeric_limits<float>::max();
}
return -std::numeric_limits<float>::infinity();
} else {
return static_cast<float>(value);
}
}
double NoLocaleStrtod(const char* str, char** endptr) {
return google::protobuf::internal::NoLocaleStrtod(str, endptr);
}
} // namespace io
} // namespace protobuf
} // namespace google
+1 -1
View File
@@ -50,6 +50,6 @@ float SafeDoubleToFloat(double value);
} // namespace io
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_IO_STRTOD_H__
+210 -164
View File
@@ -89,12 +89,13 @@
// exactly pretty.
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/io/strtod.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/stl_util.h>
namespace google {
@@ -113,39 +114,34 @@ namespace {
// Note: No class is allowed to contain '\0', since this is used to mark end-
// of-input and is handled specially.
#define CHARACTER_CLASS(NAME, EXPRESSION) \
class NAME { \
public: \
static inline bool InClass(char c) { \
return EXPRESSION; \
} \
#define CHARACTER_CLASS(NAME, EXPRESSION) \
class NAME { \
public: \
static inline bool InClass(char c) { return EXPRESSION; } \
}
CHARACTER_CLASS(Whitespace, c == ' ' || c == '\n' || c == '\t' ||
c == '\r' || c == '\v' || c == '\f');
CHARACTER_CLASS(WhitespaceNoNewline, c == ' ' || c == '\t' ||
c == '\r' || c == '\v' || c == '\f');
CHARACTER_CLASS(Whitespace, c == ' ' || c == '\n' || c == '\t' || c == '\r' ||
c == '\v' || c == '\f');
CHARACTER_CLASS(WhitespaceNoNewline,
c == ' ' || c == '\t' || c == '\r' || c == '\v' || c == '\f');
CHARACTER_CLASS(Unprintable, c < ' ' && c > '\0');
CHARACTER_CLASS(Unprintable, c<' ' && c> '\0');
CHARACTER_CLASS(Digit, '0' <= c && c <= '9');
CHARACTER_CLASS(OctalDigit, '0' <= c && c <= '7');
CHARACTER_CLASS(HexDigit, ('0' <= c && c <= '9') ||
('a' <= c && c <= 'f') ||
('A' <= c && c <= 'F'));
CHARACTER_CLASS(HexDigit, ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') ||
('A' <= c && c <= 'F'));
CHARACTER_CLASS(Letter, ('a' <= c && c <= 'z') ||
('A' <= c && c <= 'Z') ||
(c == '_'));
CHARACTER_CLASS(Letter,
('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || (c == '_'));
CHARACTER_CLASS(Alphanumeric, ('a' <= c && c <= 'z') ||
('A' <= c && c <= 'Z') ||
('0' <= c && c <= '9') ||
(c == '_'));
('A' <= c && c <= 'Z') ||
('0' <= c && c <= '9') || (c == '_'));
CHARACTER_CLASS(Escape, c == 'a' || c == 'b' || c == 'f' || c == 'n' ||
c == 'r' || c == 't' || c == 'v' || c == '\\' ||
c == '?' || c == '\'' || c == '\"');
c == 'r' || c == 't' || c == 'v' || c == '\\' ||
c == '?' || c == '\'' || c == '\"');
#undef CHARACTER_CLASS
@@ -161,20 +157,32 @@ inline int DigitValue(char digit) {
// Inline because it's only used in one place.
inline char TranslateEscape(char c) {
switch (c) {
case 'a': return '\a';
case 'b': return '\b';
case 'f': return '\f';
case 'n': return '\n';
case 'r': return '\r';
case 't': return '\t';
case 'v': return '\v';
case '\\': return '\\';
case '?': return '\?'; // Trigraphs = :(
case '\'': return '\'';
case '"': return '\"';
case 'a':
return '\a';
case 'b':
return '\b';
case 'f':
return '\f';
case 'n':
return '\n';
case 'r':
return '\r';
case 't':
return '\t';
case 'v':
return '\v';
case '\\':
return '\\';
case '?':
return '\?'; // Trigraphs = :(
case '\'':
return '\'';
case '"':
return '\"';
// We expect escape sequences to have been validated separately.
default: return '?';
default:
return '?';
}
}
@@ -186,21 +194,20 @@ ErrorCollector::~ErrorCollector() {}
Tokenizer::Tokenizer(ZeroCopyInputStream* input,
ErrorCollector* error_collector)
: input_(input),
error_collector_(error_collector),
buffer_(NULL),
buffer_size_(0),
buffer_pos_(0),
read_error_(false),
line_(0),
column_(0),
record_target_(NULL),
record_start_(-1),
allow_f_after_float_(false),
comment_style_(CPP_COMMENT_STYLE),
require_space_after_number_(true),
allow_multiline_strings_(false) {
: input_(input),
error_collector_(error_collector),
buffer_(NULL),
buffer_size_(0),
buffer_pos_(0),
read_error_(false),
line_(0),
column_(0),
record_target_(NULL),
record_start_(-1),
allow_f_after_float_(false),
comment_style_(CPP_COMMENT_STYLE),
require_space_after_number_(true),
allow_multiline_strings_(false) {
current_.line = 0;
current_.column = 0;
current_.end_column = 0;
@@ -217,6 +224,21 @@ Tokenizer::~Tokenizer() {
}
}
bool Tokenizer::report_whitespace() const { return report_whitespace_; }
// Note: `set_report_whitespace(false)` implies `set_report_newlines(false)`.
void Tokenizer::set_report_whitespace(bool report) {
report_whitespace_ = report;
report_newlines_ &= report;
}
// If true, newline tokens are reported by Next().
bool Tokenizer::report_newlines() const { return report_newlines_; }
// Note: `set_report_newlines(true)` implies `set_report_whitespace(true)`.
void Tokenizer::set_report_newlines(bool report) {
report_newlines_ = report;
report_whitespace_ |= report; // enable report_whitespace if necessary
}
// -------------------------------------------------------------------
// Internal helpers.
@@ -249,7 +271,8 @@ void Tokenizer::Refresh() {
// If we're in a token, append the rest of the buffer to it.
if (record_target_ != NULL && record_start_ < buffer_size_) {
record_target_->append(buffer_ + record_start_, buffer_size_ - record_start_);
record_target_->append(buffer_ + record_start_,
buffer_size_ - record_start_);
record_start_ = 0;
}
@@ -271,7 +294,7 @@ void Tokenizer::Refresh() {
current_char_ = buffer_[0];
}
inline void Tokenizer::RecordTo(string* target) {
inline void Tokenizer::RecordTo(std::string* target) {
record_target_ = target;
record_start_ = buffer_pos_;
}
@@ -282,14 +305,15 @@ inline void Tokenizer::StopRecording() {
// be helpful by detecting the NULL pointer, even though there's nothing
// wrong with reading zero bytes from NULL.
if (buffer_pos_ != record_start_) {
record_target_->append(buffer_ + record_start_, buffer_pos_ - record_start_);
record_target_->append(buffer_ + record_start_,
buffer_pos_ - record_start_);
}
record_target_ = NULL;
record_start_ = -1;
}
inline void Tokenizer::StartToken() {
current_.type = TYPE_START; // Just for the sake of initializing it.
current_.type = TYPE_START; // Just for the sake of initializing it.
current_.text.clear();
current_.line = line_;
current_.column = column_;
@@ -304,12 +328,12 @@ inline void Tokenizer::EndToken() {
// -------------------------------------------------------------------
// Helper methods that consume characters.
template<typename CharacterClass>
template <typename CharacterClass>
inline bool Tokenizer::LookingAt() {
return CharacterClass::InClass(current_char_);
}
template<typename CharacterClass>
template <typename CharacterClass>
inline bool Tokenizer::TryConsumeOne() {
if (CharacterClass::InClass(current_char_)) {
NextChar();
@@ -328,14 +352,14 @@ inline bool Tokenizer::TryConsume(char c) {
}
}
template<typename CharacterClass>
template <typename CharacterClass>
inline void Tokenizer::ConsumeZeroOrMore() {
while (CharacterClass::InClass(current_char_)) {
NextChar();
}
}
template<typename CharacterClass>
template <typename CharacterClass>
inline void Tokenizer::ConsumeOneOrMore(const char* error) {
if (!CharacterClass::InClass(current_char_)) {
AddError(error);
@@ -381,25 +405,21 @@ void Tokenizer::ConsumeString(char delimiter) {
}
// Possibly followed by another hex digit, but again we don't care.
} else if (TryConsume('u')) {
if (!TryConsumeOne<HexDigit>() ||
!TryConsumeOne<HexDigit>() ||
!TryConsumeOne<HexDigit>() ||
!TryConsumeOne<HexDigit>()) {
if (!TryConsumeOne<HexDigit>() || !TryConsumeOne<HexDigit>() ||
!TryConsumeOne<HexDigit>() || !TryConsumeOne<HexDigit>()) {
AddError("Expected four hex digits for \\u escape sequence.");
}
} else if (TryConsume('U')) {
// We expect 8 hex digits; but only the range up to 0x10ffff is
// legal.
if (!TryConsume('0') ||
!TryConsume('0') ||
if (!TryConsume('0') || !TryConsume('0') ||
!(TryConsume('0') || TryConsume('1')) ||
!TryConsumeOne<HexDigit>() ||
!TryConsumeOne<HexDigit>() ||
!TryConsumeOne<HexDigit>() ||
!TryConsumeOne<HexDigit>() ||
!TryConsumeOne<HexDigit>() || !TryConsumeOne<HexDigit>() ||
!TryConsumeOne<HexDigit>() || !TryConsumeOne<HexDigit>() ||
!TryConsumeOne<HexDigit>()) {
AddError("Expected eight hex digits up to 10ffff for \\U escape "
"sequence");
AddError(
"Expected eight hex digits up to 10ffff for \\U escape "
"sequence");
}
} else {
AddError("Invalid escape sequence in string literal.");
@@ -465,7 +485,7 @@ Tokenizer::TokenType Tokenizer::ConsumeNumber(bool started_with_zero,
} else if (current_char_ == '.') {
if (is_float) {
AddError(
"Already saw decimal point or exponent; can't have another one.");
"Already saw decimal point or exponent; can't have another one.");
} else {
AddError("Hex and octal numbers must be integers.");
}
@@ -474,7 +494,7 @@ Tokenizer::TokenType Tokenizer::ConsumeNumber(bool started_with_zero,
return is_float ? TYPE_FLOAT : TYPE_INTEGER;
}
void Tokenizer::ConsumeLineComment(string* content) {
void Tokenizer::ConsumeLineComment(std::string* content) {
if (content != NULL) RecordTo(content);
while (current_char_ != '\0' && current_char_ != '\n') {
@@ -485,17 +505,15 @@ void Tokenizer::ConsumeLineComment(string* content) {
if (content != NULL) StopRecording();
}
void Tokenizer::ConsumeBlockComment(string* content) {
void Tokenizer::ConsumeBlockComment(std::string* content) {
int start_line = line_;
int start_column = column_ - 2;
if (content != NULL) RecordTo(content);
while (true) {
while (current_char_ != '\0' &&
current_char_ != '*' &&
current_char_ != '/' &&
current_char_ != '\n') {
while (current_char_ != '\0' && current_char_ != '*' &&
current_char_ != '/' && current_char_ != '\n') {
NextChar();
}
@@ -524,11 +542,11 @@ void Tokenizer::ConsumeBlockComment(string* content) {
// Note: We didn't consume the '*' because if there is a '/' after it
// we want to interpret that as the end of the comment.
AddError(
"\"/*\" inside block comment. Block comments cannot be nested.");
"\"/*\" inside block comment. Block comments cannot be nested.");
} else if (current_char_ == '\0') {
AddError("End-of-file inside block comment.");
error_collector_->AddError(
start_line, start_column, " Comment started here.");
error_collector_->AddError(start_line, start_column,
" Comment started here.");
if (content != NULL) StopRecording();
break;
}
@@ -557,13 +575,46 @@ Tokenizer::NextCommentStatus Tokenizer::TryConsumeCommentStart() {
}
}
bool Tokenizer::TryConsumeWhitespace() {
if (report_newlines_) {
if (TryConsumeOne<WhitespaceNoNewline>()) {
ConsumeZeroOrMore<WhitespaceNoNewline>();
current_.type = TYPE_WHITESPACE;
return true;
}
return false;
}
if (TryConsumeOne<Whitespace>()) {
ConsumeZeroOrMore<Whitespace>();
current_.type = TYPE_WHITESPACE;
return report_whitespace_;
}
return false;
}
bool Tokenizer::TryConsumeNewline() {
if (!report_whitespace_ || !report_newlines_) {
return false;
}
if (TryConsume('\n')) {
current_.type = TYPE_NEWLINE;
return true;
}
return false;
}
// -------------------------------------------------------------------
bool Tokenizer::Next() {
previous_ = current_;
while (!read_error_) {
ConsumeZeroOrMore<Whitespace>();
StartToken();
bool report_token = TryConsumeWhitespace() || TryConsumeNewline();
EndToken();
if (report_token) {
return true;
}
switch (TryConsumeCommentStart()) {
case LINE_COMMENT:
@@ -613,8 +664,9 @@ bool Tokenizer::Next() {
current_.line == previous_.line &&
current_.column == previous_.end_column) {
// We don't accept syntax like "blah.123".
error_collector_->AddError(line_, column_ - 2,
"Need space between identifier and decimal point.");
error_collector_->AddError(
line_, column_ - 2,
"Need space between identifier and decimal point.");
}
current_.type = ConsumeNumber(false, true);
} else {
@@ -631,7 +683,8 @@ bool Tokenizer::Next() {
} else {
// Check if the high order bit is set.
if (current_char_ & 0x80) {
error_collector_->AddError(line_, column_,
error_collector_->AddError(
line_, column_,
StringPrintf("Interpreting non ascii codepoint %d.",
static_cast<unsigned char>(current_char_)));
}
@@ -664,9 +717,9 @@ namespace {
// next_leading_comments.
class CommentCollector {
public:
CommentCollector(string* prev_trailing_comments,
std::vector<string>* detached_comments,
string* next_leading_comments)
CommentCollector(std::string* prev_trailing_comments,
std::vector<std::string>* detached_comments,
std::string* next_leading_comments)
: prev_trailing_comments_(prev_trailing_comments),
detached_comments_(detached_comments),
next_leading_comments_(next_leading_comments),
@@ -687,7 +740,7 @@ class CommentCollector {
// About to read a line comment. Get the comment buffer pointer in order to
// read into it.
string* GetBufferForLineComment() {
std::string* GetBufferForLineComment() {
// We want to combine with previous line comments, but not block comments.
if (has_comment_ && !is_line_comment_) {
Flush();
@@ -699,7 +752,7 @@ class CommentCollector {
// About to read a block comment. Get the comment buffer pointer in order to
// read into it.
string* GetBufferForBlockComment() {
std::string* GetBufferForBlockComment() {
if (has_comment_) {
Flush();
}
@@ -731,16 +784,14 @@ class CommentCollector {
}
}
void DetachFromPrev() {
can_attach_to_prev_ = false;
}
void DetachFromPrev() { can_attach_to_prev_ = false; }
private:
string* prev_trailing_comments_;
std::vector<string>* detached_comments_;
string* next_leading_comments_;
std::string* prev_trailing_comments_;
std::vector<std::string>* detached_comments_;
std::string* next_leading_comments_;
string comment_buffer_;
std::string comment_buffer_;
// True if any comments were read into comment_buffer_. This can be true even
// if comment_buffer_ is empty, namely if the comment was "/**/".
@@ -754,21 +805,23 @@ class CommentCollector {
bool can_attach_to_prev_;
};
} // namespace
} // namespace
bool Tokenizer::NextWithComments(string* prev_trailing_comments,
std::vector<string>* detached_comments,
string* next_leading_comments) {
bool Tokenizer::NextWithComments(std::string* prev_trailing_comments,
std::vector<std::string>* detached_comments,
std::string* next_leading_comments) {
CommentCollector collector(prev_trailing_comments, detached_comments,
next_leading_comments);
if (current_.type == TYPE_START) {
// Ignore unicode byte order mark(BOM) if it appears at the file
// beginning. Only UTF-8 BOM (0xEF 0xBB 0xBF) is accepted.
if (TryConsume((char)0xEF)) {
if (!TryConsume((char)0xBB) || !TryConsume((char)0xBF)) {
AddError("Proto file starts with 0xEF but not UTF-8 BOM. "
"Only UTF-8 is accepted for proto file.");
if (TryConsume(static_cast<char>(0xEF))) {
if (!TryConsume(static_cast<char>(0xBB)) ||
!TryConsume(static_cast<char>(0xBF))) {
AddError(
"Proto file starts with 0xEF but not UTF-8 BOM. "
"Only UTF-8 is accepted for proto file.");
return false;
}
}
@@ -836,9 +889,7 @@ bool Tokenizer::NextWithComments(string* prev_trailing_comments,
collector.DetachFromPrev();
} else {
bool result = Next();
if (!result ||
current_.text == "}" ||
current_.text == "]" ||
if (!result || current_.text == "}" || current_.text == "]" ||
current_.text == ")") {
// It looks like we're at the end of a scope. In this case it
// makes no sense to attach a comment to the following token.
@@ -858,12 +909,12 @@ bool Tokenizer::NextWithComments(string* prev_trailing_comments,
// are given is text that the tokenizer actually parsed as a token
// of the given type.
bool Tokenizer::ParseInteger(const string& text, uint64 max_value,
uint64* output) {
bool Tokenizer::ParseInteger(const std::string& text, uint64_t max_value,
uint64_t* output) {
// Sadly, we can't just use strtoul() since it is only 32-bit and strtoull()
// is non-standard. I hate the C standard library. :(
// return strtoull(text.c_str(), NULL, 0);
// return strtoull(text.c_str(), NULL, 0);
const char* ptr = text.c_str();
int base = 10;
@@ -878,7 +929,7 @@ bool Tokenizer::ParseInteger(const string& text, uint64 max_value,
}
}
uint64 result = 0;
uint64_t result = 0;
for (; *ptr != '\0'; ptr++) {
int digit = DigitValue(*ptr);
if (digit < 0 || digit >= base) {
@@ -886,7 +937,8 @@ bool Tokenizer::ParseInteger(const string& text, uint64 max_value,
// token, but Tokenizer still think it's integer.
return false;
}
if (digit > max_value || result > (max_value - digit) / base) {
if (static_cast<uint64_t>(digit) > max_value ||
result > (max_value - digit) / base) {
// Overflow.
return false;
}
@@ -897,7 +949,7 @@ bool Tokenizer::ParseInteger(const string& text, uint64 max_value,
return true;
}
double Tokenizer::ParseFloat(const string& text) {
double Tokenizer::ParseFloat(const std::string& text) {
const char* start = text.c_str();
char* end;
double result = NoLocaleStrtod(start, &end);
@@ -916,41 +968,38 @@ double Tokenizer::ParseFloat(const string& text) {
++end;
}
GOOGLE_LOG_IF(DFATAL, end - start != text.size() || *start == '-')
<< " Tokenizer::ParseFloat() passed text that could not have been"
" tokenized as a float: " << CEscape(text);
GOOGLE_LOG_IF(DFATAL,
static_cast<size_t>(end - start) != text.size() || *start == '-')
<< " Tokenizer::ParseFloat() passed text that could not have been"
" tokenized as a float: "
<< CEscape(text);
return result;
}
// Helper to append a Unicode code point to a string as UTF8, without bringing
// in any external dependencies.
static void AppendUTF8(uint32 code_point, string* output) {
uint32 tmp = 0;
static void AppendUTF8(uint32_t code_point, std::string* output) {
uint32_t tmp = 0;
int len = 0;
if (code_point <= 0x7f) {
tmp = code_point;
len = 1;
} else if (code_point <= 0x07ff) {
tmp = 0x0000c080 |
((code_point & 0x07c0) << 2) |
(code_point & 0x003f);
tmp = 0x0000c080 | ((code_point & 0x07c0) << 2) | (code_point & 0x003f);
len = 2;
} else if (code_point <= 0xffff) {
tmp = 0x00e08080 |
((code_point & 0xf000) << 4) |
((code_point & 0x0fc0) << 2) |
(code_point & 0x003f);
tmp = 0x00e08080 | ((code_point & 0xf000) << 4) |
((code_point & 0x0fc0) << 2) | (code_point & 0x003f);
len = 3;
} else if (code_point <= 0x1fffff) {
tmp = 0xf0808080 |
((code_point & 0x1c0000) << 6) |
((code_point & 0x03f000) << 4) |
((code_point & 0x000fc0) << 2) |
(code_point & 0x003f);
} else if (code_point <= 0x10ffff) {
tmp = 0xf0808080 | ((code_point & 0x1c0000) << 6) |
((code_point & 0x03f000) << 4) | ((code_point & 0x000fc0) << 2) |
(code_point & 0x003f);
len = 4;
} else {
// UTF-16 is only defined for code points up to 0x10FFFF, and UTF-8 is
// normally only defined up to there as well.
// Unicode code points end at 0x10FFFF, so this is out-of-range.
// ConsumeString permits hex values up to 0x1FFFFF, and FetchUnicodePoint
// doesn't perform a range check.
StringAppendF(output, "\\U%08x", code_point);
return;
}
@@ -960,7 +1009,7 @@ static void AppendUTF8(uint32 code_point, string* output) {
// Try to read <len> hex digits from ptr, and stuff the numeric result into
// *result. Returns true if that many digits were successfully consumed.
static bool ReadHexDigits(const char* ptr, int len, uint32* result) {
static bool ReadHexDigits(const char* ptr, int len, uint32_t* result) {
*result = 0;
if (len == 0) return false;
for (const char* end = ptr + len; ptr < end; ++ptr) {
@@ -975,26 +1024,27 @@ static bool ReadHexDigits(const char* ptr, int len, uint32* result) {
// surrogate. These numbers are in a reserved range of Unicode code points, so
// if we encounter such a pair we know how to parse it and convert it into a
// single code point.
static const uint32 kMinHeadSurrogate = 0xd800;
static const uint32 kMaxHeadSurrogate = 0xdc00;
static const uint32 kMinTrailSurrogate = 0xdc00;
static const uint32 kMaxTrailSurrogate = 0xe000;
static const uint32_t kMinHeadSurrogate = 0xd800;
static const uint32_t kMaxHeadSurrogate = 0xdc00;
static const uint32_t kMinTrailSurrogate = 0xdc00;
static const uint32_t kMaxTrailSurrogate = 0xe000;
static inline bool IsHeadSurrogate(uint32 code_point) {
static inline bool IsHeadSurrogate(uint32_t code_point) {
return (code_point >= kMinHeadSurrogate) && (code_point < kMaxHeadSurrogate);
}
static inline bool IsTrailSurrogate(uint32 code_point) {
static inline bool IsTrailSurrogate(uint32_t code_point) {
return (code_point >= kMinTrailSurrogate) &&
(code_point < kMaxTrailSurrogate);
(code_point < kMaxTrailSurrogate);
}
// Combine a head and trail surrogate into a single Unicode code point.
static uint32 AssembleUTF16(uint32 head_surrogate, uint32 trail_surrogate) {
static uint32_t AssembleUTF16(uint32_t head_surrogate,
uint32_t trail_surrogate) {
GOOGLE_DCHECK(IsHeadSurrogate(head_surrogate));
GOOGLE_DCHECK(IsTrailSurrogate(trail_surrogate));
return 0x10000 + (((head_surrogate - kMinHeadSurrogate) << 10) |
(trail_surrogate - kMinTrailSurrogate));
(trail_surrogate - kMinTrailSurrogate));
}
// Convert the escape sequence parameter to a number of expected hex digits.
@@ -1008,12 +1058,11 @@ static inline int UnicodeLength(char key) {
// to parse that sequence. On success, returns a pointer to the first char
// beyond that sequence, and fills in *code_point. On failure, returns ptr
// itself.
static const char* FetchUnicodePoint(const char* ptr, uint32* code_point) {
static const char* FetchUnicodePoint(const char* ptr, uint32_t* code_point) {
const char* p = ptr;
// Fetch the code point.
const int len = UnicodeLength(*p++);
if (!ReadHexDigits(p, len, code_point))
return ptr;
if (!ReadHexDigits(p, len, code_point)) return ptr;
p += len;
// Check if the code point we read is a "head surrogate." If so, then we
@@ -1021,7 +1070,7 @@ static const char* FetchUnicodePoint(const char* ptr, uint32* code_point) {
// "trail surrogate," and together they form a UTF-16 pair which decodes into
// a single Unicode point. Trail surrogates may only use \u, not \U.
if (IsHeadSurrogate(*code_point) && *p == '\\' && *(p + 1) == 'u') {
uint32 trail_surrogate;
uint32_t trail_surrogate;
if (ReadHexDigits(p + 2, 4, &trail_surrogate) &&
IsTrailSurrogate(trail_surrogate)) {
*code_point = AssembleUTF16(*code_point, trail_surrogate);
@@ -1036,14 +1085,15 @@ static const char* FetchUnicodePoint(const char* ptr, uint32* code_point) {
// The text string must begin and end with single or double quote
// characters.
void Tokenizer::ParseStringAppend(const string& text, string* output) {
void Tokenizer::ParseStringAppend(const std::string& text,
std::string* output) {
// Reminder: text[0] is always a quote character. (If text is
// empty, it's invalid, so we'll just return).
const size_t text_size = text.size();
if (text_size == 0) {
GOOGLE_LOG(DFATAL)
<< " Tokenizer::ParseStringAppend() passed text that could not"
" have been tokenized as a string: " << CEscape(text);
GOOGLE_LOG(DFATAL) << " Tokenizer::ParseStringAppend() passed text that could not"
" have been tokenized as a string: "
<< CEscape(text);
return;
}
@@ -1092,7 +1142,7 @@ void Tokenizer::ParseStringAppend(const string& text, string* output) {
output->push_back(static_cast<char>(code));
} else if (*ptr == 'u' || *ptr == 'U') {
uint32 unicode;
uint32_t unicode;
const char* end = FetchUnicodePoint(ptr, &unicode);
if (end == ptr) {
// Failure: Just dump out what we saw, don't try to parse it.
@@ -1114,23 +1164,19 @@ void Tokenizer::ParseStringAppend(const string& text, string* output) {
}
}
template<typename CharacterClass>
static bool AllInClass(const string& s) {
for (int i = 0; i < s.size(); ++i) {
if (!CharacterClass::InClass(s[i]))
return false;
template <typename CharacterClass>
static bool AllInClass(const std::string& s) {
for (const char character : s) {
if (!CharacterClass::InClass(character)) return false;
}
return true;
}
bool Tokenizer::IsIdentifier(const string& text) {
bool Tokenizer::IsIdentifier(const std::string& text) {
// Mirrors IDENTIFIER definition in Tokenizer::Next() above.
if (text.size() == 0)
return false;
if (!Letter::InClass(text.at(0)))
return false;
if (!AllInClass<Alphanumeric>(text.substr(1)))
return false;
if (text.size() == 0) return false;
if (!Letter::InClass(text.at(0))) return false;
if (!AllInClass<Alphanumeric>(text.substr(1))) return false;
return true;
}
+71 -42
View File
@@ -37,16 +37,19 @@
#ifndef GOOGLE_PROTOBUF_IO_TOKENIZER_H__
#define GOOGLE_PROTOBUF_IO_TOKENIZER_H__
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace io {
class ZeroCopyInputStream; // zero_copy_stream.h
class ZeroCopyInputStream; // zero_copy_stream.h
// Defined in this file.
class ErrorCollector;
@@ -61,7 +64,7 @@ typedef int ColumnNumber;
// Abstract interface for an object which collects the errors that occur
// during parsing. A typical implementation might simply print the errors
// to stdout.
class LIBPROTOBUF_EXPORT ErrorCollector {
class PROTOBUF_EXPORT ErrorCollector {
public:
inline ErrorCollector() {}
virtual ~ErrorCollector();
@@ -70,13 +73,13 @@ class LIBPROTOBUF_EXPORT ErrorCollector {
// column numbers. The numbers are zero-based, so you may want to add
// 1 to each before printing them.
virtual void AddError(int line, ColumnNumber column,
const string& message) = 0;
const std::string& message) = 0;
// Indicates that there was a warning in the input at the given line and
// column numbers. The numbers are zero-based, so you may want to add
// 1 to each before printing them.
virtual void AddWarning(int line, ColumnNumber column,
const string& message) { }
virtual void AddWarning(int /* line */, ColumnNumber /* column */,
const std::string& /* message */) {}
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector);
@@ -88,7 +91,7 @@ class LIBPROTOBUF_EXPORT ErrorCollector {
// precise descriptions. Whitespace and comments are skipped. By default,
// C- and C++-style comments are recognized, but other styles can be used by
// calling set_comment_style().
class LIBPROTOBUF_EXPORT Tokenizer {
class PROTOBUF_EXPORT Tokenizer {
public:
// Construct a Tokenizer that reads and tokenizes text from the given
// input stream and writes errors to the given error_collector.
@@ -97,8 +100,8 @@ class LIBPROTOBUF_EXPORT Tokenizer {
~Tokenizer();
enum TokenType {
TYPE_START, // Next() has not yet been called.
TYPE_END, // End of input reached. "text" is empty.
TYPE_START, // Next() has not yet been called.
TYPE_END, // End of input reached. "text" is empty.
TYPE_IDENTIFIER, // A sequence of letters, digits, and underscores, not
// starting with a digit. It is an error for a number
@@ -119,12 +122,19 @@ class LIBPROTOBUF_EXPORT Tokenizer {
TYPE_SYMBOL, // Any other printable character, like '!' or '+'.
// Symbols are always a single character, so "!+$%" is
// four tokens.
TYPE_WHITESPACE, // A sequence of whitespace. This token type is only
// produced if report_whitespace() is true. It is not
// reported for whitespace within comments or strings.
TYPE_NEWLINE, // A newline (\n). This token type is only
// produced if report_whitespace() is true and
// report_newlines() is true. It is not reported for
// newlines in comments or strings.
};
// Structure representing a token read from the token stream.
struct Token {
TokenType type;
string text; // The exact text of the token as it appeared in
std::string text; // The exact text of the token as it appeared in
// the input. e.g. tokens of TYPE_STRING will still
// be escaped and in quotes.
@@ -190,32 +200,32 @@ class LIBPROTOBUF_EXPORT Tokenizer {
// /* Block comment attached to
// * grault. */
// optional int32 grault = 6;
bool NextWithComments(string* prev_trailing_comments,
std::vector<string>* detached_comments,
string* next_leading_comments);
bool NextWithComments(std::string* prev_trailing_comments,
std::vector<std::string>* detached_comments,
std::string* next_leading_comments);
// Parse helpers ---------------------------------------------------
// Parses a TYPE_FLOAT token. This never fails, so long as the text actually
// comes from a TYPE_FLOAT token parsed by Tokenizer. If it doesn't, the
// result is undefined (possibly an assert failure).
static double ParseFloat(const string& text);
static double ParseFloat(const std::string& text);
// Parses a TYPE_STRING token. This never fails, so long as the text actually
// comes from a TYPE_STRING token parsed by Tokenizer. If it doesn't, the
// result is undefined (possibly an assert failure).
static void ParseString(const string& text, string* output);
static void ParseString(const std::string& text, std::string* output);
// Identical to ParseString, but appends to output.
static void ParseStringAppend(const string& text, string* output);
static void ParseStringAppend(const std::string& text, std::string* output);
// Parses a TYPE_INTEGER token. Returns false if the result would be
// greater than max_value. Otherwise, returns true and sets *output to the
// result. If the text is not from a Token of type TYPE_INTEGER originally
// parsed by a Tokenizer, the result is undefined (possibly an assert
// failure).
static bool ParseInteger(const string& text, uint64 max_value,
uint64* output);
static bool ParseInteger(const std::string& text, uint64_t max_value,
uint64_t* output);
// Options ---------------------------------------------------------
@@ -249,24 +259,34 @@ class LIBPROTOBUF_EXPORT Tokenizer {
allow_multiline_strings_ = allow;
}
// If true, whitespace tokens are reported by Next().
// Note: `set_report_whitespace(false)` implies `set_report_newlines(false)`.
bool report_whitespace() const;
void set_report_whitespace(bool report);
// If true, newline tokens are reported by Next().
// Note: `set_report_newlines(true)` implies `set_report_whitespace(true)`.
bool report_newlines() const;
void set_report_newlines(bool report);
// External helper: validate an identifier.
static bool IsIdentifier(const string& text);
static bool IsIdentifier(const std::string& text);
// -----------------------------------------------------------------
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer);
Token current_; // Returned by current().
Token previous_; // Returned by previous().
Token current_; // Returned by current().
Token previous_; // Returned by previous().
ZeroCopyInputStream* input_;
ErrorCollector* error_collector_;
char current_char_; // == buffer_[buffer_pos_], updated by NextChar().
const char* buffer_; // Current buffer returned from input_.
int buffer_size_; // Size of buffer_.
int buffer_pos_; // Current position within the buffer.
bool read_error_; // Did we previously encounter a read error?
char current_char_; // == buffer_[buffer_pos_], updated by NextChar().
const char* buffer_; // Current buffer returned from input_.
int buffer_size_; // Size of buffer_.
int buffer_pos_; // Current position within the buffer.
bool read_error_; // Did we previously encounter a read error?
// Line and column number of current_char_ within the whole input stream.
int line_;
@@ -276,7 +296,7 @@ class LIBPROTOBUF_EXPORT Tokenizer {
// Call RecordTo(&str) to start recording and StopRecording() to stop.
// E.g. StartToken() calls RecordTo(&current_.text). record_start_ is the
// position within the current buffer where recording started.
string* record_target_;
std::string* record_target_;
int record_start_;
// Options.
@@ -284,6 +304,8 @@ class LIBPROTOBUF_EXPORT Tokenizer {
CommentStyle comment_style_;
bool require_space_after_number_;
bool allow_multiline_strings_;
bool report_whitespace_ = false;
bool report_newlines_ = false;
// Since we count columns we need to interpret tabs somehow. We'll take
// the standard 8-character definition for lack of any way to do better.
@@ -299,7 +321,7 @@ class LIBPROTOBUF_EXPORT Tokenizer {
// Read a new buffer from the input.
void Refresh();
inline void RecordTo(string* target);
inline void RecordTo(std::string* target);
inline void StopRecording();
// Called when the current character is the first character of a new
@@ -311,7 +333,7 @@ class LIBPROTOBUF_EXPORT Tokenizer {
inline void EndToken();
// Convenience method to add an error at the current line and column.
void AddError(const string& message) {
void AddError(const std::string& message) {
error_collector_->AddError(line_, column_, message);
}
@@ -334,9 +356,9 @@ class LIBPROTOBUF_EXPORT Tokenizer {
TokenType ConsumeNumber(bool started_with_zero, bool started_with_dot);
// Consume the rest of a line.
void ConsumeLineComment(string* content);
void ConsumeLineComment(std::string* content);
// Consume until "*/".
void ConsumeBlockComment(string* content);
void ConsumeBlockComment(std::string* content);
enum NextCommentStatus {
// Started a line comment.
@@ -357,6 +379,14 @@ class LIBPROTOBUF_EXPORT Tokenizer {
// of comment it is.
NextCommentStatus TryConsumeCommentStart();
// If we're looking at a TYPE_WHITESPACE token and `report_whitespace_` is
// true, consume it and return true.
bool TryConsumeWhitespace();
// If we're looking at a TYPE_NEWLINE token and `report_newlines_` is true,
// consume it and return true.
bool TryConsumeNewline();
// -----------------------------------------------------------------
// These helper methods make the parsing code more readable. The
// "character classes" referred to are defined at the top of the .cc file.
@@ -367,45 +397,44 @@ class LIBPROTOBUF_EXPORT Tokenizer {
// Returns true if the current character is of the given character
// class, but does not consume anything.
template<typename CharacterClass>
template <typename CharacterClass>
inline bool LookingAt();
// If the current character is in the given class, consume it and return
// true. Otherwise return false.
// e.g. TryConsumeOne<Letter>()
template<typename CharacterClass>
template <typename CharacterClass>
inline bool TryConsumeOne();
// Like above, but try to consume the specific character indicated.
inline bool TryConsume(char c);
// Consume zero or more of the given character class.
template<typename CharacterClass>
template <typename CharacterClass>
inline void ConsumeZeroOrMore();
// Consume one or more of the given character class or log the given
// error message.
// e.g. ConsumeOneOrMore<Digit>("Expected digits.");
template<typename CharacterClass>
template <typename CharacterClass>
inline void ConsumeOneOrMore(const char* error);
};
// inline methods ====================================================
inline const Tokenizer::Token& Tokenizer::current() {
return current_;
}
inline const Tokenizer::Token& Tokenizer::current() { return current_; }
inline const Tokenizer::Token& Tokenizer::previous() {
return previous_;
}
inline const Tokenizer::Token& Tokenizer::previous() { return previous_; }
inline void Tokenizer::ParseString(const string& text, string* output) {
inline void Tokenizer::ParseString(const std::string& text,
std::string* output) {
output->clear();
ParseStringAppend(text, output);
}
} // namespace io
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_IO_TOKENIZER_H__
+11 -6
View File
@@ -107,11 +107,14 @@
#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace io {
@@ -121,7 +124,7 @@ class ZeroCopyOutputStream;
// Abstract interface similar to an input stream but designed to minimize
// copying.
class LIBPROTOBUF_EXPORT ZeroCopyInputStream {
class PROTOBUF_EXPORT ZeroCopyInputStream {
public:
ZeroCopyInputStream() {}
virtual ~ZeroCopyInputStream() {}
@@ -169,7 +172,7 @@ class LIBPROTOBUF_EXPORT ZeroCopyInputStream {
virtual bool Skip(int count) = 0;
// Returns the total number of bytes read since this object was created.
virtual int64 ByteCount() const = 0;
virtual int64_t ByteCount() const = 0;
private:
@@ -178,7 +181,7 @@ class LIBPROTOBUF_EXPORT ZeroCopyInputStream {
// Abstract interface similar to an output stream but designed to minimize
// copying.
class LIBPROTOBUF_EXPORT ZeroCopyOutputStream {
class PROTOBUF_EXPORT ZeroCopyOutputStream {
public:
ZeroCopyOutputStream() {}
virtual ~ZeroCopyOutputStream() {}
@@ -224,7 +227,7 @@ class LIBPROTOBUF_EXPORT ZeroCopyOutputStream {
virtual void BackUp(int count) = 0;
// Returns the total number of bytes written since this object was created.
virtual int64 ByteCount() const = 0;
virtual int64_t ByteCount() const = 0;
// Write a given chunk of data to the output. Some output streams may
// implement this in a way that avoids copying. Check AllowsAliasing() before
@@ -243,6 +246,8 @@ class LIBPROTOBUF_EXPORT ZeroCopyOutputStream {
} // namespace io
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
@@ -33,19 +33,21 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#ifndef _MSC_VER
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#include <errno.h>
#include <iostream>
#include <algorithm>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <iostream>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/io/io_win32.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/stl_util.h>
#include <google/protobuf/stubs/io_win32.h>
namespace google {
@@ -58,11 +60,11 @@ namespace io {
#define lseek(fd, offset, origin) ((off_t)-1)
// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
// them like we do below.
using google::protobuf::internal::win32::access;
using google::protobuf::internal::win32::close;
using google::protobuf::internal::win32::open;
using google::protobuf::internal::win32::read;
using google::protobuf::internal::win32::write;
using google::protobuf::io::win32::access;
using google::protobuf::io::win32::close;
using google::protobuf::io::win32::open;
using google::protobuf::io::win32::read;
using google::protobuf::io::win32::write;
#endif
namespace {
@@ -78,41 +80,35 @@ int close_no_eintr(int fd) {
} // namespace
// ===================================================================
FileInputStream::FileInputStream(int file_descriptor, int block_size)
: copying_input_(file_descriptor),
impl_(&copying_input_, block_size) {
}
: copying_input_(file_descriptor), impl_(&copying_input_, block_size) {}
bool FileInputStream::Close() {
return copying_input_.Close();
}
bool FileInputStream::Close() { return copying_input_.Close(); }
bool FileInputStream::Next(const void** data, int* size) {
return impl_.Next(data, size);
}
void FileInputStream::BackUp(int count) {
impl_.BackUp(count);
}
void FileInputStream::BackUp(int count) { impl_.BackUp(count); }
bool FileInputStream::Skip(int count) {
return impl_.Skip(count);
}
bool FileInputStream::Skip(int count) { return impl_.Skip(count); }
int64 FileInputStream::ByteCount() const {
return impl_.ByteCount();
}
int64_t FileInputStream::ByteCount() const { return impl_.ByteCount(); }
FileInputStream::CopyingFileInputStream::CopyingFileInputStream(
int file_descriptor)
: file_(file_descriptor),
close_on_delete_(false),
is_closed_(false),
errno_(0),
previous_seek_failed_(false) {
: file_(file_descriptor),
close_on_delete_(false),
is_closed_(false),
errno_(0),
previous_seek_failed_(false) {
#ifndef _WIN32
int flags = fcntl(file_, F_GETFL);
flags &= ~O_NONBLOCK;
fcntl(file_, F_SETFL, flags);
#endif
}
FileInputStream::CopyingFileInputStream::~CopyingFileInputStream() {
@@ -157,8 +153,7 @@ int FileInputStream::CopyingFileInputStream::Read(void* buffer, int size) {
int FileInputStream::CopyingFileInputStream::Skip(int count) {
GOOGLE_CHECK(!is_closed_);
if (!previous_seek_failed_ &&
lseek(file_, count, SEEK_CUR) != (off_t)-1) {
if (!previous_seek_failed_ && lseek(file_, count, SEEK_CUR) != (off_t)-1) {
// Seek succeeded.
return count;
} else {
@@ -175,43 +170,23 @@ int FileInputStream::CopyingFileInputStream::Skip(int count) {
// ===================================================================
FileOutputStream::FileOutputStream(int file_descriptor, int block_size)
: copying_output_(file_descriptor),
impl_(&copying_output_, block_size) {
}
FileOutputStream::~FileOutputStream() {
impl_.Flush();
}
FileOutputStream::FileOutputStream(int file_descriptor, int /*block_size*/)
: CopyingOutputStreamAdaptor(&copying_output_),
copying_output_(file_descriptor) {}
bool FileOutputStream::Close() {
bool flush_succeeded = impl_.Flush();
bool flush_succeeded = Flush();
return copying_output_.Close() && flush_succeeded;
}
bool FileOutputStream::Flush() {
return impl_.Flush();
}
bool FileOutputStream::Next(void** data, int* size) {
return impl_.Next(data, size);
}
void FileOutputStream::BackUp(int count) {
impl_.BackUp(count);
}
int64 FileOutputStream::ByteCount() const {
return impl_.ByteCount();
}
FileOutputStream::CopyingFileOutputStream::CopyingFileOutputStream(
int file_descriptor)
: file_(file_descriptor),
close_on_delete_(false),
is_closed_(false),
errno_(0) {
}
: file_(file_descriptor),
close_on_delete_(false),
is_closed_(false),
errno_(0) {}
FileOutputStream::~FileOutputStream() { Flush(); }
FileOutputStream::CopyingFileOutputStream::~CopyingFileOutputStream() {
if (close_on_delete_) {
@@ -236,12 +211,12 @@ bool FileOutputStream::CopyingFileOutputStream::Close() {
return true;
}
bool FileOutputStream::CopyingFileOutputStream::Write(
const void* buffer, int size) {
bool FileOutputStream::CopyingFileOutputStream::Write(const void* buffer,
int size) {
GOOGLE_CHECK(!is_closed_);
int total_written = 0;
const uint8* buffer_base = reinterpret_cast<const uint8*>(buffer);
const uint8_t* buffer_base = reinterpret_cast<const uint8_t*>(buffer);
while (total_written < size) {
int bytes;
@@ -280,17 +255,11 @@ bool IstreamInputStream::Next(const void** data, int* size) {
return impl_.Next(data, size);
}
void IstreamInputStream::BackUp(int count) {
impl_.BackUp(count);
}
void IstreamInputStream::BackUp(int count) { impl_.BackUp(count); }
bool IstreamInputStream::Skip(int count) {
return impl_.Skip(count);
}
bool IstreamInputStream::Skip(int count) { return impl_.Skip(count); }
int64 IstreamInputStream::ByteCount() const {
return impl_.ByteCount();
}
int64_t IstreamInputStream::ByteCount() const { return impl_.ByteCount(); }
IstreamInputStream::CopyingIstreamInputStream::CopyingIstreamInputStream(
std::istream* input)
@@ -298,8 +267,8 @@ IstreamInputStream::CopyingIstreamInputStream::CopyingIstreamInputStream(
IstreamInputStream::CopyingIstreamInputStream::~CopyingIstreamInputStream() {}
int IstreamInputStream::CopyingIstreamInputStream::Read(
void* buffer, int size) {
int IstreamInputStream::CopyingIstreamInputStream::Read(void* buffer,
int size) {
input_->read(reinterpret_cast<char*>(buffer), size);
int result = input_->gcount();
if (result == 0 && input_->fail() && !input_->eof()) {
@@ -313,21 +282,15 @@ int IstreamInputStream::CopyingIstreamInputStream::Read(
OstreamOutputStream::OstreamOutputStream(std::ostream* output, int block_size)
: copying_output_(output), impl_(&copying_output_, block_size) {}
OstreamOutputStream::~OstreamOutputStream() {
impl_.Flush();
}
OstreamOutputStream::~OstreamOutputStream() { impl_.Flush(); }
bool OstreamOutputStream::Next(void** data, int* size) {
return impl_.Next(data, size);
}
void OstreamOutputStream::BackUp(int count) {
impl_.BackUp(count);
}
void OstreamOutputStream::BackUp(int count) { impl_.BackUp(count); }
int64 OstreamOutputStream::ByteCount() const {
return impl_.ByteCount();
}
int64_t OstreamOutputStream::ByteCount() const { return impl_.ByteCount(); }
OstreamOutputStream::CopyingOstreamOutputStream::CopyingOstreamOutputStream(
std::ostream* output)
@@ -336,8 +299,8 @@ OstreamOutputStream::CopyingOstreamOutputStream::CopyingOstreamOutputStream(
OstreamOutputStream::CopyingOstreamOutputStream::~CopyingOstreamOutputStream() {
}
bool OstreamOutputStream::CopyingOstreamOutputStream::Write(
const void* buffer, int size) {
bool OstreamOutputStream::CopyingOstreamOutputStream::Write(const void* buffer,
int size) {
output_->write(reinterpret_cast<const char*>(buffer), size);
return output_->good();
}
@@ -346,7 +309,7 @@ bool OstreamOutputStream::CopyingOstreamOutputStream::Write(
ConcatenatingInputStream::ConcatenatingInputStream(
ZeroCopyInputStream* const streams[], int count)
: streams_(streams), stream_count_(count), bytes_retired_(0) {
: streams_(streams), stream_count_(count), bytes_retired_(0) {
}
bool ConcatenatingInputStream::Next(const void** data, int* size) {
@@ -375,12 +338,12 @@ bool ConcatenatingInputStream::Skip(int count) {
while (stream_count_ > 0) {
// Assume that ByteCount() can be used to find out how much we actually
// skipped when Skip() fails.
int64 target_byte_count = streams_[0]->ByteCount() + count;
int64_t target_byte_count = streams_[0]->ByteCount() + count;
if (streams_[0]->Skip(count)) return true;
// Hit the end of the stream. Figure out how many more bytes we still have
// to skip.
int64 final_byte_count = streams_[0]->ByteCount();
int64_t final_byte_count = streams_[0]->ByteCount();
GOOGLE_DCHECK_LT(final_byte_count, target_byte_count);
count = target_byte_count - final_byte_count;
@@ -393,7 +356,7 @@ bool ConcatenatingInputStream::Skip(int count) {
return false;
}
int64 ConcatenatingInputStream::ByteCount() const {
int64_t ConcatenatingInputStream::ByteCount() const {
if (stream_count_ == 0) {
return bytes_retired_;
} else {
@@ -402,63 +365,6 @@ int64 ConcatenatingInputStream::ByteCount() const {
}
// ===================================================================
LimitingInputStream::LimitingInputStream(ZeroCopyInputStream* input,
int64 limit)
: input_(input), limit_(limit) {
prior_bytes_read_ = input_->ByteCount();
}
LimitingInputStream::~LimitingInputStream() {
// If we overshot the limit, back up.
if (limit_ < 0) input_->BackUp(-limit_);
}
bool LimitingInputStream::Next(const void** data, int* size) {
if (limit_ <= 0) return false;
if (!input_->Next(data, size)) return false;
limit_ -= *size;
if (limit_ < 0) {
// We overshot the limit. Reduce *size to hide the rest of the buffer.
*size += limit_;
}
return true;
}
void LimitingInputStream::BackUp(int count) {
if (limit_ < 0) {
input_->BackUp(count - limit_);
limit_ = count;
} else {
input_->BackUp(count);
limit_ += count;
}
}
bool LimitingInputStream::Skip(int count) {
if (count > limit_) {
if (limit_ < 0) return false;
input_->Skip(limit_);
limit_ = 0;
return false;
} else {
if (!input_->Skip(count)) return false;
limit_ -= count;
return true;
}
}
int64 LimitingInputStream::ByteCount() const {
if (limit_ < 0) {
return input_->ByteCount() + limit_ - prior_bytes_read_;
} else {
return input_->ByteCount() - prior_bytes_read_;
}
}
// ===================================================================
} // namespace io
@@ -40,18 +40,20 @@
#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
#include <string>
#include <iosfwd>
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace io {
// ===================================================================
// A ZeroCopyInputStream which reads from a file descriptor.
@@ -60,7 +62,7 @@ namespace io {
// The latter will introduce an extra layer of buffering, harming performance.
// Also, it's conceivable that FileInputStream could someday be enhanced
// to use zero-copy file descriptors on OSs which support them.
class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream {
class PROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream {
public:
// Creates a stream that reads from the given Unix file descriptor.
// If a block_size is given, it specifies the number of bytes that
@@ -84,27 +86,27 @@ class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream {
// errno from that error. Otherwise, this is zero. Once an error
// occurs, the stream is broken and all subsequent operations will
// fail.
int GetErrno() { return copying_input_.GetErrno(); }
int GetErrno() const { return copying_input_.GetErrno(); }
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
bool Next(const void** data, int* size) override;
void BackUp(int count) override;
bool Skip(int count) override;
int64_t ByteCount() const override;
private:
class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream {
class PROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream {
public:
CopyingFileInputStream(int file_descriptor);
~CopyingFileInputStream();
~CopyingFileInputStream() override;
bool Close();
void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
int GetErrno() { return errno_; }
int GetErrno() const { return errno_; }
// implements CopyingInputStream ---------------------------------
int Read(void* buffer, int size);
int Skip(int count);
int Read(void* buffer, int size) override;
int Skip(int count) override;
private:
// The file descriptor.
@@ -137,25 +139,21 @@ class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream {
// harming performance. Also, it's conceivable that FileOutputStream could
// someday be enhanced to use zero-copy file descriptors on OSs which
// support them.
class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream {
class PROTOBUF_EXPORT FileOutputStream : public CopyingOutputStreamAdaptor {
public:
// Creates a stream that writes to the given Unix file descriptor.
// If a block_size is given, it specifies the size of the buffers
// that should be returned by Next(). Otherwise, a reasonable default
// is used.
explicit FileOutputStream(int file_descriptor, int block_size = -1);
~FileOutputStream();
~FileOutputStream() override;
// Flushes any buffers and closes the underlying file. Returns false if
// an error occurs during the process; use GetErrno() to examine the error.
// Even if an error occurs, the file descriptor is closed when this returns.
bool Close();
// Flushes FileOutputStream's buffers but does not close the
// underlying file. No special measures are taken to ensure that
// underlying operating system file object is synchronized to disk.
bool Flush();
// By default, the file descriptor is not closed when the stream is
// destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
// This leaves no way for the caller to detect if close() fails. If
@@ -167,25 +165,20 @@ class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream {
// errno from that error. Otherwise, this is zero. Once an error
// occurs, the stream is broken and all subsequent operations will
// fail.
int GetErrno() { return copying_output_.GetErrno(); }
// implements ZeroCopyOutputStream ---------------------------------
bool Next(void** data, int* size);
void BackUp(int count);
int64 ByteCount() const;
int GetErrno() const { return copying_output_.GetErrno(); }
private:
class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream {
class PROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream {
public:
CopyingFileOutputStream(int file_descriptor);
~CopyingFileOutputStream();
~CopyingFileOutputStream() override;
bool Close();
void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
int GetErrno() { return errno_; }
int GetErrno() const { return errno_; }
// implements CopyingOutputStream --------------------------------
bool Write(const void* buffer, int size);
bool Write(const void* buffer, int size) override;
private:
// The file descriptor.
@@ -200,7 +193,6 @@ class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream {
};
CopyingFileOutputStream copying_output_;
CopyingOutputStreamAdaptor impl_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream);
};
@@ -211,7 +203,7 @@ class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream {
//
// Note that for reading files (or anything represented by a file descriptor),
// FileInputStream is more efficient.
class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream {
class PROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream {
public:
// Creates a stream that reads from the given C++ istream.
// If a block_size is given, it specifies the number of bytes that
@@ -220,19 +212,19 @@ class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream {
explicit IstreamInputStream(std::istream* stream, int block_size = -1);
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
bool Next(const void** data, int* size) override;
void BackUp(int count) override;
bool Skip(int count) override;
int64_t ByteCount() const override;
private:
class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream {
class PROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream {
public:
CopyingIstreamInputStream(std::istream* input);
~CopyingIstreamInputStream();
~CopyingIstreamInputStream() override;
// implements CopyingInputStream ---------------------------------
int Read(void* buffer, int size);
int Read(void* buffer, int size) override;
// (We use the default implementation of Skip().)
private:
@@ -254,28 +246,29 @@ class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream {
//
// Note that for writing files (or anything represented by a file descriptor),
// FileOutputStream is more efficient.
class LIBPROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream {
class PROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream {
public:
// Creates a stream that writes to the given C++ ostream.
// If a block_size is given, it specifies the size of the buffers
// that should be returned by Next(). Otherwise, a reasonable default
// is used.
explicit OstreamOutputStream(std::ostream* stream, int block_size = -1);
~OstreamOutputStream();
~OstreamOutputStream() override;
// implements ZeroCopyOutputStream ---------------------------------
bool Next(void** data, int* size);
void BackUp(int count);
int64 ByteCount() const;
bool Next(void** data, int* size) override;
void BackUp(int count) override;
int64_t ByteCount() const override;
private:
class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream {
class PROTOBUF_EXPORT CopyingOstreamOutputStream
: public CopyingOutputStream {
public:
CopyingOstreamOutputStream(std::ostream* output);
~CopyingOstreamOutputStream();
~CopyingOstreamOutputStream() override;
// implements CopyingOutputStream --------------------------------
bool Write(const void* buffer, int size);
bool Write(const void* buffer, int size) override;
private:
// The stream.
@@ -299,17 +292,18 @@ class LIBPROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream {
// ConcatenatingInputStream may do odd things. It is suggested that you do
// not use ConcatenatingInputStream on streams that might produce read errors
// other than end-of-stream.
class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream {
class PROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream {
public:
// All streams passed in as well as the array itself must remain valid
// until the ConcatenatingInputStream is destroyed.
ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count);
~ConcatenatingInputStream() override = default;
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
bool Next(const void** data, int* size) override;
void BackUp(int count) override;
bool Skip(int count) override;
int64_t ByteCount() const override;
private:
@@ -317,39 +311,17 @@ class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream {
// decremented.
ZeroCopyInputStream* const* streams_;
int stream_count_;
int64 bytes_retired_; // Bytes read from previous streams.
int64_t bytes_retired_; // Bytes read from previous streams.
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream);
};
// ===================================================================
// A ZeroCopyInputStream which wraps some other stream and limits it to
// a particular byte count.
class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream {
public:
LimitingInputStream(ZeroCopyInputStream* input, int64 limit);
~LimitingInputStream();
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
private:
ZeroCopyInputStream* input_;
int64 limit_; // Decreases as we go, becomes negative if we overshoot.
int64 prior_bytes_read_; // Bytes read on underlying stream at construction
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream);
};
// ===================================================================
} // namespace io
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
@@ -37,9 +37,9 @@
#include <algorithm>
#include <limits>
#include <google/protobuf/stubs/casts.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/casts.h>
#include <google/protobuf/stubs/stl_util.h>
namespace google {
@@ -55,14 +55,12 @@ static const int kDefaultBlockSize = 8192;
// ===================================================================
ArrayInputStream::ArrayInputStream(const void* data, int size,
int block_size)
: data_(reinterpret_cast<const uint8*>(data)),
size_(size),
block_size_(block_size > 0 ? block_size : size),
position_(0),
last_returned_size_(0) {
}
ArrayInputStream::ArrayInputStream(const void* data, int size, int block_size)
: data_(reinterpret_cast<const uint8_t*>(data)),
size_(size),
block_size_(block_size > 0 ? block_size : size),
position_(0),
last_returned_size_(0) {}
bool ArrayInputStream::Next(const void** data, int* size) {
if (position_ < size_) {
@@ -73,7 +71,7 @@ bool ArrayInputStream::Next(const void** data, int* size) {
return true;
} else {
// We're at the end of the array.
last_returned_size_ = 0; // Don't let caller back up.
last_returned_size_ = 0; // Don't let caller back up.
return false;
}
}
@@ -89,7 +87,7 @@ void ArrayInputStream::BackUp(int count) {
bool ArrayInputStream::Skip(int count) {
GOOGLE_CHECK_GE(count, 0);
last_returned_size_ = 0; // Don't let caller back up.
last_returned_size_ = 0; // Don't let caller back up.
if (count > size_ - position_) {
position_ = size_;
return false;
@@ -99,20 +97,17 @@ bool ArrayInputStream::Skip(int count) {
}
}
int64 ArrayInputStream::ByteCount() const {
return position_;
}
int64_t ArrayInputStream::ByteCount() const { return position_; }
// ===================================================================
ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size)
: data_(reinterpret_cast<uint8*>(data)),
size_(size),
block_size_(block_size > 0 ? block_size : size),
position_(0),
last_returned_size_(0) {
}
: data_(reinterpret_cast<uint8_t*>(data)),
size_(size),
block_size_(block_size > 0 ? block_size : size),
position_(0),
last_returned_size_(0) {}
bool ArrayOutputStream::Next(void** data, int* size) {
if (position_ < size_) {
@@ -123,7 +118,7 @@ bool ArrayOutputStream::Next(void** data, int* size) {
return true;
} else {
// We're at the end of the array.
last_returned_size_ = 0; // Don't let caller back up.
last_returned_size_ = 0; // Don't let caller back up.
return false;
}
}
@@ -137,41 +132,33 @@ void ArrayOutputStream::BackUp(int count) {
last_returned_size_ = 0; // Don't let caller back up further.
}
int64 ArrayOutputStream::ByteCount() const {
return position_;
}
int64_t ArrayOutputStream::ByteCount() const { return position_; }
// ===================================================================
StringOutputStream::StringOutputStream(string* target)
: target_(target) {
}
StringOutputStream::StringOutputStream(std::string* target) : target_(target) {}
bool StringOutputStream::Next(void** data, int* size) {
GOOGLE_CHECK(target_ != NULL);
int old_size = target_->size();
size_t old_size = target_->size();
// Grow the string.
size_t new_size;
if (old_size < target_->capacity()) {
// Resize the string to match its capacity, since we can get away
// without a memory allocation this way.
STLStringResizeUninitialized(target_, target_->capacity());
new_size = target_->capacity();
} else {
// Size has reached capacity, try to double the size.
if (old_size > std::numeric_limits<int>::max() / 2) {
// Can not double the size otherwise it is going to cause integer
// overflow in the expression below: old_size * 2 ";
GOOGLE_LOG(ERROR) << "Cannot allocate buffer larger than kint32max for "
<< "StringOutputStream.";
return false;
}
// Double the size, also make sure that the new size is at least
// kMinimumSize.
STLStringResizeUninitialized(
target_,
std::max(old_size * 2,
kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness.
// Size has reached capacity, try to double it.
new_size = old_size * 2;
}
// Avoid integer overflow in returned '*size'.
new_size = std::min(new_size, old_size + std::numeric_limits<int>::max());
// Increase the size, also make sure that it is at least kMinimumSize.
STLStringResizeUninitialized(
target_,
std::max(new_size,
kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness.
*data = mutable_string_data(target_) + old_size;
*size = target_->size() - old_size;
@@ -181,27 +168,23 @@ bool StringOutputStream::Next(void** data, int* size) {
void StringOutputStream::BackUp(int count) {
GOOGLE_CHECK_GE(count, 0);
GOOGLE_CHECK(target_ != NULL);
GOOGLE_CHECK_LE(count, target_->size());
GOOGLE_CHECK_LE(static_cast<size_t>(count), target_->size());
target_->resize(target_->size() - count);
}
int64 StringOutputStream::ByteCount() const {
int64_t StringOutputStream::ByteCount() const {
GOOGLE_CHECK(target_ != NULL);
return target_->size();
}
void StringOutputStream::SetString(string* target) {
target_ = target;
}
// ===================================================================
int CopyingInputStream::Skip(int count) {
char junk[4096];
int skipped = 0;
while (skipped < count) {
int bytes =
Read(junk, std::min(count - skipped, implicit_cast<int>(sizeof(junk))));
int bytes = Read(junk, std::min(count - skipped,
implicit_cast<int>(sizeof(junk))));
if (bytes <= 0) {
// EOF or read error.
return skipped;
@@ -213,14 +196,13 @@ int CopyingInputStream::Skip(int count) {
CopyingInputStreamAdaptor::CopyingInputStreamAdaptor(
CopyingInputStream* copying_stream, int block_size)
: copying_stream_(copying_stream),
owns_copying_stream_(false),
failed_(false),
position_(0),
buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
buffer_used_(0),
backup_bytes_(0) {
}
: copying_stream_(copying_stream),
owns_copying_stream_(false),
failed_(false),
position_(0),
buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
buffer_used_(0),
backup_bytes_(0) {}
CopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() {
if (owns_copying_stream_) {
@@ -264,12 +246,11 @@ bool CopyingInputStreamAdaptor::Next(const void** data, int* size) {
void CopyingInputStreamAdaptor::BackUp(int count) {
GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL)
<< " BackUp() can only be called after Next().";
<< " BackUp() can only be called after Next().";
GOOGLE_CHECK_LE(count, buffer_used_)
<< " Can't back up over more bytes than were returned by the last call"
" to Next().";
GOOGLE_CHECK_GE(count, 0)
<< " Parameter to BackUp() can't be negative.";
<< " Can't back up over more bytes than were returned by the last call"
" to Next().";
GOOGLE_CHECK_GE(count, 0) << " Parameter to BackUp() can't be negative.";
backup_bytes_ = count;
}
@@ -297,13 +278,13 @@ bool CopyingInputStreamAdaptor::Skip(int count) {
return skipped == count;
}
int64 CopyingInputStreamAdaptor::ByteCount() const {
int64_t CopyingInputStreamAdaptor::ByteCount() const {
return position_ - backup_bytes_;
}
void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() {
if (buffer_.get() == NULL) {
buffer_.reset(new uint8[buffer_size_]);
buffer_.reset(new uint8_t[buffer_size_]);
}
}
@@ -317,13 +298,12 @@ void CopyingInputStreamAdaptor::FreeBuffer() {
CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor(
CopyingOutputStream* copying_stream, int block_size)
: copying_stream_(copying_stream),
owns_copying_stream_(false),
failed_(false),
position_(0),
buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
buffer_used_(0) {
}
: copying_stream_(copying_stream),
owns_copying_stream_(false),
failed_(false),
position_(0),
buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
buffer_used_(0) {}
CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() {
WriteBuffer();
@@ -332,9 +312,7 @@ CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() {
}
}
bool CopyingOutputStreamAdaptor::Flush() {
return WriteBuffer();
}
bool CopyingOutputStreamAdaptor::Flush() { return WriteBuffer(); }
bool CopyingOutputStreamAdaptor::Next(void** data, int* size) {
if (buffer_used_ == buffer_size_) {
@@ -352,18 +330,49 @@ bool CopyingOutputStreamAdaptor::Next(void** data, int* size) {
void CopyingOutputStreamAdaptor::BackUp(int count) {
GOOGLE_CHECK_GE(count, 0);
GOOGLE_CHECK_EQ(buffer_used_, buffer_size_)
<< " BackUp() can only be called after Next().";
<< " BackUp() can only be called after Next().";
GOOGLE_CHECK_LE(count, buffer_used_)
<< " Can't back up over more bytes than were returned by the last call"
" to Next().";
<< " Can't back up over more bytes than were returned by the last call"
" to Next().";
buffer_used_ -= count;
}
int64 CopyingOutputStreamAdaptor::ByteCount() const {
int64_t CopyingOutputStreamAdaptor::ByteCount() const {
return position_ + buffer_used_;
}
bool CopyingOutputStreamAdaptor::WriteAliasedRaw(const void* data, int size) {
if (size >= buffer_size_) {
if (!Flush() || !copying_stream_->Write(data, size)) {
return false;
}
GOOGLE_DCHECK_EQ(buffer_used_, 0);
position_ += size;
return true;
}
void* out;
int out_size;
while (true) {
if (!Next(&out, &out_size)) {
return false;
}
if (size <= out_size) {
std::memcpy(out, data, size);
BackUp(out_size - size);
return true;
}
std::memcpy(out, data, out_size);
data = static_cast<const char*>(data) + out_size;
size -= out_size;
}
return true;
}
bool CopyingOutputStreamAdaptor::WriteBuffer() {
if (failed_) {
// Already failed on a previous write.
@@ -385,7 +394,7 @@ bool CopyingOutputStreamAdaptor::WriteBuffer() {
void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() {
if (buffer_ == NULL) {
buffer_.reset(new uint8[buffer_size_]);
buffer_.reset(new uint8_t[buffer_size_]);
}
}
@@ -394,6 +403,63 @@ void CopyingOutputStreamAdaptor::FreeBuffer() {
buffer_.reset();
}
// ===================================================================
LimitingInputStream::LimitingInputStream(ZeroCopyInputStream* input,
int64_t limit)
: input_(input), limit_(limit) {
prior_bytes_read_ = input_->ByteCount();
}
LimitingInputStream::~LimitingInputStream() {
// If we overshot the limit, back up.
if (limit_ < 0) input_->BackUp(-limit_);
}
bool LimitingInputStream::Next(const void** data, int* size) {
if (limit_ <= 0) return false;
if (!input_->Next(data, size)) return false;
limit_ -= *size;
if (limit_ < 0) {
// We overshot the limit. Reduce *size to hide the rest of the buffer.
*size += limit_;
}
return true;
}
void LimitingInputStream::BackUp(int count) {
if (limit_ < 0) {
input_->BackUp(count - limit_);
limit_ = count;
} else {
input_->BackUp(count);
limit_ += count;
}
}
bool LimitingInputStream::Skip(int count) {
if (count > limit_) {
if (limit_ < 0) return false;
input_->Skip(limit_);
limit_ = 0;
return false;
} else {
if (!input_->Skip(count)) return false;
limit_ -= count;
return true;
}
}
int64_t LimitingInputStream::ByteCount() const {
if (limit_ < 0) {
return input_->ByteCount() + limit_ - prior_bytes_read_;
} else {
return input_->ByteCount() - prior_bytes_read_;
}
}
// ===================================================================
} // namespace io
@@ -44,18 +44,19 @@
#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
#include <memory>
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
#endif
#include <string>
#include <iosfwd>
#include <google/protobuf/io/zero_copy_stream.h>
#include <memory>
#include <string>
#include <google/protobuf/stubs/callback.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/stl_util.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace io {
@@ -63,7 +64,7 @@ namespace io {
// ===================================================================
// A ZeroCopyInputStream backed by an in-memory array of bytes.
class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream {
class PROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream {
public:
// Create an InputStream that returns the bytes pointed to by "data".
// "data" remains the property of the caller but must remain valid until
@@ -73,22 +74,23 @@ class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream {
// useful for testing; in production you would probably never want to set
// it.
ArrayInputStream(const void* data, int size, int block_size = -1);
~ArrayInputStream() override = default;
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
bool Next(const void** data, int* size) override;
void BackUp(int count) override;
bool Skip(int count) override;
int64_t ByteCount() const override;
private:
const uint8* const data_; // The byte array.
const uint8_t* const data_; // The byte array.
const int size_; // Total size of the array.
const int block_size_; // How many bytes to return at a time.
int position_;
int last_returned_size_; // How many bytes we returned last time Next()
// was called (used for error checking only).
int last_returned_size_; // How many bytes we returned last time Next()
// was called (used for error checking only).
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream);
};
@@ -96,7 +98,7 @@ class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream {
// ===================================================================
// A ZeroCopyOutputStream backed by an in-memory array of bytes.
class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream {
class PROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream {
public:
// Create an OutputStream that writes to the bytes pointed to by "data".
// "data" remains the property of the caller but must remain valid until
@@ -106,20 +108,21 @@ class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream {
// useful for testing; in production you would probably never want to set
// it.
ArrayOutputStream(void* data, int size, int block_size = -1);
~ArrayOutputStream() override = default;
// implements ZeroCopyOutputStream ---------------------------------
bool Next(void** data, int* size);
void BackUp(int count);
int64 ByteCount() const;
bool Next(void** data, int* size) override;
void BackUp(int count) override;
int64_t ByteCount() const override;
private:
uint8* const data_; // The byte array.
const int size_; // Total size of the array.
const int block_size_; // How many bytes to return at a time.
uint8_t* const data_; // The byte array.
const int size_; // Total size of the array.
const int block_size_; // How many bytes to return at a time.
int position_;
int last_returned_size_; // How many bytes we returned last time Next()
// was called (used for error checking only).
int last_returned_size_; // How many bytes we returned last time Next()
// was called (used for error checking only).
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream);
};
@@ -127,7 +130,7 @@ class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream {
// ===================================================================
// A ZeroCopyOutputStream which appends bytes to a string.
class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream {
class PROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream {
public:
// Create a StringOutputStream which appends bytes to the given string.
// The string remains property of the caller, but it is mutated in arbitrary
@@ -138,20 +141,18 @@ class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream {
// Hint: If you call target->reserve(n) before creating the stream,
// the first call to Next() will return at least n bytes of buffer
// space.
explicit StringOutputStream(string* target);
explicit StringOutputStream(std::string* target);
~StringOutputStream() override = default;
// implements ZeroCopyOutputStream ---------------------------------
bool Next(void** data, int* size);
void BackUp(int count);
int64 ByteCount() const;
protected:
void SetString(string* target);
bool Next(void** data, int* size) override;
void BackUp(int count) override;
int64_t ByteCount() const override;
private:
static const int kMinimumSize = 16;
static constexpr size_t kMinimumSize = 16;
string* target_;
std::string* target_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream);
};
@@ -173,7 +174,7 @@ class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream {
// CopyingInputStream implementations should avoid buffering if possible.
// CopyingInputStreamAdaptor does its own buffering and will read data
// in large blocks.
class LIBPROTOBUF_EXPORT CopyingInputStream {
class PROTOBUF_EXPORT CopyingInputStream {
public:
virtual ~CopyingInputStream() {}
@@ -199,7 +200,7 @@ class LIBPROTOBUF_EXPORT CopyingInputStream {
// If you want to read from file descriptors or C++ istreams, this is
// already implemented for you: use FileInputStream or IstreamInputStream
// respectively.
class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream {
class PROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream {
public:
// Creates a stream that reads from the given CopyingInputStream.
// If a block_size is given, it specifies the number of bytes that
@@ -208,17 +209,17 @@ class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream
// copying_stream unless SetOwnsCopyingStream(true) is called.
explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream,
int block_size = -1);
~CopyingInputStreamAdaptor();
~CopyingInputStreamAdaptor() override;
// Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to
// delete the underlying CopyingInputStream when it is destroyed.
void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; }
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
bool Next(const void** data, int* size) override;
void BackUp(int count) override;
bool Skip(int count) override;
int64_t ByteCount() const override;
private:
// Insures that buffer_ is not NULL.
@@ -230,16 +231,16 @@ class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream
CopyingInputStream* copying_stream_;
bool owns_copying_stream_;
// True if we have seen a permenant error from the underlying stream.
// True if we have seen a permanent error from the underlying stream.
bool failed_;
// The current position of copying_stream_, relative to the point where
// we started reading.
int64 position_;
int64_t position_;
// Data is read into this buffer. It may be NULL if no buffer is currently
// in use. Otherwise, it points to an array of size buffer_size_.
google::protobuf::scoped_array<uint8> buffer_;
std::unique_ptr<uint8_t[]> buffer_;
const int buffer_size_;
// Number of valid bytes currently in the buffer (i.e. the size last
@@ -267,7 +268,7 @@ class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream
// CopyingOutputStream implementations should avoid buffering if possible.
// CopyingOutputStreamAdaptor does its own buffering and will write data
// in large blocks.
class LIBPROTOBUF_EXPORT CopyingOutputStream {
class PROTOBUF_EXPORT CopyingOutputStream {
public:
virtual ~CopyingOutputStream() {}
@@ -283,7 +284,7 @@ class LIBPROTOBUF_EXPORT CopyingOutputStream {
// If you want to write to file descriptors or C++ ostreams, this is
// already implemented for you: use FileOutputStream or OstreamOutputStream
// respectively.
class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream {
class PROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream {
public:
// Creates a stream that writes to the given Unix file descriptor.
// If a block_size is given, it specifies the size of the buffers
@@ -291,7 +292,7 @@ class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStrea
// is used.
explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream,
int block_size = -1);
~CopyingOutputStreamAdaptor();
~CopyingOutputStreamAdaptor() override;
// Writes all pending data to the underlying stream. Returns false if a
// write error occurred on the underlying stream. (The underlying
@@ -303,9 +304,11 @@ class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStrea
void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; }
// implements ZeroCopyOutputStream ---------------------------------
bool Next(void** data, int* size);
void BackUp(int count);
int64 ByteCount() const;
bool Next(void** data, int* size) override;
void BackUp(int count) override;
int64_t ByteCount() const override;
bool WriteAliasedRaw(const void* data, int size) override;
bool AllowsAliasing() const override { return true; }
private:
// Write the current buffer, if it is present.
@@ -319,16 +322,16 @@ class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStrea
CopyingOutputStream* copying_stream_;
bool owns_copying_stream_;
// True if we have seen a permenant error from the underlying stream.
// True if we have seen a permanent error from the underlying stream.
bool failed_;
// The current position of copying_stream_, relative to the point where
// we started writing.
int64 position_;
int64_t position_;
// Data is written from this buffer. It may be NULL if no buffer is
// currently in use. Otherwise, it points to an array of size buffer_size_.
google::protobuf::scoped_array<uint8> buffer_;
std::unique_ptr<uint8_t[]> buffer_;
const int buffer_size_;
// Number of valid bytes currently in the buffer (i.e. the size last
@@ -339,6 +342,31 @@ class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStrea
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOutputStreamAdaptor);
};
// ===================================================================
// A ZeroCopyInputStream which wraps some other stream and limits it to
// a particular byte count.
class PROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream {
public:
LimitingInputStream(ZeroCopyInputStream* input, int64_t limit);
~LimitingInputStream() override;
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size) override;
void BackUp(int count) override;
bool Skip(int count) override;
int64_t ByteCount() const override;
private:
ZeroCopyInputStream* input_;
int64_t limit_; // Decreases as we go, becomes negative if we overshoot.
int64_t prior_bytes_read_; // Bytes read on underlying stream at construction
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream);
};
// ===================================================================
// mutable_string_data() and as_string_data() are workarounds to improve
@@ -356,31 +384,25 @@ class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStrea
// Return a pointer to mutable characters underlying the given string. The
// return value is valid until the next time the string is resized. We
// trust the caller to treat the return value as an array of length s->size().
inline char* mutable_string_data(string* s) {
#ifdef LANG_CXX11
inline char* mutable_string_data(std::string* s) {
// This should be simpler & faster than string_as_array() because the latter
// is guaranteed to return NULL when *s is empty, so it has to check for that.
return &(*s)[0];
#else
return string_as_array(s);
#endif
}
// as_string_data(s) is equivalent to
// ({ char* p = mutable_string_data(s); make_pair(p, p != NULL); })
// Sometimes it's faster: in some scenarios p cannot be NULL, and then the
// code can avoid that check.
inline std::pair<char*, bool> as_string_data(string* s) {
char *p = mutable_string_data(s);
#ifdef LANG_CXX11
inline std::pair<char*, bool> as_string_data(std::string* s) {
char* p = mutable_string_data(s);
return std::make_pair(p, true);
#else
return std::make_pair(p, p != NULL);
#endif
}
} // namespace io
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
@@ -28,15 +28,14 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/util/internal/error_listener.h>
#include <google/protobuf/map.h>
namespace google {
namespace protobuf {
namespace util {
namespace converter {
namespace internal {
void* const kGlobalEmptyTable[kGlobalEmptyTableSize] = {nullptr};
} // namespace converter
} // namespace util
} // namespace internal
} // namespace protobuf
} // namespace google
File diff suppressed because it is too large Load Diff
+53 -33
View File
@@ -34,10 +34,16 @@
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/map_entry_lite.h>
#include <google/protobuf/map_type_handler.h>
#include <google/protobuf/metadata.h>
#include <google/protobuf/port.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/unknown_field_set.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/port_def.inc>
#ifdef SWIG
#error "You cannot SWIG proto headers"
#endif
namespace google {
namespace protobuf {
@@ -45,11 +51,13 @@ class Arena;
namespace internal {
template <typename Derived, typename Key, typename Value,
WireFormatLite::FieldType kKeyFieldType,
WireFormatLite::FieldType kValueFieldType, int default_enum_value>
WireFormatLite::FieldType kValueFieldType>
class MapField;
}
}
} // namespace protobuf
} // namespace google
namespace google {
namespace protobuf {
namespace internal {
@@ -70,40 +78,52 @@ namespace internal {
// field.
//
// cpp type | proto type | in-memory type | MapEntry accessor type
// int32 TYPE_INT32 int32 int32
// int32 TYPE_FIXED32 int32 int32
// int32_t TYPE_INT32 int32_t int32_t
// int32_t TYPE_FIXED32 int32_t int32_t
// string TYPE_STRING ArenaStringPtr string
// FooEnum TYPE_ENUM int int
// FooMessage TYPE_MESSAGE FooMessage* FooMessage
//
// The in-memory types of primitive types can be inferred from its proto type,
// while we need to explicitly specify the cpp type if proto type is
// TYPE_MESSAGE to infer the in-memory type. Moreover, default_enum_value is
// used to initialize enum field in proto2.
// TYPE_MESSAGE to infer the in-memory type.
template <typename Derived, typename Key, typename Value,
WireFormatLite::FieldType kKeyFieldType,
WireFormatLite::FieldType kValueFieldType, int default_enum_value>
class MapEntry
: public MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
kValueFieldType, default_enum_value> {
WireFormatLite::FieldType kValueFieldType>
class MapEntry : public MapEntryImpl<Derived, Message, Key, Value,
kKeyFieldType, kValueFieldType> {
public:
MapEntry() : _internal_metadata_(NULL) {}
constexpr MapEntry() : _internal_metadata_() {}
explicit MapEntry(Arena* arena)
: MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
kValueFieldType, default_enum_value>(arena),
kValueFieldType>(arena),
_internal_metadata_(arena) {}
~MapEntry() {
Message::_internal_metadata_.template Delete<UnknownFieldSet>();
_internal_metadata_.Delete<UnknownFieldSet>();
}
typedef void InternalArenaConstructable_;
typedef void DestructorSkippable_;
InternalMetadataWithArena _internal_metadata_;
typedef typename MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
kValueFieldType>::KeyTypeHandler KeyTypeHandler;
typedef
typename MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
kValueFieldType>::ValueTypeHandler ValueTypeHandler;
size_t SpaceUsedLong() const override {
size_t size = sizeof(Derived);
size += KeyTypeHandler::SpaceUsedInMapEntryLong(this->key_);
size += ValueTypeHandler::SpaceUsedInMapEntryLong(this->value_);
return size;
}
InternalMetadata _internal_metadata_;
private:
friend class ::google::protobuf::Arena;
friend class ::PROTOBUF_NAMESPACE_ID::Arena;
template <typename C, typename K, typename V,
WireFormatLite::FieldType k_wire_type, WireFormatLite::FieldType,
int default_enum>
WireFormatLite::FieldType k_wire_type, WireFormatLite::FieldType>
friend class internal::MapField;
friend class internal::GeneratedMessageReflection;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry);
};
@@ -111,30 +131,30 @@ class MapEntry
// Specialization for the full runtime
template <typename Derived, typename Key, typename Value,
WireFormatLite::FieldType kKeyFieldType,
WireFormatLite::FieldType kValueFieldType, int default_enum_value>
struct MapEntryHelper<MapEntry<Derived, Key, Value, kKeyFieldType,
kValueFieldType, default_enum_value> >
: MapEntryHelper<MapEntryLite<Derived, Key, Value, kKeyFieldType,
kValueFieldType, default_enum_value> > {
WireFormatLite::FieldType kValueFieldType>
struct MapEntryHelper<
MapEntry<Derived, Key, Value, kKeyFieldType, kValueFieldType> >
: MapEntryHelper<
MapEntryLite<Derived, Key, Value, kKeyFieldType, kValueFieldType> > {
explicit MapEntryHelper(const MapPair<Key, Value>& map_pair)
: MapEntryHelper<MapEntryLite<Derived, Key, Value, kKeyFieldType,
kValueFieldType, default_enum_value> >(
: MapEntryHelper<
MapEntryLite<Derived, Key, Value, kKeyFieldType, kValueFieldType> >(
map_pair) {}
};
template <typename Derived, typename K, typename V,
WireFormatLite::FieldType key, WireFormatLite::FieldType value,
int default_enum>
struct DeconstructMapEntry<MapEntry<Derived, K, V, key, value, default_enum> > {
WireFormatLite::FieldType key, WireFormatLite::FieldType value>
struct DeconstructMapEntry<MapEntry<Derived, K, V, key, value> > {
typedef K Key;
typedef V Value;
static const WireFormatLite::FieldType kKeyFieldType = key;
static const WireFormatLite::FieldType kValueFieldType = value;
static const int default_enum_value = default_enum;
static constexpr WireFormatLite::FieldType kKeyFieldType = key;
static constexpr WireFormatLite::FieldType kValueFieldType = value;
};
} // namespace internal
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_MAP_ENTRY_H__

Some files were not shown because too many files have changed in this diff Show More