Compare commits

..

121 Commits

Author SHA1 Message Date
Liru Færs
ae244983b0 Nope, this was broken, woops!~ 2021-02-14 14:36:45 -05:00
Liru Færs
8d2bdd4a18 New year, new gitlab-ci; thanks Rye!~ 2021-02-14 13:51:07 -05:00
Liru Færs
246db973b4 These changes look harmless 2021-02-14 12:43:19 -05:00
Tarocco
d49c38bf18 Refactor LLDAELoader
- Many instances of null-checking if statements include both variable declaration and initialization (for scoping)
- Modern(ish) C++ conventions (e.g. range-based for loops, auto keyword)
- Local variable caching for array/iterator elements
- const keyword for variables that should not be mutated (optimization possible)
- const keyword for instance methods that should not mutate (affects LLModelLoader in one case)
- Consistent usage of un/signed types for array indexing
- Better readability/simplicity of branching
- Consolidated extractTranslation/ViaElement logic (reusability)
- Formatting
- Changes based on code review
2020-10-11 19:32:16 -04:00
Liru Færs
c1aa88c720 Fix bad VLC experience in installer. Thanks Rye~ 2020-10-07 20:02:49 -04:00
Tarocco
937618b177 Model-space transformations applied to skinned model and bind shape matrix
Skin data is retrieved in processElement() by instance_controller elements, and calling processDomModel(), replacing the daeDatabase method
2020-10-07 09:05:26 -04:00
Rye Mutt
4a0936a4b5 Enable running master builds from web 2020-10-01 00:17:09 -04:00
Rye Mutt
891286c447 Merge pull request #35 from tarocco/meshupload
Improved mesh model (DAE) loader compatibility
2020-10-01 00:10:21 -04:00
Rye Mutt
04db5d1075 Merge branch 'master' of https://github.com/RouterGray/SingularityViewer into master 2020-09-29 23:33:09 -04:00
Rye Mutt
997037a232 Update fmodstudio to 2.0.04 build 417 2020-09-29 22:52:11 -04:00
Rye Mutt
f0dfb0b080 Update openjpeg with alchemy changes 2020-09-29 22:48:31 -04:00
Tarocco
f9c07b4806 only use SID if it is not empty 2020-09-24 20:14:19 -07:00
Tarocco
9f9a21bb73 refactor: reuse local variable 2020-09-24 20:04:43 -07:00
Tarocco
386528a892 Improved mesh model (DAE) loader compatibility
Added dynamic SID joint resolution for skinning (adds compatibility for DAE files made using MAXON Cinema 4D)
2020-09-06 21:11:15 -07:00
Router Gray
4efe28cf52 Merge in offline item deliveries fix from upstream. This also reverts commit 24f54572. 2020-07-21 00:23:19 -05:00
Router Gray
2528f71bbf [Media] Add https to allowed audio urls 2020-06-16 10:57:04 -05:00
Router Gray
5610eaa839 [UI] Let the 'Dimensions' text on texture preview floaters be as wide as it wants to be so enbiggenized font sizes don't truncate it. 2020-06-16 10:57:04 -05:00
Router Gray
881cc46aa9 Add missing strings to floater_model_preview.xml 2020-06-16 10:57:04 -05:00
Router Gray
81f342e9bf [Windows][Installer] Add CRC check, add 7z to plugin reserves, remove old MS DLLs, use https for LL web start menu shortcuts 2020-06-16 10:56:49 -05:00
Router Gray
fe9d670800 [Linux] Update the debugging instructions in the viewer launch script to reflect unpackaged unstripped binary availability. 2020-06-05 13:19:32 -05:00
Router Gray
ffb54802d4 [Media] Nuke unused llmime and associated build tests, also remove unneeded includes in llmimetypes header. 2020-05-28 12:14:03 -05:00
Router Gray
518da73ad2 Drop some unused boost lexical_cast includes and associated MSVC pragmas. 2020-05-22 14:48:35 -05:00
Router Gray
3e78b74474 Now that fmt plays nice with gcc let's actually use it: replace std::to_string, boost lexical_cast and a couple miscellaneous llformats with fmt. (Alchemy sync-ish) 2020-05-20 21:07:18 -05:00
Router Gray
34a7ebf53f [Linux] Port some bits from Alchemy & future to stop using dark-ages deprecated GDK/GTK.
Todo: Revisit this and clean up some code duplication I stumbled over in the process. (legacy.cpp llwindowsdl.cpp)
2020-05-19 21:48:57 -05:00
Router Gray
45be739fea [Lib][Linux] Use system SDL not prebuilt. 2020-05-19 21:42:56 -05:00
Router Gray
68ae8afaf9 [Lib] Update abseil and fmt. 2020-05-19 16:51:29 -05:00
Router Gray
2bdcd9d07f [Linux] Target SSE 4.1. (I will make custom builds if anyone on older cpu's turns up. - RG) 2020-05-19 16:50:36 -05:00
Router Gray
24f5457203 Add setting to allow legacy UDP offline message fetch till LL fixes the cap. 2020-05-19 16:46:52 -05:00
Liru Færs
f941bc4334 [RLVa] Lie about our version of the spec, for now, I'll fix this later
RLV_VERSION is supposed to follow Marine Kelley's version,
we support most 2.9.0 features, but no 2.9.20 ones. So this is correct.

RLVa_VERSION is undocumented, play pretend by matching Kitty's version
Kitty's version has no documentation about version differences
that I can find. So we're just going to pretend to be up to date.
2020-05-19 14:00:01 -04:00
Shyotl
ab5bce69ee Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-05-16 22:52:08 -05:00
Shyotl
050a8c3923 Use sse copy for vertex and texcoord data. 2020-05-16 22:48:41 -05:00
Shyotl
8817bf53e3 Fix loading of texture precache list. 2020-05-16 22:45:50 -05:00
Shyotl
5e21037230 Fix rare shutdown crash 2020-05-16 22:44:03 -05:00
Liru Færs
cabaf0fd1c Don't use buildHTTP for login page, it might be https! Copy entire uri! 2020-05-13 19:40:52 -04:00
Shyotl
bd92a09a48 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-05-09 04:51:12 -05:00
Shyotl
61f90c665a Fix issue with persistent notifications. open_notifications.xml was accumulating inaccessible notifications. Added MaxPersistentNotifications to cap notifications. Notifications new stored per account per grid. Startup should be faster too. 2020-05-09 04:50:01 -05:00
Router Gray
32dbd40e64 Unhack the string_view workaround in llpreviewgesture, with a slightly less hacky hack in llstring. lol. Thanks Liru for making this as lean as ancient gcc can stand it to be. 2020-04-26 08:44:23 -05:00
Router Gray
a69e04a817 [Lib] Update Fmtlib, and enable it for Linux builds. This is bare bones; only removing the Linux workarounds in Cmake. 2020-04-26 00:05:02 -05:00
Router Gray
159de683e8 Correct a logical OR in llrender, and add guards against mCount dropping below zero. (Alchemy and LL sync) 2020-04-26 00:04:48 -05:00
Liru Færs
a9dbaf5e0a Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer 2020-04-23 23:23:38 -04:00
Shyotl
3c3d8c2400 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-04-23 14:57:55 -05:00
Shyotl
b4080f8e2d Demote this to llassert. 2020-04-23 14:57:30 -05:00
Shyotl
5de94d6610 Address several remaining 1.8.9.8373 crashes reported on 2020-04-23 14:56:47 -05:00
Shyotl
829045c262 Haphazard unsigned to signed casts causing problems? Shocker. 2020-04-23 14:51:06 -05:00
Liru Færs
b02d70fba0 Merge stuff from future branch and a logic bug fix by Router 2020-04-23 11:43:22 -04:00
Liru Færs
64ed6e99f0 Fix [NAME] appearing in certain i18n notifications instead of slurls
Thanks for catching this, Nai
2020-04-19 20:12:23 -04:00
Liru Færs
33d3bb2870 [Chat Logs] When migrating file to new name, respect possible new name file
If a new name file exists, copy its contents into our currently tracked
file, because we update our tracked file, the new file can only contain
more recent text (unless a name change back and forth and back happened
since last run, but then the out of order text isn't entirely our fault)

So we copy the new file's text to the bottom of our old file and then
remove the new file, so we can rename our old tracked file to the updated
name.

If we cannot perform the copy, or the delete, we bypass the migration,
leaving our old tracked file as a remnant and begin to track the new name
file because that is more proper than clinging to the old one, and thus
no history is lost to failure.
2020-04-19 20:04:25 -04:00
Liru Færs
4df2193a4c [Chat Logs] Always read from name cache on start to try to update ID Map 2020-04-19 16:40:17 -04:00
Liru Færs
343be08467 [Chat Logs] Break out migrateFile from makeLogFileName for use elsewhere 2020-04-19 15:50:50 -04:00
Liru Færs
788b83bff3 Woops, thanks for catching this, Shyotl! 2020-04-18 19:15:49 -04:00
Liru Færs
c201ac90ba Track log names in a json map AND Fix processing local log load as system
Update old style callbacks for chatFromLogFile functions to lambdas
Keep track of people's log's name using their IDs, but don't rename.
Fallback on ID if name is empty (if the grid is a meanie)
Also track group names this way, sometimes those change.
Prefer std::array, since we're in the area.
2020-04-18 00:17:05 -04:00
Shyotl
af3c66ad08 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-04-16 02:23:32 -05:00
Shyotl
9bffc4bb82 Attempt to squash spatial partition crash. 2020-04-16 00:52:55 -05:00
Shyotl
132db6225e Make Debug configuration compile once more. 2020-04-16 00:49:42 -05:00
Shyotl
257086cbfc Revert texture fetching behavior back closer to v3. 2020-04-16 00:36:56 -05:00
Liru Færs
7755f1ec52 Merge branch 'master' of https://github.com/RouterGray/SingularityViewer 2020-04-11 10:28:04 -04:00
Router Gray
c5f1ac808b Fix postcard sends, use cap for user info, stop using 'from' email as per upstream. Mark final and overrides. Thanks Nadira Fairport for reporting & Liru for help. 2020-04-11 09:22:26 -05:00
Liru Færs
1a8660909d Copy Folder ID and Open Folder In New Window for ANY folder 2020-04-10 17:40:06 -04:00
Shyotl
e6826a4c7c Fix 'is typing...' notifications never going away. 2020-04-10 16:28:37 -05:00
Router Gray
801bb8a075 Compile fix, make types agree in terniary in octree. Thanks Liru. 2020-04-10 13:21:57 -05:00
Shyotl
b2c965e22d Do not apply internal windlight parameter scaling on the sliders themselves. 2020-04-09 14:20:55 -05:00
Shyotl
be3cbc642b Update current region debug string upon cap seed request. Carry over seed cap if dead region is replaced with new. 2020-04-09 02:12:36 -05:00
Shyotl
24331d3c90 Prefer LLPointer over potential for dangling LLSpatialGroup pointers. 2020-04-09 01:56:32 -05:00
Shyotl
8a16e6c99f Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-04-08 18:18:19 -05:00
Shyotl
f36e8fbeca Better crashdump context. 2020-04-08 18:11:09 -05:00
Liru Færs
718ef09adf Fix removing/exporting picks when unable to add more
Wooops, wrote that wrong, must've been tired or something
2020-04-08 09:21:21 -04:00
Liru Færs
6443849ea9 Do not lookup strings in the toolbar per frame, ack! 2020-04-08 08:33:41 -04:00
Liru Færs
cbb7e473ba Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2020-04-08 06:59:48 -04:00
Liru Færs
118957362f Fix mismatched tag 2020-04-08 05:11:11 -04:00
Shyotl
ed7f73769f Potentially fix crash in LLSurface 2020-04-07 23:30:12 -05:00
Liru Færs
ae15dcb318 Merge 41224c57317b6c1b44528aa1dc1f13732cdffe6d from viewer-lion... sorta
Fixes broken default perms message sometimes popping up for certain avs
2020-04-07 16:55:58 -04:00
Liru Færs
c4af22481c Update mesh export code, cause why not. 2020-04-07 15:30:13 -04:00
Liru Færs
ae17f76bb4 Remove now unused LLIMInfo 2020-04-07 10:49:48 -04:00
Liru Færs
7e62d17fda Don't try to use region if it's null for permissions defaults 2020-04-07 05:56:06 -04:00
Liru Færs
f9185e8bc8 Fix mutelist popping up, I think
LLMuteList::add should return false if nothing new was added
2020-04-07 05:55:24 -04:00
Liru Færs
1361f9b57d Simplify selection of mute 2020-04-07 04:29:45 -04:00
Liru Færs
b86eae026b Sync to fix using gMessageSystem when it may not have the right message 2020-04-07 04:29:20 -04:00
Liru Færs
79d938a4f4 Sync LLMuteList code with upstream 2020-04-07 02:51:08 -04:00
Liru Færs
23068a70a2 Select Mute when muting object via Object profile 2020-04-06 07:53:42 -04:00
Shyotl
0aa5e0bb88 Close 'default permissions' window on client disconnect. Nonfunctional after that point anyhow. Also applying setting crashes due to null region after dc. 2020-04-05 14:56:35 -05:00
Router Gray
5040275969 [CMake] Releases shouldn't speak Greek. 2020-04-04 06:47:39 -05:00
Liru Færs
1daccf40ee Move the FMOD Powered By text, for Torric and others 2020-04-04 07:28:19 -04:00
Shyotl
4fd302286b Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-04-03 06:02:48 -05:00
Shyotl
18f9f19e61 Textures mid-decode potentially processing of other textures until complete. Disabled UDP texture fetch fallback when connected to official grid. 2020-04-03 06:01:58 -05:00
Liru Færs
1de6d4461a Add missing EmergencyTeleportSeconds preference to System->Security
Thanks for the heads up about this missing preferences, and for the
Spanish translation, Damian!
2020-04-03 02:53:41 -04:00
Shyotl
4198f47ab6 Fix header breakage in debug/relwithdebug 2020-04-03 00:33:19 -05:00
Shyotl
d9049ba342 Handle AISAPI throttling and status 410 a bit better. 2020-04-02 21:47:07 -05:00
Shyotl
f75ac3e4c2 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-04-02 20:09:53 -05:00
Liru Færs
06698deaca A couple more sim->region changes 2020-04-02 21:08:23 -04:00
Shyotl
445eb29bd3 Bring aisapi handling closer to LL (code 499 retry, match timeout values, etc) 2020-04-02 20:07:55 -05:00
Shyotl
cc034f6841 Fix inventory scrolling issue when navigating via keyboard. 2020-04-02 20:03:08 -05:00
Liru Færs
3c368651f1 Update crashpad, thanks Rye! 2020-04-02 20:39:01 -04:00
Damian Zhaoying
321730e384 More translations fixes in Area search and menu list owners. 2020-04-02 03:02:23 -03:00
Damian Zhaoying
c2fd88670f Fix some remaining spanish translations. 2020-04-02 02:36:20 -03:00
Liru Færs
7b03103a1f April Fools!
Ha, goteem
2020-04-01 20:52:44 -04:00
Liru Færs
ac3e19c91a Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2020-04-01 20:47:23 -04:00
Liru Færs
4c7d2224e3 Fix reverted xml change, fix formatting 2020-04-01 20:43:00 -04:00
Shyotl
3ab800d99e Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-04-01 19:26:41 -05:00
Shyotl
332cef0f84 Disable debug logging unless RelWithDeb 2020-04-01 19:26:23 -05:00
Damian Zhaoying
9de6d7627b A lot of updates and fixes for spanish language translations. 2020-04-01 20:44:41 -03:00
Liru Færs
98b42e88c1 Fix SV-2282: Incorrect terminology for TP Sound preference UI 2020-04-01 06:56:51 -04:00
Liru Færs
e642e9561a The sim is actually the region 2020-04-01 04:42:34 -04:00
Liru Færs
77f500cb64 Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2020-04-01 01:59:42 -04:00
Liru Færs
d04a8fc677 Merge branch 'master' of https://github.com/RouterGray/SingularityViewer 2020-04-01 01:59:32 -04:00
Liru Færs
6028ae7b61 Fix group notices: Have a background for the header for certain skins. 2020-04-01 01:56:58 -04:00
Shyotl
347c2cbd8b Fall in line with LL octree code. 2020-03-31 19:07:55 -05:00
Router Gray
919ffb314b [UI] Add missing 'AlreadyInGroup' to strings.xml 2020-03-30 15:24:28 -05:00
Router Gray
c033d69d54 [Linux] More follow-through on earlier manifest tuning, make always really mean always. 2020-03-30 03:06:21 -05:00
Router Gray
356d289972 User request: Add last owner profile button to object inspect. 2020-03-29 19:16:52 -05:00
Router Gray
eeabbce377 [Lib] Update abseil. (Alchemy sync) 2020-03-29 16:39:16 -05:00
Router Gray
0b992fdd46 [Lib] Update nlohmann json and switch it to FetchContent instead of prebuilts. (Alchemy sync) 2020-03-29 16:38:53 -05:00
Router Gray
a7e56d2af9 Fix an accident in a ternary. 2020-03-29 16:31:40 -05:00
Router Gray
b10619e4d8 [Linux] Don't strip binaries, even when building release, unless packaging. Makes quick debugging in the dev checkout easier.
This may need more work if we want to support building an 'install' target, bypassing packaging, but I never hear of anyone doing that.  I'll address it if needed.
2020-03-29 15:24:10 -05:00
Router Gray
74518f299c Merge remote-tracking branch 'github-liru/master' 2020-03-29 15:21:22 -05:00
Liru Færs
407b527a55 [XPTools] Fix linux crash bug, make Cancel button close Experiences floater 2020-03-29 00:43:21 -04:00
Liru Færs
b21cc835b2 Clean up old Experience UI port code 2020-03-28 16:38:14 -04:00
Shyotl
4de8c3a38e Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-03-27 02:56:20 -05:00
Shyotl
72d8b8f78c Potentially harden against region teardown crash. Screw with branching to delve more information from callstacks since dynamic annotations don't seem to work with sentry.io using crashpad lib... sadface. 2020-03-27 02:55:12 -05:00
Liru Færs
45f4f601bf nopaque 2020-03-27 02:35:06 -04:00
Liru Færs
731283aa0b Friendship accepted notifications as tips with linked names 2020-03-27 00:51:45 -04:00
Liru Færs
89ce328ba5 Fix script dialogs showing UI SLURLs when SinguReplaceLinks is false
All interface SLURLs should be force replaced.
Also fixes text boxes not respecting setting at all
2020-03-26 23:31:52 -04:00
221 changed files with 4242 additions and 4639 deletions

View File

@@ -1,166 +1,279 @@
stages:
- build
- deploy
- upload
default:
interruptible: true
timeout: 4h
variables:
AUTOBUILD_BUILD_ID: $CI_PIPELINE_ID
AUTOBUILD_INSTALLABLE_CACHE: "$CI_PROJECT_DIR/.cache/autobuild"
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
VIEWER_USE_CRASHPAD: "TRUE"
VIEWER_CRASHPAD_URL: $SENTRY_DSN
.win_build: &win_build
.win_build:
stage: build
tags:
- autobuild
- windows
cache:
key:
files:
- autobuild.xml
prefix: ${CI_JOB_NAME}
paths:
- .cache/autobuild
- .cache/pip
- .venv/
when: 'always'
before_script:
- pipenv install
- virtualenv .venv
- .\.venv\Scripts\activate.ps1
- pip install --upgrade autobuild -i https://pkg.alchemyviewer.org/repository/autobuild/simple --extra-index-url https://pypi.org/simple
script:
- If ($env:VIEWER_CHANNEL_TYPE -eq 'Project')
{
$env:VIEWER_CHANNEL_CODENAME = $env:CI_COMMIT_REF_NAME[8..100] -join ''
}
- pipenv run autobuild configure -c Release -- -DUSE_FMODSTUDIO=ON -DUSE_NVAPI=ON -DUSE_LTO=ON -DVS_DISABLE_FATAL_WARNINGS=ON
- pipenv run autobuild build -c Release --no-configure
- If ($env:VIEWER_USE_CRASHPAD -eq 'TRUE') {
- Push-Location .\build-vc-*\newview\Release\
- sentry-cli upload-dif --include-sources singularity-bin.exe singularity-bin.pdb crashpad_handler.exe crashpad_handler.pdb fmod.dll libcrypto-1_1.dll libcrypto-1_1.pdb libssl-1_1.dll libssl-1_1.pdb libcrypto-1_1-x64.dll libcrypto-1_1-x64.pdb libssl-1_1-x64.dll libssl-1_1-x64.pdb vcruntime140.dll msvcp140.dll libhunspell.dll libhunspell.pdb glod.dll
- Pop-Location }
- |
autobuild configure -c Release -- -DUSE_FMODSTUDIO=ON -DUSE_NVAPI=ON -DUSE_LTO=ON -DVS_DISABLE_FATAL_WARNINGS=ON -DREVISION_FROM_VCS=FALSE
autobuild build -c Release --no-configure
artifacts:
name: "$env:CI_COMMIT_REF_NAME-$env:CI_COMMIT_SHORT_SHA"
expire_in: 2 week
expire_in: 1 week
paths:
- build-vc-*/newview/Release/build_data.json
- build-vc-*/newview/Release/singularity-bin.pdb
- build-vc-*/newview/Release/singularity-bin.exe
- build-vc-*/newview/Release/*.pdb
- build-vc-*/newview/Release/*.dll
- build-vc-*/newview/Release/Singularity_*_Setup.exe
.beta_rules: &beta_rules
only:
- /^.*-beta$/
except:
- branches
.linux_build:
stage: build
image: r.alchemyviewer.org/singularity/infrastructure/debian-build-image:latest
tags:
- linux
- docker
cache:
key:
files:
- autobuild.xml
prefix: ${CI_JOB_NAME}
paths:
- .cache/autobuild
- .cache/pip
- .venv
when: 'always'
before_script:
- virtualenv .venv -p python2
- source .venv/bin/activate
- pip install --upgrade autobuild -i https://pkg.alchemyviewer.org/repository/autobuild/simple --extra-index-url https://pypi.org/simple
script:
- |
autobuild configure -c Release -- -DUSE_FMODSTUDIO=ON -DUSE_NVAPI=ON -DUSE_LTO=ON -DUNIX_DISABLE_FATAL_WARNINGS=ON -DREVISION_FROM_VCS=FALSE
autobuild build -c Release --no-configure
artifacts:
name: "$env:CI_COMMIT_REF_NAME-$env:CI_COMMIT_SHORT_SHA"
expire_in: 1 week
paths:
- build-linux-*/build_data.json
- build-linux-*/newview/Singularity_*.tar.xz
.release_rules: &release_rules
only:
- /^.*-release$/
except:
- branches
.win32_build:
extends: .win_build
variables:
AUTOBUILD_ADDRSIZE: 32
VIEWER_USE_CRASHPAD: "FALSE"
cache:
key:
prefix: windows32
.win64_build:
extends: .win_build
variables:
AUTOBUILD_ADDRSIZE: 64
cache:
key:
prefix: windows64
.linux32_build:
extends: .linux_build
variables:
AUTOBUILD_ADDRSIZE: 32
cache:
key:
prefix: linux32
.linux64_build:
extends: .linux_build
variables:
AUTOBUILD_ADDRSIZE: 64
cache:
key:
prefix: linux64
.master_rules:
rules:
- if: $BUILD_CHANNEL || $CI_COMMIT_TAG
when: never
- if: '$CI_PIPELINE_SOURCE == "web"'
- if: '$CI_PIPELINE_SOURCE == "schedule"'
#- if: '$CI_COMMIT_BRANCH == "master" && $CI_PIPELINE_SOURCE == "push"'
# when: delayed
# start_in: '12 hours'
variables:
VIEWER_CHANNEL_TYPE: Test
VIEWER_USE_CRASHPAD: "FALSE"
.project_rules:
rules:
- if: '$BUILD_CHANNEL == "Project" && ($CI_PIPELINE_SOURCE == "web" || $CI_PIPELINE_SOURCE == "schedule")'
- if: '$CI_COMMIT_TAG =~ /.*-project/'
variables:
VIEWER_CHANNEL_TYPE: Project
.beta_rules:
rules:
- if: '$BUILD_CHANNEL == "Beta" && ($CI_PIPELINE_SOURCE == "web" || $CI_PIPELINE_SOURCE == "schedule")'
- if: '$CI_COMMIT_TAG =~ /.*-beta/'
variables:
VIEWER_CHANNEL_TYPE: Beta
.release_rules:
rules:
- if: '$BUILD_CHANNEL == "Release" && ($CI_PIPELINE_SOURCE == "web" || $CI_PIPELINE_SOURCE == "schedule")'
- if: '$CI_COMMIT_TAG =~ /.*-release/'
variables:
VIEWER_CHANNEL_TYPE: Release
.build:master:linux64:
extends:
- .linux64_build
- .master_rules
build:master:windows32:
<<: *win_build
interruptible: true
variables:
AUTOBUILD_ADDRSIZE: 32
VIEWER_CHANNEL_TYPE: Test
VIEWER_USE_CRASHPAD: "FALSE"
only:
- schedules
extends:
- .win32_build
- .master_rules
build:master:windows64:
<<: *win_build
interruptible: true
variables:
AUTOBUILD_ADDRSIZE: 64
VIEWER_CHANNEL_TYPE: Test
VIEWER_USE_CRASHPAD: "FALSE"
only:
- schedules
extends:
- .win64_build
- .master_rules
.build:project:linux64:
extends:
- .linux64_build
- .project_rules
build:project:windows32:
<<: *win_build
interruptible: true
variables:
AUTOBUILD_ADDRSIZE: 32
VIEWER_CHANNEL_TYPE: Project
VIEWER_USE_CRASHPAD: "FALSE"
only:
- /^project-.*$/
extends:
- .win32_build
- .project_rules
build:project:windows64:
<<: *win_build
interruptible: true
variables:
AUTOBUILD_ADDRSIZE: 64
VIEWER_CHANNEL_TYPE: Project
only:
- /^project-.*$/
extends:
- .win64_build
- .project_rules
.build:beta:linux64:
extends:
- .linux64_build
- .beta_rules
build:beta:windows32:
<<: *win_build
variables:
AUTOBUILD_ADDRSIZE: 32
VIEWER_CHANNEL_TYPE: Beta
VIEWER_USE_CRASHPAD: "FALSE"
<<: *beta_rules
extends:
- .win32_build
- .beta_rules
build:beta:windows64:
<<: *win_build
variables:
AUTOBUILD_ADDRSIZE: 64
VIEWER_CHANNEL_TYPE: Beta
<<: *beta_rules
extends:
- .win64_build
- .beta_rules
.build:release:linux64:
extends:
- .linux64_build
- .release_rules
build:release:windows32:
<<: *win_build
variables:
AUTOBUILD_ADDRSIZE: 32
VIEWER_CHANNEL_TYPE: Release
VIEWER_USE_CRASHPAD: "FALSE"
<<: *release_rules
extends:
- .win32_build
- .release_rules
build:release:windows64:
<<: *win_build
variables:
AUTOBUILD_ADDRSIZE: 64
VIEWER_CHANNEL_TYPE: Release
<<: *release_rules
extends:
- .win64_build
- .release_rules
.deploy_template: &deploy_template
stage: deploy
.upload_template:
stage: upload
tags:
- autobuild
- windows
allow_failure: false
script:
- $BuildData = Get-Content .\build-vc-64\newview\Release\build_data.json | ConvertFrom-Json
- $BuildChannelVersion = $BuildData."Channel" + ' ' + $BuildData."Version"
- $UploadDestViewerDir = $BuildChannelVersion.ToLower().Replace(" ", "/")
- $UploadDestURL = "https://pkg.alchemyviewer.org/repository/viewer/${UploadDestViewerDir}"
- |
$BuildData = Get-Content .\build-vc-64\newview\Release\build_data.json | ConvertFrom-Json
$BuildChannelVersion = $BuildData."Channel" + ' ' + $BuildData."Version"
$UploadDestViewerDir = $BuildChannelVersion.ToLower().Replace(" ", "/")
$UploadDestURL = "https://pkg.alchemyviewer.org/repository/viewer/${UploadDestViewerDir}"
- $UploadParams = @{ UseBasicParsing = $true;
Method = "PUT";
Headers = @{
ContentType = "application/x-executable";
Authorization = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$env:AUTOBUILD_HTTP_USER`:$env:AUTOBUILD_HTTP_PASS")))"; };
Verbose = $true; };
$UploadParams = @{ UseBasicParsing = $true;
Method = "PUT";
Headers = @{
ContentType = "application/x-executable";
Authorization = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$env:AUTOBUILD_HTTP_USER`:$env:AUTOBUILD_HTTP_PASS")))"; };
Verbose = $true; };
- Push-Location .\build-vc-32\newview\Release\
- $FileNameWin32 = Get-ChildItem -Path . -Name -Include Singularity_*_Setup.exe
- Invoke-WebRequest @UploadParams -InFile .\$FileNameWin32 -Uri "${UploadDestURL}/${FileNameWin32}"
- Pop-Location
Push-Location .\build-linux-64\newview\
$FileNameLnx64 = Get-ChildItem -Path . -Name -Include Singularity_*.tar.xz
Invoke-WebRequest @UploadParams -InFile .\$FileNameLnx64 -Uri "${UploadDestURL}/${FileNameLnx64}"
Pop-Location
- Push-Location .\build-vc-64\newview\Release\
- $FileNameWin64 = Get-ChildItem -Path . -Name -Include Singularity_*_Setup.exe
- Invoke-WebRequest @UploadParams -InFile .\$FileNameWin64 -Uri "${UploadDestURL}/${FileNameWin64}"
- Pop-Location
Push-Location .\build-vc-64\newview\Release\
$FileNameWin64 = Get-ChildItem -Path . -Name -Include Singularity_*_Setup.exe
Invoke-WebRequest @UploadParams -InFile .\$FileNameWin64 -Uri "${UploadDestURL}/${FileNameWin64}"
- sentry-cli releases new $BuildChannelVersion
- sentry-cli releases set-commits --auto $BuildChannelVersion
- sentry-cli releases finalize $BuildChannelVersion
when: manual
If ($env:VIEWER_USE_CRASHPAD -eq 'TRUE')
{
sentry-cli upload-dif --include-sources singularity-bin.exe singularity-bin.pdb crashpad_handler.exe crashpad_handler.pdb fmod.dll libcrypto-1_1.dll libcrypto-1_1.pdb libssl-1_1.dll libssl-1_1.pdb libcrypto-1_1-x64.dll libcrypto-1_1-x64.pdb libssl-1_1-x64.dll libssl-1_1-x64.pdb vcruntime140.dll msvcp140.dll libhunspell.dll libhunspell.pdb glod.dll
}
Pop-Location
If ($env:VIEWER_USE_CRASHPAD -eq 'TRUE')
{
sentry-cli releases new $BuildChannelVersion
sentry-cli releases set-commits --auto $BuildChannelVersion
sentry-cli releases finalize $BuildChannelVersion
}
deploy_project:
<<: *deploy_template
upload:project:
extends:
- .upload_template
rules:
- if: '$BUILD_CHANNEL == "Project" && ($CI_PIPELINE_SOURCE == "web" || $CI_PIPELINE_SOURCE == "schedule")'
when: manual
- if: '$CI_COMMIT_TAG =~ /.*-project/'
when: manual
environment:
name: qa
only:
- /^project-.*$/
deploy_beta:
<<: *deploy_template
upload:beta:
extends:
- .upload_template
rules:
- if: '$BUILD_CHANNEL == "Beta" && ($CI_PIPELINE_SOURCE == "web" || $CI_PIPELINE_SOURCE == "schedule")'
when: manual
- if: '$CI_COMMIT_TAG =~ /.*-beta/'
when: manual
environment:
name: staging
<<: *beta_rules
name: beta
deploy_release:
<<: *deploy_template
upload:release:
extends:
- .upload_template
rules:
- if: '$BUILD_CHANNEL == "Release" && ($CI_PIPELINE_SOURCE == "web" || $CI_PIPELINE_SOURCE == "schedule")'
when: manual
- if: '$CI_COMMIT_TAG =~ /.*-release/'
when: manual
environment:
name: production
<<: *release_rules
name: release

View File

@@ -410,11 +410,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>4614b29cc98021cf1770a8290171602b</string>
<string>a96fda7ad5cee967823f5c94390ba35b</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/crashpad/windows/crashpad-ce32d093.7-windows-7.tar.bz2</string>
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/crashpad/windows/crashpad-c6d76a90.194-windows-194.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -424,18 +424,18 @@
<key>archive</key>
<map>
<key>hash</key>
<string>d801461b7a6a40fffab828aa1e01e3e6</string>
<string>5ff95ca1007ed2dc300b59de17453201</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/crashpad/windows64/crashpad-ce32d093.7-windows64-7.tar.bz2</string>
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/crashpad/windows64/crashpad-c6d76a90.194-windows64-194.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>ce32d093.7</string>
<string>c6d76a90.194</string>
</map>
<key>curl</key>
<map>
@@ -876,11 +876,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>ccd495598894c8e2e541a348015ee3f0</string>
<string>7f631a7f1742a5786e1f9de1d2424350</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>/opt/devel/fmodstudio-2.00.07.200182252-linux64-200182252.tar.bz2</string>
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/linux64/fmodstudio-2.01.04.417-linux64-417.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -890,11 +890,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>d32efb193ffcd73bcba4875ddfd17bf0</string>
<string>50ce25e855c10d3b39f5461f34661c7f</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows/fmodstudio-2.00.07.4-windows-4.tar.bz2</string>
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows/fmodstudio-2.01.04.417-windows-417.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -904,18 +904,18 @@
<key>archive</key>
<map>
<key>hash</key>
<string>0604fd6b53ceaf14ce04d0de1bea51b8</string>
<string>e13b156ca861c36b388e18df0e8e20fb</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows64/fmodstudio-2.00.07.4-windows64-4.tar.bz2</string>
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows64/fmodstudio-2.01.04.417-windows64-417.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>2.00.07.4</string>
<string>2.01.04.417</string>
</map>
<key>fonts</key>
<map>
@@ -1933,38 +1933,6 @@
<key>version</key>
<string>7.11.1.297294</string>
</map>
<key>modernjson</key>
<map>
<key>copyright</key>
<string>Copyright (c) 2013-2018 Niels Lohmann</string>
<key>description</key>
<string>JSON for Modern C++</string>
<key>license</key>
<string>MIT</string>
<key>license_file</key>
<string>LICENSES/modernjson.txt</string>
<key>name</key>
<string>modernjson</string>
<key>platforms</key>
<map>
<key>common</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>6f11eca7e2a6ca61f9217e949a64f026</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://depot.alchemyviewer.org/pub/common/lib/modernjson-3.2.0-common-201809210551.tar.bz2</string>
</map>
<key>name</key>
<string>common</string>
</map>
</map>
<key>version</key>
<string>3.2.0</string>
</map>
<key>nvapi</key>
<map>
<key>copyright</key>

View File

@@ -85,6 +85,7 @@ if (WINDOWS)
/TP
/W3
/c
/Zc:__cplusplus
/Zc:forScope
/Zc:rvalueCast
/Zc:wchar_t
@@ -135,6 +136,10 @@ if (LINUX)
-DLL_LINUX=1
-DAPPID=secondlife
-D_REENTRANT
-DGDK_DISABLE_DEPRECATED
-DGTK_DISABLE_DEPRECATED
-DGSEAL_ENABLE
-DGTK_DISABLE_SINGLE_INCLUDES
)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
@@ -204,10 +209,10 @@ if (LINUX)
if (${ARCH} STREQUAL "x86_64")
add_definitions(-pipe)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffast-math")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -ffast-math")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -ffast-math")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ffast-math")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffast-math -msse4.1")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -ffast-math -msse4.1")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -ffast-math -msse4.1")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ffast-math -msse4.1")
else (${ARCH} STREQUAL "x86_64")
if (NOT STANDALONE)
set(MARCH_FLAG " -march=pentium4")

View File

@@ -50,7 +50,6 @@ set(cmake_SOURCE_FILES
GooglePerfTools.cmake
Hunspell.cmake
JPEG.cmake
Json.cmake
LLAddBuildTest.cmake
LLAppearance.cmake
LLAudio.cmake

View File

@@ -3,6 +3,7 @@
include(APR)
include(Boost)
include(EXPAT)
include(Linking)
include(ZLIB)
if (DARWIN)
@@ -18,7 +19,9 @@ set(LLCOMMON_INCLUDE_DIRS
${Boost_INCLUDE_DIRS}
)
set(LLCOMMON_LIBRARIES llcommon)
set(LLCOMMON_LIBRARIES llcommon
fmt::fmt
)
set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a shared library.")
if(LLCOMMON_LINK_SHARED)

View File

@@ -1,9 +1,8 @@
# -*- cmake -*-
include(OpenGL)
include(Prebuilt)
if (STANDALONE)
if (LINUX)
include(FindSDL)
# This should be done by FindSDL. Sigh.
@@ -12,14 +11,7 @@ if (STANDALONE)
SDL_INCLUDE_DIR
SDL_LIBRARY
)
else (STANDALONE)
if (LINUX)
use_prebuilt_binary(SDL)
set (SDL_FOUND TRUE)
set (SDL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
set (SDL_LIBRARY SDL)
endif (LINUX)
endif (STANDALONE)
endif (LINUX)
if (SDL_FOUND)
add_definitions(-DLL_SDL=1)

View File

@@ -50,12 +50,10 @@ if (LINUX)
set(DL_LIBRARY dl)
set(RT_LIBRARY rt)
set(PTHREAD_LIBRARY pthread)
set(FMT_LIBRARY "")
else (LINUX)
set(DL_LIBRARY "")
set(RT_LIBRARY "")
set(PTHREAD_LIBRARY "")
set(FMT_LIBRARY fmt::fmt)
endif (LINUX)
if (WINDOWS)
@@ -77,6 +75,6 @@ else (WINDOWS)
set(WINDOWS_LIBRARIES "")
endif (WINDOWS)
mark_as_advanced(DL_LIBRARY RT_LIBRARY PTHREAD_LIBRARY FMT_LIBRARY WINDOWS_LIBRARIES)
mark_as_advanced(DL_LIBRARY RT_LIBRARY PTHREAD_LIBRARY WINDOWS_LIBRARIES)
endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)

View File

@@ -270,6 +270,8 @@ if (NOT VIEWER_CHANNEL_GRK)
set(VIEWER_CHANNEL_GRK "\\u03B1") # "α"
elseif (VIEWER_CHANNEL_TYPE MATCHES "Beta")
set(VIEWER_CHANNEL_GRK "\\u03B2") # "β"
else()
set(VIEWER_CHANNEL_GRK "")
endif ()
endif (NOT VIEWER_CHANNEL_GRK)

View File

@@ -9,16 +9,23 @@ FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v2.11.0
GIT_SHALLOW TRUE
)
FetchContent_Declare(
fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 6.1.2
GIT_TAG 8d78045e7cb44d39ad4cd95dd27816b8749e1944
)
FetchContent_Declare(
nlohmann_json
GIT_REPOSITORY https://github.com/nlohmann/json.git
GIT_TAG v3.7.3
GIT_SHALLOW TRUE
)
FetchContent_Declare(
absl
GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git
GIT_TAG 29235139149790f5afc430c11cec8f1eb1677607
GIT_TAG 768eb2ca2857342673fcd462792ce04b8bac3fa3
)
# This is a hack because absl has dumb cmake
@@ -40,9 +47,16 @@ if (BUILD_TESTING)
endif()
#Download the rest of the libraries
if(WINDOWS)
FetchContent_MakeAvailable(fmt)
endif()
# Typically you don't care so much for a third party library's tests to be
# run from your own project's code.
set(JSON_BuildTests OFF CACHE INTERNAL "")
# If you only include this third party in PRIVATE source files, you do not
# need to install it when your main project gets installed.
set(JSON_Install OFF CACHE INTERNAL "")
FetchContent_MakeAvailable(nlohmann_json)
unset(CMAKE_FOLDER)
unset(CMAKE_POSITION_INDEPENDENT_CODE)

View File

@@ -26,6 +26,7 @@ set(openjpeg_SOURCE_FILES
mct.c
mqc.c
openjpeg.c
opj_malloc.c
phix_manager.c
pi.c
ppix_manager.c

View File

@@ -31,11 +31,16 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#define OPJ_SKIP_POISON
#include "opj_includes.h"
#ifdef __SSE__
#include <xmmintrin.h>
#endif
#include "opj_includes.h"
#if defined(__GNUC__)
#pragma GCC poison malloc calloc realloc free
#endif
/** @defgroup DWT DWT - Implementation of a discrete wavelet transform */
/*@{*/
@@ -499,7 +504,7 @@ void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec) {
/* <summary> */
/* Determine maximum computed resolution level for inverse wavelet transform */
/* </summary> */
static int dwt_decode_max_resolution(opj_tcd_resolution_t* restrict r, int i) {
static int dwt_decode_max_resolution(opj_tcd_resolution_t* OPJ_RESTRICT r, int i) {
int mr = 1;
int w;
while( --i ) {
@@ -531,7 +536,7 @@ static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1
v.mem = h.mem;
while( --numres) {
int * restrict tiledp = tilec->data;
int * OPJ_RESTRICT tiledp = tilec->data;
int j;
++tr;
@@ -565,48 +570,49 @@ static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1
opj_aligned_free(h.mem);
}
static void v4dwt_interleave_h(v4dwt_t* restrict w, float* restrict a, int x, int size){
float* restrict bi = (float*) (w->wavelet + w->cas);
static void v4dwt_interleave_h(v4dwt_t* OPJ_RESTRICT w, float* OPJ_RESTRICT a, int x, int size) {
float* OPJ_RESTRICT bi = (float*)(w->wavelet + w->cas);
int count = w->sn;
int i, k;
for(k = 0; k < 2; ++k){
if (count + 3 * x < size && ((size_t) a & 0x0f) == 0 && ((size_t) bi & 0x0f) == 0 && (x & 0x0f) == 0) {
for (k = 0; k < 2; ++k) {
if (count + 3 * x < size && ((size_t)a & 0x0f) == 0 && ((size_t)bi & 0x0f) == 0 && (x & 0x0f) == 0) {
/* Fast code path */
for(i = 0; i < count; ++i){
for (i = 0; i < count; ++i) {
int j = i;
bi[i*8 ] = a[j];
bi[i * 8] = a[j];
j += x;
bi[i*8 + 1] = a[j];
bi[i * 8 + 1] = a[j];
j += x;
bi[i*8 + 2] = a[j];
bi[i * 8 + 2] = a[j];
j += x;
bi[i*8 + 3] = a[j];
bi[i * 8 + 3] = a[j];
}
} else {
}
else {
/* Slow code path */
for(i = 0; i < count; ++i){
int j = i;
bi[i*8 ] = a[j];
j += x;
if(j > size) continue;
bi[i*8 + 1] = a[j];
j += x;
if(j > size) continue;
bi[i*8 + 2] = a[j];
j += x;
if(j > size) continue;
bi[i*8 + 3] = a[j];
for (i = 0; i < count; ++i) {
int j = i;
bi[i * 8] = a[j];
j += x;
if (j > size) continue;
bi[i * 8 + 1] = a[j];
j += x;
if (j > size) continue;
bi[i * 8 + 2] = a[j];
j += x;
if (j > size) continue;
bi[i * 8 + 3] = a[j];
}
}
}
bi = (float*) (w->wavelet + 1 - w->cas);
bi = (float*)(w->wavelet + 1 - w->cas);
a += w->sn;
size -= w->sn;
count = w->dn;
}
}
static void v4dwt_interleave_v(v4dwt_t* restrict v , float* restrict a , int x){
v4* restrict bi = v->wavelet + v->cas;
static void v4dwt_interleave_v(v4dwt_t* OPJ_RESTRICT v , float* OPJ_RESTRICT a , int x){
v4* OPJ_RESTRICT bi = v->wavelet + v->cas;
int i;
for(i = 0; i < v->sn; ++i){
memcpy(&bi[i*2], &a[i*x], 4 * sizeof(float));
@@ -621,7 +627,7 @@ static void v4dwt_interleave_v(v4dwt_t* restrict v , float* restrict a , int x){
#ifdef __SSE__
static void v4dwt_decode_step1_sse(v4* w, int count, const __m128 c){
__m128* restrict vw = (__m128*) w;
__m128* OPJ_RESTRICT vw = (__m128*) w;
int i;
/* 4x unrolled loop */
for(i = 0; i < count >> 2; ++i){
@@ -642,22 +648,39 @@ static void v4dwt_decode_step1_sse(v4* w, int count, const __m128 c){
}
static void v4dwt_decode_step2_sse(v4* l, v4* w, int k, int m, __m128 c){
__m128* restrict vl = (__m128*) l;
__m128* restrict vw = (__m128*) w;
__m128* OPJ_RESTRICT vl = (__m128*) l;
__m128* OPJ_RESTRICT vw = (__m128*) w;
int i;
__m128 tmp1, tmp2, tmp3;
tmp1 = vl[0];
for(i = 0; i < m; ++i){
for (i = 0; i < m - 3; i += 4) {
__m128 tmp4, tmp5, tmp6, tmp7, tmp8, tmp9;
tmp2 = vw[-1];
tmp3 = vw[0];
tmp4 = vw[1];
tmp5 = vw[2];
tmp6 = vw[3];
tmp7 = vw[4];
tmp8 = vw[5];
tmp9 = vw[6];
vw[-1] = _mm_add_ps(tmp2, _mm_mul_ps(_mm_add_ps(tmp1, tmp3), c));
vw[1] = _mm_add_ps(tmp4, _mm_mul_ps(_mm_add_ps(tmp3, tmp5), c));
vw[3] = _mm_add_ps(tmp6, _mm_mul_ps(_mm_add_ps(tmp5, tmp7), c));
vw[5] = _mm_add_ps(tmp8, _mm_mul_ps(_mm_add_ps(tmp7, tmp9), c));
tmp1 = tmp9;
vw += 8;
}
for ( ; i < m; ++i) {
tmp2 = vw[-1];
tmp3 = vw[ 0];
vw[-1] = _mm_add_ps(tmp2, _mm_mul_ps(_mm_add_ps(tmp1, tmp3), c));
tmp1 = tmp3;
vw += 2;
}
vl = vw - 2;
if(m >= k){
return;
}
vl = vw - 2;
c = _mm_add_ps(c, c);
c = _mm_mul_ps(c, vl[0]);
for(; m < k; ++m){
@@ -670,7 +693,7 @@ static void v4dwt_decode_step2_sse(v4* l, v4* w, int k, int m, __m128 c){
#else
static void v4dwt_decode_step1(v4* w, int count, const float c){
float* restrict fw = (float*) w;
float* OPJ_RESTRICT fw = (float*) w;
int i;
for(i = 0; i < count; ++i){
float tmp1 = fw[i*8 ];
@@ -685,8 +708,8 @@ static void v4dwt_decode_step1(v4* w, int count, const float c){
}
static void v4dwt_decode_step2(v4* l, v4* w, int k, int m, float c){
float* restrict fl = (float*) l;
float* restrict fw = (float*) w;
float* OPJ_RESTRICT fl = (float*) l;
float* OPJ_RESTRICT fw = (float*) w;
int i;
for(i = 0; i < m; ++i){
float tmp1_1 = fl[0];
@@ -737,42 +760,44 @@ static void v4dwt_decode_step2(v4* l, v4* w, int k, int m, float c){
/* <summary> */
/* Inverse 9-7 wavelet transform in 1-D. */
/* </summary> */
static void v4dwt_decode(v4dwt_t* restrict dwt){
static void v4dwt_decode(v4dwt_t* OPJ_RESTRICT dwt){
int a, b;
if(dwt->cas == 0) {
if(!((dwt->dn > 0) || (dwt->sn > 1))){
if (dwt->dn <= 0 && dwt->sn <= 1) {
return;
}
a = 0;
b = 1;
}else{
if(!((dwt->sn > 0) || (dwt->dn > 1))) {
if (dwt->sn <= 0 && dwt->dn <= 1) {
return;
}
a = 1;
b = 0;
}
v4* OPJ_RESTRICT waveleta = dwt->wavelet + a;
v4* OPJ_RESTRICT waveletb = dwt->wavelet + b;
#ifdef __SSE__
v4dwt_decode_step1_sse(dwt->wavelet+a, dwt->sn, _mm_set1_ps(K));
v4dwt_decode_step1_sse(dwt->wavelet+b, dwt->dn, _mm_set1_ps(c13318));
v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(dwt_delta));
v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_gamma));
v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(dwt_beta));
v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_alpha));
v4dwt_decode_step1_sse(waveleta, dwt->sn, _mm_set1_ps(K));
v4dwt_decode_step1_sse(waveletb, dwt->dn, _mm_set1_ps(c13318));
v4dwt_decode_step2_sse(waveletb, waveleta + 1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(dwt_delta));
v4dwt_decode_step2_sse(waveleta, waveletb + 1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_gamma));
v4dwt_decode_step2_sse(waveletb, waveleta + 1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(dwt_beta));
v4dwt_decode_step2_sse(waveleta, waveletb + 1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_alpha));
#else
v4dwt_decode_step1(dwt->wavelet+a, dwt->sn, K);
v4dwt_decode_step1(dwt->wavelet+b, dwt->dn, c13318);
v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_delta);
v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_gamma);
v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_beta);
v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_alpha);
v4dwt_decode_step1(waveleta, dwt->sn, K);
v4dwt_decode_step1(waveletb, dwt->dn, c13318);
v4dwt_decode_step2(waveletb, waveleta + 1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_delta);
v4dwt_decode_step2(waveleta, waveletb + 1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_gamma);
v4dwt_decode_step2(waveletb, waveleta + 1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_beta);
v4dwt_decode_step2(waveleta, waveletb + 1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_alpha);
#endif
}
/* <summary> */
/* Inverse 9-7 wavelet transform in 2-D. */
/* </summary> */
void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){
void dwt_decode_real(opj_tcd_tilecomp_t* OPJ_RESTRICT tilec, int numres){
v4dwt_t h;
v4dwt_t v;
@@ -787,7 +812,7 @@ void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){
v.wavelet = h.wavelet;
while( --numres) {
float * restrict aj = (float*) tilec->data;
float * OPJ_RESTRICT aj = (float*) tilec->data;
int bufsize = (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0);
int j;

View File

@@ -29,11 +29,16 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#define OPJ_SKIP_POISON
#include "opj_includes.h"
#ifdef __SSE__
#include <xmmintrin.h>
#endif
#include "opj_includes.h"
#if defined(__GNUC__)
#pragma GCC poison malloc calloc realloc free
#endif
/* <summary> */
/* This table contains the norms of the basis function of the reversible MCT. */
@@ -49,17 +54,38 @@ static const double mct_norms_real[3] = { 1.732, 1.805, 1.573 };
/* Foward reversible MCT. */
/* </summary> */
void mct_encode(
int* restrict c0,
int* restrict c1,
int* restrict c2,
int* OPJ_RESTRICT c0,
int* OPJ_RESTRICT c1,
int* OPJ_RESTRICT c2,
int n)
{
int i;
for(i = 0; i < n; ++i) {
int i = 0;
#ifdef __SSE2__
/* Buffers are normally aligned on 16 bytes... */
if (((size_t)c0 & 0xf) == 0 && ((size_t)c1 & 0xf) == 0 && ((size_t)c2 & 0xf) == 0) {
const int cnt = n & ~3U;
for (; i < cnt; i += 4) {
__m128i y, u, v;
__m128i r = _mm_load_si128((const __m128i*) & (c0[i]));
__m128i g = _mm_load_si128((const __m128i*) & (c1[i]));
__m128i b = _mm_load_si128((const __m128i*) & (c2[i]));
y = _mm_add_epi32(g, g);
y = _mm_add_epi32(y, b);
y = _mm_add_epi32(y, r);
y = _mm_srai_epi32(y, 2);
u = _mm_sub_epi32(b, g);
v = _mm_sub_epi32(r, g);
_mm_store_si128((__m128i*) & (c0[i]), y);
_mm_store_si128((__m128i*) & (c1[i]), u);
_mm_store_si128((__m128i*) & (c2[i]), v);
}
}
#endif
for (; i < n; ++i) {
int r = c0[i];
int g = c1[i];
int b = c2[i];
int y = (r + (g * 2) + b) >> 2;
int y = (r + g + g + b) >> 2;
int u = b - g;
int v = r - g;
c0[i] = y;
@@ -72,13 +98,32 @@ void mct_encode(
/* Inverse reversible MCT. */
/* </summary> */
void mct_decode(
int* restrict c0,
int* restrict c1,
int* restrict c2,
int* OPJ_RESTRICT c0,
int* OPJ_RESTRICT c1,
int* OPJ_RESTRICT c2,
int n)
{
int i;
for (i = 0; i < n; ++i) {
int i = 0;
#ifdef __SSE2__
/* Buffers are normally aligned on 16 bytes... */
if (((size_t)c0 & 0xf) == 0 && ((size_t)c1 & 0xf) == 0 && ((size_t)c2 & 0xf) == 0) {
const int cnt = n & ~3U;
for (; i < cnt; i += 4) {
__m128i r, g, b;
__m128i y = _mm_load_si128((const __m128i*) & (c0[i]));
__m128i u = _mm_load_si128((const __m128i*) & (c1[i]));
__m128i v = _mm_load_si128((const __m128i*) & (c2[i]));
g = y;
g = _mm_sub_epi32(g, _mm_srai_epi32(_mm_add_epi32(u, v), 2));
r = _mm_add_epi32(v, g);
b = _mm_add_epi32(u, g);
_mm_store_si128((__m128i*) & (c0[i]), r);
_mm_store_si128((__m128i*) & (c1[i]), g);
_mm_store_si128((__m128i*) & (c2[i]), b);
}
}
#endif
for (; i < n; ++i) {
int y = c0[i];
int u = c1[i];
int v = c2[i];
@@ -102,13 +147,119 @@ double mct_getnorm(int compno) {
/* Foward irreversible MCT. */
/* </summary> */
void mct_encode_real(
int* restrict c0,
int* restrict c1,
int* restrict c2,
int* OPJ_RESTRICT c0,
int* OPJ_RESTRICT c1,
int* OPJ_RESTRICT c2,
int n)
{
int i;
for(i = 0; i < n; ++i) {
int i = 0;
#ifdef __SSE4_1__
/* Buffers are normally aligned on 16 bytes... */
if (((size_t)c0 & 0xf) == 0 && ((size_t)c1 & 0xf) == 0 && ((size_t)c2 & 0xf) == 0) {
const int cnt = n & ~3U;
const __m128i ry = _mm_set1_epi32(2449);
const __m128i gy = _mm_set1_epi32(4809);
const __m128i by = _mm_set1_epi32(934);
const __m128i ru = _mm_set1_epi32(1382);
const __m128i gu = _mm_set1_epi32(2714);
const __m128i gv = _mm_set1_epi32(3430);
const __m128i bv = _mm_set1_epi32(666);
const __m128i mulround = _mm_shuffle_epi32(_mm_cvtsi32_si128(4096), _MM_SHUFFLE(1, 0, 1, 0));
for (; i < cnt; i += 4) {
__m128i lo, hi, y, u, v;
__m128i r = _mm_load_si128((const __m128i*) & (c0[i]));
__m128i g = _mm_load_si128((const __m128i*) & (c1[i]));
__m128i b = _mm_load_si128((const __m128i*) & (c2[i]));
hi = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(r, ry);
hi = _mm_mul_epi32(hi, ry);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
y = _mm_blend_epi16(lo, hi, 0xCC);
hi = _mm_shuffle_epi32(g, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(g, gy);
hi = _mm_mul_epi32(hi, gy);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
y = _mm_add_epi32(y, _mm_blend_epi16(lo, hi, 0xCC));
hi = _mm_shuffle_epi32(b, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(b, by);
hi = _mm_mul_epi32(hi, by);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
y = _mm_add_epi32(y, _mm_blend_epi16(lo, hi, 0xCC));
_mm_store_si128((__m128i*) & (c0[i]), y);
lo = _mm_cvtepi32_epi64(_mm_shuffle_epi32(b, _MM_SHUFFLE(3, 2, 2, 0)));
hi = _mm_cvtepi32_epi64(_mm_shuffle_epi32(b, _MM_SHUFFLE(3, 2, 3, 1)));
lo = _mm_slli_epi64(lo, 12);
hi = _mm_slli_epi64(hi, 12);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
u = _mm_blend_epi16(lo, hi, 0xCC);
hi = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(r, ru);
hi = _mm_mul_epi32(hi, ru);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
u = _mm_sub_epi32(u, _mm_blend_epi16(lo, hi, 0xCC));
hi = _mm_shuffle_epi32(g, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(g, gu);
hi = _mm_mul_epi32(hi, gu);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
u = _mm_sub_epi32(u, _mm_blend_epi16(lo, hi, 0xCC));
_mm_store_si128((__m128i*) & (c1[i]), u);
lo = _mm_cvtepi32_epi64(_mm_shuffle_epi32(r, _MM_SHUFFLE(3, 2, 2, 0)));
hi = _mm_cvtepi32_epi64(_mm_shuffle_epi32(r, _MM_SHUFFLE(3, 2, 3, 1)));
lo = _mm_slli_epi64(lo, 12);
hi = _mm_slli_epi64(hi, 12);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
v = _mm_blend_epi16(lo, hi, 0xCC);
hi = _mm_shuffle_epi32(g, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(g, gv);
hi = _mm_mul_epi32(hi, gv);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
v = _mm_sub_epi32(v, _mm_blend_epi16(lo, hi, 0xCC));
hi = _mm_shuffle_epi32(b, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(b, bv);
hi = _mm_mul_epi32(hi, bv);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
v = _mm_sub_epi32(v, _mm_blend_epi16(lo, hi, 0xCC));
_mm_store_si128((__m128i*) & (c2[i]), v);
}
}
#endif
for (; i < n; ++i) {
int r = c0[i];
int g = c1[i];
int b = c2[i];
@@ -125,19 +276,21 @@ void mct_encode_real(
/* Inverse irreversible MCT. */
/* </summary> */
void mct_decode_real(
float* restrict c0,
float* restrict c1,
float* restrict c2,
float* OPJ_RESTRICT c0,
float* OPJ_RESTRICT c1,
float* OPJ_RESTRICT c2,
int n)
{
int i;
#ifdef __SSE__
int count;
__m128 vrv, vgu, vgv, vbu;
vrv = _mm_set1_ps(1.402f);
vgu = _mm_set1_ps(0.34413f);
vgv = _mm_set1_ps(0.71414f);
vbu = _mm_set1_ps(1.772f);
for (i = 0; i < (n >> 3); ++i) {
count = n >> 3;
for (i = 0; i < count; ++i) {
__m128 vy, vu, vv;
__m128 vr, vg, vb;
@@ -174,7 +327,7 @@ void mct_decode_real(
float u = c1[i];
float v = c2[i];
float r = y + (v * 1.402f);
float g = y - (u * 0.34413f) - (v * (0.71414f));
float g = y - (u * 0.34413f) - (v * 0.71414f);
float b = y + (u * 1.772f);
c0[i] = r;
c1[i] = g;

View File

@@ -40,33 +40,71 @@
==========================================================
*/
/*
The inline keyword is supported by C99 but not by C90.
Most compilers implement their own version of this keyword ...
*/
#ifndef INLINE
#if defined(_MSC_VER)
#define INLINE __forceinline
#elif defined(__GNUC__)
#define INLINE __inline__
#elif defined(__MWERKS__)
#define INLINE inline
#else
/* add other compilers here ... */
#define INLINE
#endif /* defined(<Compiler>) */
#endif /* INLINE */
#if defined(OPJ_STATIC) || !defined(_WIN32)
#define OPJ_API
#define OPJ_CALLCONV
#else
#define OPJ_CALLCONV __stdcall
/*
The following ifdef block is the standard way of creating macros which make exporting
The following ifdef block is the standard way of creating macros which make exporting
from a DLL simpler. All files within this DLL are compiled with the OPJ_EXPORTS
symbol defined on the command line. this symbol should not be defined on any project
that uses this DLL. This way any other project whose source files include this file see
OPJ_API functions as being imported from a DLL, wheras this DLL sees symbols
that uses this DLL. This way any other project whose source files include this file see
OPJ_API functions as being imported from a DLL, whereas this DLL sees symbols
defined with this macro as being exported.
*/
#if defined(OPJ_EXPORTS) || defined(DLL_EXPORT)
#define OPJ_API __declspec(dllexport)
#else
#define OPJ_API __declspec(dllimport)
#endif /* OPJ_EXPORTS */
# if defined(OPJ_EXPORTS) || defined(DLL_EXPORT)
# define OPJ_API __declspec(dllexport)
# else
# define OPJ_API __declspec(dllimport)
# endif /* OPJ_EXPORTS */
#endif /* !OPJ_STATIC || !_WIN32 */
typedef int opj_bool;
#define OPJ_TRUE 1
#define OPJ_FALSE 0
typedef char OPJ_CHAR;
typedef float OPJ_FLOAT32;
typedef double OPJ_FLOAT64;
typedef unsigned char OPJ_BYTE;
#include "opj_stdint.h"
typedef int8_t OPJ_INT8;
typedef uint8_t OPJ_UINT8;
typedef int16_t OPJ_INT16;
typedef uint16_t OPJ_UINT16;
typedef int32_t OPJ_INT32;
typedef uint32_t OPJ_UINT32;
typedef int64_t OPJ_INT64;
typedef uint64_t OPJ_UINT64;
typedef int64_t OPJ_OFF_T; /* 64-bit file offset type */
#include <stdio.h>
typedef size_t OPJ_SIZE_T;
/* Avoid compile-time warning because parameter is not used */
#define OPJ_ARG_NOT_USED(x) (void)(x)
/*
/*
==========================================================
Useful constant definitions
==========================================================

View File

@@ -40,6 +40,8 @@
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <assert.h>
#include <limits.h>
/*
==========================================================
@@ -54,56 +56,115 @@
==========================================================
*/
/* Are restricted pointers available? (C99) */
#if (__STDC_VERSION__ >= 199901L)
#define OPJ_RESTRICT restrict
#else
/* Not a C99 compiler */
#if defined(__GNUC__)
#define OPJ_RESTRICT __restrict__
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
#define OPJ_RESTRICT __restrict
#else
#define OPJ_RESTRICT /* restrict */
#endif
#endif
/* Ignore GCC attributes if this is not GCC */
#ifndef __GNUC__
#define __attribute__(x) /* __attribute__(x) */
#endif
/*
The inline keyword is supported by C99 but not by C90.
Most compilers implement their own version of this keyword ...
*/
#ifndef INLINE
#if defined(_MSC_VER)
#define INLINE __forceinline
#elif defined(__GNUC__)
#define INLINE __inline__
#elif defined(__MWERKS__)
#define INLINE inline
#else
/* add other compilers here ... */
#define INLINE
#endif /* defined(<Compiler>) */
#endif /* INLINE */
/* Are restricted pointers available? (C99) */
#if (__STDC_VERSION__ != 199901L)
/* Not a C99 compiler */
#ifdef __GNUC__
#define restrict __restrict__
#else
#define restrict /* restrict */
#endif
#endif
/* MSVC and Borland C do not have lrintf */
#if defined(_MSC_VER) || defined(__BORLANDC__)
static INLINE long lrintf(float f){
/* MSVC before 2013 and Borland C do not have lrintf */
#if defined(_MSC_VER)
#include <intrin.h>
static INLINE long opj_lrintf(float f)
{
#ifdef _M_X64
return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f));
#else
return _mm_cvt_ss2si(_mm_load_ss(&f));
/* commented out line breaks many tests */
/* return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f)); */
#elif defined(_M_IX86)
int i;
_asm{
fld f
fistp i
};
return i;
#else
return (long)((f>0.0f) ? (f + 0.5f) : (f - 0.5f));
#endif
}
#elif defined(__BORLANDC__)
static INLINE long opj_lrintf(float f)
{
#ifdef _M_X64
return (long)((f > 0.0f) ? (f + 0.5f) : (f - 0.5f));
#else
int i;
_asm {
fld f
fistp i
};
return i;
#endif
}
#else
static INLINE long opj_lrintf(float f)
{
return lrintf(f);
}
#endif
#if defined(_MSC_VER) && (_MSC_VER < 1400)
#define vsnprintf _vsnprintf
#endif
/* MSVC x86 is really bad at doing int64 = int32 * int32 on its own. Use intrinsic. */
#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) && defined(_M_IX86)
# include <intrin.h>
# pragma intrinsic(__emul)
#endif
/* Apparently Visual Studio doesn't define __SSE__ / __SSE2__ macros */
#if defined(_M_X64)
/* Intel 64bit support SSE and SSE2 */
# ifndef __SSE__
# define __SSE__ 1
# endif
# ifndef __SSE2__
# define __SSE2__ 1
# endif
# if !defined(__SSE4_1__) && defined(__AVX__)
# define __SSE4_1__ 1
# endif
#endif
/* For x86, test the value of the _M_IX86_FP macro. */
/* See https://msdn.microsoft.com/en-us/library/b0084kay.aspx */
#if defined(_M_IX86_FP)
# if _M_IX86_FP >= 1
# ifndef __SSE__
# define __SSE__ 1
# endif
# endif
# if _M_IX86_FP >= 2
# ifndef __SSE2__
# define __SSE2__ 1
# endif
# endif
#endif
/* Type to use for bit-fields in internal headers */
typedef unsigned int OPJ_BITFIELD;
#define OPJ_UNUSED(x) (void)x
#include "j2k_lib.h"
#include "opj_malloc.h"
#include "event.h"

View File

@@ -0,0 +1,249 @@
/*
* The copyright in this software is being made available under the 2-clauses
* BSD License, included below. This software may be subject to other third
* party and contributor rights, including patent rights, and no such rights
* are granted under this license.
*
* Copyright (c) 2015, Mathieu Malaterre <mathieu.malaterre@gmail.com>
* Copyright (c) 2015, Matthieu Darbois
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* 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.
*/
#define OPJ_SKIP_POISON
#include "opj_includes.h"
#if defined(OPJ_HAVE_MALLOC_H) && defined(OPJ_HAVE_MEMALIGN)
# include <malloc.h>
#endif
#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif
static INLINE void *opj_aligned_alloc_n(size_t alignment, size_t size)
{
void* ptr;
/* alignment shall be power of 2 */
assert((alignment != 0U) && ((alignment & (alignment - 1U)) == 0U));
/* alignment shall be at least sizeof(void*) */
assert(alignment >= sizeof(void*));
if (size == 0U) { /* prevent implementation defined behavior of realloc */
return NULL;
}
#if defined(OPJ_HAVE_POSIX_MEMALIGN)
/* aligned_alloc requires c11, restrict to posix_memalign for now. Quote:
* This function was introduced in POSIX 1003.1d. Although this function is
* superseded by aligned_alloc, it is more portable to older POSIX systems
* that do not support ISO C11. */
if (posix_memalign(&ptr, alignment, size)) {
ptr = NULL;
}
/* older linux */
#elif defined(OPJ_HAVE_MEMALIGN)
ptr = memalign(alignment, size);
/* _MSC_VER */
#elif defined(OPJ_HAVE__ALIGNED_MALLOC)
ptr = _aligned_malloc(size, alignment);
#else
/*
* Generic aligned malloc implementation.
* Uses size_t offset for the integer manipulation of the pointer,
* as uintptr_t is not available in C89 to do
* bitwise operations on the pointer itself.
*/
alignment--;
{
size_t offset;
OPJ_UINT8 *mem;
/* Room for padding and extra pointer stored in front of allocated area */
size_t overhead = alignment + sizeof(void *);
/* let's be extra careful */
assert(alignment <= (SIZE_MAX - sizeof(void *)));
/* Avoid integer overflow */
if (size > (SIZE_MAX - overhead)) {
return NULL;
}
mem = (OPJ_UINT8*)malloc(size + overhead);
if (mem == NULL) {
return mem;
}
/* offset = ((alignment + 1U) - ((size_t)(mem + sizeof(void*)) & alignment)) & alignment; */
/* Use the fact that alignment + 1U is a power of 2 */
offset = ((alignment ^ ((size_t)(mem + sizeof(void*)) & alignment)) + 1U) &
alignment;
ptr = (void *)(mem + sizeof(void*) + offset);
((void**) ptr)[-1] = mem;
}
#endif
return ptr;
}
static INLINE void *opj_aligned_realloc_n(void *ptr, size_t alignment,
size_t new_size)
{
void *r_ptr;
/* alignment shall be power of 2 */
assert((alignment != 0U) && ((alignment & (alignment - 1U)) == 0U));
/* alignment shall be at least sizeof(void*) */
assert(alignment >= sizeof(void*));
if (new_size == 0U) { /* prevent implementation defined behavior of realloc */
return NULL;
}
/* no portable aligned realloc */
#if defined(OPJ_HAVE_POSIX_MEMALIGN) || defined(OPJ_HAVE_MEMALIGN)
/* glibc doc states one can mix aligned malloc with realloc */
r_ptr = realloc(ptr, new_size); /* fast path */
/* we simply use `size_t` to cast, since we are only interest in binary AND
* operator */
if (((size_t)r_ptr & (alignment - 1U)) != 0U) {
/* this is non-trivial to implement a portable aligned realloc, so use a
* simple approach where we do not need a function that return the size of an
* allocated array (eg. _msize on Windows, malloc_size on MacOS,
* malloc_usable_size on systems with glibc) */
void *a_ptr = opj_aligned_alloc_n(alignment, new_size);
if (a_ptr != NULL) {
memcpy(a_ptr, r_ptr, new_size);
}
free(r_ptr);
r_ptr = a_ptr;
}
/* _MSC_VER */
#elif defined(OPJ_HAVE__ALIGNED_MALLOC)
r_ptr = _aligned_realloc(ptr, new_size, alignment);
#else
if (ptr == NULL) {
return opj_aligned_alloc_n(alignment, new_size);
}
alignment--;
{
void *oldmem;
OPJ_UINT8 *newmem;
size_t overhead = alignment + sizeof(void *);
/* let's be extra careful */
assert(alignment <= (SIZE_MAX - sizeof(void *)));
/* Avoid integer overflow */
if (new_size > SIZE_MAX - overhead) {
return NULL;
}
oldmem = ((void**) ptr)[-1];
newmem = (OPJ_UINT8*)realloc(oldmem, new_size + overhead);
if (newmem == NULL) {
return newmem;
}
if (newmem == oldmem) {
r_ptr = ptr;
} else {
size_t old_offset;
size_t new_offset;
/* realloc created a new copy, realign the copied memory block */
old_offset = (size_t)((OPJ_UINT8*)ptr - (OPJ_UINT8*)oldmem);
/* offset = ((alignment + 1U) - ((size_t)(mem + sizeof(void*)) & alignment)) & alignment; */
/* Use the fact that alignment + 1U is a power of 2 */
new_offset = ((alignment ^ ((size_t)(newmem + sizeof(void*)) & alignment)) +
1U) & alignment;
new_offset += sizeof(void*);
r_ptr = (void *)(newmem + new_offset);
if (new_offset != old_offset) {
memmove(newmem + new_offset, newmem + old_offset, new_size);
}
((void**) r_ptr)[-1] = newmem;
}
}
#endif
return r_ptr;
}
void * opj_malloc(size_t size)
{
if (size == 0U) { /* prevent implementation defined behavior of realloc */
return NULL;
}
return malloc(size);
}
void * opj_calloc(size_t num, size_t size)
{
if (num == 0 || size == 0) {
/* prevent implementation defined behavior of realloc */
return NULL;
}
return calloc(num, size);
}
void *opj_aligned_malloc(size_t size)
{
return opj_aligned_alloc_n(16U, size);
}
void * opj_aligned_realloc(void *ptr, size_t size)
{
return opj_aligned_realloc_n(ptr, 16U, size);
}
void *opj_aligned_32_malloc(size_t size)
{
return opj_aligned_alloc_n(32U, size);
}
void * opj_aligned_32_realloc(void *ptr, size_t size)
{
return opj_aligned_realloc_n(ptr, 32U, size);
}
void opj_aligned_free(void* ptr)
{
#if defined(OPJ_HAVE_POSIX_MEMALIGN) || defined(OPJ_HAVE_MEMALIGN)
free(ptr);
#elif defined(OPJ_HAVE__ALIGNED_MALLOC)
_aligned_free(ptr);
#else
/* Generic implementation has malloced pointer stored in front of used area */
if (ptr != NULL) {
free(((void**) ptr)[-1]);
}
#endif
}
void * opj_realloc(void *ptr, size_t new_size)
{
if (new_size == 0U) { /* prevent implementation defined behavior of realloc */
return NULL;
}
return realloc(ptr, new_size);
}
void opj_free(void *ptr)
{
free(ptr);
}

View File

@@ -1,4 +1,9 @@
/*
* The copyright in this software is being made available under the 2-clauses
* BSD License, included below. This software may be subject to other third
* party and contributor rights, including patent rights, and no such rights
* are granted under this license.
*
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* Copyright (c) 2007, Callum Lerwick <seg@haxxed.com>
* All rights reserved.
@@ -24,8 +29,10 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __OPJ_MALLOC_H
#define __OPJ_MALLOC_H
#ifndef OPJ_MALLOC_H
#define OPJ_MALLOC_H
#include <stddef.h>
/**
@file opj_malloc.h
@brief Internal functions
@@ -36,6 +43,17 @@ The functions in opj_malloc.h are internal utilities used for memory management.
/** @defgroup MISC MISC - Miscellaneous internal functions */
/*@{*/
/* FIXME: These should be set with cmake tests, but we're currently not requiring use of cmake */
#ifdef _WIN32
#define OPJ_HAVE__ALIGNED_MALLOC
#else /* Not _WIN32 */
#if defined(__sun)
#define OPJ_HAVE_MEMALIGN
#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
#define OPJ_HAVE_POSIX_MEMALIGN
#endif
#endif
/** @name Exported functions */
/*@{*/
/* ----------------------------------------------------------------------- */
@@ -45,90 +63,32 @@ Allocate an uninitialized memory block
@param size Bytes to allocate
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
*/
#ifdef ALLOC_PERF_OPT
void * OPJ_CALLCONV opj_malloc(size_t size);
#else
#define opj_malloc(size) malloc(size)
#endif
void * opj_malloc(size_t size);
/**
Allocate a memory block with elements initialized to 0
@param num Blocks to allocate
@param size Bytes per block to allocate
@param numOfElements Blocks to allocate
@param sizeOfElements Bytes per block to allocate
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
*/
#ifdef ALLOC_PERF_OPT
void * OPJ_CALLCONV opj_calloc(size_t _NumOfElements, size_t _SizeOfElements);
#else
#define opj_calloc(num, size) calloc(num, size)
#endif
void * opj_calloc(size_t numOfElements, size_t sizeOfElements);
/**
Allocate memory aligned to a 16 byte boundry
Allocate memory aligned to a 16 byte boundary
@param size Bytes to allocate
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
*/
/* FIXME: These should be set with cmake tests, but we're currently not requiring use of cmake */
#ifdef _WIN32
/* Someone should tell the mingw people that their malloc.h ought to provide _mm_malloc() */
#ifdef __GNUC__
#include <mm_malloc.h>
#define HAVE_MM_MALLOC
#else /* MSVC, Intel C++ */
#include <malloc.h>
#ifdef _mm_malloc
#define HAVE_MM_MALLOC
#endif
#endif
#else /* Not _WIN32 */
#if defined(__sun)
#define HAVE_MEMALIGN
#elif defined(__FreeBSD__)
#define HAVE_POSIX_MEMALIGN
/* Linux x86_64 and OSX always align allocations to 16 bytes */
#elif !defined(__amd64__) && !defined(__APPLE__) && !defined(_AIX)
#define HAVE_MEMALIGN
#include <malloc.h>
#endif
#endif
void * opj_aligned_malloc(size_t size);
void * opj_aligned_realloc(void *ptr, size_t size);
void opj_aligned_free(void* ptr);
#define opj_aligned_malloc(size) malloc(size)
#define opj_aligned_free(m) free(m)
#ifdef HAVE_MM_MALLOC
#undef opj_aligned_malloc
#define opj_aligned_malloc(size) _mm_malloc(size, 16)
#undef opj_aligned_free
#define opj_aligned_free(m) _mm_free(m)
#endif
#ifdef HAVE_MEMALIGN
extern void* memalign(size_t, size_t);
#undef opj_aligned_malloc
#define opj_aligned_malloc(size) memalign(16, (size))
#undef opj_aligned_free
#define opj_aligned_free(m) free(m)
#endif
#ifdef HAVE_POSIX_MEMALIGN
#undef opj_aligned_malloc
extern int posix_memalign(void**, size_t, size_t);
static INLINE void* __attribute__ ((malloc)) opj_aligned_malloc(size_t size){
void* mem = NULL;
posix_memalign(&mem, 16, size);
return mem;
}
#undef opj_aligned_free
#define opj_aligned_free(m) free(m)
#endif
#ifdef ALLOC_PERF_OPT
#undef opj_aligned_malloc
#define opj_aligned_malloc(size) opj_malloc(size)
#undef opj_aligned_free
#define opj_aligned_free(m) opj_free(m)
#endif
/**
Allocate memory aligned to a 32 byte boundary
@param size Bytes to allocate
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
*/
void * opj_aligned_32_malloc(size_t size);
void * opj_aligned_32_realloc(void *ptr, size_t size);
/**
Reallocate memory blocks.
@@ -136,23 +96,15 @@ Reallocate memory blocks.
@param s New size in bytes
@return Returns a void pointer to the reallocated (and possibly moved) memory block
*/
#ifdef ALLOC_PERF_OPT
void * OPJ_CALLCONV opj_realloc(void * m, size_t s);
#else
#define opj_realloc(m, s) realloc(m, s)
#endif
void * opj_realloc(void * m, size_t s);
/**
Deallocates or frees a memory block.
@param m Previously allocated memory block to be freed
*/
#ifdef ALLOC_PERF_OPT
void OPJ_CALLCONV opj_free(void * m);
#else
#define opj_free(m) free(m)
#endif
void opj_free(void * m);
#ifdef __GNUC__
#if defined(__GNUC__) && !defined(OPJ_SKIP_POISON)
#pragma GCC poison malloc calloc realloc free
#endif
@@ -161,5 +113,5 @@ void OPJ_CALLCONV opj_free(void * m);
/*@}*/
#endif /* __OPJ_MALLOC_H */
#endif /* OPJ_MALLOC_H */

View File

@@ -0,0 +1,51 @@
/*
* The copyright in this software is being made available under the 2-clauses
* BSD License, included below. This software may be subject to other third
* party and contributor rights, including patent rights, and no such rights
* are granted under this license.
*
* Copyright (c) 2012, Mathieu Malaterre <mathieu.malaterre@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* 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 OPJ_STDINT_H
#define OPJ_STDINT_H
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || _MSC_VER >= 1900
#include <stdint.h>
#else
#if defined(_WIN32)
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#error unsupported platform
#endif
#endif
#endif /* OPJ_STDINT_H */

View File

@@ -1427,7 +1427,7 @@ void t1_encode_cblks(
opj_tcd_resolution_t *res = &tilec->resolutions[resno];
for (bandno = 0; bandno < res->numbands; ++bandno) {
opj_tcd_band_t* restrict band = &res->bands[bandno];
opj_tcd_band_t* OPJ_RESTRICT band = &res->bands[bandno];
int bandconst = 8192 * 8192 / ((int) floor(band->stepsize * 8192));
for (precno = 0; precno < res->pw * res->ph; ++precno) {
@@ -1435,8 +1435,8 @@ void t1_encode_cblks(
for (cblkno = 0; cblkno < prc->cw * prc->ch; ++cblkno) {
opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
int* restrict datap;
int* restrict tiledp;
int* OPJ_RESTRICT datap;
int* OPJ_RESTRICT tiledp;
int cblk_w;
int cblk_h;
int i, j;
@@ -1517,14 +1517,14 @@ void t1_decode_cblks(
opj_tcd_resolution_t* res = &tilec->resolutions[resno];
for (bandno = 0; bandno < res->numbands; ++bandno) {
opj_tcd_band_t* restrict band = &res->bands[bandno];
opj_tcd_band_t* OPJ_RESTRICT band = &res->bands[bandno];
for (precno = 0; precno < res->pw * res->ph; ++precno) {
opj_tcd_precinct_t* precinct = &band->precincts[precno];
for (cblkno = 0; cblkno < precinct->cw * precinct->ch; ++cblkno) {
opj_tcd_cblk_dec_t* cblk = &precinct->cblks.dec[cblkno];
int* restrict datap;
int* OPJ_RESTRICT datap;
int cblk_w, cblk_h;
int x, y;
int i, j;
@@ -1566,7 +1566,7 @@ void t1_decode_cblks(
}
if (tccp->qmfbid == 1) {
int* restrict tiledp = &tilec->data[(y * tile_w) + x];
int* OPJ_RESTRICT tiledp = &tilec->data[(y * tile_w) + x];
for (j = 0; j < cblk_h; ++j) {
for (i = 0; i < cblk_w; ++i) {
int tmp = datap[(j * cblk_w) + i];
@@ -1574,9 +1574,9 @@ void t1_decode_cblks(
}
}
} else { /* if (tccp->qmfbid == 0) */
float* restrict tiledp = (float*) &tilec->data[(y * tile_w) + x];
float* OPJ_RESTRICT tiledp = (float*) &tilec->data[(y * tile_w) + x];
for (j = 0; j < cblk_h; ++j) {
float* restrict tiledp2 = tiledp;
float* OPJ_RESTRICT tiledp2 = tiledp;
for (i = 0; i < cblk_w; ++i) {
float tmp = *datap * band->stepsize;
*tiledp2 = tmp;

View File

@@ -194,7 +194,7 @@ int main(){
printf("/* This file was automatically generated by t1_generate_luts.c */\n\n");
// lut_ctxno_zc
/* lut_ctxno_zc */
for (j = 0; j < 4; ++j) {
for (i = 0; i < 256; ++i) {
int orient = j;
@@ -215,7 +215,7 @@ int main(){
}
printf("%i\n};\n\n", lut_ctxno_zc[1023]);
// lut_ctxno_sc
/* lut_ctxno_sc */
printf("static char lut_ctxno_sc[256] = {\n ");
for (i = 0; i < 255; ++i) {
printf("0x%x, ", t1_init_ctxno_sc(i << 4));
@@ -224,7 +224,7 @@ int main(){
}
printf("0x%x\n};\n\n", t1_init_ctxno_sc(255 << 4));
// lut_spb
/* lut_spb */
printf("static char lut_spb[256] = {\n ");
for (i = 0; i < 255; ++i) {
printf("%i, ", t1_init_spb(i << 4));

View File

@@ -30,6 +30,7 @@
*/
#include "opj_includes.h"
#include <assert.h>
/** @defgroup T2 T2 - Implementation of a tier-2 coding */
/*@{*/
@@ -340,13 +341,15 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
int precno = pi->precno; /* precinct value */
int layno = pi->layno; /* quality layer value */
opj_tcd_resolution_t* res = &tile->comps[compno].resolutions[resno];
unsigned char *hd = NULL;
int present;
opj_bio_t *bio = NULL; /* BIO component */
opj_tcd_resolution_t* res;
assert(&tile->comps[compno] != NULL);
res = &tile->comps[compno].resolutions[resno];
if (layno == 0) {
for (bandno = 0; bandno < res->numbands; bandno++) {
opj_tcd_band_t *band = &res->bands[bandno];

View File

@@ -1507,7 +1507,7 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno
for(j = res->y0; j < res->y1; ++j) {
for(i = res->x0; i < res->x1; ++i) {
float tmp = ((float*)tilec->data)[i - res->x0 + (j - res->y0) * tw];
int v = lrintf(tmp);
int v = opj_lrintf(tmp);
v += adjust;
imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max);
}

View File

@@ -24,11 +24,6 @@
* $/LicenseInfo$
*/
#if LL_MSVC
// disable warning about boost::lexical_cast returning uninitialized data
// when it fails to parse the string
#pragma warning (disable:4701)
#endif
#include "linden_common.h"
@@ -230,7 +225,7 @@ void LLAvatarAppearance::initInstance()
for (U32 lod = 0; lod < mesh_dict->mLOD; lod++)
{
LLAvatarJointMesh* mesh = createAvatarJointMesh();
std::string mesh_name = "m" + mesh_dict->mName + std::to_string(lod);
std::string mesh_name = fmt::format(FMT_STRING("m{:s}{:d}"), mesh_dict->mName, lod);
// We pre-pended an m - need to capitalize first character for camelCase
mesh_name[1] = toupper(mesh_name[1]);
mesh->setName(mesh_name);

View File

@@ -12,7 +12,6 @@ include(Linking)
include(Boost)
include(OpenSSL)
include(LLSharedLibs)
include(Json)
include(Copy3rdPartyLibs)
include(ZLIB)
include(URIPARSER)
@@ -300,6 +299,9 @@ target_link_libraries(
${Boost_SYSTEM_LIBRARY}
${CORESERVICES_LIBRARY}
${URIPARSER_LIBRARY}
fmt::fmt
nlohmann_json::nlohmann_json
absl::strings
${RT_LIBRARY}
)

View File

@@ -353,8 +353,14 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
// NEW Macros for debugging, allow the passing of a string tag
#ifdef SHOW_DEBUG
#define DO_DEBUG_LOG
#else
#define DO_DEBUG_LOG if (false)
#endif
// Pass comma separated list of tags (currently only supports up to 0, 1, or 2)
#define LL_DEBUGS(...) lllog(LLError::LEVEL_DEBUG, false, false, ##__VA_ARGS__)
#define LL_DEBUGS(...) DO_DEBUG_LOG lllog(LLError::LEVEL_DEBUG, false, false, ##__VA_ARGS__)
#define LL_INFOS(...) lllog(LLError::LEVEL_INFO, false, false, ##__VA_ARGS__)
#define LL_WARNS(...) lllog(LLError::LEVEL_WARN, false, false, ##__VA_ARGS__)
#define LL_ERRS(...) lllog(LLError::LEVEL_ERROR, false, false, ##__VA_ARGS__)
@@ -363,12 +369,12 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
// Only print the log message once (good for warnings or infos that would otherwise
// spam the log file over and over, such as tighter loops).
#define LL_DEBUGS_ONCE(...) lllog(LLError::LEVEL_DEBUG, true, false, ##__VA_ARGS__)
#define LL_DEBUGS_ONCE(...) DO_DEBUG_LOG lllog(LLError::LEVEL_DEBUG, true, false, ##__VA_ARGS__)
#define LL_INFOS_ONCE(...) lllog(LLError::LEVEL_INFO, true, false, ##__VA_ARGS__)
#define LL_WARNS_ONCE(...) lllog(LLError::LEVEL_WARN, true, false, ##__VA_ARGS__)
// No function name
#define LL_DEBUGS_NF(...) lllog(LLError::LEVEL_DEBUG, false, true, ##__VA_ARGS__)
#define LL_DEBUGS_NF(...) DO_DEBUG_LOG {lllog(LLError::LEVEL_DEBUG, false, true, ##__VA_ARGS__)
#define LL_INFOS_NF(...) lllog(LLError::LEVEL_INFO, false, true, ##__VA_ARGS__)
#define LL_WARNS_NF(...) lllog(LLError::LEVEL_WARN, false, true, ##__VA_ARGS__)
#define LL_ERRS_NF(...) lllog(LLError::LEVEL_ERROR, false, true, ##__VA_ARGS__)

View File

@@ -34,6 +34,16 @@
#ifndef LL_LLFORMAT_H
#define LL_LLFORMAT_H
#if defined(LL_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
#include <fmt/format.h>
#include <fmt/printf.h>
#if defined(LL_CLANG)
#pragma clang diagnostic pop
#endif
// Use as follows:
// LL_INFOS() << llformat("Test:%d (%.2f %.2f)", idx, x, y) << LL_ENDL;
//

View File

@@ -1072,8 +1072,8 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
// the size, and read it.
U32 size_nbo = 0;
read(istr, (char*)&size_nbo, sizeof(U32)); /*Flawfinder: ignore*/
S32 size = (S32)ntohl(size_nbo);
if(mCheckLimits && (size > mMaxBytesLeft))
S32 size = (S32)ntohl(size_nbo); // Can return negative size if > 2^31.
if(size < 0 || mCheckLimits && (size > mMaxBytesLeft))
{
parse_count = PARSE_FAILURE;
}
@@ -1113,7 +1113,11 @@ S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map) const
map = LLSD::emptyMap();
U32 value_nbo = 0;
read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/
S32 size = (S32)ntohl(value_nbo);
S32 size = (S32)ntohl(value_nbo); // Can return negative size if > 2^31.
if (size < 0)
{
return PARSE_FAILURE;
}
S32 parse_count = 0;
S32 count = 0;
char c = get(istr);
@@ -1167,7 +1171,11 @@ S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array) const
array = LLSD::emptyArray();
U32 value_nbo = 0;
read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/
S32 size = (S32)ntohl(value_nbo);
S32 size = (S32)ntohl(value_nbo); // Can return negative size if > 2^31.
if (size < 0)
{
return PARSE_FAILURE;
}
// *FIX: This would be a good place to reserve some space in the
// array...
@@ -1208,8 +1216,8 @@ bool LLSDBinaryParser::parseString(
// *FIX: This is memory inefficient.
U32 value_nbo = 0;
read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/
S32 size = (S32)ntohl(value_nbo);
if(mCheckLimits && (size > mMaxBytesLeft)) return false;
S32 size = (S32)ntohl(value_nbo); // Can return negative size if > 2^31.
if(size < 0 || mCheckLimits && (size > mMaxBytesLeft)) return false;
std::vector<char> buf;
if(size)
{

View File

@@ -1354,8 +1354,7 @@ void LLStringUtil::formatNumber(std::string& numStr, std::string decimals)
if (convertToS32(numStr, intStr))
{
strStream << intStr;
numStr = strStream.str();
numStr = fmt::to_string(intStr);
}
}
else
@@ -1435,14 +1434,14 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,
{
struct tm * gmt = gmtime (&loc_seconds);
LLStringUtil::format_map_t args;
args["[MDAY]"] = llformat ("%d", gmt->tm_mday);
args["[MDAY]"] = fmt::to_string(gmt->tm_mday);
replacement = LLStringOps::sDayFormat;
LLStringUtil::format(replacement, args);
}
else if (code == "%-d")
{
struct tm * gmt = gmtime (&loc_seconds);
replacement = llformat ("%d", gmt->tm_mday); // day of the month without leading zero
replacement = fmt::to_string(gmt->tm_mday); // day of the month without leading zero
}
else if( !LLStringOps::sAM.empty() && !LLStringOps::sPM.empty() && code == "%p" )
{

View File

@@ -29,6 +29,16 @@
#include <boost/optional/optional.hpp>
#include <string>
#if __cplusplus < 201606
#include <absl/strings/string_view.h>
namespace std {
typedef absl::string_view string_view;
}
#else
#include <string_view>
#endif
#include <cstdio>
//#include <locale>
#include <iomanip>

View File

@@ -126,9 +126,12 @@ public:
// Returns true if this rotation is orthonormal with det ~= 1
inline bool isOkRotation() const;
} LL_ALIGN_POSTFIX(16);
#if !defined(LL_DEBUG)
static_assert(std::is_trivial<LLMatrix3a>::value, "LLMatrix3a must be a trivial type");
static_assert(std::is_standard_layout<LLMatrix3a>::value, "LLMatrix3a must be a standard layout type");
static_assert(std::is_trivial<LLRotation>::value, "LLRotation must be a trivial type");
static_assert(std::is_standard_layout<LLRotation>::value, "LLRotation must be a standard layout type");
#endif
#endif

View File

@@ -718,6 +718,8 @@ inline std::ostream& operator<<(std::ostream& s, const LLMatrix4a& m)
void matMulBoundBox(const LLMatrix4a &a, const LLVector4a *in_extents, LLVector4a *out_extents);
#if !defined(LL_DEBUG)
static_assert(std::is_trivial<LLMatrix4a>::value, "LLMatrix4a must be a trivial type");
static_assert(std::is_standard_layout<LLMatrix4a>::value, "LLMatrix4a must be a standard layout type");
#endif
#endif

View File

@@ -45,6 +45,7 @@
#endif
extern U32 gOctreeMaxCapacity;
extern float gOctreeMinSize;
extern U32 gOctreeReserveCapacity;
#if LL_DEBUG
#define LL_OCTREE_PARANOIA_CHECK 0
@@ -404,7 +405,7 @@ public:
F32 size = mSize[0];
F32 p_size = size * 2.f;
return (radius <= 0.001f && size <= 0.001f) ||
return (radius <= gOctreeMinSize && size <= gOctreeMinSize) ||
(radius <= p_size && radius > size);
}
@@ -511,7 +512,7 @@ public:
//is it here?
if (isInside(data->getPositionGroup()))
{
if (((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius())) ||
if ((((getElementCount() < gOctreeMaxCapacity || getSize()[0] <= gOctreeMinSize) && contains(data->getBinRadius())) ||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
{ //it belongs here
/*mElementCount++;
@@ -566,8 +567,9 @@ public:
LLVector4a val;
val.setSub(center, getCenter());
val.setAbs(val);
S32 lt = val.lessThan(LLVector4a::getEpsilon()).getGatheredBits() & 0x7;
LLVector4a min_diff(gOctreeMinSize);
S32 lt = val.lessThan(min_diff).getGatheredBits() & 0x7;
if( lt == 0x7 )
{
@@ -616,6 +618,7 @@ public:
}
#endif
llassert(size[0] >= gOctreeMinSize*0.5f);
//make the new kid
child = new LLOctreeNode<T>(center, size, this);
addChild(child);
@@ -623,10 +626,7 @@ public:
child->insert(data);
}
}
// Singu note: now that we allow wider range in octree, discard them here
// if they fall out of range
#if 0
else
else if (parent)
{
//it's not in here, give it to the root
OCT_ERRS << "Octree insertion failed, starting over from root!" << LL_ENDL;
@@ -639,12 +639,15 @@ public:
parent = node->getOctParent();
}
if(node != this)
{
node->insert(data);
}
node->insert(data);
}
else
{
// It's not in here, and we are root.
// LLOctreeRoot::insert() should have expanded
// root by now, something is wrong
OCT_ERRS << "Octree insertion failed! Root expansion failed." << LL_ENDL;
}
#endif
return false;
}
@@ -1050,10 +1053,15 @@ public:
{
LLOctreeNode<T>::insert(data);
}
else
else if (node->isInside(data->getPositionGroup()))
{
node->insert(data);
}
else
{
// calling node->insert(data) will return us to root
OCT_ERRS << "Failed to insert data at child node" << LL_ENDL;
}
}
else if (this->getChildCount() == 0)
{
@@ -1088,6 +1096,8 @@ public:
this->setSize(size2);
this->updateMinMax();
llassert(size[0] >= gOctreeMinSize);
//copy our children to a new branch
LLOctreeNode<T>* newnode = new LLOctreeNode<T>(center, size, this);

View File

@@ -104,7 +104,8 @@ private:
LL_ALIGN_16(LLVector4a mV);
} LL_ALIGN_POSTFIX(16);
#if !defined(LL_DEBUG)
static_assert(std::is_trivial<LLPlane>::value, "LLPlane must be a trivial type");
static_assert(std::is_standard_layout<LLPlane>::value, "LLPlane must be a standard layout type");
#endif
#endif // LL_LLPLANE_H

View File

@@ -105,7 +105,9 @@ protected:
} LL_ALIGN_POSTFIX(16);
#if !defined(LL_DEBUG)
static_assert(std::is_trivial<LLQuaternion2>::value, "LLQuaternion2 must be a trivial type");
static_assert(std::is_standard_layout<LLQuaternion2>::value, "LLQuaternion2 must be a standard layout type");
#endif
#endif

View File

@@ -350,6 +350,8 @@ inline std::ostream& operator<<(std::ostream& s, const LLVector4a& v)
return s;
}
#if !defined(LL_DEBUG)
static_assert(std::is_trivial<LLVector4a>::value, "LLVector4a must be a be a trivial type");
static_assert(std::is_standard_layout<LLVector4a>::value, "LLVector4a must be a standard layout type");
#endif
#endif

View File

@@ -64,7 +64,6 @@ set(llmessage_SOURCE_FILES
llmessagetemplate.cpp
llmessagetemplateparser.cpp
llmessagethrottle.cpp
llmime.cpp
llnamevalue.cpp
llnullcipher.cpp
llpacketack.cpp
@@ -163,7 +162,6 @@ set(llmessage_HEADER_FILES
llmessagetemplate.h
llmessagetemplateparser.h
llmessagethrottle.h
llmime.h
llmsgvariabletype.h
llnamevalue.h
llnullcipher.h
@@ -241,7 +239,6 @@ if (LL_TESTS)
include(Tut)
SET(llmessage_TEST_SOURCE_FILES
llmime.cpp
llnamevalue.cpp
lltrustedmessageservice.cpp
lltemplatemessagedispatcher.cpp

View File

@@ -960,4 +960,5 @@ P(webProfileResponders);
P(wholeModelFeeResponder);
P(wholeModelUploadResponder);
P2(XMLRPCResponder, connect_40s);
P(getUpdateInfoResponder);
P(getUpdateInfoResponder);
P2(AISAPIResponder, connect_60s);

View File

@@ -262,6 +262,8 @@ LLCacheName::~LLCacheName()
delete &impl;
}
const ReverseCache& LLCacheName::getReverseMap() const { return impl.mReverseCache; }
LLCacheName::Impl::Impl(LLMessageSystem* msg)
: mMsg(msg), mUpstreamHost(LLHost::invalid)
{

View File

@@ -57,6 +57,8 @@ public:
LLCacheName(LLMessageSystem* msg, const LLHost& upstream_host);
~LLCacheName();
const std::map<std::string, LLUUID>& getReverseMap() const;
// registers the upstream host
// for viewers, this is the currently connected simulator
// for simulators, this is the data server

View File

@@ -58,103 +58,6 @@ const std::string SYSTEM_FROM("Second Life");
const std::string INTERACTIVE_SYSTEM_FROM("F387446C-37C4-45f2-A438-D99CBDBB563B");
const S32 IM_TTL = 1;
/**
* LLIMInfo
*/
LLIMInfo::LLIMInfo() :
mFromGroup(FALSE),
mParentEstateID(0),
mOffline(0),
mViewerThinksToIsOnline(false),
mIMType(IM_NOTHING_SPECIAL),
mTimeStamp(0),
mSource(IM_FROM_SIM),
mTTL(IM_TTL)
{
}
LLIMInfo::LLIMInfo(
const LLUUID& from_id,
BOOL from_group,
const LLUUID& to_id,
EInstantMessage im_type,
const std::string& name,
const std::string& message,
const LLUUID& id,
U32 parent_estate_id,
const LLUUID& region_id,
const LLVector3& position,
LLSD data,
U8 offline,
U32 timestamp,
EIMSource source,
S32 ttl) :
mFromID(from_id),
mFromGroup(from_group),
mToID(to_id),
mParentEstateID(0),
mRegionID(region_id),
mPosition(position),
mOffline(offline),
mViewerThinksToIsOnline(false),
mIMType(im_type),
mID(id),
mTimeStamp(timestamp),
mName(name),
mMessage(message),
mData(data),
mSource(source),
mTTL(ttl)
{
}
LLIMInfo::LLIMInfo(LLMessageSystem* msg, EIMSource source, S32 ttl) :
mViewerThinksToIsOnline(false),
mSource(source),
mTTL(ttl)
{
unpackMessageBlock(msg);
}
LLIMInfo::~LLIMInfo()
{
}
void LLIMInfo::packInstantMessage(LLMessageSystem* msg) const
{
LL_DEBUGS() << "LLIMInfo::packInstantMessage()" << LL_ENDL;
msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
packMessageBlock(msg);
}
void LLIMInfo::packMessageBlock(LLMessageSystem* msg) const
{
// Construct binary bucket
std::vector<U8> bucket;
if (mData.has("binary_bucket"))
{
bucket = mData["binary_bucket"].asBinary();
}
pack_instant_message_block(
msg,
mFromID,
mFromGroup,
LLUUID::null,
mToID,
mName,
mMessage,
mOffline,
mIMType,
mID,
mParentEstateID,
mRegionID,
mPosition,
mTimeStamp,
&bucket[0],
bucket.size());
}
void pack_instant_message(
LLMessageSystem* msg,
const LLUUID& from_id,
@@ -264,124 +167,3 @@ void pack_instant_message_block(
}
msg->addBinaryDataFast(_PREHASH_BinaryBucket, bb, binary_bucket_size);
}
void LLIMInfo::unpackMessageBlock(LLMessageSystem* msg)
{
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, mFromID);
msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, mFromGroup);
msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, mToID);
msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, mParentEstateID);
msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, mRegionID);
msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, mPosition);
msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Offline, mOffline);
U8 dialog;
msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Dialog, dialog);
mIMType = (EInstantMessage) dialog;
msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, mID);
msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_Timestamp, mTimeStamp);
msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, mName);
msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, mMessage);
S32 binary_bucket_size = llmin(
MTUBYTES,
msg->getSizeFast(
_PREHASH_MessageBlock,
_PREHASH_BinaryBucket));
if(binary_bucket_size > 0)
{
std::vector<U8> bucket;
bucket.resize(binary_bucket_size);
msg->getBinaryDataFast(
_PREHASH_MessageBlock,
_PREHASH_BinaryBucket,
&bucket[0],
0,
0,
binary_bucket_size);
mData["binary_bucket"] = bucket;
}
else
{
mData.clear();
}
}
LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info)
{
LLSD param_version;
param_version["version"] = 1;
LLSD param_message;
param_message["from_id"] = im_info->mFromID;
param_message["from_group"] = im_info->mFromGroup;
param_message["to_id"] = im_info->mToID;
param_message["from_name"] = im_info->mName;
param_message["message"] = im_info->mMessage;
param_message["type"] = (S32)im_info->mIMType;
param_message["id"] = im_info->mID;
param_message["timestamp"] = (S32)im_info->mTimeStamp;
param_message["offline"] = (S32)im_info->mOffline;
param_message["parent_estate_id"] = (S32)im_info->mParentEstateID;
param_message["region_id"] = im_info->mRegionID;
param_message["position"] = ll_sd_from_vector3(im_info->mPosition);
param_message["data"] = im_info->mData;
param_message["source"]= im_info->mSource;
param_message["ttl"] = im_info->mTTL;
LLSD param_agent;
param_agent["agent_id"] = im_info->mFromID;
LLSD params;
params["version_params"] = param_version;
params["message_params"] = param_message;
params["agent_params"] = param_agent;
return params;
}
LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd)
{
LLSD param_message = im_info_sd["message_params"];
LLSD param_agent = im_info_sd["agent_params"];
LLPointer<LLIMInfo> im_info = new LLIMInfo(
param_message["from_id"].asUUID(),
param_message["from_group"].asBoolean(),
param_message["to_id"].asUUID(),
(EInstantMessage) param_message["type"].asInteger(),
param_message["from_name"].asString(),
param_message["message"].asString(),
param_message["id"].asUUID(),
(U32) param_message["parent_estate_id"].asInteger(),
param_message["region_id"].asUUID(),
ll_vector3_from_sd(param_message["position"]),
param_message["data"],
(U8) param_message["offline"].asInteger(),
(U32) param_message["timestamp"].asInteger(),
(EIMSource)param_message["source"].asInteger(),
param_message["ttl"].asInteger());
return im_info;
}
LLPointer<LLIMInfo> LLIMInfo::clone()
{
return new LLIMInfo(
mFromID,
mFromGroup,
mToID,
mIMType,
mName,
mMessage,
mID,
mParentEstateID,
mRegionID,
mPosition,
mData,
mOffline,
mTimeStamp,
mSource,
mTTL);
}

View File

@@ -225,62 +225,6 @@ extern const std::string INTERACTIVE_SYSTEM_FROM;
// Number of retry attempts on sending the im.
extern const S32 IM_TTL;
class LLIMInfo : public LLRefCount
{
protected:
LLIMInfo();
~LLIMInfo();
public:
LLIMInfo(LLMessageSystem* msg,
EIMSource source = IM_FROM_SIM,
S32 ttl = IM_TTL);
LLIMInfo(
const LLUUID& from_id,
BOOL from_group,
const LLUUID& to_id,
EInstantMessage im_type,
const std::string& name,
const std::string& message,
const LLUUID& id,
U32 parent_estate_id,
const LLUUID& region_id,
const LLVector3& position,
LLSD data,
U8 offline,
U32 timestamp,
EIMSource source,
S32 ttl = IM_TTL);
void packInstantMessage(LLMessageSystem* msg) const;
void packMessageBlock(LLMessageSystem* msg) const;
void unpackMessageBlock(LLMessageSystem* msg);
LLPointer<LLIMInfo> clone();
public:
LLUUID mFromID;
BOOL mFromGroup;
LLUUID mToID;
U32 mParentEstateID;
LLUUID mRegionID;
LLVector3 mPosition;
U8 mOffline;
bool mViewerThinksToIsOnline;
EInstantMessage mIMType;
LLUUID mID;
U32 mTimeStamp;
std::string mName;
std::string mMessage;
LLSD mData;
EIMSource mSource;
S32 mTTL;
};
LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd);
LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info);
void pack_instant_message(
LLMessageSystem* msgsystem,
const LLUUID& from_id,

View File

@@ -1,629 +0,0 @@
/**
* @file llmime.cpp
* @author Phoenix
* @date 2006-12-20
* @brief Implementation of mime tools.
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llmime.h"
#include <vector>
#include "llmemorystream.h"
/**
* Useful constants.
*/
// Headers specified in rfc-2045 will be canonicalized below.
static const std::string CONTENT_LENGTH("Content-Length");
static const std::string CONTENT_TYPE("Content-Type");
static const S32 KNOWN_HEADER_COUNT = 6;
static const std::string KNOWN_HEADER[KNOWN_HEADER_COUNT] =
{
CONTENT_LENGTH,
CONTENT_TYPE,
std::string("MIME-Version"),
std::string("Content-Transfer-Encoding"),
std::string("Content-ID"),
std::string("Content-Description"),
};
// parser helpers
static const std::string MULTIPART("multipart");
static const std::string BOUNDARY("boundary");
static const std::string END_OF_CONTENT_PARAMETER("\r\n ;\t");
static const std::string SEPARATOR_PREFIX("--");
//static const std::string SEPARATOR_SUFFIX("\r\n");
/*
Content-Type: multipart/mixed; boundary="segment"
Content-Length: 24832
--segment
Content-Type: image/j2c
Content-Length: 23715
<data>
--segment
Content-Type: text/xml; charset=UTF-8
<meta data>
EOF
*/
/**
* LLMimeIndex
*/
/**
* @class LLMimeIndex::Impl
* @brief Implementation details of the mime index class.
* @see LLMimeIndex
*/
class LLMimeIndex::Impl
{
public:
Impl() : mOffset(-1), mUseCount(1)
{}
Impl(LLSD headers, S32 offset) :
mHeaders(headers), mOffset(offset), mUseCount(1)
{}
public:
LLSD mHeaders;
S32 mOffset;
S32 mUseCount;
typedef std::vector<LLMimeIndex> sub_part_t;
sub_part_t mAttachments;
};
LLSD LLMimeIndex::headers() const
{
return mImpl->mHeaders;
}
S32 LLMimeIndex::offset() const
{
return mImpl->mOffset;
}
S32 LLMimeIndex::contentLength() const
{
// Find the content length in the headers.
S32 length = -1;
LLSD content_length = mImpl->mHeaders[CONTENT_LENGTH];
if(content_length.isDefined())
{
length = content_length.asInteger();
}
return length;
}
std::string LLMimeIndex::contentType() const
{
std::string type;
LLSD content_type = mImpl->mHeaders[CONTENT_TYPE];
if(content_type.isDefined())
{
type = content_type.asString();
}
return type;
}
bool LLMimeIndex::isMultipart() const
{
bool multipart = false;
LLSD content_type = mImpl->mHeaders[CONTENT_TYPE];
if(content_type.isDefined())
{
std::string type = content_type.asString();
int comp = type.compare(0, MULTIPART.size(), MULTIPART);
if(0 == comp)
{
multipart = true;
}
}
return multipart;
}
S32 LLMimeIndex::subPartCount() const
{
return mImpl->mAttachments.size();
}
LLMimeIndex LLMimeIndex::subPart(S32 index) const
{
LLMimeIndex part;
if((index >= 0) && (index < (S32)mImpl->mAttachments.size()))
{
part = mImpl->mAttachments[index];
}
return part;
}
LLMimeIndex::LLMimeIndex() : mImpl(new LLMimeIndex::Impl)
{
}
LLMimeIndex::LLMimeIndex(LLSD headers, S32 content_offset) :
mImpl(new LLMimeIndex::Impl(headers, content_offset))
{
}
LLMimeIndex::LLMimeIndex(const LLMimeIndex& mime) :
mImpl(mime.mImpl)
{
++mImpl->mUseCount;
}
LLMimeIndex::~LLMimeIndex()
{
if(0 == --mImpl->mUseCount)
{
delete mImpl;
}
}
LLMimeIndex& LLMimeIndex::operator=(const LLMimeIndex& mime)
{
// Increment use count first so that we handle self assignment
// automatically.
++mime.mImpl->mUseCount;
if(0 == --mImpl->mUseCount)
{
delete mImpl;
}
mImpl = mime.mImpl;
return *this;
}
bool LLMimeIndex::attachSubPart(LLMimeIndex sub_part)
{
// *FIX: Should we check for multi-part?
if(mImpl->mAttachments.size() < S32_MAX)
{
mImpl->mAttachments.push_back(sub_part);
return true;
}
return false;
}
/**
* LLMimeParser
*/
/**
* @class LLMimeParser::Impl
* @brief Implementation details of the mime parser class.
* @see LLMimeParser
*/
class LLMimeParser::Impl
{
public:
// @brief Constructor.
Impl();
// @brief Reset this for a new parse.
void reset();
/**
* @brief Parse a mime entity to find the index information.
*
* This method will scan the istr until a single complete mime
* entity is read, an EOF, or limit bytes have been scanned. The
* istr will be modified by this parsing, so pass in a temporary
* stream or rewind/reset the stream after this call.
* @param istr An istream which contains a mime entity.
* @param limit The maximum number of bytes to scan.
* @param separator The multipart separator if it is known.
* @param is_subpart Set true if parsing a multipart sub part.
* @param index[out] The parsed output.
* @return Returns true if an index was parsed and no errors occurred.
*/
bool parseIndex(
std::istream& istr,
S32 limit,
const std::string& separator,
bool is_subpart,
LLMimeIndex& index);
protected:
/**
* @brief parse the headers.
*
* At the end of a successful parse, mScanCount will be at the
* start of the content.
* @param istr The input stream.
* @param limit maximum number of bytes to process
* @param headers[out] A map of the headers found.
* @return Returns true if the parse was successful.
*/
bool parseHeaders(std::istream& istr, S32 limit, LLSD& headers);
/**
* @brief Figure out the separator string from a content type header.
*
* @param multipart_content_type The content type value from the headers.
* @return Returns the separator string.
*/
std::string findSeparator(std::string multipart_content_type);
/**
* @brief Scan through istr past the separator.
*
* @param istr The input stream.
* @param limit Maximum number of bytes to scan.
* @param separator The multipart separator.
*/
void scanPastSeparator(
std::istream& istr,
S32 limit,
const std::string& separator);
/**
* @brief Scan through istr past the content of the current mime part.
*
* @param istr The input stream.
* @param limit Maximum number of bytes to scan.
* @param headers The headers for this mime part.
* @param separator The multipart separator if known.
*/
void scanPastContent(
std::istream& istr,
S32 limit,
LLSD headers,
const std::string separator);
/**
* @brief Eat CRLF.
*
* This method has no concept of the limit, so ensure you have at
* least 2 characters left to eat before hitting the limit. This
* method will increment mScanCount as it goes.
* @param istr The input stream.
* @return Returns true if CRLF was found and consumed off of istr.
*/
bool eatCRLF(std::istream& istr);
// @brief Returns true if parsing should continue.
bool continueParse() const { return (!mError && mContinue); }
// @brief anonymous enumeration for parse buffer size.
enum
{
LINE_BUFFER_LENGTH = 1024
};
protected:
S32 mScanCount;
bool mContinue;
bool mError;
char mBuffer[LINE_BUFFER_LENGTH];
};
LLMimeParser::Impl::Impl()
{
reset();
}
void LLMimeParser::Impl::reset()
{
mScanCount = 0;
mContinue = true;
mError = false;
mBuffer[0] = '\0';
}
bool LLMimeParser::Impl::parseIndex(
std::istream& istr,
S32 limit,
const std::string& separator,
bool is_subpart,
LLMimeIndex& index)
{
LLSD headers;
bool parsed_something = false;
if(parseHeaders(istr, limit, headers))
{
parsed_something = true;
LLMimeIndex mime(headers, mScanCount);
index = mime;
if(index.isMultipart())
{
// Figure out the separator, scan past it, and recurse.
std::string ct = headers[CONTENT_TYPE].asString();
std::string sep = findSeparator(ct);
scanPastSeparator(istr, limit, sep);
while(continueParse() && parseIndex(istr, limit, sep, true, mime))
{
index.attachSubPart(mime);
}
}
else
{
// Scan to the end of content.
scanPastContent(istr, limit, headers, separator);
if(is_subpart)
{
scanPastSeparator(istr, limit, separator);
}
}
}
if(mError) return false;
return parsed_something;
}
bool LLMimeParser::Impl::parseHeaders(
std::istream& istr,
S32 limit,
LLSD& headers)
{
while(continueParse())
{
// Get the next line.
// We subtract 1 from the limit so that we make sure
// not to read past limit when we get() the newline.
S32 max_get = llmin((S32)LINE_BUFFER_LENGTH, limit - mScanCount - 1);
istr.getline(mBuffer, max_get, '\r');
mScanCount += (S32)istr.gcount();
int c = istr.get();
if(EOF == c)
{
mContinue = false;
return false;
}
++mScanCount;
if(c != '\n')
{
mError = true;
return false;
}
if(mScanCount >= limit)
{
mContinue = false;
}
// Check if that's the end of headers.
if('\0' == mBuffer[0])
{
break;
}
// Split out the name and value.
// *NOTE: The use of strchr() here is safe since mBuffer is
// guaranteed to be NULL terminated from the call to getline()
// above.
char* colon = strchr(mBuffer, ':');
if(!colon)
{
mError = true;
return false;
}
// Cononicalize the name part, and store the name: value in
// the headers structure. We do this by iterating through
// 'known' headers and replacing the value found with the
// correct one.
// *NOTE: Not so efficient, but iterating through a small
// subset should not be too much of an issue.
std::string name(mBuffer, colon++ - mBuffer);
while(isspace(*colon)) ++colon;
std::string value(colon);
for(S32 ii = 0; ii < KNOWN_HEADER_COUNT; ++ii)
{
if(0 == LLStringUtil::compareInsensitive(name, KNOWN_HEADER[ii]))
{
name = KNOWN_HEADER[ii];
break;
}
}
headers[name] = value;
}
if(headers.isUndefined()) return false;
return true;
}
std::string LLMimeParser::Impl::findSeparator(std::string header)
{
// 01234567890
//Content-Type: multipart/mixed; boundary="segment"
std::string separator;
std::string::size_type pos = header.find(BOUNDARY);
if(std::string::npos == pos) return separator;
pos += BOUNDARY.size() + 1;
std::string::size_type end;
if(header[pos] == '"')
{
// the boundary is quoted, find the end from pos, and take the
// substring.
end = header.find('"', ++pos);
if(std::string::npos == end)
{
// poorly formed boundary.
mError = true;
}
}
else
{
// otherwise, it's every character until a whitespace, end of
// line, or another parameter begins.
end = header.find_first_of(END_OF_CONTENT_PARAMETER, pos);
if(std::string::npos == end)
{
// it goes to the end of the string.
end = header.size();
}
}
if(!mError) separator = header.substr(pos, end - pos);
return separator;
}
void LLMimeParser::Impl::scanPastSeparator(
std::istream& istr,
S32 limit,
const std::string& sep)
{
std::ostringstream ostr;
ostr << SEPARATOR_PREFIX << sep;
std::string separator = ostr.str();
bool found_separator = false;
while(!found_separator && continueParse())
{
// Subtract 1 from the limit so that we make sure not to read
// past limit when we get() the newline.
S32 max_get = llmin((S32)LINE_BUFFER_LENGTH, limit - mScanCount - 1);
istr.getline(mBuffer, max_get, '\r');
mScanCount += (S32)istr.gcount();
if(istr.gcount() >= LINE_BUFFER_LENGTH - 1)
{
// that's way too long to be a separator, so ignore it.
continue;
}
int c = istr.get();
if(EOF == c)
{
mContinue = false;
return;
}
++mScanCount;
if(c != '\n')
{
mError = true;
return;
}
if(mScanCount >= limit)
{
mContinue = false;
}
if(0 == LLStringUtil::compareStrings(std::string(mBuffer), separator))
{
found_separator = true;
}
}
}
void LLMimeParser::Impl::scanPastContent(
std::istream& istr,
S32 limit,
LLSD headers,
const std::string separator)
{
if(headers.has(CONTENT_LENGTH))
{
S32 content_length = headers[CONTENT_LENGTH].asInteger();
// Subtract 2 here for the \r\n after the content.
S32 max_skip = llmin(content_length, limit - mScanCount - 2);
istr.ignore(max_skip);
mScanCount += max_skip;
// *NOTE: Check for hitting the limit and eof here before
// checking for the trailing EOF, because our mime parser has
// to gracefully handle incomplete mime entites.
if((mScanCount >= limit) || istr.eof())
{
mContinue = false;
}
else if(!eatCRLF(istr))
{
mError = true;
return;
}
}
}
bool LLMimeParser::Impl::eatCRLF(std::istream& istr)
{
int c = istr.get();
++mScanCount;
if(c != '\r')
{
return false;
}
c = istr.get();
++mScanCount;
if(c != '\n')
{
return false;
}
return true;
}
LLMimeParser::LLMimeParser() : mImpl(* new LLMimeParser::Impl)
{
}
LLMimeParser::~LLMimeParser()
{
delete & mImpl;
}
void LLMimeParser::reset()
{
mImpl.reset();
}
bool LLMimeParser::parseIndex(std::istream& istr, LLMimeIndex& index)
{
std::string separator;
return mImpl.parseIndex(istr, S32_MAX, separator, false, index);
}
bool LLMimeParser::parseIndex(
const std::vector<U8>& buffer,
LLMimeIndex& index)
{
LLMemoryStream mstr(&buffer[0], buffer.size());
return parseIndex(mstr, buffer.size() + 1, index);
}
bool LLMimeParser::parseIndex(
std::istream& istr,
S32 limit,
LLMimeIndex& index)
{
std::string separator;
return mImpl.parseIndex(istr, limit, separator, false, index);
}
bool LLMimeParser::parseIndex(const U8* buffer, S32 length, LLMimeIndex& index)
{
LLMemoryStream mstr(buffer, length);
return parseIndex(mstr, length + 1, index);
}
/*
bool LLMimeParser::verify(std::istream& isr, LLMimeIndex& index) const
{
return false;
}
bool LLMimeParser::verify(U8* buffer, S32 length, LLMimeIndex& index) const
{
LLMemoryStream mstr(buffer, length);
return verify(mstr, index);
}
*/

View File

@@ -1,292 +0,0 @@
/**
* @file llmime.h
* @author Phoenix
* @date 2006-12-20
* @brief Declaration of mime tools.
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLMIME_H
#define LL_LLMIME_H
#include <string>
#include "llsd.h"
/**
* This file declares various tools for parsing and creating MIME
* objects as described in RFCs 2045, 2046, 2047, 2048, and 2049.
*/
/**
* @class LLMimeIndex
* @brief Skeletal information useful for handling mime packages.
* @see LLMimeParser
*
* An instance of this class is the parsed output from a LLMimeParser
* which then allows for easy access into a data stream to find and
* get what you want out of it.
*
* This class meant as a tool to quickly find what you seek in a
* parsed mime entity. As such, it does not have useful support for
* modification of a mime entity and specializes the interface toward
* querying data from a fixed mime entity. Modifying an instance of
* LLMimeIndx does not alter a mime entity and changes to a mime
* entity itself are not propogated into an instance of a LLMimeIndex.
*
* Usage:<br>
* LLMimeIndex mime_index;<br>
* std::ifstream fstr("package.mime", ios::binary);<br>
* LLMimeParser parser;<br>
* if(parser.parseIndex(fstr, mime_index))<br>
* {<br>
* std::vector<U8> content;<br>
* content.resize(mime_index.contentLength());<br>
* fstr.seekg(mime_index.offset(), ios::beg);<br>
* // ...do work on fstr and content<br>
* }<br>
*/
class LLMimeIndex
{
public:
/* @name Client interface.
*/
//@{
/**
* @brief Get the full parsed headers for this.
*
* If there are any headers, it will be a map of header name to
* the value found on the line. The name is everything before the
* colon, and the value is the string found after the colon to the
* end of the line after trimming leading whitespace. So, for
* example:
* Content-Type: text/plain
* would become an entry in the headers of:
* headers["Content-Type"] == "text/plain"
*
* If this instance of an index was generated by the
* LLMimeParser::parseIndex() call, all header names in rfc2045
* will be capitalized as in rfc, eg Content-Length and
* MIME-Version, not content-length and mime-version.
* @return Returns an LLSD map of header name to value. Returns
* undef if there are no headers.
*/
LLSD headers() const;
/**
* @brief Get the content offset.
*
* @return Returns the number of bytes to the start of the data
* segment from the start of serialized mime entity. Returns -1 if
* offset is not known.
*/
S32 offset() const;
/**
* @brief Get the length of the data segment for this mime part.
*
* @return Returns the content length in bytes. Returns -1 if
* length is not known.
*/
S32 contentLength() const;
/**
* @brief Get the mime type associated with this node.
*
* @return Returns the mimetype.
*/
std::string contentType() const;
/**
* @brief Helper method which simplifies parsing the return from type()
*
* @return Returns true if this is a multipart mime, and therefore
* getting subparts will succeed.
*/
bool isMultipart() const;
/**
* @brief Get the number of atachments.
*
* @return Returns the number of sub-parts for this.
*/
S32 subPartCount() const;
/**
* @brief Get the indicated attachment.
*
* @param index Value from 0 to (subPartCount() - 1).
* @return Returns the indicated sub-part, or an invalid mime
* index on failure.
*/
LLMimeIndex subPart(S32 index) const;
//@}
/* @name Interface for building, testing, and helpers for typical use.
*/
//@{
/**
* @brief Default constructor - creates a useless LLMimeIndex.
*/
LLMimeIndex();
/**
* @brief Full constructor.
*
* @param headers The complete headers.
* @param content_offset The number of bytes to the start of the
* data segment of this mime entity from the start of the stream
* or buffer.
*/
LLMimeIndex(LLSD headers, S32 content_offset);
/**
* @brief Copy constructor.
*
* @param mime The other mime object.
*/
LLMimeIndex(const LLMimeIndex& mime);
// @brief Destructor.
~LLMimeIndex();
/*
* @breif Assignment operator.
*
* @param mime The other mime object.
* @return Returns this after assignment.
*/
LLMimeIndex& operator=(const LLMimeIndex& mime);
/**
* @brief Add attachment information as a sub-part to a multipart mime.
*
* @param sub_part the part to attach.
* @return Returns true on success, false on failure.
*/
bool attachSubPart(LLMimeIndex sub_part);
//@}
protected:
// Implementation.
class Impl;
Impl* mImpl;
};
/**
* @class LLMimeParser
* @brief This class implements a MIME parser and verifier.
*
* THOROUGH_DESCRIPTION
*/
class LLMimeParser
{
public:
// @brief Make a new mime parser.
LLMimeParser();
// @brief Mime parser Destructor.
~LLMimeParser();
// @brief Reset internal state of this parser.
void reset();
/* @name Index generation interface.
*/
//@{
/**
* @brief Parse a stream to find the mime index information.
*
* This method will scan the istr until a single complete mime
* entity is read or EOF. The istr will be modified by this
* parsing, so pass in a temporary stream or rewind/reset the
* stream after this call.
* @param istr An istream which contains a mime entity.
* @param index[out] The parsed output.
* @return Returns true if an index was parsed and no errors occurred.
*/
bool parseIndex(std::istream& istr, LLMimeIndex& index);
/**
* @brief Parse a vector to find the mime index information.
*
* @param buffer A vector with data to parse.
* @param index[out] The parsed output.
* @return Returns true if an index was parsed and no errors occurred.
*/
bool parseIndex(const std::vector<U8>& buffer, LLMimeIndex& index);
/**
* @brief Parse a stream to find the mime index information.
*
* This method will scan the istr until a single complete mime
* entity is read, an EOF, or limit bytes have been scanned. The
* istr will be modified by this parsing, so pass in a temporary
* stream or rewind/reset the stream after this call.
* @param istr An istream which contains a mime entity.
* @param limit The maximum number of bytes to scan.
* @param index[out] The parsed output.
* @return Returns true if an index was parsed and no errors occurred.
*/
bool parseIndex(std::istream& istr, S32 limit, LLMimeIndex& index);
/**
* @brief Parse a memory bufffer to find the mime index information.
*
* @param buffer The start of the buffer to parse.
* @param buffer_length The length of the buffer.
* @param index[out] The parsed output.
* @return Returns true if an index was parsed and no errors occurred.
*/
bool parseIndex(const U8* buffer, S32 buffer_length, LLMimeIndex& index);
//@}
/**
* @brief
*
* @return
*/
//bool verify(std::istream& istr, LLMimeIndex& index) const;
/**
* @brief
*
* @return
*/
//bool verify(U8* buffer, S32 buffer_length, LLMimeIndex& index) const;
protected:
// Implementation.
class Impl;
Impl& mImpl;
private:
// @brief Not implemneted to prevent copy consturction.
LLMimeParser(const LLMimeParser& parser);
// @brief Not implemneted to prevent assignment.
LLMimeParser& operator=(const LLMimeParser& mime);
};
#endif // LL_LLMIME_H

View File

@@ -31,7 +31,6 @@
#include "llnamevalue.h"
#include "u64.h"
#include "llstring.h"
#include "llstringtable.h"
@@ -149,7 +148,7 @@ void LLNameValue::init(const char *name, const char *data, const char *type, con
else if (!strcmp(mStringType, "U64"))
{
mType = NVT_U64;
mNameValueReference.u64 = new U64(str_to_U64(ll_safe_string(data)));
mNameValueReference.u64 = new U64(std::stoull(data));
}
else if (!strcmp(mStringType, "VEC3"))
{
@@ -919,9 +918,7 @@ std::string LLNameValue::printData() const
break;
case NVT_U64:
{
char u64_string[U64_BUFFER_LEN]; /* Flawfinder: ignore */
U64_to_str(*mNameValueReference.u64, u64_string, sizeof(u64_string));
buffer = u64_string;
buffer = fmt::to_string(*mNameValueReference.u64);
}
break;
case NVT_VEC3:
@@ -952,11 +949,7 @@ std::ostream& operator<<(std::ostream& s, const LLNameValue &a)
s << *(a.mNameValueReference.u32);
break;
case NVT_U64:
{
char u64_string[U64_BUFFER_LEN]; /* Flawfinder: ignore */
U64_to_str(*a.mNameValueReference.u64, u64_string, sizeof(u64_string));
s << u64_string;
}
s << (*a.mNameValueReference.u64);
break;
case NVT_VEC3:
s << *(a.mNameValueReference.vec3);

View File

@@ -30,7 +30,6 @@
#include "lluuid.h"
#include "llerror.h"
#include "llmath.h"
#include "u64.h"
//number of bytes sent in each message
const U32 LL_XFER_CHUNK_SIZE = 1000;
@@ -347,12 +346,12 @@ void LLXfer::abort (S32 result_code)
if (result_code != LL_ERR_CIRCUIT_GONE)
{
gMessageSystem->newMessageFast(_PREHASH_AbortXfer);
gMessageSystem->nextBlockFast(_PREHASH_XferID);
gMessageSystem->addU64Fast(_PREHASH_ID, mID);
gMessageSystem->addS32Fast(_PREHASH_Result, result_code);
gMessageSystem->sendMessage(mRemoteHost);
gMessageSystem->newMessageFast(_PREHASH_AbortXfer);
gMessageSystem->nextBlockFast(_PREHASH_XferID);
gMessageSystem->addU64Fast(_PREHASH_ID, mID);
gMessageSystem->addS32Fast(_PREHASH_Result, result_code);
gMessageSystem->sendMessage(mRemoteHost);
}
mStatus = e_LL_XFER_ABORTED;
@@ -363,7 +362,7 @@ void LLXfer::abort (S32 result_code)
std::string LLXfer::getFileName()
{
return U64_to_str(mID);
return fmt::to_string(mID);
}
///////////////////////////////////////////////////////////

View File

@@ -35,7 +35,6 @@
#include "llerror.h"
#include "lluuid.h"
#include "u64.h"
const F32 LL_XFER_REGISTRATION_TIMEOUT = 60.0f; // timeout if a registered transfer hasn't been requested in 60 seconds
const F32 LL_PACKET_TIMEOUT = 3.0f; // packet timeout at 3 s
@@ -543,11 +542,10 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user
if (fdata_size < 0 ||
fdata_size > BUF_SIZE)
{
char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */
LL_WARNS("Xfer") << "Received invalid xfer data size of " << fdata_size
<< " in packet number " << packetnum
<< " from " << mesgsys->getSender()
<< " for xfer id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF))
<< " for xfer id: " << fmt::to_string(id)
<< LL_ENDL;
return;
}
@@ -556,10 +554,9 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user
xferp = findXferByID(id, mReceiveList);
if (!xferp)
{
char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */
LL_WARNS("Xfer") << "received xfer data from " << mesgsys->getSender()
<< " for non-existent xfer id: "
<< U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << LL_ENDL;
<< fmt::to_string(id) << LL_ENDL;
return;
}
@@ -765,8 +762,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
mesgsys->getBOOL("XferID", "UseBigPackets", b_use_big_packets);
mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id);
char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */
LL_INFOS("Xfer") << "xfer request id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF))
LL_INFOS("Xfer") << "xfer request id: " << fmt::to_string(id)
<< " to " << mesgsys->getSender() << LL_ENDL;
mesgsys->getStringFast(_PREHASH_XferID, _PREHASH_Filename, local_filename);
@@ -890,9 +886,8 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
}
else
{ // no uuid or filename - use the ID sent
char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */
LL_INFOS("Xfer") << "starting memory transfer: "
<< U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << " to "
<< fmt::to_string(id) << " to "
<< mesgsys->getSender() << LL_ENDL;
xferp = findXferByID(id, mSendList);
@@ -903,7 +898,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
}
else
{
LL_INFOS("Xfer") << "Warning: xfer ID " << U64_BUF << " not found." << LL_ENDL;
LL_INFOS("Xfer") << "Warning: xfer ID " << fmt::to_string(id) << " not found." << LL_ENDL;
result = LL_ERR_FILE_NOT_FOUND;
}
}
@@ -937,12 +932,12 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
{ // Not many transfers in progress already, so start immediately
xferp->sendNextPacket();
changeNumActiveXfers(xferp->mRemoteHost,1);
LL_DEBUGS("Xfer") << "Starting xfer ID " << U64_to_str(id) << " immediately" << LL_ENDL;
LL_DEBUGS("Xfer") << "Starting xfer ID " << fmt::to_string(id) << " immediately" << LL_ENDL;
}
else if (mHardLimitOutgoingXfersPerCircuit == 0 ||
(host_statusp->mNumActive + host_statusp->mNumPending) < mHardLimitOutgoingXfersPerCircuit)
{ // Must close the file handle and wait for earlier ones to complete
LL_INFOS("Xfer") << " queueing xfer request id " << U64_to_str(id) << ", "
LL_INFOS("Xfer") << " queueing xfer request id " << fmt::to_string(id) << ", "
<< host_statusp->mNumActive << " active and "
<< host_statusp->mNumPending << " pending ahead of this one"
<< LL_ENDL;
@@ -983,13 +978,13 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
}
else
{
LL_WARNS("Xfer") << "LLXferManager::processFileRequest() - no LLHostStatus found for id " << U64_to_str(id)
LL_WARNS("Xfer") << "LLXferManager::processFileRequest() - no LLHostStatus found for id " << fmt::to_string(id)
<< " host " << xferp->mRemoteHost << LL_ENDL;
}
}
else
{
LL_WARNS("Xfer") << "LLXferManager::processFileRequest() - no xfer found for id " << U64_to_str(id) << LL_ENDL;
LL_WARNS("Xfer") << "LLXferManager::processFileRequest() - no xfer found for id " << fmt::to_string(id) << LL_ENDL;
}
}
@@ -1113,7 +1108,7 @@ void LLXferManager::retransmitUnackedPackets()
{
if (xferp->reopenFileHandle())
{
LL_WARNS("Xfer") << "Error re-opening file handle for xfer ID " << U64_to_str(xferp->mID)
LL_WARNS("Xfer") << "Error re-opening file handle for xfer ID " << fmt::to_string(xferp->mID)
<< " to host " << xferp->mRemoteHost << LL_ENDL;
xferp->abort(LL_ERR_CANNOT_OPEN_FILE);
iter = mSendList.erase(iter);
@@ -1122,7 +1117,7 @@ void LLXferManager::retransmitUnackedPackets()
}
else
{ // No error re-opening the file, send the first packet
LL_DEBUGS("Xfer") << "Moving pending xfer ID " << U64_to_str(xferp->mID) << " to active" << LL_ENDL;
LL_DEBUGS("Xfer") << "Moving pending xfer ID " << fmt::to_string(xferp->mID) << " to active" << LL_ENDL;
xferp->sendNextPacket();
changeNumActiveXfers(xferp->mRemoteHost,1);
}
@@ -1136,7 +1131,7 @@ void LLXferManager::retransmitUnackedPackets()
// so we don't blow through bandwidth.
//
while (mXferAckQueue.size())
while (!mXferAckQueue.empty())
{
if (mAckThrottle.checkOverflow(1000.0f*8.0f))
{

View File

@@ -73,7 +73,6 @@
#include "llxfermanager.h"
#include "timing.h"
#include "llquaternion.h"
#include "u64.h"
#include "v3dmath.h"
#include "v3math.h"
#include "v4math.h"
@@ -2600,54 +2599,54 @@ void LLMessageSystem::summarizeLogs(std::ostream& str)
// Incoming
str << buffer << std::endl << "Incoming:" << std::endl;
tmp_str = U64_to_str(mTotalBytesIn);
tmp_str = fmt::to_string(mTotalBytesIn);
buffer = llformat( "Total bytes received: %20s (%5.2f kbits per second)", tmp_str.c_str(), ((F32)mTotalBytesIn * 0.008f) / run_time);
str << buffer << std::endl;
tmp_str = U64_to_str(mPacketsIn);
tmp_str = fmt::to_string(mPacketsIn);
buffer = llformat( "Total packets received: %20s (%5.2f packets per second)", tmp_str.c_str(), ((F32) mPacketsIn / run_time));
str << buffer << std::endl;
buffer = llformat( "Average packet size: %20.0f bytes", (F32)mTotalBytesIn / (F32)mPacketsIn);
str << buffer << std::endl;
tmp_str = U64_to_str(mReliablePacketsIn);
tmp_str = fmt::to_string(mReliablePacketsIn);
buffer = llformat( "Total reliable packets: %20s (%5.2f%%)", tmp_str.c_str(), 100.f * ((F32) mReliablePacketsIn)/((F32) mPacketsIn + 1));
str << buffer << std::endl;
tmp_str = U64_to_str(mCompressedPacketsIn);
tmp_str = fmt::to_string(mCompressedPacketsIn);
buffer = llformat( "Total compressed packets: %20s (%5.2f%%)", tmp_str.c_str(), 100.f * ((F32) mCompressedPacketsIn)/((F32) mPacketsIn + 1));
str << buffer << std::endl;
S64 savings = mUncompressedBytesIn - mCompressedBytesIn;
tmp_str = U64_to_str(savings);
tmp_str = fmt::to_string(savings);
buffer = llformat( "Total compression savings: %20s bytes", tmp_str.c_str());
str << buffer << std::endl;
tmp_str = U64_to_str(savings/(mCompressedPacketsIn +1));
tmp_str = fmt::to_string(savings/(mCompressedPacketsIn +1));
buffer = llformat( "Avg comp packet savings: %20s (%5.2f : 1)", tmp_str.c_str(), ((F32) mUncompressedBytesIn)/((F32) mCompressedBytesIn+1));
str << buffer << std::endl;
tmp_str = U64_to_str(savings/(mPacketsIn+1));
tmp_str = fmt::to_string(savings/(mPacketsIn+1));
buffer = llformat( "Avg overall comp savings: %20s (%5.2f : 1)", tmp_str.c_str(), ((F32) mTotalBytesIn + (F32) savings)/((F32) mTotalBytesIn + 1.f));
// Outgoing
str << buffer << std::endl << std::endl << "Outgoing:" << std::endl;
tmp_str = U64_to_str(mTotalBytesOut);
tmp_str = fmt::to_string(mTotalBytesOut);
buffer = llformat( "Total bytes sent: %20s (%5.2f kbits per second)", tmp_str.c_str(), ((F32)mTotalBytesOut * 0.008f) / run_time );
str << buffer << std::endl;
tmp_str = U64_to_str(mPacketsOut);
tmp_str = fmt::to_string(mPacketsOut);
buffer = llformat( "Total packets sent: %20s (%5.2f packets per second)", tmp_str.c_str(), ((F32)mPacketsOut / run_time));
str << buffer << std::endl;
buffer = llformat( "Average packet size: %20.0f bytes", (F32)mTotalBytesOut / (F32)mPacketsOut);
str << buffer << std::endl;
tmp_str = U64_to_str(mReliablePacketsOut);
tmp_str = fmt::to_string(mReliablePacketsOut);
buffer = llformat( "Total reliable packets: %20s (%5.2f%%)", tmp_str.c_str(), 100.f * ((F32) mReliablePacketsOut)/((F32) mPacketsOut + 1));
str << buffer << std::endl;
tmp_str = U64_to_str(mCompressedPacketsOut);
tmp_str = fmt::to_string(mCompressedPacketsOut);
buffer = llformat( "Total compressed packets: %20s (%5.2f%%)", tmp_str.c_str(), 100.f * ((F32) mCompressedPacketsOut)/((F32) mPacketsOut + 1));
str << buffer << std::endl;
savings = mUncompressedBytesOut - mCompressedBytesOut;
tmp_str = U64_to_str(savings);
tmp_str = fmt::to_string(savings);
buffer = llformat( "Total compression savings: %20s bytes", tmp_str.c_str());
str << buffer << std::endl;
tmp_str = U64_to_str(savings/(mCompressedPacketsOut +1));
tmp_str = fmt::to_string(savings/(mCompressedPacketsOut +1));
buffer = llformat( "Avg comp packet savings: %20s (%5.2f : 1)", tmp_str.c_str(), ((F32) mUncompressedBytesOut)/((F32) mCompressedBytesOut+1));
str << buffer << std::endl;
tmp_str = U64_to_str(savings/(mPacketsOut+1));
tmp_str = fmt::to_string(savings/(mPacketsOut+1));
buffer = llformat( "Avg overall comp savings: %20s (%5.2f : 1)", tmp_str.c_str(), ((F32) mTotalBytesOut + (F32) savings)/((F32) mTotalBytesOut + 1.f));
str << buffer << std::endl << std::endl;
buffer = llformat( "SendPacket failures: %20d", mSendPacketFailureCount);

View File

@@ -1,445 +0,0 @@
/**
* @file llmime_test.cpp
* @author Phoenix
* @date 2006-12-24
* @brief BRIEF_DESC of llmime_test.cpp
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llsdserialize.h"
#include "../llmime.h"
#include "../test/lltut.h"
namespace tut
{
struct mime_index
{
};
typedef test_group<mime_index> mime_index_t;
typedef mime_index_t::object mime_index_object_t;
tut::mime_index_t tut_mime_index("LLMime");
template<> template<>
void mime_index_object_t::test<1>()
{
LLMimeIndex mime;
ensure("no headers", mime.headers().isUndefined());
ensure_equals("invalid offset", mime.offset(), -1);
ensure_equals("invalid content length", mime.contentLength(), -1);
ensure("no content type", mime.contentType().empty());
ensure("not multipart", !mime.isMultipart());
ensure_equals("no attachments", mime.subPartCount(), 0);
}
template<> template<>
void mime_index_object_t::test<2>()
{
const S32 CONTENT_LENGTH = 6000;
const S32 CONTENT_OFFSET = 100;
const std::string CONTENT_TYPE = std::string("image/j2c");
LLSD headers;
headers["Content-Length"] = CONTENT_LENGTH;
headers["Content-Type"] = CONTENT_TYPE;
LLMimeIndex mime(headers, CONTENT_OFFSET);
ensure("headers are map", mime.headers().isMap());
ensure_equals("offset", mime.offset(), CONTENT_OFFSET);
ensure_equals("content length", mime.contentLength(), CONTENT_LENGTH);
ensure_equals("type is image/j2c", mime.contentType(), CONTENT_TYPE);
ensure("not multipart", !mime.isMultipart());
ensure_equals("no attachments", mime.subPartCount(), 0);
}
template<> template<>
void mime_index_object_t::test<3>()
{
const S32 MULTI_CONTENT_LENGTH = 8000;
const S32 MULTI_CONTENT_OFFSET = 100;
const std::string MULTI_CONTENT_TYPE = std::string("multipart/mixed");
LLSD headers;
headers["Content-Length"] = MULTI_CONTENT_LENGTH;
headers["Content-Type"] = MULTI_CONTENT_TYPE;
LLMimeIndex mime(headers, MULTI_CONTENT_OFFSET);
LL_INFOS() << "headers: " << LLSDOStreamer<LLSDNotationFormatter>(headers)
<< LL_ENDL;
const S32 META_CONTENT_LENGTH = 700;
const S32 META_CONTENT_OFFSET = 69;
const std::string META_CONTENT_TYPE = std::string(
"text/llsd+xml");
headers = LLSD::emptyMap();
headers["Content-Length"] = META_CONTENT_LENGTH;
headers["Content-Type"] = META_CONTENT_TYPE;
LLMimeIndex meta(headers, META_CONTENT_OFFSET);
mime.attachSubPart(meta);
const S32 IMAGE_CONTENT_LENGTH = 6000;
const S32 IMAGE_CONTENT_OFFSET = 200;
const std::string IMAGE_CONTENT_TYPE = std::string("image/j2c");
headers = LLSD::emptyMap();
headers["Content-Length"] = IMAGE_CONTENT_LENGTH;
headers["Content-Type"] = IMAGE_CONTENT_TYPE;
LLMimeIndex image(headers, IMAGE_CONTENT_OFFSET);
mime.attachSubPart(image);
// make sure we have a valid multi-part
ensure("is multipart", mime.isMultipart());
ensure_equals("multi offset", mime.offset(), MULTI_CONTENT_OFFSET);
ensure_equals(
"multi content length",
mime.contentLength(),
MULTI_CONTENT_LENGTH);
ensure_equals("two attachments", mime.subPartCount(), 2);
// make sure ranged gets do the right thing with out of bounds
// sub-parts.
LLMimeIndex invalid_child(mime.subPart(-1));
ensure("no headers", invalid_child.headers().isUndefined());
ensure_equals("invalid offset", invalid_child.offset(), -1);
ensure_equals(
"invalid content length", invalid_child.contentLength(), -1);
ensure("no content type", invalid_child.contentType().empty());
ensure("not multipart", !invalid_child.isMultipart());
ensure_equals("no attachments", invalid_child.subPartCount(), 0);
invalid_child = mime.subPart(2);
ensure("no headers", invalid_child.headers().isUndefined());
ensure_equals("invalid offset", invalid_child.offset(), -1);
ensure_equals(
"invalid content length", invalid_child.contentLength(), -1);
ensure("no content type", invalid_child.contentType().empty());
ensure("not multipart", !invalid_child.isMultipart());
ensure_equals("no attachments", invalid_child.subPartCount(), 0);
}
template<> template<>
void mime_index_object_t::test<4>()
{
const S32 MULTI_CONTENT_LENGTH = 8000;
const S32 MULTI_CONTENT_OFFSET = 100;
const std::string MULTI_CONTENT_TYPE = std::string("multipart/mixed");
LLSD headers;
headers["Content-Length"] = MULTI_CONTENT_LENGTH;
headers["Content-Type"] = MULTI_CONTENT_TYPE;
LLMimeIndex mime(headers, MULTI_CONTENT_OFFSET);
const S32 META_CONTENT_LENGTH = 700;
const S32 META_CONTENT_OFFSET = 69;
const std::string META_CONTENT_TYPE = std::string(
"application/llsd+xml");
headers = LLSD::emptyMap();
headers["Content-Length"] = META_CONTENT_LENGTH;
headers["Content-Type"] = META_CONTENT_TYPE;
LLMimeIndex meta(headers, META_CONTENT_OFFSET);
mime.attachSubPart(meta);
const S32 IMAGE_CONTENT_LENGTH = 6000;
const S32 IMAGE_CONTENT_OFFSET = 200;
const std::string IMAGE_CONTENT_TYPE = std::string("image/j2c");
headers = LLSD::emptyMap();
headers["Content-Length"] = IMAGE_CONTENT_LENGTH;
headers["Content-Type"] = IMAGE_CONTENT_TYPE;
LLMimeIndex image(headers, IMAGE_CONTENT_OFFSET);
mime.attachSubPart(image);
// check what we have
ensure("is multipart", mime.isMultipart());
ensure_equals("multi offset", mime.offset(), MULTI_CONTENT_OFFSET);
ensure_equals(
"multi content length",
mime.contentLength(),
MULTI_CONTENT_LENGTH);
ensure_equals("two attachments", mime.subPartCount(), 2);
LLMimeIndex actual_meta = mime.subPart(0);
ensure_equals(
"meta type", actual_meta.contentType(), META_CONTENT_TYPE);
ensure_equals(
"meta offset", actual_meta.offset(), META_CONTENT_OFFSET);
ensure_equals(
"meta content length",
actual_meta.contentLength(),
META_CONTENT_LENGTH);
LLMimeIndex actual_image = mime.subPart(1);
ensure_equals(
"image type", actual_image.contentType(), IMAGE_CONTENT_TYPE);
ensure_equals(
"image offset", actual_image.offset(), IMAGE_CONTENT_OFFSET);
ensure_equals(
"image content length",
actual_image.contentLength(),
IMAGE_CONTENT_LENGTH);
}
/*
template<> template<>
void mime_index_object_t::test<5>()
{
}
template<> template<>
void mime_index_object_t::test<6>()
{
}
template<> template<>
void mime_index_object_t::test<7>()
{
}
template<> template<>
void mime_index_object_t::test<8>()
{
}
template<> template<>
void mime_index_object_t::test<>()
{
}
*/
}
namespace tut
{
struct mime_parse
{
};
typedef test_group<mime_parse> mime_parse_t;
typedef mime_parse_t::object mime_parse_object_t;
tut::mime_parse_t tut_mime_parse("LLMimeParse");
template<> template<>
void mime_parse_object_t::test<1>()
{
// parse one mime object
const std::string SERIALIZED_MIME("Content-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n");
std::stringstream istr;
istr.str(SERIALIZED_MIME);
LLMimeIndex mime;
LLMimeParser parser;
bool ok = parser.parseIndex(istr, mime);
ensure("Parse successful.", ok);
ensure_equals("content type", mime.contentType(), "text/plain");
ensure_equals("content length", mime.contentLength(), 200);
ensure_equals("offset", mime.offset(), 49);
}
template<> template<>
void mime_parse_object_t::test<2>()
{
// make sure we only parse one.
const std::string SERIALIZED_MIME("Content-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n\r\nContent-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n\r\n");
std::stringstream istr;
istr.str(SERIALIZED_MIME);
LLMimeIndex mime;
LLMimeParser parser;
bool ok = parser.parseIndex(istr, mime);
ensure("Parse successful.", ok);
ensure("not multipart.", !mime.isMultipart());
ensure_equals("content type", mime.contentType(), "text/plain");
ensure_equals("content length", mime.contentLength(), 200);
ensure_equals("offset", mime.offset(), 49);
}
template<> template<>
void mime_parse_object_t::test<3>()
{
// test multi-part and lack of content length for some of it.
/*
Content-Type: multipart/mixed; boundary="segment"rnContent-Length: 148rnrn--segmentrnContent-Type: text/plainrnrnsome datarnrn--segmentrnContent-Type: text/xml; charset=UTF-8rnContent-Length: 22rnrn<llsd><undef /></llsd>rnrn
*/
const std::string SERIALIZED_MIME("Content-Type: multipart/mixed; boundary=\"segment\"\r\nContent-Length: 150\r\n\r\n--segment\r\nContent-Type: text/plain\r\n\r\nsome data\r\n\r\n--segment\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n");
std::stringstream istr;
istr.str(SERIALIZED_MIME);
LLMimeIndex mime;
LLMimeParser parser;
bool ok = parser.parseIndex(istr, mime);
ensure("Parse successful.", ok);
ensure("is multipart.", mime.isMultipart());
ensure_equals("sub-part count", mime.subPartCount(), 2);
ensure_equals("content length", mime.contentLength(), 150);
ensure_equals("data offset for multipart", mime.offset(), 74);
LLMimeIndex mime_plain(mime.subPart(0));
ensure_equals(
"first part type",
mime_plain.contentType(),
"text/plain");
ensure_equals(
"first part content length not known.",
mime_plain.contentLength(),
-1);
ensure_equals("first part offset", mime_plain.offset(), 113);
LLMimeIndex mime_xml(mime.subPart(1));
ensure_equals(
"second part type",
mime_xml.contentType(),
"text/xml; charset=UTF-8");
ensure_equals(
"second part content length",
mime_xml.contentLength(),
22);
ensure_equals("second part offset", mime_xml.offset(), 198);
}
template<> template<>
void mime_parse_object_t::test<4>()
{
// test multi-part, unquoted separator, and premature eof conditions
/*
Content-Type: multipart/mixed; boundary=segmentrnContent-Length: 220rnrn--segmentrnContent-Type: text/plainrnContent-Length: 55rnrnhow are you today?rnI do not know. I guess I am:n'fine'rnrn--segmentrnContent-Type: text/xml; charset=UTF-8rnContent-Length: 22rnrn<llsd><undef /></llsd>rnrn */
const std::string SERIALIZED_MIME("Content-Type: multipart/mixed; boundary=segment\r\nContent-Length: 220\r\n\r\n--segment\r\nContent-Type: text/plain\r\nContent-Length: 55\r\n\r\nhow are you today?\r\nI do not know. I guess I am:\n'fine'\r\n\r\n--segment\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n");
std::stringstream istr;
istr.str(SERIALIZED_MIME);
LLMimeIndex mime;
LLMimeParser parser;
bool ok = parser.parseIndex(istr, mime);
ensure("Parse successful.", ok);
ensure("is multipart.", mime.isMultipart());
ensure_equals("sub-part count", mime.subPartCount(), 2);
ensure_equals("content length", mime.contentLength(), 220);
ensure_equals("data offset for multipart", mime.offset(), 72);
LLMimeIndex mime_plain(mime.subPart(0));
ensure_equals(
"first part type",
mime_plain.contentType(),
"text/plain");
ensure_equals(
"first part content length",
mime_plain.contentLength(),
55);
ensure_equals("first part offset", mime_plain.offset(), 131);
LLMimeIndex mime_xml(mime.subPart(1));
ensure_equals(
"second part type",
mime_xml.contentType(),
"text/xml; charset=UTF-8");
ensure_equals(
"second part content length",
mime_xml.contentLength(),
22);
ensure_equals("second part offset", mime_xml.offset(), 262);
}
template<> template<>
void mime_parse_object_t::test<5>()
{
// test multi-part with multiple params
const std::string SERIALIZED_MIME("Content-Type: multipart/mixed; boundary=segment; comment=\"testing multiple params.\"\r\nContent-Length: 220\r\n\r\n--segment\r\nContent-Type: text/plain\r\nContent-Length: 55\r\n\r\nhow are you today?\r\nI do not know. I guess I am:\n'fine'\r\n\r\n--segment\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n");
std::stringstream istr;
istr.str(SERIALIZED_MIME);
LLMimeIndex mime;
LLMimeParser parser;
bool ok = parser.parseIndex(istr, mime);
ensure("Parse successful.", ok);
ensure("is multipart.", mime.isMultipart());
ensure_equals("sub-part count", mime.subPartCount(), 2);
ensure_equals("content length", mime.contentLength(), 220);
LLMimeIndex mime_plain(mime.subPart(0));
ensure_equals(
"first part type",
mime_plain.contentType(),
"text/plain");
ensure_equals(
"first part content length",
mime_plain.contentLength(),
55);
LLMimeIndex mime_xml(mime.subPart(1));
ensure_equals(
"second part type",
mime_xml.contentType(),
"text/xml; charset=UTF-8");
ensure_equals(
"second part content length",
mime_xml.contentLength(),
22);
}
template<> template<>
void mime_parse_object_t::test<6>()
{
// test multi-part with no specified boundary and eof
/*
Content-Type: multipart/relatedrnContent-Length: 220rnrn--rnContent-Type: text/plainrnContent-Length: 55rnrnhow are you today?rnI do not know. I guess I am:n'fine'rnrn--rnContent-Type: text/xml; charset=UTF-8rnContent-Length: 22rnrn<llsd><undef /></llsd>rnrn
*/
const std::string SERIALIZED_MIME("Content-Type: multipart/related\r\nContent-Length: 500\r\n\r\n--\r\nContent-Type: text/plain\r\nContent-Length: 55\r\n\r\nhow are you today?\r\nI do not know. I guess I am:\n'fine'\r\n\r\n--\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n");
std::stringstream istr;
istr.str(SERIALIZED_MIME);
LLMimeIndex mime;
LLMimeParser parser;
bool ok = parser.parseIndex(istr, mime);
ensure("Parse successful.", ok);
ensure("is multipart.", mime.isMultipart());
ensure_equals("sub-part count", mime.subPartCount(), 2);
ensure_equals("content length", mime.contentLength(), 500);
ensure_equals("data offset for multipart", mime.offset(), 56);
LLMimeIndex mime_plain(mime.subPart(0));
ensure_equals(
"first part type",
mime_plain.contentType(),
"text/plain");
ensure_equals(
"first part content length",
mime_plain.contentLength(),
55);
ensure_equals("first part offset", mime_plain.offset(), 108);
LLMimeIndex mime_xml(mime.subPart(1));
ensure_equals(
"second part type",
mime_xml.contentType(),
"text/xml; charset=UTF-8");
ensure_equals(
"second part content length",
mime_xml.contentLength(),
22);
ensure_equals("second part offset", mime_xml.offset(), 232);
}
/*
template<> template<>
void mime_parse_object_t::test<>()
{
}
template<> template<>
void mime_parse_object_t::test<>()
{
}
template<> template<>
void mime_parse_object_t::test<>()
{
}
template<> template<>
void mime_parse_object_t::test<>()
{
}
*/
}

File diff suppressed because it is too large Load Diff

View File

@@ -5,21 +5,21 @@
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2013, Linden Research, Inc.
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -42,13 +42,13 @@ class domMesh;
class LLDAELoader : public LLModelLoader
{
public:
typedef std::map<std::string, LLImportMaterial> material_map;
typedef std::map<std::string, LLImportMaterial> material_map;
typedef std::map<daeElement*, std::vector<LLPointer<LLModel> > > dae_model_map;
dae_model_map mModelsMap;
dae_model_map mModelsMap;
LLDAELoader(
std::string filename,
S32 lod,
std::string filename,
S32 lod,
LLModelLoader::load_callback_t load_cb,
LLModelLoader::joint_lookup_func_t joint_lookup_func,
LLModelLoader::texture_load_func_t texture_load_func,
@@ -56,41 +56,40 @@ public:
void* opaque_userdata,
JointTransformMap& jointTransformMap,
JointNameSet& jointsFromNodes,
std::map<std::string, std::string>& jointAliasMap,
std::map<std::string, std::string>& jointAliasMap,
U32 maxJointsPerMesh,
U32 modelLimit,
bool preprocess);
virtual ~LLDAELoader() ;
virtual ~LLDAELoader();
virtual bool OpenFile(const std::string& filename);
protected:
void processElement(daeElement* element, bool& badElement, DAE* dae);
void processElement(daeElement* element, bool& badElement, DAE* dae, daeElement* domRoot);
void processDomModel(LLModel* model, DAE* dae, daeElement* pRoot, domMesh* mesh, domSkin* skin);
material_map getMaterials(LLModel* model, domInstance_geometry* instance_geo, DAE* dae);
LLImportMaterial profileToMaterial(domProfile_COMMON* material, DAE* dae);
LLColor4 getDaeColor(daeElement* element);
daeElement* getChildFromElement( daeElement* pElement, std::string const & name );
bool isNodeAJoint( domNode* pNode );
void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms );
void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform );
void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform );
void extractTranslationViaSID( daeElement* pElement, LLMatrix4& transform );
void buildJointToNodeMappingFromScene( daeElement* pRoot );
void processJointToNodeMapping( domNode* pNode );
void processChildJoints( domNode* pParentNode );
material_map getMaterials(LLModel* model, domInstance_geometry* instance_geo, DAE* dae) const;
LLImportMaterial profileToMaterial(domProfile_COMMON* material, DAE* dae) const;
LLColor4 getDaeColor(daeElement* element) const;
bool verifyCount( int expected, int result );
daeElement* getChildFromElement(daeElement* pElement, std::string const& name);
bool isNodeAJoint(const domNode* pNode) const;
void processJointNode(domNode* pNode, JointTransformMap& jointTransforms);
void extractTranslation(const domTranslate* pTranslate, LLMatrix4& transform) const;
void extractTranslationViaSID(daeElement* pElement, LLMatrix4& transform) const;
void buildJointToNodeMappingFromScene(daeElement* pRoot);
void processJointToNodeMapping(domNode* pNode);
void processChildJoints(domNode* pParentNode);
bool verifyCount(const size_t expected, const size_t result) const;
//Verify that a controller matches vertex counts
bool verifyController( domController* pController );
bool verifyController(const domController* pController) const;
static bool addVolumeFacesFromDomMesh(LLModel* model, domMesh* mesh);
static bool createVolumeFacesFromDomMesh(LLModel* model, domMesh *mesh);
static bool createVolumeFacesFromDomMesh(LLModel* model, domMesh* mesh);
static LLModel* loadModelFromDomMesh(domMesh* mesh);
@@ -99,11 +98,11 @@ protected:
//
bool loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& models_out, U32 submodel_limit);
static std::string getElementLabel(daeElement *element);
static size_t getSuffixPosition(std::string label);
static std::string getLodlessLabel(daeElement *element);
static std::string getElementLabel(daeElement* element);
static size_t getSuffixPosition(const std::string label);
static std::string getLodlessLabel(daeElement* element);
static std::string preprocessDAE(std::string filename);
static std::string preprocessDAE(const std::string filename);
private:
U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels

View File

@@ -99,7 +99,7 @@ public:
S32 mLod;
LLMatrix4 mTransform;
LLMatrix4 mTransform, mBindTransform;
BOOL mFirstTransform;
LLVector3 mExtents[2];
@@ -180,7 +180,7 @@ public:
//-----------------------------------------------------------------------------
// isNodeAJoint()
//-----------------------------------------------------------------------------
bool isNodeAJoint(const char* name)
bool isNodeAJoint(const char* name) const
{
return name != NULL && mJointMap.find(name) != mJointMap.end();
}

View File

@@ -2146,7 +2146,7 @@ void LLRender::setLineWidth(F32 line_width)
}
if (mNewContext.lineWidth != line_width || mDirty)
{
if (mMode == LLRender::LINES || LLRender::LINE_STRIP)
if (mMode == LLRender::LINES || mMode == LLRender::LINE_STRIP)
{
flush();
}
@@ -2483,16 +2483,17 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count)
mTexcoordsp[mCount] = mTexcoordsp[mCount - 1];
}
mVerticesp.copyArray(mCount, verts, vert_count);
for (S32 i = 0; i < vert_count; i++)
{
mVerticesp[mCount] = verts[i];
mCount++;
mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
mColorsp[mCount] = mColorsp[mCount-1];
}
mVerticesp[mCount] = mVerticesp[mCount-1];
if (mCount > 0) // ND: Guard against crashes if mCount is zero, yes it can happen
mVerticesp[mCount] = mVerticesp[mCount-1];
mPrimitiveReset = false;
}
@@ -2520,17 +2521,20 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32
mTexcoordsp[mCount] = mTexcoordsp[mCount - 1];
}
mVerticesp.copyArray(mCount, verts, vert_count);
mTexcoordsp.copyArray(mCount, uvs, vert_count);
for (S32 i = 0; i < vert_count; i++)
{
mVerticesp[mCount] = verts[i];
mTexcoordsp[mCount] = uvs[i];
mCount++;
mColorsp[mCount] = mColorsp[mCount-1];
}
mVerticesp[mCount] = mVerticesp[mCount-1];
mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
if (mCount > 0)
{
mVerticesp[mCount] = mVerticesp[mCount - 1];
mTexcoordsp[mCount] = mTexcoordsp[mCount - 1];
}
mPrimitiveReset = false;
}
@@ -2564,9 +2568,12 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLCo
mColorsp.copyArray(mCount, colors, vert_count);
mCount += vert_count;
mVerticesp[mCount] = mVerticesp[mCount-1];
mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
mColorsp[mCount] = mColorsp[mCount-1];
if (mCount > 0)
{
mVerticesp[mCount] = mVerticesp[mCount - 1];
mTexcoordsp[mCount] = mTexcoordsp[mCount - 1];
mColorsp[mCount] = mColorsp[mCount - 1];
}
mPrimitiveReset = false;
}

View File

@@ -1197,6 +1197,10 @@ void LLVertexBuffer::genBuffer(U32 size)
{
mMappedData = sDynamicVBOPool.allocate(mGLBuffer, mSize);
}
if ((sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB) && !mMappedData)
{
LL_ERRS() << "mMappedData allocation failedd" << LL_ENDL;
}
sGLCount++;
}
@@ -1213,6 +1217,10 @@ void LLVertexBuffer::genIndices(U32 size)
{
mMappedIndexData = sDynamicIBOPool.allocate(mGLIndices, mIndicesSize);
}
if ((sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB) && !mMappedIndexData)
{
LL_ERRS() << "mMappedIndexData allocation failedd" << LL_ENDL;
}
sGLCount++;
}
@@ -1848,6 +1856,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
LL_ERRS() << "Attempted to map a specific range of a buffer that was already mapped." << LL_ENDL;
}
bool was_locked = mIndexLocked;
if (!mIndexLocked)
{
mIndexLocked = true;
@@ -1942,6 +1951,10 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
LL_ERRS() << "glMapBuffer returned NULL (no index data)" << LL_ENDL;
}
else if (was_locked)
{
LL_ERRS() << "mIndexLocked was true but no Index data allocated" << LL_ENDL;
}
else
{
LL_ERRS() << "memory allocation for Index data failed. " << LL_ENDL;

View File

@@ -2475,7 +2475,7 @@ BOOL LLLineEditor::evaluateFloat()
else
{
// Replace the expression with the result
std::string result_str = llformat("%f", result);
std::string result_str = fmt::to_string(result);
setText(result_str);
selectAll();
}

View File

@@ -74,8 +74,9 @@ private:
bool historyHandler(const LLSD& payload)
{
// we ignore "load" messages, but rewrite the persistence file on any other
// onDelete handes "delete" message, so skip that too.
std::string sigtype = payload["sigtype"];
if (sigtype != "load")
if (sigtype != "load" && sigtype != "delete")
{
savePersistentNotifications();
}
@@ -85,11 +86,15 @@ private:
// The history channel gets all notifications except those that have been cancelled
static bool historyFilter(LLNotificationPtr pNotification)
{
return !pNotification->isCancelled();
return pNotification->isPersistent() && !pNotification->isCancelled() && !pNotification->isRespondedTo() && !pNotification->isExpired();
}
void savePersistentNotifications()
{
if (mLoading)
{
return;
}
LL_INFOS() << "Saving open notifications to " << mFileName << LL_ENDL;
llofstream notify_file(mFileName.c_str());
@@ -104,6 +109,9 @@ private:
LLSD& data = output["data"];
AILOCK_mItems;
static LLCachedControl<S32> maxPersistentNotificaitons("MaxPersistentNotifications");
for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
{
if (!LLNotificationTemplates::instance().templateExists((*it)->getName())) continue;
@@ -111,7 +119,15 @@ private:
// only store notifications flagged as persisting
LLNotificationTemplatePtr templatep = LLNotificationTemplates::instance().getTemplate((*it)->getName());
if (!templatep->mPersist) continue;
if ((*it)->isCancelled() || (*it)->isExpired() || (*it)->isRespondedTo()) continue;
if (data.size() >= maxPersistentNotificaitons)
{
LL_WARNS() << "Too many persistent notifications."
<< " Saved " << maxPersistentNotificaitons << " of " << mItems.size()
<< " persistent notifications." << LL_ENDL;
break;
}
data.append((*it)->asLLSD());
}
@@ -121,53 +137,75 @@ private:
void loadPersistentNotifications()
{
if (mLoading)
{
return;
}
mLoading = true;
LL_INFOS() << "Loading open notifications from " << mFileName << LL_ENDL;
llifstream notify_file(mFileName.c_str());
if (!notify_file.is_open())
while (true)
{
LL_WARNS() << "Failed to open " << mFileName << LL_ENDL;
return;
}
llifstream notify_file(mFileName.c_str());
if (!notify_file.is_open())
{
LL_WARNS() << "Failed to open " << mFileName << LL_ENDL;
break;
}
LLSD input;
LLPointer<LLSDParser> parser = new LLSDXMLParser();
if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
{
LL_WARNS() << "Failed to parse open notifications" << LL_ENDL;
return;
}
LLSD input;
LLPointer<LLSDParser> parser = new LLSDXMLParser();
if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
{
LL_WARNS() << "Failed to parse open notifications" << LL_ENDL;
break;
}
if (input.isUndefined()) return;
std::string version = input["version"];
if (version != NOTIFICATION_PERSIST_VERSION)
{
LL_WARNS() << "Bad open notifications version: " << version << LL_ENDL;
return;
}
LLSD& data = input["data"];
if (data.isUndefined()) return;
if (input.isUndefined()) return;
std::string version = input["version"];
if (version != NOTIFICATION_PERSIST_VERSION)
{
LL_WARNS() << "Bad open notifications version: " << version << LL_ENDL;
break;
}
LLSD& data = input["data"];
if (data.isUndefined()) break;
LLNotifications& instance = LLNotifications::instance();
for (LLSD::array_const_iterator notification_it = data.beginArray();
notification_it != data.endArray();
++notification_it)
{
instance.add(LLNotificationPtr(new LLNotification(*notification_it)));
S32 processed_notifications = 0;
static LLCachedControl<S32> maxPersistentNotificaitons("MaxPersistentNotifications");
LLNotifications& instance = LLNotifications::instance();
for (LLSD::array_const_iterator notification_it = data.beginArray();
notification_it != data.endArray();
++notification_it)
{
if (processed_notifications++ >= maxPersistentNotificaitons)
{
LL_WARNS() << "Too many persistent notifications."
<< " Processed " << maxPersistentNotificaitons << " of " << data.size() << " persistent notifications." << LL_ENDL;
break;
}
instance.add(LLNotificationPtr(new LLNotification(*notification_it)));
}
break;
}
mLoading = false;
savePersistentNotifications();
}
//virtual
void onDelete(LLNotificationPtr pNotification)
{
// we want to keep deleted notifications in our log
AILOCK_mItems;
mItems.insert(pNotification);
return;
{
AILOCK_mItems;
mItems.erase(pNotification); // Delete immediately.
}
savePersistentNotifications();
}
private:
bool mLoading = false;
std::string mFileName;
};
@@ -277,6 +315,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLXMLNodeP
}
LLNotificationForm::LLNotificationForm(const LLSD& sd)
: mIgnore(IGNORE_NO)
{
if (sd.isArray())
{
@@ -904,9 +943,9 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
// if we have it in our list, pass on the delete, then delete it, else do nothing
if (wasFound)
{
onDelete(pNotification);
abortProcessing = mChanged(payload);
mItems.erase(pNotification);
onDelete(pNotification);
}
}
return abortProcessing;
@@ -1146,13 +1185,6 @@ void LLNotifications::createDefaultChannels()
LLNotificationChannel::buildChannel("Visible", "Ignore",
&LLNotificationFilters::includeEverything);
// create special history channel
//std::string notifications_log_file = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml" );
// use ^^^ when done debugging notifications serialization
std::string notifications_log_file = gDirUtilp->getExpandedFilename ( LL_PATH_USER_SETTINGS, "open_notifications.xml" );
// this isn't a leak, don't worry about the empty "new"
new LLNotificationHistoryChannel(notifications_log_file);
// connect action methods to these channels
LLNotifications::instance().getChannel("Expiration")->
connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1));
@@ -1164,6 +1196,14 @@ void LLNotifications::createDefaultChannels()
connectFailedFilter(&handleIgnoredNotification);
}
void LLNotifications::onLoginCompleted()
{
// create special history channel
std::string notifications_log_file = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "singu_open_notifications_" + gHippoGridManager->getCurrentGrid()->getGridName() + ".xml");
// this isn't a leak, don't worry about the empty "new"
new LLNotificationHistoryChannel(notifications_log_file );
}
static std::string sStringSkipNextTime("Skip this dialog next time");
static std::string sStringAlwaysChoose("Always choose this option");

View File

@@ -796,6 +796,7 @@ public:
// OK to call more than once because it will reload
bool loadNotifications();
void createDefaultChannels();
void onLoginCompleted();
// we provide a collection of simple add notification functions so that it's reasonable to create notifications in one line
LLNotificationPtr add(const std::string& name,

View File

@@ -414,7 +414,7 @@ void LLResMgr::getIntegerString( std::string& output, S32 input ) const
{
if (fraction == remaining_count)
{
fraction_string = llformat("%d", fraction);
fraction_string = fmt::to_string(fraction);
}
else
{

View File

@@ -3201,7 +3201,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLS
// empty columns strings index by ordinal
if (column.empty())
{
column = llformat("%d", col_index);
column = fmt::to_string(col_index);
}
LLScrollListColumn* columnp = getColumn(column);

View File

@@ -45,12 +45,13 @@
#if LL_GTK
extern "C" {
# include <gtk/gtk.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#if GTK_CHECK_VERSION(2, 24, 0)
#include <gdk/gdkx.h>
#endif
}
#include <locale.h>
#include <clocale>
#endif // LL_GTK
extern "C" {
@@ -1543,7 +1544,7 @@ BOOL LLWindowSDL::SDLReallyCaptureInput(BOOL capture)
XUngrabPointer(mSDL_Display, CurrentTime);
// Make sure the ungrab happens RIGHT NOW.
XSync(mSDL_Display, False);
XSync(mSDL_Display, FALSE);
} else
{
newmode = SDL_GRAB_QUERY; // neutral
@@ -2269,8 +2270,12 @@ S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 typ
gWindowImplementation->mSDL_XWindowID != None)
{
gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin
GdkWindow *gdkwin = gdk_window_foreign_new(gWindowImplementation->mSDL_XWindowID);
gdk_window_set_transient_for(GTK_WIDGET(win)->window, gdkwin);
#if GTK_CHECK_VERSION(2, 24, 0)
GdkWindow* gdkwin = gdk_x11_window_foreign_new_for_display(gdk_display_get_default(), static_cast<Window>(gWindowImplementation->mSDL_XWindowID));
#else
GdkWindow* gdkwin = gdk_window_foreign_new(static_cast<GdkNativeWindow>(gWindowImplementation->mSDL_XWindowID));
#endif
gdk_window_set_transient_for(gtk_widget_get_window(GTK_WIDGET(win)), gdkwin);
}
# endif //LL_X11
@@ -2384,12 +2389,16 @@ BOOL LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b)
if (mSDL_XWindowID != None)
{
gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin
GdkWindow *gdkwin = gdk_window_foreign_new(mSDL_XWindowID);
gdk_window_set_transient_for(GTK_WIDGET(win)->window, gdkwin);
#if GTK_CHECK_VERSION(2, 24, 0)
GdkWindow* gdkwin = gdk_x11_window_foreign_new_for_display(gdk_display_get_default(), static_cast<Window>(mSDL_XWindowID));
#else
GdkWindow* gdkwin = gdk_window_foreign_new(static_cast<GdkNativeWindow>(mSDL_XWindowID));
#endif
gdk_window_set_transient_for(gtk_widget_get_window(GTK_WIDGET(win)), gdkwin);
}
# endif //LL_X11
#endif //LL_X11
GtkColorSelection *colorsel = GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG(win)->colorsel);
GtkColorSelection *colorsel = GTK_COLOR_SELECTION (gtk_color_selection_dialog_get_color_selection (GTK_COLOR_SELECTION_DIALOG(win)));
GdkColor color, orig_color;
orig_color.pixel = 0;
@@ -2415,8 +2424,6 @@ BOOL LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b)
gtk_window_set_modal(GTK_WINDOW(win), TRUE);
gtk_widget_show_all(win);
// hide the help button - we don't service it.
gtk_widget_hide(GTK_COLOR_SELECTION_DIALOG(win)->help_button);
gtk_main();
if (response == GTK_RESPONSE_OK &&
@@ -2498,7 +2505,7 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async)
if (mSDL_Display)
{
// Just in case - before forking.
XSync(mSDL_Display, False);
XSync(mSDL_Display, FALSE);
}
# endif // LL_X11
@@ -2548,7 +2555,7 @@ void LLWindowSDL::bringToFront()
if (mSDL_Display && !mFullscreen)
{
XRaiseWindow(mSDL_Display, mSDL_XWindowID);
XSync(mSDL_Display, False);
XSync(mSDL_Display, FALSE);
}
#endif // LL_X11
}

View File

@@ -18,7 +18,6 @@ include(FMODSTUDIO)
include(GeneratePrecompiledHeader)
include(GLOD)
include(Hunspell)
include(Json)
include(LLAddBuildTest)
include(LLAppearance)
include(LLAudio)
@@ -63,7 +62,6 @@ include_directories(
${STATEMACHINE_INCLUDE_DIRS}
${DBUSGLIB_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIRS}
${JSON_INCLUDE_DIR}
${GLOD_INCLUDE_DIR}
${LLAUDIO_INCLUDE_DIRS}
${LLCHARACTER_INCLUDE_DIRS}
@@ -1710,7 +1708,8 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLAPPEARANCE_LIBRARIES}
absl::flat_hash_map
absl::node_hash_map
${FMT_LIBRARY}
nlohmann_json::nlohmann_json
fmt::fmt
)
if (LINUX)

View File

@@ -24,7 +24,6 @@
#include "llviewerobjectlist.h"
#include <time.h>
#include <boost/lexical_cast.hpp>
class NACLAntiSpamQueue
{

View File

@@ -1 +1 @@
1.8.7
1.8.9

View File

@@ -10576,6 +10576,17 @@ This should be as low as possible, but too low may break functionality</string>
<key>Value</key>
<real>1.6</real>
</map>
<key>MaxPersistentNotifications</key>
<map>
<key>Comment</key>
<string>Maximum amount of persistent notifications</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<real>250</real>
</map>
<key>MaxSelectDistance</key>
<map>
<key>Comment</key>
@@ -12628,6 +12639,18 @@ This should be as low as possible, but too low may break functionality</string>
<integer>128</integer>
</map>
<key>OctreeMinimumNodeSize</key>
<map>
<key>Comment</key>
<string>Minimum size of any octree node</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.01</real>
</map>
<key>OctreeReserveNodeCapacity</key>
<map>
<key>Comment</key>

View File

@@ -207,6 +207,7 @@ void LLPrefsAscentSys::refreshValues()
mDisplayScriptJumps = gSavedSettings.getBOOL("AscentDisplayTotalScriptJumps");
mNumScriptDiff = gSavedSettings.getF32("Ascentnumscriptdiff");
mReplaceLinks = gSavedSettings.getBOOL("SinguReplaceLinks");
mEmergencySeconds = gSavedPerAccountSettings.getU32("EmergencyTeleportSeconds");
mLandmark = gSavedPerAccountSettings.getString("EmergencyTeleportLandmark");
mLandmarkBackup = gSavedPerAccountSettings.getString("EmergencyTeleportLandmarkBackup");
@@ -353,6 +354,7 @@ void LLPrefsAscentSys::cancel()
gSavedSettings.setBOOL("AscentDisplayTotalScriptJumps", mDisplayScriptJumps);
gSavedSettings.setF32("Ascentnumscriptdiff", mNumScriptDiff);
gSavedSettings.setBOOL("SinguReplaceLinks", mReplaceLinks);
gSavedPerAccountSettings.setU32("EmergencyTeleportSeconds", mEmergencySeconds);
gSavedPerAccountSettings.setString("EmergencyTeleportLandmark", mLandmark);
gSavedPerAccountSettings.setString("EmergencyTeleportLandmarkBackup", mLandmarkBackup);

View File

@@ -118,6 +118,7 @@ private:
bool mDisplayScriptJumps;
bool mReplaceLinks;
F32 mNumScriptDiff;
U32 mEmergencySeconds;
std::string mLandmark;
std::string mLandmarkBackup;

View File

@@ -163,10 +163,11 @@ Wavefront::Wavefront(LLFace* face, LLPolyMesh* mesh, const LLXform* transform, c
if (transform_normals) Transform(normals, transform_normals);
const U32 pcount = mesh ? mesh->getNumFaces() : (vb->getNumIndices()/3); //indices
const U16 offset = face->getIndicesStart(); //indices
const U32 offset = face->getIndicesStart(); //indices
for (U32 i = 0; i < pcount; ++i)
{
triangles.push_back(tri(getIndices[i * 3 + offset] + start, getIndices[i * 3 + 1 + offset] + start, getIndices[i * 3 + 2 + offset] + start));
const auto off = i * 3 + offset;
triangles.push_back(tri(getIndices[off] + start, getIndices[off + 1] + start, getIndices[off + 2] + start));
}
}
@@ -174,9 +175,9 @@ void Wavefront::Transform(vert_t& v, const LLXform* x) //recursive
{
LLMatrix4 m;
x->getLocalMat4(m);
for (vert_t::iterator iterv = v.begin(); iterv != v.end(); ++iterv)
for (auto& i : v)
{
iterv->first = iterv->first * m;
i.first = i.first * m;
}
if (const LLXform* xp = x->getParent()) Transform(v, xp);
@@ -186,9 +187,9 @@ void Wavefront::Transform(vec3_t& v, const LLXform* x) //recursive
{
LLMatrix4 m;
x->getLocalMat4(m);
for (vec3_t::iterator iterv = v.begin(); iterv != v.end(); ++iterv)
for (auto& i : v)
{
*iterv = *iterv * m;
i = i * m;
}
if (const LLXform* xp = x->getParent()) Transform(v, xp);
@@ -252,9 +253,9 @@ namespace
asset_id_matches);
// See if any of the inventory items matching this sculpt id are exportable
for (U32 i = 0; i < items.size(); i++)
for (const auto& item : items)
{
const LLPermissions item_permissions = items[i]->getPermissions();
const LLPermissions item_permissions = item->getPermissions();
if (item_permissions.allowExportBy(gAgentID, LFSimFeatureHandler::instance().exportPolicy()))
{
return true;
@@ -269,9 +270,9 @@ namespace
}
}
class LFSaveSelectedObjects : public view_listener_t
class LFSaveSelectedObjects final : public view_listener_t
{
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) override
{
if (LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection())
{
@@ -288,10 +289,10 @@ namespace
S32 included = 0;
for (LLObjectSelection::iterator iter = selection->begin(); iter != selection->end(); ++iter)
{
total++;
++total;
LLSelectNode* node = *iter;
if (!can_export_node(node)) continue;
included++;
++included;
wfsaver->Add(node->getObject());
}
if (wfsaver->obj_v.empty())
@@ -322,12 +323,12 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too!
{
offset = -av_vo->getRenderPosition();
avatar_joint_list_t vjv = av_vo->mMeshLOD;
for (avatar_joint_list_t::const_iterator itervj = vjv.begin(); itervj != vjv.end(); ++itervj)
for (const auto& itervj : vjv)
{
const LLViewerJoint* vj = dynamic_cast<LLViewerJoint*>(*itervj);
const auto* vj = dynamic_cast<const LLViewerJoint*>(itervj);
if (!vj || vj->mMeshParts.empty()) continue;
LLViewerJointMesh* vjm = dynamic_cast<LLViewerJointMesh*>(vj->mMeshParts[0]); //highest LOD
auto* vjm = dynamic_cast<LLViewerJointMesh*>(vj->mMeshParts[0]); //highest LOD
if (!vjm) continue;
vjm->updateJointGeometry();
@@ -355,21 +356,19 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too!
Add(Wavefront(face, pm, NULL, &normfix));
}
for (LLVOAvatar::attachment_map_t::const_iterator iter = av_vo->mAttachmentPoints.begin(); iter != av_vo->mAttachmentPoints.end(); ++iter)
for (const auto& ap : av_vo->mAttachmentPoints)
{
LLViewerJointAttachment* ja = iter->second;
LLViewerJointAttachment* ja = ap.second;
if (!ja) continue;
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator itero = ja->mAttachedObjects.begin(); itero != ja->mAttachedObjects.end(); ++itero)
for (const auto& o : ja->mAttachedObjects)
{
LLViewerObject* o = *itero;
if (!o) continue;
std::vector<LLViewerObject*> prims;
o->addThisAndAllChildren(prims);
for (std::vector<LLViewerObject* >::iterator iterc = prims.begin(); iterc != prims.end(); ++iterc)
for (const auto& c : prims)
{
const LLViewerObject* c = *iterc;
if (!c) continue;
if (LLSelectNode* n = LLSelectMgr::getInstance()->getSelection()->findNode(const_cast<LLViewerObject*>(c)))
{
@@ -400,9 +399,9 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too!
}
namespace
{
class LFSaveSelectedAvatar : public view_listener_t
class LFSaveSelectedAvatar final : public view_listener_t
{
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) override
{
if (const LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()))
{
@@ -446,49 +445,48 @@ bool WavefrontSaver::saveFile(LLFILE* fp)
int num = 0;
int index = 0;
for (std::vector<Wavefront>::iterator w_iter = obj_v.begin(); w_iter != obj_v.end(); ++w_iter)
for (const auto& obj : obj_v)
{
int count = 0;
std::string name = (*w_iter).name;
std::string name = obj.name;
if (name.empty()) name = llformat("%d", num++);
vert_t vertices = (*w_iter).vertices;
vec3_t normals = (*w_iter).normals;
tri_t triangles = (*w_iter).triangles;
auto& vertices = obj.vertices;
auto& normals = obj.normals;
auto& triangles = obj.triangles;
//Write Object
write_or_bust(fp, "o " + name + "\n");
write_or_bust(fp, "o " + name + '\n');
//Write vertices; swap axes if necessary
static const LLCachedControl<bool> swapYZ("OBJExportSwapYZ", false);
const double xm = swapYZ ? -1.0 : 1.0;
const int y = swapYZ ? 2 : 1;
const int z = swapYZ ? 1 : 2;
for (vert_t::iterator v_iter = vertices.begin(); v_iter != vertices.end(); ++v_iter)
for (const auto& vert : vertices)
{
++count;
const LLVector3 v = v_iter->first + offset;
const LLVector3 v = vert.first + offset;
write_or_bust(fp, llformat("v %f %f %f\n",v[0] * xm, v[y], v[z]));
}
for (vec3_t::iterator n_iter = normals.begin(); n_iter != normals.end(); ++n_iter)
for (const auto& n : normals)
{
const LLVector3 n = *n_iter;
write_or_bust(fp, llformat("vn %f %f %f\n",n[0] * xm, n[y], n[z]));
}
for (vert_t::iterator v_iter = vertices.begin(); v_iter != vertices.end(); ++v_iter)
for (const auto& vert : vertices)
{
write_or_bust(fp, llformat("vt %f %f\n", v_iter->second[0], v_iter->second[1]));
write_or_bust(fp, llformat("vt %f %f\n", vert.second[0], vert.second[1]));
}
//Write triangles
for (tri_t::iterator t_iter = triangles.begin(); t_iter != triangles.end(); ++t_iter)
for (const auto& triangle : triangles)
{
const int f1 = t_iter->v0 + index + 1;
const int f2 = t_iter->v1 + index + 1;
const int f3 = t_iter->v2 + index + 1;
const int f1 = triangle.v0 + index + 1;
const int f2 = triangle.v1 + index + 1;
const int f3 = triangle.v2 + index + 1;
write_or_bust(fp, llformat("f %d/%d/%d %d/%d/%d %d/%d/%d\n",
f1,f1,f1,f2,f2,f2,f3,f3,f3));
}

View File

@@ -32,16 +32,18 @@
// library includes
#include "aifilepicker.h"
#include "llavatarnamecache.h"
#include "llnotificationsutil.h"
// newview includes
#include "lfsimfeaturehandler.h"
#include "llface.h"
#include "llvovolume.h"
#include "llviewerinventory.h"
#include "llinventorymodel.h"
#include "llinventoryfunctions.h"
#include "llface.h"
#include "llversioninfo.h"
#include "llviewerinventory.h"
#include "llviewertexturelist.h"
#include "llvovolume.h"
// menu includes
#include "llevent.h"
@@ -74,11 +76,11 @@ typedef LLMemberListener<LLView> view_listener_t;
namespace DAEExportUtil
{
static LLUUID LL_TEXTURE_PLYWOOD = LLUUID("89556747-24cb-43ed-920b-47caed15465f");
static LLUUID LL_TEXTURE_BLANK = LLUUID("5748decc-f629-461c-9a36-a35a221fe21f");
static LLUUID LL_TEXTURE_INVISIBLE = LLUUID("38b86f85-2575-52a9-a531-23108d8da837");
static LLUUID LL_TEXTURE_TRANSPARENT = LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903");
static LLUUID LL_TEXTURE_MEDIA = LLUUID("8b5fec65-8d8d-9dc5-cda8-8fdf2716e361");
const auto LL_TEXTURE_PLYWOOD = LLUUID("89556747-24cb-43ed-920b-47caed15465f");
const auto LL_TEXTURE_BLANK = LLUUID("5748decc-f629-461c-9a36-a35a221fe21f");
const auto LL_TEXTURE_INVISIBLE = LLUUID("38b86f85-2575-52a9-a531-23108d8da837");
const auto LL_TEXTURE_TRANSPARENT = LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903");
const auto LL_TEXTURE_MEDIA = LLUUID("8b5fec65-8d8d-9dc5-cda8-8fdf2716e361");
enum image_format_type
{
@@ -105,23 +107,17 @@ namespace DAEExportUtil
// See if any of the inventory items matching this texture id are exportable
ExportPolicy policy = LFSimFeatureHandler::instance().exportPolicy();
for (size_t i = 0; i < items.size(); i++)
for (const auto& item : items)
{
const LLPermissions item_permissions = items[i]->getPermissions();
const LLPermissions item_permissions = item->getPermissions();
if (item_permissions.allowExportBy(gAgentID, policy))
{
if (name != NULL)
{
(*name) = items[i]->getName();
}
if (name) *name = item->getName();
return true;
}
}
if (name != NULL)
{
(*name) = id.getString();
}
if (name) *name = id.getString();
return (policy & ep_full_perm) == ep_full_perm;
}
@@ -206,7 +202,7 @@ public:
}
}
BOOL postBuild()
BOOL postBuild() override
{
mFileName = getChildView("file name editor");
mExportBtn = getChildView("export button");
@@ -306,14 +302,9 @@ public:
S32 getNumExportableTextures()
{
S32 res = 0;
for (DAESaver::string_list_t::const_iterator t = mSaver.mTextureNames.begin(); t != mSaver.mTextureNames.end(); ++t)
for (const auto& name : mSaver.mTextureNames)
{
std::string name = *t;
if (!name.empty())
{
++res;
}
if (!name.empty()) ++res;
}
return res;
@@ -365,7 +356,7 @@ public:
gIdleCallbacks.addFunction(saveTexturesWorker, this);
}
class CacheReadResponder : public LLTextureCache::ReadResponder
class CacheReadResponder final : public LLTextureCache::ReadResponder
{
private:
LLPointer<LLImageFormatted> mFormattedImage;
@@ -413,7 +404,7 @@ public:
mImageLocal = imagelocal;
}
virtual void completed(bool success)
void completed(bool success) override
{
if (success && mFormattedImage.notNull() && mImageSize > 0)
{
@@ -546,10 +537,8 @@ void DAESaver::updateTextureInfo()
{
LLTextureEntry* te = obj->getTE(face_num);
const LLUUID id = te->getID();
if (std::find(mTextures.begin(), mTextures.end(), id) != mTextures.end())
{
continue;
}
if (std::find(mTextures.begin(), mTextures.end(), id) != mTextures.end()) continue;
mTextures.push_back(id);
std::string name;
if (id != DAEExportUtil::LL_TEXTURE_BLANK && DAEExportUtil::canExportTexture(id, &name))
@@ -566,7 +555,6 @@ void DAESaver::updateTextureInfo()
}
}
class v4adapt
{
private:
@@ -579,7 +567,7 @@ public:
}
};
void DAESaver::addSource(daeElement* mesh, const char* src_id, std::string params, const std::vector<F32> &vals)
void DAESaver::addSource(daeElement* mesh, const char* src_id, const std::string& params, const std::vector<F32> &vals)
{
daeElement* source = mesh->add("source");
source->setAttribute("id", src_id);
@@ -588,9 +576,9 @@ void DAESaver::addSource(daeElement* mesh, const char* src_id, std::string param
src_array->setAttribute("id", llformat("%s-%s", src_id, "array").c_str());
src_array->setAttribute("count", llformat("%d", vals.size()).c_str());
for (U32 i = 0; i < vals.size(); i++)
for (const auto& val : vals)
{
((domFloat_array*)src_array)->getValue().append(vals[i]);
static_cast<domFloat_array*>(src_array)->getValue().append(val);
}
domAccessor* acc = daeSafeCast<domAccessor>(source->add("technique_common accessor"));
@@ -598,10 +586,10 @@ void DAESaver::addSource(daeElement* mesh, const char* src_id, std::string param
acc->setCount(vals.size() / params.size());
acc->setStride(params.size());
for (std::string::iterator p_iter = params.begin(); p_iter != params.end(); ++p_iter)
for (const auto& param : params)
{
domElement* pX = acc->add("param");
pX->setAttribute("name", llformat("%c", *p_iter).c_str());
pX->setAttribute("name", (LLStringUtil::null + param).c_str());
pX->setAttribute("type", "float");
}
}
@@ -650,7 +638,7 @@ void DAESaver::addPolygons(daeElement* mesh, const char* geomID, const char* mat
{
for (S32 i = 0; i < face->mNumIndices; i++)
{
U16 index = index_offset + face->mIndices[i];
U32 index = index_offset + face->mIndices[i];
(p->getValue()).append(index);
if (i % 3 == 0)
{
@@ -710,11 +698,21 @@ void DAESaver::transformTexCoord(S32 num_vert, LLVector2* coord, LLVector3* posi
bool DAESaver::saveDAE(std::string filename)
{
// Collada expects file and folder names to be escaped
// Note: cdom::nativePathToUri()
// Same as in LLDAELoader::OpenFile()
const char* allowed =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"%-._~:\"|\\/";
std::string uri_filename = LLURI::escape(filename, allowed);
mAllMaterials.clear();
mTotalNumMaterials = 0;
DAE dae;
// First set the filename to save
daeElement* root = dae.add(filename);
daeElement* root = dae.add(uri_filename);
// Obligatory elements in header
daeElement* asset = root->add("asset");
@@ -734,9 +732,13 @@ bool DAESaver::saveDAE(std::string filename)
up_axis->setCharData("Z_UP");
// File creator
std::string author;
if (!LLAvatarNameCache::getNSName(gAgentID, author))
author = "Unknown";
daeElement* contributor = asset->add("contributor");
contributor->add("author")->setCharData(LLAppViewer::instance()->getSecondLifeTitle() + " User");
contributor->add("authoring_tool")->setCharData(LLAppViewer::instance()->getSecondLifeTitle() + " Collada Export");
contributor->add("author")->setCharData(author);
contributor->add("authoring_tool")->setCharData(LLVersionInfo::getChannelAndVersion() + " Collada Export");
daeElement* images = root->add("library_images");
daeElement* geomLib = root->add("library_geometries");
@@ -825,7 +827,6 @@ bool DAESaver::saveDAE(std::string filename)
}
}
addSource(mesh, llformat("%s-%s", geomID, "positions").c_str(), "XYZ", position_data);
addSource(mesh, llformat("%s-%s", geomID, "normals").c_str(), "XYZ", normal_data);
addSource(mesh, llformat("%s-%s", geomID, "map0").c_str(), "ST", uv_data);
@@ -845,12 +846,11 @@ bool DAESaver::saveDAE(std::string filename)
// Add triangles
if (gSavedSettings.getBOOL("DAEExportConsolidateMaterials"))
{
for (U32 objMaterial = 0; objMaterial < objMaterials.size(); objMaterial++)
for (const auto& objMaterial : objMaterials)
{
int_list_t faces;
getFacesWithMaterial(obj, objMaterials[objMaterial], &faces);
std::string matName = objMaterials[objMaterial].name;
addPolygons(mesh, geomID, (matName + "-material").c_str(), obj, &faces);
getFacesWithMaterial(obj, objMaterial, &faces);
addPolygons(mesh, geomID, (objMaterial.name + "-material").c_str(), obj, &faces);
}
}
else
@@ -888,12 +888,12 @@ bool DAESaver::saveDAE(std::string filename)
// Bind materials
daeElement* tq = nodeGeometry->add("bind_material technique_common");
for (U32 objMaterial = 0; objMaterial < objMaterials.size(); objMaterial++)
for (const auto& objMaterial : objMaterials)
{
std::string matName = objMaterials[objMaterial].name;
daeElement* instanceMaterial = tq->add("instance_material");
instanceMaterial->setAttribute("symbol", (matName + "-material").c_str());
instanceMaterial->setAttribute("target", ("#" + matName + "-material").c_str());
std::string matName = objMaterial.name + "-material";
instanceMaterial->setAttribute("symbol", matName.c_str());
instanceMaterial->setAttribute("target", ('#' + matName).c_str());
}
nodeGeometry->setAttribute("url", llformat("#%s-%s", geomID, "mesh").c_str());
@@ -904,12 +904,12 @@ bool DAESaver::saveDAE(std::string filename)
generateEffects(effects);
// Materials
for (U32 objMaterial = 0; objMaterial < mAllMaterials.size(); objMaterial++)
for (const auto& objMaterial : mAllMaterials)
{
daeElement* mat = materials->add("material");
mat->setAttribute("id", (mAllMaterials[objMaterial].name + "-material").c_str());
mat->setAttribute("id", (objMaterial.name + "-material").c_str());
daeElement* matEffect = mat->add("instance_effect");
matEffect->setAttribute("url", ("#" + mAllMaterials[objMaterial].name + "-fx").c_str());
matEffect->setAttribute("url", ('#' + objMaterial.name + "-fx").c_str());
}
root->add("scene instance_visual_scene")->setAttribute("url", "#Scene");
@@ -930,11 +930,11 @@ DAESaver::MaterialInfo DAESaver::getMaterial(LLTextureEntry* te)
{
if (gSavedSettings.getBOOL("DAEExportConsolidateMaterials"))
{
for (U32 i=0; i < mAllMaterials.size(); i++)
for (const auto& mat : mAllMaterials)
{
if (mAllMaterials[i].matches(te))
if (mat.matches(te))
{
return mAllMaterials[i];
return mat;
}
}
}
@@ -944,7 +944,7 @@ DAESaver::MaterialInfo DAESaver::getMaterial(LLTextureEntry* te)
ret.color = te->getColor();
ret.name = llformat("Material%d", mAllMaterials.size());
mAllMaterials.push_back(ret);
return mAllMaterials[mAllMaterials.size() - 1];
return ret;
}
void DAESaver::getMaterials(LLViewerObject* obj, material_list_t* ret)
@@ -954,10 +954,7 @@ void DAESaver::getMaterials(LLViewerObject* obj, material_list_t* ret)
{
LLTextureEntry* te = obj->getTE(face_num);
if (skipFace(te))
{
continue;
}
if (skipFace(te)) continue;
MaterialInfo mat = getMaterial(te);
@@ -968,7 +965,7 @@ void DAESaver::getMaterials(LLViewerObject* obj, material_list_t* ret)
}
}
void DAESaver::getFacesWithMaterial(LLViewerObject* obj, MaterialInfo& mat, int_list_t* ret)
void DAESaver::getFacesWithMaterial(LLViewerObject* obj, const MaterialInfo& mat, int_list_t* ret)
{
S32 num_faces = obj->getVolume()->getNumVolumeFaces();
for (S32 face_num = 0; face_num < num_faces; ++face_num)
@@ -985,11 +982,11 @@ void DAESaver::generateEffects(daeElement *effects)
// Effects (face color, alpha)
bool export_textures = gSavedSettings.getBOOL("DAEExportTextures");
for (U32 mat = 0; mat < mAllMaterials.size(); mat++)
for (const auto& mat : mAllMaterials)
{
LLColor4 color = mAllMaterials[mat].color;
LLColor4 color = mat.color;
domEffect* effect = (domEffect*)effects->add("effect");
effect->setId((mAllMaterials[mat].name + "-fx").c_str());
effect->setId((mat.name + "-fx").c_str());
daeElement* profile = effect->add("profile_COMMON");
std::string colladaName;
@@ -999,7 +996,7 @@ void DAESaver::generateEffects(daeElement *effects)
U32 i = 0;
for (; i < mTextures.size(); i++)
{
if (mAllMaterials[mat].textureID == mTextures[i])
if (mat.textureID == mTextures[i])
{
textID = mTextures[i];
break;
@@ -1043,19 +1040,18 @@ void DAESaver::generateEffects(daeElement *effects)
void DAESaver::generateImagesSection(daeElement* images)
{
for (U32 i=0; i < mTextureNames.size(); i++)
for (const auto& name : mTextureNames)
{
std::string name = mTextureNames[i];
if (name.empty()) continue;
std::string colladaName = name + "_" + mImageFormat;
std::string colladaName = name + '_' + mImageFormat;
daeElement* image = images->add("image");
image->setAttribute("id", colladaName.c_str());
image->setAttribute("name", colladaName.c_str());
image->add("init_from")->setCharData(LLURI::escape(name + "." + mImageFormat));
image->add("init_from")->setCharData(LLURI::escape(name + '.' + mImageFormat));
}
}
class DAESaveSelectedObjects : public view_listener_t
class DAESaveSelectedObjects final : public view_listener_t
{
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
{

View File

@@ -33,50 +33,29 @@ class LLViewerObject;
class DAESaver
{
public:
class MaterialInfo
struct MaterialInfo
{
public:
LLUUID textureID;
LLColor4 color;
std::string name;
bool matches(LLTextureEntry* te)
bool matches(LLTextureEntry* te) const
{
return (textureID == te->getID()) && (color == te->getColor());
}
bool operator== (const MaterialInfo& rhs)
bool operator== (const MaterialInfo& rhs) const
{
return (textureID == rhs.textureID) && (color == rhs.color) && (name == rhs.name);
}
bool operator!= (const MaterialInfo& rhs)
bool operator!= (const MaterialInfo& rhs) const
{
return !(*this == rhs);
}
MaterialInfo()
{
}
MaterialInfo(const MaterialInfo& rhs)
{
textureID = rhs.textureID;
color = rhs.color;
name = rhs.name;
}
MaterialInfo& operator= (const MaterialInfo& rhs)
{
textureID = rhs.textureID;
color = rhs.color;
name = rhs.name;
return *this;
}
};
typedef std::vector<std::pair<LLViewerObject*,std::string> > obj_info_t;
typedef std::vector<std::pair<LLViewerObject*,std::string>> obj_info_t;
typedef uuid_vec_t id_list_t;
typedef std::vector<std::string> string_list_t;
typedef std::vector<S32> int_list_t;
@@ -97,12 +76,12 @@ public:
private:
void transformTexCoord(S32 num_vert, LLVector2* coord, LLVector3* positions, LLVector3* normals, LLTextureEntry* te, LLVector3 scale);
void addSource(daeElement* mesh, const char* src_id, std::string params, const std::vector<F32> &vals);
void addSource(daeElement* mesh, const char* src_id, const std::string& params, const std::vector<F32> &vals);
void addPolygons(daeElement* mesh, const char* geomID, const char* materialID, LLViewerObject* obj, int_list_t* faces_to_include);
bool skipFace(LLTextureEntry *te);
MaterialInfo getMaterial(LLTextureEntry* te);
void getMaterials(LLViewerObject* obj, material_list_t* ret);
void getFacesWithMaterial(LLViewerObject* obj, MaterialInfo& mat, int_list_t* ret);
void getFacesWithMaterial(LLViewerObject* obj, const MaterialInfo& mat, int_list_t* ret);
void generateEffects(daeElement *effects);
void generateImagesSection(daeElement* images);
};

View File

@@ -95,6 +95,9 @@
;File Handling
SetOverwrite on
;Verify CRC
CRCCheck on
;--------------------------------
;Interface Settings
@@ -209,6 +212,7 @@
!insertmacro MUI_RESERVEFILE_LANGDLL
ReserveFile "${NSISDIR}\Plugins\x86-unicode\INetC.dll"
ReserveFile "${NSISDIR}\Plugins\x86-unicode\nsDialogs.dll"
ReserveFile "${NSISDIR}\Plugins\x86-unicode\nsis7z.dll"
ReserveFile "${NSISDIR}\Plugins\x86-unicode\StartMenu.dll"
ReserveFile "${NSISDIR}\Plugins\x86-unicode\StdUtils.dll"
ReserveFile "${NSISDIR}\Plugins\x86-unicode\System.dll"
@@ -406,7 +410,14 @@ Section "Viewer"
SetOutPath "$INSTDIR"
;Remove old shader files first so fallbacks will work.
RMDir /r "$INSTDIR\app_settings\shaders\*"
;Remove old Microsoft DLLs, reboot if needed
Delete /REBOOTOK "$INSTDIR\api-ms-win-*.dll"
Delete /REBOOTOK "$INSTDIR\concrt*.dll"
Delete /REBOOTOK "$INSTDIR\msvcp*.dll"
Delete /REBOOTOK "$INSTDIR\ucrtbase.dll"
Delete /REBOOTOK "$INSTDIR\vccorlib*.dll"
Delete /REBOOTOK "$INSTDIR\vcruntime*.dll"
;This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py
%%INSTALL_FILES%%
@@ -416,9 +427,9 @@ Section "Viewer"
;Download LibVLC
!ifdef WIN64_BIN_BUILD
inetc::get /RESUME "Failed to download VLC media package. Retry?" "https://videolan.mirrors.hivelocity.net/vlc/3.0.8/win64/vlc-3.0.8-win64.7z" "$TEMP\AlchemyInst\libvlc.7z" /END
inetc::get /RESUME "Failed to download VLC media package. Retry?" "https://download.videolan.org/pub/videolan/vlc/3.0.8/win64/vlc-3.0.8-win64.7z" "$TEMP\AlchemyInst\libvlc.7z" /END
!else
inetc::get /RESUME "Failed to download VLC media package. Retry?" "https://videolan.mirrors.hivelocity.net/vlc/3.0.8/win32/vlc-3.0.8-win32.7z" "$TEMP\AlchemyInst\libvlc.7z" /END
inetc::get /RESUME "Failed to download VLC media package. Retry?" "https://download.videolan.org/pub/videolan/vlc/3.0.8/win32/vlc-3.0.8-win32.7z" "$TEMP\AlchemyInst\libvlc.7z" /END
!endif
Nsis7z::ExtractWithDetails "$TEMP\AlchemyInst\libvlc.7z" "Unpacking media plugins %s..."
Rename "$TEMP\AlchemyInst\vlc-3.0.8\libvlc.dll" "$INSTDIR\llplugin\libvlc.dll"
@@ -457,9 +468,9 @@ Section "Viewer"
CreateShortCut "$SMPROGRAMS\$STARTMENUFOLDER\$INSTSHORTCUT.lnk" "$\"$INSTDIR\$INSTEXE$\"" "$SHORTCUT_LANG_PARAM"
CreateShortCut "$SMPROGRAMS\$STARTMENUFOLDER\Uninstall $INSTSHORTCUT.lnk" "$\"$INSTDIR\uninst.exe$\"" ""
!endif
WriteINIStr "$SMPROGRAMS\$STARTMENUFOLDER\SL Create Account.url" "InternetShortcut" "URL" "http://join.secondlife.com/"
WriteINIStr "$SMPROGRAMS\$STARTMENUFOLDER\SL Your Account.url" "InternetShortcut" "URL" "http://www.secondlife.com/account/"
WriteINIStr "$SMPROGRAMS\$STARTMENUFOLDER\SL Scripting Language Help.url" "InternetShortcut" "URL" "http://wiki.secondlife.com/wiki/LSL_Portal"
WriteINIStr "$SMPROGRAMS\$STARTMENUFOLDER\SL Create Account.url" "InternetShortcut" "URL" "https://join.secondlife.com/"
WriteINIStr "$SMPROGRAMS\$STARTMENUFOLDER\SL Your Account.url" "InternetShortcut" "URL" "https://www.secondlife.com/account/"
WriteINIStr "$SMPROGRAMS\$STARTMENUFOLDER\SL Scripting Language Help.url" "InternetShortcut" "URL" "https://wiki.secondlife.com/wiki/LSL_Portal"
!insertmacro MUI_STARTMENU_WRITE_END

View File

@@ -55,9 +55,8 @@
## - For advanced debugging cases, you can run the viewer under the
## control of another program, such as strace, gdb, or valgrind. If
## you're building your own viewer, bear in mind that the executable
## in the bin directory will be stripped: you should replace it with
## an unstripped binary before you run.
## you're building your own viewer, run the configure step with
## -DPACKAGE:BOOL=OFF to produce an unstripped binary for debugging.
if [ -n "$ASCENDED_DEVELOPER" ]; then
if [ "$ASCENDED_DEVELOPER" = "1" ]; then
export LL_WRAPPER='gdb --args'

View File

@@ -40,11 +40,21 @@
/// Classes for AISv3 support.
///----------------------------------------------------------------------------
extern AIHTTPTimeoutPolicy AISAPIResponder_timeout;
class AISCommand final : public LLHTTPClient::ResponderWithCompleted
{
public:
typedef boost::function<void()> command_func_type;
// AISCommand - base class for retry-able HTTP requests using the AISv3 cap.
// Limit max in flight requests to 2. Server was aggressively throttling otherwise.
constexpr static U8 sMaxActiveAISCommands = 4;
static U8 sActiveAISCommands;
static std::queue< boost::intrusive_ptr< AISCommand > > sPendingAISCommands;
virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return AISAPIResponder_timeout; }
AISCommand(AISAPI::COMMAND_TYPE type, const char* name, const LLUUID& targetId, AISAPI::completion_t callback) :
mCommandFunc(NULL),
mRetryPolicy(new LLAdaptiveRetryPolicy(1.0, 32.0, 2.0, 10)),
@@ -53,10 +63,30 @@ public:
mName(name),
mType(type)
{}
virtual ~AISCommand()
{
if (mActive)
{
--sActiveAISCommands;
while (sActiveAISCommands < sMaxActiveAISCommands && !sPendingAISCommands.empty())
{
sPendingAISCommands.front()->dispatch();
sPendingAISCommands.pop();
}
}
}
void run( command_func_type func )
{
(mCommandFunc = func)();
mCommandFunc = func;
if (sActiveAISCommands >= sMaxActiveAISCommands)
{
sPendingAISCommands.push(this);
}
else
{
dispatch();
}
}
char const* getName(void) const override
@@ -64,6 +94,17 @@ public:
return mName;
}
private:
void dispatch()
{
if (LLApp::isQuitting())
{
return;
}
++sActiveAISCommands;
mActive = true;
(mCommandFunc)();
}
void markComplete()
{
// Command func holds a reference to self, need to release it
@@ -72,42 +113,56 @@ public:
mRetryPolicy->onSuccess();
}
void malformedResponse() { mStatus = HTTP_INTERNAL_ERROR_OTHER; mReason = llformat("Malformed response contents (original code: %d)", mStatus); }
bool onFailure()
{
bool retry = mStatus != HTTP_INTERNAL_ERROR_OTHER && mStatus != 410; // We handle these and stop
LL_WARNS("Inventory") << "Inventory error: " << dumpResponse() << LL_ENDL;
if (retry) mRetryPolicy->onFailure(mStatus, getResponseHeaders());
mRetryPolicy->onFailure(mStatus, getResponseHeaders());
F32 seconds_to_wait;
if (retry && mRetryPolicy->shouldRetry(seconds_to_wait))
if (mRetryPolicy->shouldRetry(seconds_to_wait))
{
if (mStatus == 503)
{
// Pad delay a bit more since we're getting throttled.
seconds_to_wait += 10.f + ll_frand(4.f);
}
LL_WARNS("Inventory") << "Retrying in " << seconds_to_wait << "seconds due to inventory error for " << getName() <<": " << dumpResponse() << LL_ENDL;
doAfterInterval(mCommandFunc,seconds_to_wait);
return true;
}
else
{
// Command func holds a reference to self, need to release it
// after a success or final failure.
// *TODO: Notify user? This seems bad.
LL_WARNS("Inventory") << "Abort due to inventory error for " << getName() <<": " << dumpResponse() << LL_ENDL;
mCommandFunc = no_op;
return false;
}
return retry;
}
protected:
void httpCompleted() override
{
AISAPI::InvokeAISCommandCoro(this, getURL(), mTargetId, getContent(), mCompletionFunc, (AISAPI::COMMAND_TYPE)mType);
// Continue through if successful or longer retrying,
if (isGoodStatus(mStatus) || !onFailure())
{
markComplete();
AISAPI::InvokeAISCommandCoro(this, getURL(), mTargetId, getContent(), mCompletionFunc, (AISAPI::COMMAND_TYPE)mType);
}
}
private:
command_func_type mCommandFunc;
LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
AISAPI::completion_t mCompletionFunc;
const LLUUID mTargetId;
const char* mName;
bool mActive = false;
AISAPI::COMMAND_TYPE mType;
};
U8 AISCommand::sActiveAISCommands = 0;
std::queue< boost::intrusive_ptr< AISCommand > > AISCommand::sPendingAISCommands;
//=========================================================================
const std::string AISAPI::INVENTORY_CAP_NAME("InventoryAPIv3");
const std::string AISAPI::LIBRARY_CAP_NAME("LibraryAPIv3");
@@ -312,21 +367,18 @@ void AISAPI::UpdateItem(const LLUUID &itemId, const LLSD &updates, completion_t
boost::intrusive_ptr< AISCommand > responder = new AISCommand(UPDATEITEM, "UpdateItem",itemId, callback);
responder->run(boost::bind(&LLHTTPClient::patch, url, updates, responder/*,*/ DEBUG_CURLIO_PARAM(debug_off), keep_alive, (AIStateMachine*)NULL, 0));
}
void AISAPI::InvokeAISCommandCoro(AISCommand* responder,
void AISAPI::InvokeAISCommandCoro(LLHTTPClient::ResponderWithCompleted* responder,
std::string url,
LLUUID targetId, LLSD result, completion_t callback, COMMAND_TYPE type)
{
LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL;
auto status = responder->getStatus();
auto status = responder->getStatus();
if (!responder->isGoodStatus(status) || !result.isMap())
{
if (!result.isMap())
{
responder->malformedResponse();
}
else if (status == 410) //GONE
{
LL_WARNS("Inventory") << "Inventory error: " << status << ": " << responder->getReason() << LL_ENDL;
if (status == 410) //GONE
{
// Item does not exist or was already deleted from server.
// parent folder is out of sync
@@ -360,11 +412,12 @@ void AISAPI::InvokeAISCommandCoro(AISCommand* responder,
}
}
}
// Keep these statuses accounted for in the responder too
if (responder->onFailure()) // If we're retrying, exit early.
return;
if (!result.isMap())
{
LL_WARNS("Inventory") << "Inventory error: Malformed response contents" << LL_ENDL;
}
LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL;
}
else responder->markComplete();
gInventory.onAISUpdateReceived("AISCommand", result);

View File

@@ -72,7 +72,7 @@ private:
static std::string getInvCap();
static std::string getLibCap();
static void InvokeAISCommandCoro(class AISCommand* responder,
static void InvokeAISCommandCoro(LLHTTPClient::ResponderWithCompleted* responder,
std::string url, LLUUID targetId, LLSD body,
completion_t callback, COMMAND_TYPE type);
};

View File

@@ -26,7 +26,6 @@
#include "llviewerprecompiledheaders.h"
#include <boost/lexical_cast.hpp>
#include "llagent.h"
#include "llagentcamera.h"
#include "llagentwearables.h"
@@ -3994,7 +3993,7 @@ LLSD LLAppearanceMgr::dumpCOF() const
LLUUID linked_asset_id(linked_item->getAssetUUID());
md5.update((unsigned char*)linked_asset_id.mData, 16);
U32 flags = linked_item->getFlags();
md5.update(boost::lexical_cast<std::string>(flags));
md5.update(fmt::to_string(flags));
}
else if (LLAssetType::AT_LINK_FOLDER != inv_item->getActualType())
{

View File

@@ -235,7 +235,7 @@ struct crashpad_annotation : public crashpad::Annotation {
crashpad_annotation(const char* name) : crashpad::Annotation(T, name, buffer.data())
{}
void set(const std::string& src) {
LL_INFOS() << name() << ": " << src.c_str() << LL_ENDL;
//LL_INFOS() << name() << ": " << src.c_str() << LL_ENDL;
const size_t min_size = llmin(SIZE, src.size());
memcpy(buffer.data(), src.data(), min_size);
buffer.data()[SIZE - 1] = '\0';
@@ -243,18 +243,27 @@ struct crashpad_annotation : public crashpad::Annotation {
}
};
#define DEFINE_CRASHPAD_ANNOTATION(name, len) \
static crashpad_annotation<len> g_crashpad_annotation_##name##_buffer(#name);
static crashpad_annotation<len> g_crashpad_annotation_##name##_buffer("sentry[tags]["#name"]");
#define DEFINE_CRASHPAD_ANNOTATION_EXTRA(name, len) \
static crashpad_annotation<len> g_crashpad_annotation_##name##_buffer("sentry[extra]["#name"]");
#define SET_CRASHPAD_ANNOTATION_VALUE(name, value) \
g_crashpad_annotation_##name##_buffer.set(value);
#else
#define SET_CRASHPAD_ANNOTATION_VALUE(name, value)
#define DEFINE_CRASHPAD_ANNOTATION_EXTRA(name, len)
#define DEFINE_CRASHPAD_ANNOTATION(name, len)
#endif
DEFINE_CRASHPAD_ANNOTATION(fatal_message, 512);
DEFINE_CRASHPAD_ANNOTATION_EXTRA(fatal_message, 512);
DEFINE_CRASHPAD_ANNOTATION(grid_name, 64);
DEFINE_CRASHPAD_ANNOTATION(cpu_string, 128);
DEFINE_CRASHPAD_ANNOTATION(startup_state, 32);
DEFINE_CRASHPAD_ANNOTATION(region_name, 64);
DEFINE_CRASHPAD_ANNOTATION_EXTRA(cpu_string, 128);
DEFINE_CRASHPAD_ANNOTATION_EXTRA(gpu_string, 128);
DEFINE_CRASHPAD_ANNOTATION_EXTRA(gl_version, 128);
DEFINE_CRASHPAD_ANNOTATION_EXTRA(session_duration, 32);
DEFINE_CRASHPAD_ANNOTATION_EXTRA(startup_state, 32);
DEFINE_CRASHPAD_ANNOTATION_EXTRA(memory_sys, 32);
DEFINE_CRASHPAD_ANNOTATION_EXTRA(memory_alloc, 32);
////// Windows-specific includes to the bottom - nasty defines in these pollute the preprocessor
//
@@ -1076,6 +1085,8 @@ bool LLAppViewer::init()
gGLManager.getGLInfo(gDebugInfo);
gGLManager.printGLInfoString();
writeDebugInfo();
// Load Default bindings
load_default_bindings(gSavedSettings.getBOOL("LiruUseZQSDKeys"));
@@ -1163,6 +1174,8 @@ bool LLAppViewer::init()
// save the graphics card
gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString();
writeDebugInfo();
// Save the current version to the prefs file
gSavedSettings.setString("LastRunVersion",
LLVersionInfo::getChannelAndVersion());
@@ -1180,6 +1193,8 @@ bool LLAppViewer::init()
gGLActive = FALSE;
LLViewerMedia::initClass();
LL_INFOS("InitInfo") << "Viewer media initialized." << LL_ENDL ;
writeDebugInfo();
return true;
}
@@ -1331,6 +1346,12 @@ bool LLAppViewer::mainLoop()
//clear call stack records
LL_CLEAR_CALLSTACKS();
#ifdef USE_CRASHPAD
// Not event based. Update per frame
SET_CRASHPAD_ANNOTATION_VALUE(session_duration, fmt::to_string(LLFrameTimer::getElapsedSeconds()));
SET_CRASHPAD_ANNOTATION_VALUE(memory_alloc, fmt::to_string((LLMemory::getCurrentRSS() >> 10)/1000.f));
#endif
//check memory availability information
checkMemory() ;
@@ -2784,7 +2805,13 @@ void LLAppViewer::writeDebugInfo(bool isStatic)
#else
SET_CRASHPAD_ANNOTATION_VALUE(fatal_message, gDebugInfo["FatalMessage"].asString());
SET_CRASHPAD_ANNOTATION_VALUE(grid_name, gDebugInfo["GridName"].asString());
SET_CRASHPAD_ANNOTATION_VALUE(region_name, gDebugInfo["CurrentRegion"].asString());
SET_CRASHPAD_ANNOTATION_VALUE(cpu_string, gDebugInfo["CPUInfo"]["CPUString"].asString());
SET_CRASHPAD_ANNOTATION_VALUE(gpu_string, gDebugInfo["GraphicsCard"].asString());
SET_CRASHPAD_ANNOTATION_VALUE(gl_version, gDebugInfo["GLInfo"]["GLVersion"].asString());
SET_CRASHPAD_ANNOTATION_VALUE(session_duration, fmt::to_string(LLFrameTimer::getElapsedSeconds()));
SET_CRASHPAD_ANNOTATION_VALUE(memory_alloc, fmt::to_string((LLMemory::getCurrentRSS() >> 10) / 1000.f));
SET_CRASHPAD_ANNOTATION_VALUE(memory_sys, fmt::to_string(gDebugInfo["RAMInfo"]["Physical"].asInteger() * 0.001f));
#endif
}
@@ -2969,8 +2996,8 @@ void LLAppViewer::handleViewerCrash()
gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
gDebugInfo["Dynamic"]["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds());
gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
gDebugInfo["Dynamic"]["RAMInfo"]["Allocated"] = (LLSD::Integer) LLMemory::getCurrentRSS() >> 10;
gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin();
gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
@@ -4832,11 +4859,14 @@ void LLAppViewer::disconnectViewer()
// floater_sound_preview.xml
// floater_animation_preview.xml
// files.
// A more generic mechanism would be nice..
LLFloater* fl = static_cast<LLFloater*>(*it);
if (fl
&& (fl->getName() == "Image Preview"
|| fl->getName() == "Sound Preview"
|| fl->getName() == "Animation Preview"
|| fl->getName() == "perm prefs"
))
{
floaters_to_close.push_back(fl);
@@ -5054,6 +5084,10 @@ void LLAppViewer::handleLoginComplete()
}
mOnLoginCompleted();
// Singu Note: This would usually be registered via mOnLoginCompleted, but that would require code in newview regardless so.. just call directly here.
LLNotifications::instance().onLoginCompleted();
// Singu Note: Due to MAINT-4001, we must do this here, it lives in LLSidepanelInventory::updateInbox upstream.
// Consolidate Received items
// We shouldn't have to do that but with a client/server system relying on a "well known folder" convention,

View File

@@ -349,7 +349,10 @@ bool LLAttachmentsMgr::getPendingAttachments(uuid_set_t& ids) const
ids.clear();
// Returns the union of the LL maintained list of attachments that are waiting for link creation and our maintained list of attachments that are pending link creation
set_union(mRecentlyArrivedAttachments.begin(), mRecentlyArrivedAttachments.end(), mPendingAttachLinks.begin(), mPendingAttachLinks.end(), std::inserter(ids, ids.begin()));
ids.insert(mRecentlyArrivedAttachments.begin(), mRecentlyArrivedAttachments.end());
ids.insert(mPendingAttachLinks.begin(), mPendingAttachLinks.end());
// Singu Note: "Expression: Sequence not ordered" using std::set_union
//set_union(mRecentlyArrivedAttachments.begin(), mRecentlyArrivedAttachments.end(), mPendingAttachLinks.begin(), mPendingAttachLinks.end(), std::inserter(ids, ids.begin()));
return !ids.empty();
}

View File

@@ -531,17 +531,24 @@ void LLChatBar::sendChat( EChatType type )
// static
void LLChatBar::startChat(const char* line)
{
if (!gChatBar || !gChatBar->getParent())
{
return;
}
gChatBar->getParent()->setVisible(TRUE);
gChatBar->setKeyboardFocus(TRUE);
gSavedSettings.setBOOL("ChatVisible", TRUE);
if (line && gChatBar->mInputEditor)
if (gChatBar->mInputEditor)
{
std::string line_string(line);
gChatBar->mInputEditor->setText(line_string);
if (line)
{
std::string line_string(line);
gChatBar->mInputEditor->setText(line_string);
}
// always move cursor to end so users don't obliterate chat when accidentally hitting WASD
gChatBar->mInputEditor->setCursorToEnd();
}
// always move cursor to end so users don't obliterate chat when accidentally hitting WASD
gChatBar->mInputEditor->setCursorToEnd();
}
@@ -550,7 +557,8 @@ void LLChatBar::startChat(const char* line)
void LLChatBar::stopChat()
{
// In simple UI mode, we never release focus from the chat bar
gChatBar->setKeyboardFocus(FALSE);
if (gChatBar)
gChatBar->setKeyboardFocus(FALSE);
// If we typed a movement key and pressed return during the
// same frame, the keyboard handlers will see the key as having
@@ -562,7 +570,8 @@ void LLChatBar::stopChat()
gAgent.stopTyping();
// hide chat bar so it doesn't grab focus back
gChatBar->getParent()->setVisible(FALSE);
if (gChatBar && gChatBar->getParent())
gChatBar->getParent()->setVisible(FALSE);
gSavedSettings.setBOOL("ChatVisible", FALSE);
}

View File

@@ -515,6 +515,10 @@ void LLCloudLayer::connectNeighbor(LLCloudLayer *cloudp, U32 direction)
return;
}
if (mNeighbors[direction])
{
mNeighbors[direction]->mNeighbors[gDirOpposite[direction]] = NULL;
}
mNeighbors[direction] = cloudp;
if (cloudp)
mNeighbors[direction]->mNeighbors[gDirOpposite[direction]] = this;

View File

@@ -1596,11 +1596,7 @@ void LLSpatialBridge::cleanupReferences()
LLDrawable::cleanupReferences();
if (mDrawable)
{
/*
DON'T DO THIS -- this should happen through octree destruction
mDrawable->setSpatialGroup(NULL);
mDrawable->setGroup(NULL);
if (mDrawable->getVObj())
{
LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
@@ -1608,17 +1604,18 @@ void LLSpatialBridge::cleanupReferences()
iter != child_list.end(); iter++)
{
LLViewerObject* child = *iter;
LLDrawable* drawable = child->mDrawable;
LLDrawable* drawable = child->mDrawable;
if (drawable)
{
drawable->setSpatialGroup(NULL);
drawable->setGroup(NULL);
}
}
}*/
}
LLPointer<LLDrawable> drawablep = mDrawable;
LLPointer<LLSpatialBridge> bridgep = mDrawable->getSpatialBridge();
mDrawable->setSpatialBridge(nullptr);
mDrawable = nullptr;
drawablep->setSpatialBridge(nullptr);
bridgep = nullptr;
}
}

View File

@@ -52,7 +52,6 @@
#include "llworld.h"
#include <boost/date_time.hpp>
#include <boost/lexical_cast.hpp>
// [RLVa:KB]
#include "rlvhandler.h"
@@ -1006,7 +1005,7 @@ void LLFloaterAvatarList::refreshAvatarList()
color = sRadarTextYoung;
}
}
agep.value = age_set ? boost::lexical_cast<std::string>(entry->mAge) : "?";
agep.value = age_set ? fmt::to_string(entry->mAge) : "?";
agep.color = color;
element.columns.add(agep);
}
@@ -1069,7 +1068,7 @@ void LLFloaterAvatarList::refreshAvatarList()
else
{
LLStringUtil::format_map_t args;
args["[COUNT]"] = boost::lexical_cast<std::string>(mAvatars.size());
args["[COUNT]"] = fmt::to_string(mAvatars.size());
setTitle(getString("TitleWithCount", args));
}

View File

@@ -277,19 +277,19 @@ void LLFloaterBuyCurrencyUI::updateUI()
S32 balance = gStatusBar->getBalance();
childShow("balance_label");
childShow("balance_amount");
childSetTextArg("balance_amount", "[AMT]", llformat("%d", balance));
childSetTextArg("balance_amount", "[AMT]", fmt::to_string(balance));
childSetTextArg("balance_amount", "[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol());
S32 buying = mManager.getAmount();
childShow("buying_label");
childShow("buying_amount");
childSetTextArg("buying_amount", "[AMT]", llformat("%d", buying));
childSetTextArg("buying_amount", "[AMT]", fmt::to_string(buying));
childSetTextArg("buying_amount", "[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol());
S32 total = balance + buying;
childShow("total_label");
childShow("total_amount");
childSetTextArg("total_amount", "[AMT]", llformat("%d", total));
childSetTextArg("total_amount", "[AMT]", fmt::to_string(total));
childSetTextArg("total_amount", "[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol());
childSetVisible("purchase_warning_repurchase", false);

View File

@@ -79,7 +79,7 @@
//
LLColor4 agent_chat_color(const LLUUID& id, const std::string&, bool local_chat = true);
LLColor4 get_text_color(const LLChat& chat, bool from_im = false);
void show_log_browser(const std::string&, const std::string&);
void show_log_browser(const std::string&, const LLUUID&);
//
// Member Functions
@@ -96,7 +96,7 @@ LLFloaterChat::LLFloaterChat(const LLSD& seed)
LLTextEditor* history_editor_with_mute = getChild<LLTextEditor>("Chat History Editor with mute");
getChild<LLUICtrl>("show mutes")->setCommitCallback(boost::bind(&LLFloaterChat::onClickToggleShowMute, this, _2, getChild<LLTextEditor>("Chat History Editor"), history_editor_with_mute));
getChild<LLUICtrl>("chat_history_open")->setCommitCallback(boost::bind(show_log_browser, "chat", "chat"));
getChild<LLUICtrl>("chat_history_open")->setCommitCallback(boost::bind(show_log_browser, "chat", LLUUID::null));
}
LLFloaterChat::~LLFloaterChat()
@@ -243,7 +243,7 @@ void log_chat_text(const LLChat& chat)
else
histstr = chat.mText;
LLLogChat::saveHistory(std::string("chat"), histstr);
LLLogChat::saveHistory("chat", LLUUID::null, histstr);
}
// static
void LLFloaterChat::addChatHistory(LLChat& chat, bool log_to_file)
@@ -535,28 +535,19 @@ LLColor4 get_text_color(const LLChat& chat, bool from_im)
//static
void LLFloaterChat::loadHistory()
{
LLLogChat::loadHistory("chat", &chatFromLogFile, (void*)LLFloaterChat::getInstance());
LLLogChat::loadHistory("chat", LLUUID::null, boost::bind(&LLFloaterChat::chatFromLogFile, getInstance(), _1, _2));
}
//static
void LLFloaterChat::chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata)
void LLFloaterChat::chatFromLogFile(LLLogChat::ELogLineType type, const std::string& line)
{
switch (type)
bool log_line = type == LLLogChat::LOG_LINE;
if (log_line || gSavedPerAccountSettings.getBOOL("LogChat"))
{
case LLLogChat::LOG_EMPTY:
if (gSavedPerAccountSettings.getBOOL("LogChat"))
addChatHistory(static_cast<LLFloaterChat*>(userdata)->getString("IM_logging_string"), false);
break;
case LLLogChat::LOG_END:
if (gSavedPerAccountSettings.getBOOL("LogChat"))
addChatHistory(static_cast<LLFloaterChat*>(userdata)->getString("IM_end_log_string"), false);
break;
case LLLogChat::LOG_LINE:
addChatHistory(line, FALSE);
break;
default:
// nothing
break;
LLStyleSP style(new LLStyle(true, gSavedSettings.getColor4("LogChatColor"), LLStringUtil::null));
const auto text = log_line ? line : getString(type == LLLogChat::LOG_END ? "IM_end_log_string" : "IM_logging_string");
for (const auto& ed_name : { "Chat History Editor", "Chat History Editor with mute" })
getChild<LLTextEditor>(ed_name)->appendText(text, false, true, style, false);
}
}

View File

@@ -73,7 +73,7 @@ public:
static void triggerAlerts(const std::string& text);
void onClickToggleShowMute(bool show_mute, class LLTextEditor* history_editor, LLTextEditor* history_editor_with_mute);
static void chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata);
void chatFromLogFile(LLLogChat::ELogLineType type, const std::string& line);
static void loadHistory();
static void* createSpeakersPanel(void* data);
static void* createChatPanel(void* data);

View File

@@ -58,6 +58,7 @@ LLFloaterInspect::LLFloaterInspect(const LLSD&)
mDirty(FALSE)
{
mCommitCallbackRegistrar.add("Inspect.OwnerProfile", boost::bind(&LLFloaterInspect::onClickOwnerProfile, this));
mCommitCallbackRegistrar.add("Inspect.LastOwnerProfile", boost::bind(&LLFloaterInspect::onClickLastOwnerProfile, this));
mCommitCallbackRegistrar.add("Inspect.CreatorProfile", boost::bind(&LLFloaterInspect::onClickCreatorProfile, this));
mCommitCallbackRegistrar.add("Inspect.SelectObject", boost::bind(&LLFloaterInspect::onSelectObject, this));
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inspect.xml");
@@ -166,6 +167,36 @@ void LLFloaterInspect::onClickOwnerProfile()
}
}
void LLFloaterInspect::onClickLastOwnerProfile()
{
if(mObjectList->getAllSelected().size() == 0) return;
LLScrollListItem* first_selected =mObjectList->getFirstSelected();
if (first_selected)
{
LLUUID selected_id = first_selected->getUUID();
struct f : public LLSelectedNodeFunctor
{
LLUUID obj_id;
f(const LLUUID& id) : obj_id(id) {}
virtual bool apply(LLSelectNode* node)
{
return (obj_id == node->getObject()->getID());
}
} func(selected_id);
LLSelectNode* node = mObjectSelection->getFirstNode(&func);
if(node)
{
const LLUUID& last_owner_id = node->mPermissions->getLastOwner();
// [RLVa:KB] - Checked: 2010-08-25 (RLVa-1.2.2a) | Modified: RLVa-1.0.0e
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES) || gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMETAGS))
if (last_owner_id == node->mPermissions->getOwner()) return;
// [/RLVa:KB]
LLAvatarActions::showProfile(last_owner_id);
}
}
}
void LLFloaterInspect::onSelectObject()
{
if(LLFloaterInspect::getSelectedUUID() != LLUUID::null)

View File

@@ -60,6 +60,7 @@ public:
virtual void onFocusReceived();
void onClickCreatorProfile();
void onClickOwnerProfile();
void onClickLastOwnerProfile();
void onSelectObject();
LLScrollListCtrl* mObjectList;

View File

@@ -1454,7 +1454,7 @@ void LLPanelLandObjects::onClickReturnOwnerList()
LLSD args;
args["NAME"] = mSelectedName;
args["N"] = std::to_string(mSelectedCount);
args["N"] = fmt::to_string(mSelectedCount);
if (mSelectedIsGroup)
{
LLNotificationsUtil::add("ReturnObjectsDeededToGroup", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerList, this, _1, _2));
@@ -1665,7 +1665,7 @@ void LLPanelLandObjects::onClickReturnOwnerObjects()
LLUUID owner_id = parcel->getOwnerID();
LLSD args;
args["N"] = std::to_string(owned);
args["N"] = fmt::to_string(owned);
if (owner_id == gAgent.getID())
{

View File

@@ -45,8 +45,6 @@
#include "llmutelist.h"
#include "llnamelistctrl.h"
#include <boost/lexical_cast.hpp>
//
// Constants
//

View File

@@ -148,7 +148,7 @@ S32 LLFloaterNameDesc::getExpectedUploadCost() const
LLAssetType::EType asset_type = exten == "wav" ? LLAssetType::AT_SOUND
: (exten == "anim" || exten == "bvh") ? LLAssetType::AT_ANIMATION
: exten != "lsl" ? LLAssetType::AT_TEXTURE
: asset_type = LLAssetType::AT_NONE;
: LLAssetType::AT_NONE;
S32 upload_cost = -1;
if (asset_type != LLAssetType::AT_NONE)

View File

@@ -114,7 +114,7 @@ void LLFloaterObjectIMInfo::onClickMute()
// [/RLVa:KB]
LLMuteList::instance().add(LLMute(mOwnerID, mName, mGroupOwned ? LLMute::GROUP : LLMute::AGENT));
LLFloaterMute::showInstance();
LLFloaterMute::showInstance()->selectMute(mOwnerID);
close();
}

View File

@@ -42,6 +42,7 @@
#include "llviewerwindow.h"
#include "lluictrlfactory.h"
#include "llpermissions.h"
#include "llsdserialize.h"
#include "hippogridmanager.h"
extern class AIHTTPTimeoutPolicy floaterPermsResponder_timeout;
@@ -63,6 +64,25 @@ U32 LLFloaterPerms::getEveryonePerms(std::string prefix)
return flags;
}
//static
U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix)
{
U32 flags = PERM_MOVE;
if ( gSavedSettings.getBOOL(prefix+"NextOwnerCopy") )
{
flags |= PERM_COPY;
}
if ( gSavedSettings.getBOOL(prefix+"NextOwnerModify") )
{
flags |= PERM_MODIFY;
}
if ( gSavedSettings.getBOOL(prefix+"NextOwnerTransfer") )
{
flags |= PERM_TRANSFER;
}
return flags;
}
//static
U32 LLFloaterPerms::getNextOwnerPermsInverted(std::string prefix)
{
@@ -83,25 +103,6 @@ U32 LLFloaterPerms::getNextOwnerPermsInverted(std::string prefix)
return flags;
}
//static
U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix)
{
U32 flags = PERM_MOVE;
if ( gSavedSettings.getBOOL(prefix+"NextOwnerCopy") )
{
flags |= PERM_COPY;
}
if ( gSavedSettings.getBOOL(prefix+"NextOwnerModify") )
{
flags |= PERM_MODIFY;
}
if ( gSavedSettings.getBOOL(prefix+"NextOwnerTransfer") )
{
flags |= PERM_TRANSFER;
}
return flags;
}
namespace
{
void handle_checkboxes(LLView* view, const std::string& ctrl_name, const LLSD& value, const std::string& type)
@@ -138,6 +139,7 @@ LLFloaterPermsDefault::LLFloaterPermsDefault(const LLSD& seed)
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml");
}
// String equivalents of enum Categories - initialization order must match enum order!
const std::string LLFloaterPermsDefault::sCategoryNames[CAT_LAST] =
{
@@ -224,41 +226,66 @@ void LLFloaterPermsDefault::onClickCancel()
close();
}
class LLFloaterPermsResponder : public LLHTTPClient::ResponderWithResult
struct LLFloaterPermsRequester final : LLSingleton<LLFloaterPermsRequester>
{
friend class LLSingleton<LLFloaterPermsRequester>;
std::string mUrl;
LLSD mReport;
U8 mRetriesCount = 0;
static void init(const std::string url, const LLSD report)
{
auto& inst = instance();
inst.mUrl = url;
inst.mReport = report;
inst.retry();
}
bool retry();
};
class LLFloaterPermsResponder final : public LLHTTPClient::ResponderWithResult
{
public:
LLFloaterPermsResponder() : LLHTTPClient::ResponderWithResult() {}
private:
static std::string sPreviousReason;
void httpFailure(void)
void httpFailure() override
{
// <singu> Prevent 404s from annoying the user all the tme
if (mStatus == HTTP_NOT_FOUND)
LL_INFOS("FloaterPermsResponder") << "Failed to send default permissions to simulator. 404, reason: " << mReason << LL_ENDL;
else
// </singu>
auto* requester = LLFloaterPermsRequester::getIfExists();
if (!requester || requester->retry()) return;
LLFloaterPermsRequester::deleteSingleton();
const std::string& reason = getReason();
// Do not display the same error more than once in a row
if (mReason != sPreviousReason)
if (reason != sPreviousReason)
{
sPreviousReason = mReason;
sPreviousReason = reason;
LLSD args;
args["REASON"] = mReason;
args["REASON"] = reason;
LLNotificationsUtil::add("DefaultObjectPermissions", args);
}
}
void httpSuccess(void)
void httpSuccess() override
{
//const LLSD& content = getContent();
//dump_sequential_xml("perms_responder_result.xml", content);
// Since we have had a successful POST call be sure to display the next error message
// even if it is the same as a previous one.
sPreviousReason = "";
mCapSent = true;
LL_INFOS("FloaterPermsResponder") << "Sent default permissions to simulator" << LL_ENDL;
LL_INFOS("ObjectPermissionsFloater") << "Default permissions successfully sent to simulator" << LL_ENDL;
}
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy() const { return floaterPermsResponder_timeout; }
/*virtual*/ char const* getName() const { return "LLFloaterPermsResponder"; }
AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy() const override { return floaterPermsResponder_timeout; }
char const* getName() const override { return "LLFloaterPermsResponder"; }
};
bool LLFloaterPermsRequester::retry()
{
if (++mRetriesCount < 5)
{
LLHTTPClient::post(mUrl, mReport, new LLFloaterPermsResponder);
return true;
}
return false;
}
std::string LLFloaterPermsResponder::sPreviousReason;
void LLFloaterPermsDefault::sendInitialPerms()
@@ -266,12 +293,13 @@ void LLFloaterPermsDefault::sendInitialPerms()
if (!mCapSent)
{
updateCap();
mCapSent = true;
}
}
void LLFloaterPermsDefault::updateCap()
{
std::string object_url = gAgent.getRegion()->getCapability("AgentPreferences");
std::string object_url = gAgent.getRegionCapability("AgentPreferences");
if (!object_url.empty())
{
@@ -283,13 +311,24 @@ void LLFloaterPermsDefault::updateCap()
report["default_object_perm_masks"]["NextOwner"] =
(LLSD::Integer)LLFloaterPerms::getNextOwnerPerms(sCategoryNames[CAT_OBJECTS]);
LLHTTPClient::post(object_url, report, new LLFloaterPermsResponder());
{
std::ostringstream sent_perms_log;
LLSDSerialize::toPrettyXML(report, sent_perms_log);
LL_DEBUGS("ObjectPermissionsFloater") << "Sending default permissions to '"
<< object_url << "'\n"
<< sent_perms_log.str() << LL_ENDL;
}
LLFloaterPermsRequester::init(object_url, report);
}
else
{
LL_DEBUGS("ObjectPermissionsFloater") << "AgentPreferences cap not available." << LL_ENDL;
}
}
void LLFloaterPermsDefault::ok()
{
// Changes were already applied to saved settings.
// Changes were already applied automatically to saved settings.
// Refreshing internal values makes it official.
refresh();
@@ -302,11 +341,11 @@ void LLFloaterPermsDefault::cancel()
{
for (U32 iter = CAT_OBJECTS; iter < CAT_LAST; iter++)
{
gSavedSettings.setBOOL(sCategoryNames[iter]+"ShareWithGroup", mShareWithGroup[iter]);
gSavedSettings.setBOOL(sCategoryNames[iter]+"EveryoneCopy", mEveryoneCopy[iter]);
gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerCopy", mNextOwnerCopy[iter]);
gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerModify", mNextOwnerModify[iter]);
gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerTransfer", mNextOwnerTransfer[iter]);
gSavedSettings.setBOOL(sCategoryNames[iter]+"ShareWithGroup", mShareWithGroup[iter]);
gSavedSettings.setBOOL(sCategoryNames[iter]+"EveryoneCopy", mEveryoneCopy[iter]);
gSavedPerAccountSettings.setBOOL(sCategoryNames[iter]+"EveryoneExport", mEveryoneExport[iter]);
}
}

View File

@@ -103,11 +103,7 @@ void LLFloaterPostcard::init()
if(!gAgent.getID().isNull())
{
// we're logged in, so we can get this info.
gMessageSystem->newMessageFast(_PREHASH_UserInfoRequest);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
gAgent.sendReliableMessage();
gAgent.sendAgentUserInfoRequest();
}
sInstances.insert(this);
@@ -233,7 +229,7 @@ void LLFloaterPostcard::onClose(bool app_quitting)
destroy();
}
class LLSendPostcardResponder : public LLAssetUploadResponder
class LLSendPostcardResponder final : public LLAssetUploadResponder
{
private:
int mSnapshotIndex;
@@ -248,22 +244,22 @@ public:
{
}
// *TODO define custom uploadFailed here so it's not such a generic message
/*virtual*/ void uploadComplete(const LLSD& content)
void uploadComplete(const LLSD& content) override final
{
// we don't care about what the server returns from this post, just clean up the UI
LLFloaterSnapshot::savePostcardDone(true, mSnapshotIndex);
}
/*virtual*/ void uploadFailure(const LLSD& content)
void uploadFailure(const LLSD& content) override final
{
LLAssetUploadResponder::uploadFailure(content);
LLFloaterSnapshot::savePostcardDone(false, mSnapshotIndex);
}
/*virtual*/ void httpFailure(void)
void httpFailure(void) override final
{
LLAssetUploadResponder::httpFailure();
LLFloaterSnapshot::savePostcardDone(false, mSnapshotIndex);
}
/*virtual*/ char const* getName(void) const { return "LLSendPostcardResponder"; }
char const* getName(void) const override final { return "LLSendPostcardResponder"; }
};
// static
@@ -273,7 +269,6 @@ void LLFloaterPostcard::onClickSend(void* data)
{
LLFloaterPostcard *self = (LLFloaterPostcard *)data;
std::string from(self->childGetValue("from_form").asString());
std::string to(self->childGetValue("to_form").asString());
boost::regex emailFormat("[A-Za-z0-9.%+-_]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}(,[ \t]*[A-Za-z0-9.%+-_]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,})*");
@@ -284,12 +279,6 @@ void LLFloaterPostcard::onClickSend(void* data)
return;
}
if (from.empty() || !boost::regex_match(from, emailFormat))
{
LLNotificationsUtil::add("PromptSelfEmail");
return;
}
std::string subject(self->childGetValue("subject_form").asString());
if(subject.empty() || !self->mHasFirstMsgFocus)
{
@@ -349,10 +338,8 @@ void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data,
// static
void LLFloaterPostcard::updateUserInfo(const std::string& email)
{
for (instance_list_t::iterator iter = sInstances.begin();
iter != sInstances.end(); ++iter)
for (auto& instance : sInstances)
{
LLFloaterPostcard *instance = *iter;
const std::string& text = instance->childGetValue("from_form").asString();
if (text.empty())
{
@@ -416,7 +403,6 @@ void LLFloaterPostcard::sendPostcard()
// the capability already encodes: agent ID, region ID
body["pos-global"] = mPosTakenGlobal.getValue();
body["to"] = childGetValue("to_form").asString();
body["from"] = childGetValue("from_form").asString();
body["name"] = childGetValue("name_form").asString();
body["subject"] = childGetValue("subject_form").asString();
body["msg"] = childGetValue("msg_form").asString();

View File

@@ -46,17 +46,17 @@ class LLLineEditor;
class LLButton;
class LLImageJPEG;
class LLFloaterPostcard
class LLFloaterPostcard final
: public LLFloater
{
public:
LLFloaterPostcard(LLImageJPEG* jpeg, LLViewerTexture *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global, int index);
/*virtual*/ ~LLFloaterPostcard();
/*virtual*/ ~LLFloaterPostcard() override;
/*virtual*/ void init();
/*virtual*/ BOOL postBuild();
/*virtual*/ void draw();
/*virtual*/ void onClose(bool app_quitting);
void init();
/*virtual*/ BOOL postBuild() override;
/*virtual*/ void draw() override;
/*virtual*/ void onClose(bool app_quitting) override;
static LLFloaterPostcard* showFromSnapshot(LLImageJPEG *jpeg, LLViewerTexture *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global, int index);

View File

@@ -43,11 +43,6 @@
#include "llcombobox.h"
#include "lllineeditor.h"
#include "llviewerwindow.h"
#if LL_MSVC
// disable boost::lexical_cast warning
#pragma warning (disable:4702)
#endif
#include <boost/lexical_cast.hpp>
LLFloaterPostProcess* LLFloaterPostProcess::sPostProcess = NULL;
@@ -190,7 +185,7 @@ void LLFloaterPostProcess::syncMenu()
//llsd["uniform"][1]=>"uniform[1]"
for(S32 i=0;i<it->second.size();++i)
{
childSetValue(it->first+'['+boost::lexical_cast<std::string>(i)+']',it->second[i]);
childSetValue(it->first+'['+fmt::to_string(i)+']',it->second[i]);
}
}
else

View File

@@ -302,10 +302,10 @@ void LLFloaterWindLight::syncMenu()
// blue horizon
param_mgr->mBlueHorizon = cur_params.getVector(param_mgr->mBlueHorizon.mName, err);
//setColorSwatch("WLBlueHorizon", param_mgr->mBlueHorizon, WL_BLUE_HORIZON_DENSITY_SCALE);
childSetValue("WLBlueHorizonR", param_mgr->mBlueHorizon.r);
childSetValue("WLBlueHorizonG", param_mgr->mBlueHorizon.g);
childSetValue("WLBlueHorizonB", param_mgr->mBlueHorizon.b);
childSetValue("WLBlueHorizonI", param_mgr->mBlueHorizon.i);
childSetValue("WLBlueHorizonR", param_mgr->mBlueHorizon.r / WL_BLUE_HORIZON_DENSITY_SCALE);
childSetValue("WLBlueHorizonG", param_mgr->mBlueHorizon.g / WL_BLUE_HORIZON_DENSITY_SCALE);
childSetValue("WLBlueHorizonB", param_mgr->mBlueHorizon.b / WL_BLUE_HORIZON_DENSITY_SCALE);
childSetValue("WLBlueHorizonI", param_mgr->mBlueHorizon.i / WL_BLUE_HORIZON_DENSITY_SCALE);
// haze density, horizon, mult, and altitude
param_mgr->mHazeDensity = cur_params.getFloat(param_mgr->mHazeDensity.mName, err);
@@ -320,20 +320,20 @@ void LLFloaterWindLight::syncMenu()
// blue density
param_mgr->mBlueDensity = cur_params.getVector(param_mgr->mBlueDensity.mName, err);
//setColorSwatch("WLBlueDensity", param_mgr->mBlueDensity, WL_BLUE_HORIZON_DENSITY_SCALE);
childSetValue("WLBlueDensityR", param_mgr->mBlueDensity.r);
childSetValue("WLBlueDensityG", param_mgr->mBlueDensity.g);
childSetValue("WLBlueDensityB", param_mgr->mBlueDensity.b);
childSetValue("WLBlueDensityI", param_mgr->mBlueDensity.i);
childSetValue("WLBlueDensityR", param_mgr->mBlueDensity.r / WL_BLUE_HORIZON_DENSITY_SCALE);
childSetValue("WLBlueDensityG", param_mgr->mBlueDensity.g / WL_BLUE_HORIZON_DENSITY_SCALE);
childSetValue("WLBlueDensityB", param_mgr->mBlueDensity.b / WL_BLUE_HORIZON_DENSITY_SCALE);
childSetValue("WLBlueDensityI", param_mgr->mBlueDensity.i / WL_BLUE_HORIZON_DENSITY_SCALE);
// Lighting
// sunlight
param_mgr->mSunlight = cur_params.getVector(param_mgr->mSunlight.mName, err);
//setColorSwatch("WLSunlight", param_mgr->mSunlight, WL_SUN_AMBIENT_SLIDER_SCALE);
childSetValue("WLSunlightR", param_mgr->mSunlight.r);
childSetValue("WLSunlightG", param_mgr->mSunlight.g);
childSetValue("WLSunlightB", param_mgr->mSunlight.b);
childSetValue("WLSunlightI", param_mgr->mSunlight.i);
childSetValue("WLSunlightR", param_mgr->mSunlight.r / WL_SUN_AMBIENT_SLIDER_SCALE);
childSetValue("WLSunlightG", param_mgr->mSunlight.g / WL_SUN_AMBIENT_SLIDER_SCALE);
childSetValue("WLSunlightB", param_mgr->mSunlight.b / WL_SUN_AMBIENT_SLIDER_SCALE);
childSetValue("WLSunlightI", param_mgr->mSunlight.i / WL_SUN_AMBIENT_SLIDER_SCALE);
// glow
param_mgr->mGlow = cur_params.getVector(param_mgr->mGlow.mName, err);
@@ -343,10 +343,10 @@ void LLFloaterWindLight::syncMenu()
// ambient
param_mgr->mAmbient = cur_params.getVector(param_mgr->mAmbient.mName, err);
//setColorSwatch("WLAmbient", param_mgr->mAmbient, WL_SUN_AMBIENT_SLIDER_SCALE);
childSetValue("WLAmbientR", param_mgr->mAmbient.r);
childSetValue("WLAmbientG", param_mgr->mAmbient.g);
childSetValue("WLAmbientB", param_mgr->mAmbient.b);
childSetValue("WLAmbientI", param_mgr->mAmbient.i);
childSetValue("WLAmbientR", param_mgr->mAmbient.r / WL_SUN_AMBIENT_SLIDER_SCALE);
childSetValue("WLAmbientG", param_mgr->mAmbient.g / WL_SUN_AMBIENT_SLIDER_SCALE);
childSetValue("WLAmbientB", param_mgr->mAmbient.b / WL_SUN_AMBIENT_SLIDER_SCALE);
childSetValue("WLAmbientI", param_mgr->mAmbient.i / WL_SUN_AMBIENT_SLIDER_SCALE);
childSetValue("WLSunAngle", param_mgr->mCurParams.getFloat("sun_angle",err) / F_TWO_PI);
childSetValue("WLEastAngle", param_mgr->mCurParams.getFloat("east_angle",err) / F_TWO_PI);
@@ -356,10 +356,10 @@ void LLFloaterWindLight::syncMenu()
// Cloud Color
param_mgr->mCloudColor = cur_params.getVector(param_mgr->mCloudColor.mName, err);
//setColorSwatch("WLCloudColor", param_mgr->mCloudColor, WL_CLOUD_SLIDER_SCALE);
childSetValue("WLCloudColorR", param_mgr->mCloudColor.r);
childSetValue("WLCloudColorG", param_mgr->mCloudColor.g);
childSetValue("WLCloudColorB", param_mgr->mCloudColor.b);
childSetValue("WLCloudColorI", param_mgr->mCloudColor.i);
childSetValue("WLCloudColorR", param_mgr->mCloudColor.r / WL_CLOUD_SLIDER_SCALE);
childSetValue("WLCloudColorG", param_mgr->mCloudColor.g / WL_CLOUD_SLIDER_SCALE);
childSetValue("WLCloudColorB", param_mgr->mCloudColor.b / WL_CLOUD_SLIDER_SCALE);
childSetValue("WLCloudColorI", param_mgr->mCloudColor.i / WL_CLOUD_SLIDER_SCALE);
// Cloud
param_mgr->mCloudMain = cur_params.getVector(param_mgr->mCloudMain.mName, err);
@@ -513,18 +513,7 @@ void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, void* userdata)
std::string name = color_ctrl->mSliderName;
name.append("I");
if (color_ctrl->isSunOrAmbientColor)
{
childSetValue(name, color_ctrl->r / WL_SUN_AMBIENT_SLIDER_SCALE);
}
else if (color_ctrl->isBlueHorizonOrDensity)
{
childSetValue(name, color_ctrl->r / WL_BLUE_HORIZON_DENSITY_SCALE);
}
else
{
childSetValue(name, color_ctrl->r);
}
childSetValue(name, sldr_ctrl->getValueF32());
}
color_ctrl->update(LLWLParamManager::getInstance()->mCurParams);

View File

@@ -2010,7 +2010,7 @@ void LLFolderView::scrollToShowSelection()
// However we allow scrolling for folder views with mAutoSelectOverride
// (used in Places SP) as an exception because the selection in them
// is not reset during items filtering. See STORM-133.
if ( (!LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mAutoSelectOverride)
if ( (LLInventoryModelBackgroundFetch::instance().isEverythingFetched() || mAutoSelectOverride)
&& mSelectedItems.size() )
{
mNeedsScroll = TRUE;

View File

@@ -54,7 +54,6 @@
#include "hippogridmanager.h"
#include <boost/lexical_cast.hpp>
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
///----------------------------------------------------------------------------
@@ -97,7 +96,7 @@ LLFloaterPay::LLFloaterPay(const std::string& name,
for(U32 i = 0; i < MAX_PAY_BUTTONS; ++i)
{
mQuickPayButton[i] = getChild<LLButton>("fastpay " + boost::lexical_cast<std::string>(mQuickPayInfo[i]));
mQuickPayButton[i] = getChild<LLButton>("fastpay " + fmt::to_string(mQuickPayInfo[i]));
mQuickPayButton[i]->setClickedCallback(boost::bind(&LLFloaterPay::onGive,this,boost::ref(mQuickPayInfo[i])));
mQuickPayButton[i]->setVisible(FALSE);
mQuickPayButton[i]->setLabelArg("[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol());

View File

@@ -150,8 +150,9 @@ LLGroupNotifyBox::LLGroupNotifyBox(const std::string& subject,
auto links = new LLTextEditor(std::string("group"), LLRect(x, y + 5, RIGHT, bottom), S32_MAX, LLStringUtil::null, nullptr, false, true); // Top adjustment to line up with icon
links->setBorderVisible(FALSE);
links->setReadOnlyFgColor(text_color);
links->setReadOnlyBgColor(LLColor4::transparent);
static const auto header_bg_color = gColors.getColor("GroupNotifyHeaderBGColor");
if (header_bg_color[VALPHA]) links->setReadOnlyFgColor(text_color);
links->setReadOnlyBgColor(header_bg_color);
links->setEnabled(false);
links->setTakesNonScrollClicks(TRUE);
links->setHideScrollbarForShortDocs(TRUE);

View File

@@ -94,7 +94,7 @@ void LLHUDIcon::renderIcon(BOOL for_select)
if (mHidden)
return;
if (mSourceObject.isNull() || mImagep.isNull())
if (mSourceObject.isNull() || mImagep.isNull() || mSourceObject->mDrawable.isNull())
{
markDead();
return;

View File

@@ -375,9 +375,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(
if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
{
LLLogChat::loadHistory(mLogLabel,
&chatFromLogFile,
(void *)this);
LLLogChat::loadHistory(mLogLabel, mSessionType == P2P_SESSION ? mOtherParticipantUUID : mSessionUUID, boost::bind(&LLFloaterIMPanel::chatFromLogFile, this, _1, _2));
}
if ( !mSessionInitialized )
@@ -801,7 +799,7 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, LLColor4 incol
// Now we're adding the actual line of text, so erase the
// "Foo is typing..." text segment, and the optional timestamp
// if it was present. JC
removeTypingIndicator(NULL);
removeTypingIndicator(source);
// Actually add the line
bool prepend_newline = true;
@@ -861,7 +859,7 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, LLColor4 incol
// Floater title contains display name -> bad idea to use that as filename
// mLogLabel, however, is the old legacy name
//LLLogChat::saveHistory(getTitle(),histstr);
LLLogChat::saveHistory(mLogLabel, histstr);
LLLogChat::saveHistory(mLogLabel, mSessionType == P2P_SESSION ? mOtherParticipantUUID : mSessionUUID, histstr);
// [/Ansariel: Display name support]
}
@@ -1179,9 +1177,9 @@ void LLFloaterIMPanel::onFlyoutCommit(LLComboBox* flyout, const LLSD& value)
}
}
void show_log_browser(const std::string& name, const std::string& id)
void show_log_browser(const std::string& name, const LLUUID& id)
{
const std::string file(LLLogChat::makeLogFileName(name));
const std::string file(LLLogChat::makeLogFileName(name, id));
if (!LLFile::isfile(file))
{
make_ui_sound("UISndBadKeystroke");
@@ -1195,7 +1193,7 @@ void show_log_browser(const std::string& name, const std::string& id)
}
LLFloaterWebContent::Params p;
p.url("file:///" + file);
p.id(id);
p.id(id.asString());
p.show_chrome(false);
p.trusted_content(true);
LLFloaterWebContent::showInstance("log", p); // If we passed id instead of "log", there would be no control over how many log browsers opened at once.
@@ -1206,8 +1204,8 @@ void LLFloaterIMPanel::onClickHistory()
if (mOtherParticipantUUID.notNull())
{
// [Ansariel: Display name support]
//show_log_browser(getTitle(), mOtherParticipantUUID.asString());
show_log_browser(mLogLabel, mOtherParticipantUUID.asString());
//show_log_browser(getTitle(), mSessionType == P2P_SESSION ? mOtherParticipantUUID : mSessionUUID);
show_log_browser(mLogLabel, mSessionType == P2P_SESSION ? mOtherParticipantUUID : mSessionUUID);
// [/Ansariel: Display name support]
}
}
@@ -1458,7 +1456,7 @@ void LLFloaterIMPanel::onSendMsg()
bool other_was_typing = mOtherTyping;
addHistoryLine(utf8_text, gSavedSettings.getColor("UserChatColor"), true, gAgentID, name);
if (other_was_typing) addTypingIndicator(mOtherTypingName);
if (other_was_typing) addTypingIndicator(mOtherParticipantUUID);
}
}
else
@@ -1588,90 +1586,99 @@ void LLFloaterIMPanel::sendTypingState(bool typing)
}
void LLFloaterIMPanel::processIMTyping(const LLIMInfo* im_info, bool typing)
void LLFloaterIMPanel::processIMTyping(const LLUUID& from_id, BOOL typing)
{
if (typing)
{
// other user started typing
std::string name;
if (!LLAvatarNameCache::getNSName(im_info->mFromID, name)) name = im_info->mName;
addTypingIndicator(name);
addTypingIndicator(from_id);
}
else
{
// other user stopped typing
removeTypingIndicator(im_info);
removeTypingIndicator(from_id);
}
}
void LLFloaterIMPanel::addTypingIndicator(const std::string &name)
void LLFloaterIMPanel::addTypingIndicator(const LLUUID& from_id)
{
// we may have lost a "stop-typing" packet, don't add it twice
if (!mOtherTyping)
// Singu TODO: Actually implement this?
/* Operation of "<name> is typing" state machine:
Not Typing state:
User types in P2P IM chat ... Send Start Typing, save Started time,
start Idle Timer (N seconds) go to Typing state
Typing State:
User enters a non-return character: if Now - Started > ME_TYPING_TIMEOUT, send
Start Typing, restart Idle Timer
User enters a return character: stop Idle Timer, send IM and Stop
Typing, go to Not Typing state
Idle Timer expires: send Stop Typing, go to Not Typing state
The recipient has a complementary state machine in which a Start Typing
that is not followed by either an IM or another Start Typing within OTHER_TYPING_TIMEOUT
seconds switches the sender out of typing state.
This has the nice quality of being self-healing for lost start/stop
messages while adding messages only for the (relatively rare) case of a
user who types a very long message (one that takes more than ME_TYPING_TIMEOUT seconds
to type).
Note: OTHER_TYPING_TIMEOUT must be > ME_TYPING_TIMEOUT for proper operation of the state machine
*/
// We may have lost a "stop-typing" packet, don't add it twice
if (from_id.notNull() && !mOtherTyping)
{
mOtherTyping = true;
// Save im_info so that removeTypingIndicator can be properly called because a timeout has occurred
LLAvatarNameCache::getNSName(from_id, mOtherTypingName);
mTypingLineStartIndex = mHistoryEditor->getWText().length();
LLUIString typing_start = sTypingStartString;
typing_start.setArg("[NAME]", name);
typing_start.setArg("[NAME]", mOtherTypingName);
addHistoryLine(typing_start, gSavedSettings.getColor4("SystemChatColor"), false);
mOtherTypingName = name;
mOtherTyping = true;
// Update speaker
LLIMSpeakerMgr* speaker_mgr = mSpeakers;
if ( speaker_mgr )
{
speaker_mgr->setSpeakerTyping(from_id, TRUE);
}
mOtherTyping = true; // addHistoryLine clears this flag. Set it again.
}
// MBW -- XXX -- merge from release broke this (argument to this function changed from an LLIMInfo to a name)
// Richard will fix.
// mSpeakers->setSpeakerTyping(im_info->mFromID, TRUE);
}
void LLFloaterIMPanel::removeTypingIndicator(const LLIMInfo* im_info)
void LLFloaterIMPanel::removeTypingIndicator(const LLUUID& from_id)
{
if (mOtherTyping)
{
// Must do this first, otherwise addHistoryLine calls us again.
mOtherTyping = false;
S32 chars_to_remove = mHistoryEditor->getWText().length() - mTypingLineStartIndex;
mHistoryEditor->removeTextFromEnd(chars_to_remove);
if (im_info)
if (from_id.notNull())
{
mSpeakers->setSpeakerTyping(im_info->mFromID, FALSE);
mSpeakers->setSpeakerTyping(from_id, FALSE);
}
}
}
//static
void LLFloaterIMPanel::chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata)
void LLFloaterIMPanel::chatFromLogFile(LLLogChat::ELogLineType type, const std::string& line)
{
LLFloaterIMPanel* self = (LLFloaterIMPanel*)userdata;
std::string message = line;
switch (type)
bool log_line = type == LLLogChat::LOG_LINE;
if (log_line || gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
{
case LLLogChat::LOG_EMPTY:
// add warning log enabled message
if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
{
message = LLFloaterChat::getInstance()->getString("IM_logging_string");
}
break;
case LLLogChat::LOG_END:
// add log end message
if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
{
message = LLFloaterChat::getInstance()->getString("IM_end_log_string");
}
break;
case LLLogChat::LOG_LINE:
// just add normal lines from file
break;
default:
// nothing
break;
LLStyleSP style(new LLStyle(true, gSavedSettings.getColor4("LogChatColor"), LLStringUtil::null));
mHistoryEditor->appendText(log_line ? line :
getString(type == LLLogChat::LOG_END ? "IM_end_log_string" : "IM_logging_string"),
false, true, style, false);
}
//self->addHistoryLine(line, LLColor4::grey, FALSE);
LLStyleSP style(new LLStyle(true, gSavedSettings.getColor4("LogChatColor"), LLStringUtil::null));
self->mHistoryEditor->appendText(message, false, true, style, false);
}
void LLFloaterIMPanel::showSessionStartError(

View File

@@ -39,7 +39,6 @@
class LLAvatarName;
class LLIMSpeakerMgr;
class LLIMInfo;
class LLInventoryCategory;
class LLInventoryItem;
class LLLineEditor;
@@ -126,8 +125,8 @@ public:
void sessionInitReplyReceived(const LLUUID& im_session_id);
// Handle other participant in the session typing.
void processIMTyping(const LLIMInfo* im_info, bool typing);
static void chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata);
void processIMTyping(const LLUUID& from_id, BOOL typing);
void chatFromLogFile(LLLogChat::ELogLineType type, const std::string& line);
//show error statuses to the user
void showSessionStartError(const std::string& error_string);
@@ -177,10 +176,10 @@ private:
void setTyping(bool typing);
// Add the "User is typing..." indicator.
void addTypingIndicator(const std::string &name);
void addTypingIndicator(const LLUUID& from_id);
// Remove the "User is typing..." indicator.
void removeTypingIndicator(const LLIMInfo* im_info);
void removeTypingIndicator(const LLUUID& from_id = LLUUID::null);
void sendTypingState(bool typing);

View File

@@ -560,7 +560,7 @@ void LLIMProcessing::processNewMessage(const LLUUID& from_id,
chat.mFromID = from_id;
chat.mFromName = name;
chat.mSourceType = (from_id.isNull() || (name == SYSTEM_FROM)) ? CHAT_SOURCE_SYSTEM :
(dialog == IM_FROM_TASK && dialog == IM_FROM_TASK_AS_ALERT) ? CHAT_SOURCE_OBJECT : CHAT_SOURCE_AGENT;
(dialog == IM_FROM_TASK || dialog == IM_FROM_TASK_AS_ALERT) ? CHAT_SOURCE_OBJECT : CHAT_SOURCE_AGENT;
bool is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat)
// object IMs contain sender object id in session_id (STORM-1209)
@@ -641,8 +641,7 @@ void LLIMProcessing::processNewMessage(const LLUUID& from_id,
{
RlvUtil::sendBusyMessage(from_id, RlvStrings::getVersion(), session_id);
// We won't receive a typing stop message, so do that manually (see comment at the end of LLFloaterIMPanel::sendMsg)
LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
gIMMgr->processIMTypingStop(im_info);
gIMMgr->processIMTypingStop(from_id, dialog);
}
// [/RLVa:KB]
else if (offline == IM_ONLINE
@@ -918,16 +917,15 @@ void LLIMProcessing::processNewMessage(const LLUUID& from_id,
autoresponder_finish(show_autoresponded, session_id, from_id, name, itemid, is_muted);
}
}
LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
gIMMgr->processIMTypingStart(im_info);
gIMMgr->processIMTypingStart(from_id, dialog);
script_msg_api(from_id.asString() + ", 4");
}
break;
case IM_TYPING_STOP:
{
LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
gIMMgr->processIMTypingStop(im_info);
gIMMgr->processIMTypingStop(from_id, dialog);
script_msg_api(from_id.asString() + ", 5");
}
break;
@@ -1198,41 +1196,41 @@ void LLIMProcessing::processNewMessage(const LLUUID& from_id,
}
else // IM_TASK_INVENTORY_OFFERED
{
if (offline == IM_OFFLINE && session_id.isNull() && aux_id.notNull() && binary_bucket_size > sizeof(S8)* 5)
if (sizeof(S8) == binary_bucket_size)
{
// cap received offline message
std::string str_bucket = ll_safe_string((char*)binary_bucket, binary_bucket_size);
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
tokenizer tokens(str_bucket, sep);
tokenizer::iterator iter = tokens.begin();
info->mType = (LLAssetType::EType)(atoi((*(iter++)).c_str()));
// Note There is more elements in 'tokens' ...
info->mObjectID = LLUUID::null;
info->mFromObject = TRUE;
info->mType = (LLAssetType::EType) binary_bucket[0];
}
else
{
if (sizeof(S8) != binary_bucket_size)
{
LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL;
delete info;
break;
}
info->mType = (LLAssetType::EType) binary_bucket[0];
info->mObjectID = LLUUID::null;
info->mFromObject = TRUE;
}
/*RIDER*/ // The previous version of the protocol returned the wrong binary bucket... we
// still might be able to figure out the type... even though the offer is not retrievable.
// Should be safe to remove once DRTSIM-451 fully deploys
std::string str_bucket(reinterpret_cast<char *>(binary_bucket));
std::string str_type(str_bucket.substr(0, str_bucket.find('|')));
std::stringstream type_convert(str_type);
S32 type;
type_convert >> type;
// We could try AT_UNKNOWN which would be more accurate, but that causes an auto decline
info->mType = static_cast<LLAssetType::EType>(type);
// Don't break in the case of a bad binary bucket. Go ahead and show the
// accept/decline popup even though it will not do anything.
LL_WARNS("Messaging") << "Malformed inventory offer from object, type might be " << info->mType << LL_ENDL;
}
info->mObjectID = LLUUID::null;
info->mFromObject = TRUE;
}
info->mIM = dialog;
info->mFromID = from_id;
info->mFromGroup = from_group;
info->mTransactionID = session_id;
info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
info->mTransactionID = session_id.notNull() ? session_id : aux_id;
info->mFromName = name;
info->mDesc = message;
info->mHost = sender;
@@ -1842,7 +1840,7 @@ void LLIMProcessing::processNewMessage(const LLUUID& from_id,
strings.push_back(from_id.asString());
send_generic_message("requestonlinenotification", strings);
args["NAME"] = name;
args["NAME"] = LLAvatarActions::getSLURL(from_id);
LLSD payload;
payload["from_id"] = from_id;
LLAvatarNameCache::get(from_id, boost::bind(&notification_display_name_callback, _1, _2, "FriendshipAccepted", args, payload));
@@ -1897,6 +1895,11 @@ void LLIMProcessing::requestOfflineMessages()
void LLIMProcessing::requestOfflineMessagesCoro(const LLCoroResponder& responder)
{
if (LLApp::isQuitting() || !gAgent.getRegion())
{
return;
}
auto status = responder.getStatus();
if (!responder.isGoodStatus(status)) // success = httpResults["success"].asBoolean();
@@ -1945,8 +1948,6 @@ void LLIMProcessing::requestOfflineMessagesCoro(const LLCoroResponder& responder
LL_INFOS("Messaging") << "Processing offline messages." << LL_ENDL;
std::vector<U8> data;
S32 binary_bucket_size = 0;
LLHost sender = gAgent.getRegion()->getHost();
LLSD::array_iterator i = messages.beginArray();
@@ -1955,12 +1956,31 @@ void LLIMProcessing::requestOfflineMessagesCoro(const LLCoroResponder& responder
{
const LLSD &message_data(*i);
LLVector3 position(message_data["local_x"].asReal(), message_data["local_y"].asReal(), message_data["local_z"].asReal());
data = message_data["binary_bucket"].asBinary();
binary_bucket_size = data.size(); // message_data["count"] always 0
U32 parent_estate_id = message_data.has("parent_estate_id") ? message_data["parent_estate_id"].asInteger() : 1; // 1 - IMMainland
/* RIDER: Many fields in this message are using a '_' rather than the standard '-'. This
* should be changed but would require tight coordination with the simulator.
*/
LLVector3 position;
if (message_data.has("position"))
{
position.setValue(message_data["position"]);
}
else
{
position.set(message_data["local_x"].asReal(), message_data["local_y"].asReal(), message_data["local_z"].asReal());
}
// Todo: once dirtsim-369 releases, remove one of the int/str options
std::vector<U8> bin_bucket;
if (message_data.has("binary_bucket"))
{
bin_bucket = message_data["binary_bucket"].asBinary();
}
#if 0
else
{
bin_bucket.push_back(0);
}
#endif
// Todo: once drtsim-451 releases, remove the string option
BOOL from_group;
if (message_data["from_group"].isInteger())
{
@@ -1973,20 +1993,21 @@ void LLIMProcessing::requestOfflineMessagesCoro(const LLCoroResponder& responder
auto agentName = message_data["from_agent_name"].asString();
auto message = message_data["message"].asString();
LLIMProcessing::processNewMessage(message_data["from_agent_id"].asUUID(),
LLIMProcessing::processNewMessage(
message_data["from_agent_id"].asUUID(),
from_group,
message_data["to_agent_id"].asUUID(),
IM_OFFLINE,
(EInstantMessage)message_data["dialog"].asInteger(),
LLUUID::null, // session id, since there is none we can only use frienship/group invite caps
message_data["timestamp"].asInteger(),
message_data.has("offline") ? static_cast<U8>(message_data["offline"].asInteger()) : IM_OFFLINE,
static_cast<EInstantMessage>(message_data["dialog"].asInteger()),
message_data["transaction-id"].asUUID(),
static_cast<U32>(message_data["timestamp"].asInteger()),
agentName,
message,
parent_estate_id,
message_data.has("parent_estate_id") ? static_cast<U32>(message_data["parent_estate_id"].asInteger()) : 1U, // 1 - IMMainland
message_data["region_id"].asUUID(),
position,
&data[0],
binary_bucket_size,
bin_bucket.data(),
bin_bucket.size(),
sender,
message_data["asset_id"].asUUID()); // not necessarily an asset
}

View File

@@ -1138,23 +1138,23 @@ void LLIMMgr::noteMutedUsers(LLFloaterIMPanel* floater,
}
}
void LLIMMgr::processIMTypingStart(const LLIMInfo* im_info)
void LLIMMgr::processIMTypingStart(const LLUUID& from_id, const EInstantMessage im_type)
{
processIMTypingCore(im_info, TRUE);
processIMTypingCore(from_id, im_type, TRUE);
}
void LLIMMgr::processIMTypingStop(const LLIMInfo* im_info)
void LLIMMgr::processIMTypingStop(const LLUUID& from_id, const EInstantMessage im_type)
{
processIMTypingCore(im_info, FALSE);
processIMTypingCore(from_id, im_type, FALSE);
}
void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
void LLIMMgr::processIMTypingCore(const LLUUID& from_id, const EInstantMessage im_type, BOOL typing)
{
LLUUID session_id = computeSessionID(im_info->mIMType, im_info->mFromID);
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
if (floater)
LLUUID session_id = computeSessionID(im_type, from_id);
LLFloaterIMPanel* im_floater = findFloaterBySession(session_id);
if (im_floater)
{
floater->processIMTyping(im_info, typing);
im_floater->processIMTyping(from_id, typing);
}
}
@@ -1275,10 +1275,10 @@ LLFloaterChatterBox* LLIMMgr::getFloater()
return LLFloaterChatterBox::getInstance(LLSD());
}
class LLViewerChatterBoxSessionStartReply : public LLHTTPNode
class LLViewerChatterBoxSessionStartReply final : public LLHTTPNode
{
public:
virtual void describe(Description& desc) const
void describe(Description& desc) const override
{
desc.shortInfo("Used for receiving a reply to a request to initialize an ChatterBox session");
desc.postAPI();
@@ -1287,18 +1287,15 @@ public:
desc.source(__FILE__, __LINE__);
}
virtual void post(ResponsePtr response,
void post(ResponsePtr response,
const LLSD& context,
const LLSD& input) const
const LLSD& input) const override
{
LLSD body;
LLUUID temp_session_id;
LLUUID session_id;
bool success;
body = input["body"];
success = body["success"].asBoolean();
temp_session_id = body["temp_session_id"].asUUID();
LLSD body = input["body"];
bool success = body["success"].asBoolean();
LLUUID temp_session_id = body["temp_session_id"].asUUID();
if ( success )
{
@@ -1336,10 +1333,10 @@ public:
}
};
class LLViewerChatterBoxSessionEventReply : public LLHTTPNode
class LLViewerChatterBoxSessionEventReply final : public LLHTTPNode
{
public:
virtual void describe(Description& desc) const
void describe(Description& desc) const override
{
desc.shortInfo("Used for receiving a reply to a ChatterBox session event");
desc.postAPI();
@@ -1348,24 +1345,18 @@ public:
desc.source(__FILE__, __LINE__);
}
virtual void post(ResponsePtr response,
void post(ResponsePtr response,
const LLSD& context,
const LLSD& input) const
const LLSD& input) const override
{
LLUUID session_id;
bool success;
LLSD body = input["body"];
success = body["success"].asBoolean();
session_id = body["session_id"].asUUID();
bool success = body["success"].asBoolean();
LLUUID session_id = body["session_id"].asUUID();
if ( !success )
{
//throw an error dialog
LLFloaterIMPanel* floater =
gIMMgr->findFloaterBySession(session_id);
if (floater)
if (auto* floater = gIMMgr->findFloaterBySession(session_id))
{
floater->showSessionEventError(
body["event"].asString(),
@@ -1378,46 +1369,40 @@ public:
class LLViewerForceCloseChatterBoxSession: public LLHTTPNode
{
public:
virtual void post(ResponsePtr response,
void post(ResponsePtr response,
const LLSD& context,
const LLSD& input) const
const LLSD& input) const override
{
LLUUID session_id;
std::string reason;
LLUUID session_id = input["body"]["session_id"].asUUID();
std::string reason = input["body"]["reason"].asString();
session_id = input["body"]["session_id"].asUUID();
reason = input["body"]["reason"].asString();
LLFloaterIMPanel* floater =
gIMMgr ->findFloaterBySession(session_id);
if ( floater )
if (auto* floater = gIMMgr ->findFloaterBySession(session_id))
{
floater->showSessionForceClose(reason);
}
}
};
class LLViewerChatterBoxSessionAgentListUpdates : public LLHTTPNode
class LLViewerChatterBoxSessionAgentListUpdates final : public LLHTTPNode
{
public:
virtual void post(
void post(
ResponsePtr responder,
const LLSD& context,
const LLSD& input) const
const LLSD& input) const override
{
const LLUUID& session_id = input["body"]["session_id"].asUUID();
gIMMgr->processAgentListUpdates(session_id, input["body"]);
}
};
class LLViewerChatterBoxSessionUpdate : public LLHTTPNode
class LLViewerChatterBoxSessionUpdate final : public LLHTTPNode
{
public:
virtual void post(
void post(
ResponsePtr responder,
const LLSD& context,
const LLSD& input) const
const LLSD& input) const override
{
LLUUID session_id = input["body"]["session_id"].asUUID();
LLFloaterIMPanel* im_floater = gIMMgr->findFloaterBySession(session_id);
@@ -1445,14 +1430,14 @@ void leave_group_chat(const LLUUID& from_id, const LLUUID& session_id)
gIMMgr->removeSession(session_id);
}
class LLViewerChatterBoxInvitation : public LLHTTPNode
class LLViewerChatterBoxInvitation final : public LLHTTPNode
{
public:
virtual void post(
void post(
ResponsePtr response,
const LLSD& context,
const LLSD& input) const
const LLSD& input) const override
{
//for backwards compatiblity reasons...we need to still
//check for 'text' or 'voice' invitations...bleh
@@ -1582,10 +1567,9 @@ public:
LLFloaterChat::addChat(chat, TRUE, is_this_agent);
//K now we want to accept the invitation
std::string url = gAgent.getRegion()->getCapability(
"ChatSessionRequest");
std::string url = gAgent.getRegionCapability("ChatSessionRequest");
if ( url != "" )
if (!url.empty())
{
LLSD data;
data["method"] = "accept invitation";

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