Compare commits

...

287 Commits

Author SHA1 Message Date
Liru Færs
dfcdb6ba09 Make gitlab ci work even if there's no linux build 2021-02-14 17:15:37 -05:00
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
Liru Færs
28e5270d87 All agent SLURLs should use the name system names, not just profile ones. 2020-03-25 23:57:05 -04:00
Shyotl
4a237de72a Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-03-25 22:37:23 -05:00
Shyotl
e91aac1dd9 For science. Let's see if sentry.io accepts these annotations... 2020-03-25 22:35:29 -05:00
Liru Færs
7cab44a17d Merge branch 'master' of https://github.com/RouterGray/SingularityViewer 2020-03-25 05:47:34 -04:00
Liru Færs
cf57624688 Fix IsNearby check having invalid logic and hiding options because of it 2020-03-24 22:41:23 -04:00
Liru Færs
c7448f290d Fix inverted logic for benefits on opensim 2020-03-24 17:42:21 -04:00
Liru Færs
55f9937238 Fix looping over empty age strings on OpenSim, no longer retry on SL 2020-03-24 16:27:16 -04:00
Liru Færs
ac1ef4d1ba Hide temp upload on SL 2020-03-23 21:39:08 -04:00
Liru Færs
ee1baafb59 Actually Delete LLView copy constructor 2020-03-23 21:20:21 -04:00
Liru Færs
9522e385cd Merge viewer-benefits
Replace MAX_AGENT_ATTACHMENTS with sim based response
Replace max groups with benefits based response
Upload costs are now handled by sim response
Removed no-longer-needed lleconomy files and classes
Removed dead fields from hippolimits and hippogridmanager
Also removed lame LL code that is redundant and silly

On non SL grids, when values are not provided for benefits, they will be
set to the values granting maximum liberty.
Old standardized responses still work when benefits aren't implemented.
2020-03-23 20:15:59 -04:00
Router Gray
a9b047b168 Minor compile fixes: move a declaration out of a namespace, add an include 2020-03-23 11:47:17 -05:00
Liru Færs
8c6e6143c2 Fix accidental paste in aosystem init 2020-03-23 09:11:13 -04:00
Liru Færs
0704876dfd Comment out unused macros in llviewerregion.h 2020-03-23 09:10:46 -04:00
Liru Færs
54b75a3219 Add SinguOwnerSayAsErrors to make llOwnerSay spew to debug console instead 2020-03-23 08:44:25 -04:00
Liru Færs
11d59d1b00 Merge branch 'master' of git://github.com/Shyotl/SingularityViewer
# Conflicts:
#	indra/newview/llsurface.cpp
2020-03-23 01:04:25 -04:00
Liru Færs
4e042db404 Merge branch 'master' of https://github.com/RouterGray/SingularityViewer 2020-03-23 01:03:25 -04:00
Liru Færs
0f6285b2e9 Split up floaterao.* into aosystem.* and aostate.h, also further refactor 2020-03-22 15:02:08 -04:00
Liru Færs
a3d2107bfd Fix an oopsie woopsie, thanks bready doggy 2020-03-22 10:46:30 -04:00
Liru Færs
a66c91bc5a Labels for agent slurls should use the default name system 2020-03-22 10:36:54 -04:00
Liru Færs
4602602a5f Link owner name in inventory offers from objects 2020-03-22 10:03:51 -04:00
Liru Færs
0511d5903a erase iters properly, please 2020-03-22 09:53:47 -04:00
Liru Færs
7597ce3b37 Force Swim button for AO, for when you wanna swim above water
Force Swim forces swims to be enabled
2020-03-22 09:52:54 -04:00
Liru Færs
7509d929d8 Make everyone upset! Reorganize group notices!
Feature request: clickable names and group names
Remove dead space in group notices that has always plagued us
2020-03-22 09:07:46 -04:00
Liru Færs
c7e03600aa Fix constant reallocation of texture fetch command queue because...who..uses a vector..for a fifo...
By Rye, thanks!
2020-03-22 07:46:20 -04:00
Liru Færs
4871f5ed8e AO Refactor
Should fix AO not turning on without opening floater first

Cleans up code
Reduces memory footprint, especially when not in use
Removes unused functions and parameters
Decouples AO from Floater class (AOSystem)
Removes duplicate Idle state
Formalizes singleton patterns of globals
Centralizes override handling into override structs
Fall back on simple english notecard explanation when missing config ini
Fixes sitting override playing when sitting is disabled (and acting weird)
Moves the bulk of override handling into override structs
No longer state-based, now tracks using per-struct playing field
2020-03-22 07:42:24 -04:00
Router Gray
e5a6f1e2d9 [CMake Linux] Fix my being too rushed in Copy3rdParty, restore openal 2020-03-16 03:38:55 -05:00
Shyotl
a29491658b Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git
# Conflicts:
#	indra/llmath/lloctree.h
#	indra/newview/llsurface.cpp
2020-03-15 00:53:20 -05:00
Shyotl
26976b715d Fixup minor use after free issues, and improper mutex usage in meshrepo. Also fixed some compiler warnings. 2020-03-15 00:46:57 -05:00
Liru Færs
8d564d6ed1 Follow Pilot algorithm tweak: Fly if already flying or target is above 2020-03-10 17:00:02 -04:00
Liru Færs
18fbac26dc Correct comment in follow pilot code 2020-03-10 16:32:14 -04:00
Liru Færs
9f82933149 Reduce repeated follow pilot code 2020-03-10 16:31:51 -04:00
Liru Færs
9b7aa959b0 Fix unresolved links in caution notifications 2020-03-10 16:30:37 -04:00
Liru Færs
1c46c26e6b Notifications with tooltips on buttons, for when text is too long! 2020-03-10 16:29:10 -04:00
Liru Færs
506c6aaa9e Use INetC instead of NSISdl, thanks Rye! 2020-03-10 16:27:48 -04:00
Liru Færs
dd61d475cb Prevent use of outdated notecard import by removing it from LLTextEditor
LLViewerTextEditor properly overrides this anyway.
2020-03-05 04:09:46 -05:00
Liru Færs
6e5eed7957 Fix focus on Object Owners
Just noticed this must've slipped out of a previous commit
2020-03-04 15:45:04 -05:00
Liru Færs
7859c0a191 Fix the ancient way of magic text box hack wherein multiple buttons works
Also when muting scripts through notification, properly pop mute dialog
2020-03-03 22:02:44 -05:00
Liru Færs
ef46d21582 Final 2020-03-03 21:51:54 -05:00
Router Gray
5071c1e0cf Merge remote-tracking branch 'github-liru/master' into NixTesting 2020-03-01 09:42:35 -06:00
Router Gray
ecd52a9e1a [Cmake] Comment out unused llplugincookiestore. 2020-03-01 09:42:00 -06:00
Router Gray
0a6a47a099 [Linux] Use system X11. 2020-03-01 09:42:00 -06:00
Router Gray
9880fe225e [Linux] Use system libraries for dbus-glib, gtk-atk-pango-glib, and ogg-vorbis. 2020-03-01 09:42:00 -06:00
Liru Færs
5d44552a60 Allow UI scale values as low as .5 to better meet HiDPI needs
Adapted from Rye's work on Alchemy, Thanks!
2020-03-01 09:21:59 -05:00
Liru Færs
ffa32f8c98 Fix linux compile 2020-03-01 03:51:47 -05:00
Liru Færs
b7086a993d Merge branch 'master' of git://github.com/Shyotl/SingularityViewer
# Conflicts:
#	indra/llmath/lloctree.h
#	indra/newview/llsurface.cpp
2020-03-01 03:39:30 -05:00
Shyotl
d2d172f6ec Allow oversized images when performing raw snapshots. 2020-02-29 22:51:45 -06:00
Shyotl
34f6ea4db2 Rework LLSurface[Patch]. Abuse weak_ptr for now. Rewrote connectNeighbor. LLSurfacePatch no longer calls parent LLSurface with this poiter, instead parent surface just handles return value and controls its own behavior [Requred for weak_ptr/shared_ptr change. 2020-02-29 22:33:51 -06:00
Shyotl
d8c4db17f2 Make gcc happy again.. 2020-02-29 22:15:46 -06:00
Shyotl
c340dde03d Speculative fixes. 2020-02-29 22:15:27 -06:00
Liru Færs
e502b87b63 Ooops, forgot to save the rewrite of this that actually fixes it 2020-02-29 11:16:46 -05:00
Liru Færs
d6f320fb5e Clean up Object SLURL right click menu with a few submenus 2020-02-29 08:20:50 -05:00
Liru Færs
e4eca079e6 Allow right clicking object UI labels to interact with their owners! 2020-02-29 08:19:41 -05:00
Liru Færs
68ceac3678 llDialog & llTextBox with linked owner name and object name 2020-02-29 06:46:20 -05:00
Liru Færs
991d603a0c Don't copy around strings and UUIDs, LL... pls 2020-02-29 05:57:36 -05:00
Liru Færs
74a6f7382a When possible, populate the owner id of our llviewerobjects 2020-02-29 05:51:07 -05:00
Liru Færs
9264482dc3 Small patch to french translation, thanks Nomade 2020-02-29 04:47:53 -05:00
Liru Færs
1a61c49fc7 Display name change notifications that link to the user 2020-02-29 04:47:17 -05:00
Liru Færs
c2480d7227 When muting an object via pie menu, select it in the mute floater 2020-02-29 04:46:15 -05:00
Liru Færs
72b5976605 Merge to fix missing agent slurl handler for removefriend and (un)block 2020-02-29 04:45:37 -05:00
Liru Færs
1b742aa933 Menu finals and overrides 2020-02-28 22:33:37 -05:00
Liru Færs
9412f631fa Object->Derender from Object UIs 2020-02-28 01:31:34 -05:00
Router Gray
be07df3043 [Lib] Update Linux dullahan 2020-02-26 23:54:22 -06:00
Router Gray
8f89127900 [CEF] Catch a missed change for dullahan update. OCDly fix an indentation. 2020-02-26 23:24:36 -06:00
Router Gray
c72059e73f [CMake CEF] How was this even working? Set dependencies and link targets to cef instead of webkit. 2020-02-26 07:21:48 -06:00
Router Gray
2fc2b7c12b Sync some mime types with upstream, also remove erroneous 'video/libvlc' mimetype. There is no such mimetype. 2020-02-26 07:05:41 -06:00
Liru Færs
a652cb4f0a Collaboration between myself and Router the Gray to Flinux 2020-02-25 13:25:12 -05:00
Liru Færs
16b8980d28 Fix the new window inventory folder floater, and opt it to squeak! 2020-02-25 12:52:41 -05:00
Liru Færs
841a55c266 Remove duplicate setText line that was failing anyway. 2020-02-25 10:23:37 -05:00
Liru Færs
2aa6adfd46 Pip, Squeak. 2020-02-25 08:04:31 -05:00
Liru Færs
bac0b3d745 Update FMOD Studio to 2.00.07 2020-02-25 06:55:05 -05:00
Liru Færs
b08b597397 Merge branch 'master' of git://github.com/Shyotl/SingularityViewer
# Conflicts:
#	indra/llcommon/llsd.cpp
#	indra/llcommon/llsdserialize.cpp
#	indra/newview/llspeakers.cpp
#	indra/newview/llviewermessage.cpp
2020-02-25 06:51:41 -05:00
Shyotl
25cb81221e Don't use clamp mode on av mesh. 2020-02-25 02:36:32 -06:00
Liru Færs
4f5749878f Merge branch 'master' of https://github.com/RouterGray/SingularityViewer
# Conflicts:
#	indra/newview/llexperiencelog.cpp
2020-02-25 03:33:49 -05:00
Liru Færs
2aa3ba4d36 Fix crashes that were reported when using object right click menu
Menu entries that cannot work when an object vanishes will gracefully fail.
2020-02-25 03:29:41 -05:00
Liru Færs
6a2421e2e7 Fix dumb build warning on windows 2020-02-25 03:27:37 -05:00
Liru Færs
e78061b077 Hide group voting tab on secondlife, it is no longer used there. 2020-02-25 03:27:06 -05:00
Liru Færs
379f97e15a Buncha small fixes, mainly from alchemy
Update firestorm jira url
Maintain sorting and and scroll position when refreshing region tracker
Add missing CrashHostUrl setting
And a buncha other tinies, probably a crash fix or two.
2020-02-25 03:26:33 -05:00
Liru Færs
2afd2c500b Update VLC and Dullahan. Update vcredist deployment. Thanks Alchemy! 2020-02-25 03:21:27 -05:00
Liru Færs
0c3e144547 Properly sized FMOD logo, 40 pixels high. Inspired by Alchemy, thanks Rye!¶ 2020-02-25 03:08:01 -05:00
Liru Færs
842d1b8d93 Add LLIMProcessing and support for new message caps! And UserInfo cap!
Also delayed sound support!
Fixed memory leaks and pass by values that LL likes to introduce.
Extended LLCoroResponder to have a responder for Raw strings, also clean it
Adds friend request message logging.
2020-02-25 03:04:58 -05:00
Shyotl
5c2c2a8c01 Minor cleanup. Octree vfunc reduction. Range-based for loops with map/array llsd types. 2020-02-25 01:50:50 -06:00
Router Gray
61f0837114 Make Linux and LLExperienceLog play nice. Thanks Liru. 2020-02-24 17:30:40 -06:00
Router Gray
aa95d8fe3d [LL] Update the login splash page for LL grids. 2020-02-24 06:37:42 -06:00
Router Gray
a52c4779c8 Make event notifications say 'Dismiss' instead of 'Cancel'. 2020-02-23 13:44:24 -06:00
Router Gray
1ece0e6051 [UI] Add Copy Folder UUID to inventory actions 2020-02-19 12:40:33 -06:00
Liru Færs
6a56d048c0 Don't confuse the user by showing loading when refreshing item's experience
Also reorganize some code in that area to be cleaner
2020-02-11 20:19:04 -05:00
Liru Færs
e34999b6a9 Fix missing string for experience profile button tooltip in scripts 2020-02-11 19:49:11 -05:00
Liru Færs
103b2c0f33 Fix layout of item properties floater 2020-02-11 19:07:39 -05:00
Liru Færs
2fe45cb8c2 Fix group inventory receiveds not displaying properly in chat history
Also fix linking to an avatar profile when a group's object gives an item
2020-02-11 18:34:45 -05:00
Liru Færs
64a44d6c1b Fix size and position of folder floaters not being restored from setting 2020-02-11 18:31:47 -05:00
Liru Færs
3073a175d7 Add LiruUseMarkedColor to disable use of mark color in the new places 2020-02-11 17:39:46 -05:00
Liru Færs
3b550c3a93 Fix the Jira URL bug we brought up at the last TPV meeting 2020-02-11 15:13:42 -05:00
Liru Færs
1d2c0cb8c6 Script permission dialogs should link back to the object and its owner 2020-02-11 15:09:48 -05:00
Liru Færs
2f369299c5 Object info with right-clickable owner naame, also improve code overall 2020-02-11 15:06:39 -05:00
Liru Færs
e65b513562 Syncy stuffs 2020-02-11 13:04:05 -05:00
Liru Færs
6959b688be Fix the issue with thin resize space in inventory folder floaters 2020-02-11 12:20:33 -05:00
Liru Færs
7db999d801 Fix copyright being 2019, thanks Del 2020-02-11 12:17:05 -05:00
Liru Færs
703ad01c8b AntiSpam refactor!
Adds SLURLs to antispam notifications
Reduces weight of antispam to either global queue, multiple queues, or none
Renames variables to make more sense
Repositions code, cleans up code, uses modern C++, etc
This fixes a bit of a leak or two, especially with antispam turned off!
Also fixes the endless leak of queue expansion by cleaning up while idle
When changing between global and individual queues, they're now purged.
Also made some improvements to previous commit, woops.
Also fix wrong logic for is_linden and chat source type for objects
2020-02-11 12:16:44 -05:00
Liru Færs
199879aea8 Break out functions for getting object owner, owner and object slurls 2020-02-09 18:52:06 -05:00
Liru Færs
eefa0f07a7 Reduce reused getBOOL 2020-02-09 18:28:48 -05:00
Liru Færs
6e6fb44bdb Fix potential crash, thanks Rye and Testicular! 2020-02-09 18:28:10 -05:00
Liru Færs
0892d14933 Fix debit permission Allow being too long, and remove newlines from it 2020-02-09 04:34:55 -05:00
Liru Færs
400da6ec92 Fix out of order and duplicate preferences 2020-02-09 04:33:20 -05:00
Liru Færs
18539831d1 Request: Just show viewer's short name in update notification, not channel 2020-02-09 04:32:27 -05:00
Liru Færs
9548270306 Buncha tinies
Link name in inventory offer received chat message
Fix shupdate compile missing ; and include from two commits ago
Update links used in menu_viewer.xml, I have things to do today...
And move inventory button on toolbar to between favs and received
2020-02-07 09:00:03 -05:00
Liru Færs
44aec1384a Fix crash in object weights when null selection 2020-02-07 08:03:57 -05:00
Liru Færs
42139835d5 Redo update checker responder to be more like unstable branch 2020-02-07 08:02:44 -05:00
Liru Færs
49f0f8e28f [XP Tools] Further UI beautification
Refix all the panels that weren't good enough.
Fix settingss and default rects
Remove unused
Fix toolbar prefs floater
Use text editors for "URLs" we can't control, they resolve nicer anyway
Fix Texture Ctrl on profile not popping out on click
Fix Maturity string on profile not displaying
Also update about floater credits according to modern data.
2020-02-07 07:48:58 -05:00
Inusaito Sayori
36b75b2398 A Massive Experience Tools (and Unstable Branch) Merge
[XP Tools] Initial merge Cherry Pick

Also modernize llfloaterauction internally, but leave the ui the same for now.
Breaks out script_question_mute() in llviewermessage.cpp to better sync with upstream
Adds support for UnknownScriptQuestion notification (translators need to translate this one~)
RLVa note: Rewrote RLVa permissions handling block just a bit.
Added 13 new capabilities from the XP Tools, I doubt all of them really exist.
Minor update to LLComboBox, decided against implementing LLIconsComboBox for now.
Modified LLExperienceLog::notify to lookup names and display them along with the slurls since our editors don't do that automatically.
Experience tweak: Changed a few notify's to notifytips so that we can click the links to experience profiles from chat instead of via hacked in buttons
Migrated LLFloaterCompileQueue to a proper Instance Tracker so we can call getKey
Modernized LLSD, gives us reverse iterators and the new debugging impl. We needed the reverse iterators.
Experience tweak: Added virtual destructors to responders.
Updated llhandle.h to allow calling getDerivedHandle in public.
Updated LLScrollContainer and LLScrollBar to be more modern.
Added LLFlatListView/flat_list_view from upstream - these don't seem work though?
Added some newer login/logout strings to strings.xml
Thanks for the default timeout policies, Aleric~
To avoid needing to scroll through tabs, about land tabs now are as big as they need to be to display their labels, same on groups
Group Members and Roles has been renamed to just Members because this allows the new Experiences tab enough room to display.
Thanks to Henri Beauchamp (Cool VL Viewer) for the setupList augmentation. (without it, I'd still be stuck)
Thanks to Shyotl for the helpsies~
Added the LSL constants, events, and functions that LL neglected to put in.
Added click callbacks and name lookups for profile linky texts~

Merge is up to 22b4cdc
Old TODO: Get the uis looking nice (profiles? Experiences... floater) - done
Old TODO: Make sure flatlistviews look okay... - Not using
Old TODO: Fix LLFloaterExperiencePicker, right now the panel does not show. - unsure
Old TODO: Remove the llfloaterabout.cpp change. - done

Merges llexperiencecache with upstream and unstable
Introduces LLCoroResponder, TODO: Make everything use this.
Updates Reporter floater to the latest, supports the new cap thingy

Also adds these commits/changes:
[XPTools] Double clicking experiences in namelists should open the profile
Add List.CopyNames support for Experiences
[XP Tools] Some UI work, I'll do more later
[XPTools] More UI Stuff, Later is now!
Allow getSLURL for experiences
WIP Experience list menu
Also make EXPERIENCE > OBJECT, because mainline started OBJECT already
[XPTools] Add Experience support to Name UI
[XPTools] Fix experience profile UI 9c3067e843265587e91c659200a8d783acf2d9b2
[XPTools] Fix experience location showing "last" and getting set to "last"
[XPTools] Move Experiences floater from view menu to world menu
[XPTools] Fix up more UI
[XPTools] Fix experiences panels
[XPTools] Hide pieces of the Experiences menu when they're not usable
[XPTools] More UI work, mostly to get the menus working
[XPTools] The events list is for events, not experiences, remove menu

# Conflicts:
#	indra/llcommon/llsd.cpp - merge with unstable branch
#	indra/llmessage/message_prehash.cpp
#	indra/llmessage/message_prehash.h
#	indra/llui/llscrollbar.cpp
#	indra/llui/llscrollcontainer.cpp
#	indra/llui/llurlentry.cpp
#	indra/llui/llurlregistry.cpp
#	indra/newview/app_settings/keywords.ini
#	indra/newview/app_settings/settings.xml
#	indra/newview/llappviewer.cpp
#	indra/newview/llappviewer.h
#	indra/newview/llassetuploadresponders.cpp
#	indra/newview/llcompilequeue.* - merge stable
#	indra/newview/llfloaterabout.cpp
#	indra/newview/llfloaterland.* - merge unstable
#	indra/newview/llfloaterproperties.cpp
#	indra/newview/llfloaterregioninfo.* - merge unstable
#	indra/newview/llmenucommands.cpp - merge unstable
#	indra/newview/llpreviewscript.cpp - merge unstable
#	indra/newview/llviewermessage.cpp - merge unstable
#	indra/newview/llviewerregion.cpp - merge unstable
#	indra/newview/skins/default/textures/textures.xml - merge unstable
#	indra/newview/skins/default/xui/en-us/strings.xml - merge unstable
2020-02-04 21:18:47 -05:00
Liru Færs
9a53824d6d Move click_for_profile into LLNameUI base for use in nameboxes
This allows having a linked name text on profiles without it stealing mouse
2020-01-31 14:32:45 -05:00
Router Gray
a9e2672820 [Lib] Update Linux Fmod to 2.00.07 2020-01-22 01:40:52 -06:00
Router Gray
138cf5d4f8 [AIS] Apparently friending a class isn't friendly enough. 2020-01-22 01:38:40 -06:00
Liru Færs
4b2e358783 Sync LLInventoryModel and LLViewerInventory with upstream 2020-01-21 03:18:44 -05:00
Liru Færs
851b3659ee Improve AISv3 code to retry less aggressively
Syncs LLAISAPI with upstream alchemy
Thanks to Kitty Barnett for Appearance-SyncAttach patch
Fixes typos, uses more modern C++ features,
Accounts for VERSION_UNKNOWN so the viewer won't get stuck
Adds in support for 410 GONE response
No longer retries on empty map, malformed response.
2020-01-21 03:18:43 -05:00
Liru Færs
27d4e05f2b Prevent crash 37 2020-01-21 03:18:43 -05:00
Liru Færs
deade4438d Fix login favorites and copy Landmark SLURL missing z-axis (height) 2020-01-21 03:18:43 -05:00
Liru Færs
deafc6814d Fix crashes from badly formed json responses (LL's fault)
Adds LlsdFromJsonString, an exception-free wrapper for parsing json strings
LLSD objects that failed to parse through this will be the type Undefined.

Fixes crashes 36, 1G, 33, 21, and 3A.
2020-01-21 03:18:43 -05:00
Liru Færs
1fd6e91c68 Clean up update checker dependencies 2020-01-21 03:18:42 -05:00
Liru Færs
67126ab494 Wooops, our update checker is broken since the beta started! 2020-01-21 03:18:42 -05:00
Router Gray
e3318fb0d2 Add missing Nvidia GTX cards to gpu table. Used Cool VL Viewer's source, thanks Henri Beauchamp 2020-01-20 16:55:40 -06:00
Liru Færs
e9d28ee5c1 Inventory offers should link offerer avatar/group name 2020-01-17 23:44:41 -05:00
Liru Færs
2ffc99aecf Clean up useless code 2020-01-17 23:35:55 -05:00
Liru Færs
450afff50b [VMM] Drop zone is no longer WIP, and neither are the tabs
Searching tabs is still kinda wonky though... This needs investigation
2020-01-17 17:20:31 -05:00
Liru Færs
570b0d3c5b [VMM] Make the marketplace panel a dropzone, drag and drop anywhere~
Fixes Deltek's issue with not being able to drop in the zone
nor in the empty space where there are not folders in the listings
2020-01-17 17:19:01 -05:00
Liru Færs
09daa2a865 [VMM] Background transparency is important, even in marketplace drop zone 2020-01-17 17:14:25 -05:00
Liru Færs
e97837e103 Friendship Offered should link receiver's name 2020-01-17 14:33:38 -05:00
Liru Færs
84add2d864 This comment forgot to be saved 2020-01-17 10:54:07 -05:00
Liru Færs
4c224def62 Update FMOD Studio 2020-01-17 02:29:52 -05:00
Liru Færs
2242a1d101 Fix a bunch of disconnectNeighbor crashes in LLSurface 2020-01-17 02:27:56 -05:00
Liru Færs
b957c0930d Fix dumb in LLSurface, don't do dumb math 2020-01-17 02:27:48 -05:00
Liru Færs
f7434711ad [Follow] Reset No Progress count when target's position changes 2020-01-17 02:26:40 -05:00
Liru Færs
5f0b23edd7 [Follow] Try to sit on far away objects by moving closer
Groundsit if that still fails
2020-01-17 02:25:45 -05:00
Liru Færs
2eff62ad0d [Follow] Fix orbiting leader after follow sitting and standing up 2020-01-17 01:32:05 -05:00
Liru Færs
686795618a If object sitting while following, bypass follow logic block 2020-01-17 01:30:39 -05:00
Liru Færs
5c8c5a2c45 Condense autopilot no progress code into getAutoPilotNoProgress() 2020-01-17 00:04:31 -05:00
Liru Færs
d98b99f7b3 [Follow] Fall into walking code if RLV Sit restricted
Mostly space changes
2020-01-16 17:47:17 -05:00
Liru Færs
8d472a9c7b Rearrange some Follow code 2020-01-16 17:43:14 -05:00
Liru Færs
3747d79143 [Follow] Fly if we aren't rendering the avatar 2020-01-16 17:40:50 -05:00
Liru Færs
910a5557ab Sync some code in hopes to squish Marketplace wire chewed popups
A query url will no longer be built in making the request
The status of marketplace will no longer get reset to uninitialized upon
region change.
Merchant status will no longer be requested on regions without the DD cap
2020-01-16 17:10:08 -05:00
Liru Færs
8163448a6c [RLVa] Always show your own hover tip 2020-01-15 23:55:42 -05:00
Liru Færs
ac0e93dcad People don't seem to know what an ARC is... it's Complexity 2020-01-15 23:55:13 -05:00
Liru Færs
ed420c3645 Add Edit and Add to Selection to Object UI menus 2020-01-15 19:46:49 -05:00
Liru Færs
b872860443 Fix crash in land floater init when null region (disconnected?)
Fixes crash 2E
Cleans up code
2020-01-15 14:00:00 -05:00
Liru Færs
992f4c7b5d Modernize/sync LLSpeakers code 2020-01-15 12:57:58 -05:00
Liru Færs
8f15478ba4 Condense code~ 2020-01-15 12:56:56 -05:00
Liru Færs
1c371e7be6 Allow touching multiple objects in succession 2020-01-14 19:37:53 -05:00
Liru Færs
937c80f694 Fix an oopsie in Debug Settings, Thanks for the heads up, Yuriko 2020-01-14 15:53:42 -05:00
Liru Færs
15bd41bd71 Add Touch to object ui menus 2020-01-14 15:52:58 -05:00
Liru Færs
b9156b7955 Combine send_ObjectDeGrab and send_ObjectGrab repetitive code 2020-01-14 10:49:46 -05:00
Liru Færs
623a484ae3 Woops, gotta do a char array for that, also set errno to 0 2020-01-13 18:35:08 -05:00
Liru Færs
2ace698101 [Follow] Automatically accept Teleport Requests/Offers from the leader 2020-01-13 02:20:33 -05:00
Liru Færs
34e0c722e7 Don't cancel autopilot when escaping out of customize appearance 2020-01-13 01:34:06 -05:00
Liru Færs
82ee06a6bd Add Find on Map to avatar UI menus 2020-01-13 01:33:26 -05:00
Liru Færs
584ee8fffe const byref autopilot accessors 2020-01-13 00:29:51 -05:00
Liru Færs
d80d232ee5 Don't cancel follow if the target disappears, wait for them 2020-01-12 23:57:20 -05:00
Liru Færs
de47736038 Ignore object kills if our region is null
Fixes crash 1R
2020-01-12 20:06:01 -05:00
Liru Færs
0da16e6034 Some days, I scream in the faces of cats 2020-01-12 16:27:19 -05:00
Liru Færs
6c9a156610 Maybe fix pusssycat's issue with clicking for group profile being broken 2020-01-12 14:47:52 -05:00
Liru Færs
1726c27078 Fix for Linux file rename failures, thanks Taya and Router! 2020-01-12 13:23:02 -05:00
Liru Færs
64b43a47b5 Clean up ScriptCounter code more 2020-01-12 12:33:10 -05:00
Liru Færs
8005a58ed5 Script Counting on an avatar now shows their SLURL, instead of just a name 2020-01-11 21:53:29 -05:00
Liru Færs
d1d42701f5 Fix taya's linux crash, thanks to taya and router!
Crash was due to invalidated iterator
2020-01-11 21:00:16 -05:00
Liru Færs
c57fceff17 Modernizing scriptcounter code 2020-01-11 20:23:31 -05:00
Liru Færs
265336463d Add FMOD Logo to login screen to comply with licensing
Adds code to hide the new UI when compiled without FMOD Studio
2020-01-11 04:32:42 -05:00
Liru Færs
3ba1c88672 Remove reference to dead control 2020-01-11 03:01:28 -05:00
496 changed files with 25953 additions and 15657 deletions

View File

@@ -1,166 +1,282 @@
stages: stages:
- build - build
- deploy - upload
default:
interruptible: true
timeout: 4h
variables: 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_USE_CRASHPAD: "TRUE"
VIEWER_CRASHPAD_URL: $SENTRY_DSN VIEWER_CRASHPAD_URL: $SENTRY_DSN
.win_build: &win_build .win_build:
stage: build stage: build
tags: tags:
- autobuild - autobuild
- windows - windows
cache:
key:
files:
- autobuild.xml
prefix: ${CI_JOB_NAME}
paths:
- .cache/autobuild
- .cache/pip
- .venv/
when: 'always'
before_script: 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: script:
- If ($env:VIEWER_CHANNEL_TYPE -eq 'Project') - |
{ autobuild configure -c Release -- -DUSE_FMODSTUDIO=ON -DUSE_NVAPI=ON -DUSE_LTO=ON -DVS_DISABLE_FATAL_WARNINGS=ON -DREVISION_FROM_VCS=FALSE
$env:VIEWER_CHANNEL_CODENAME = $env:CI_COMMIT_REF_NAME[8..100] -join '' autobuild build -c Release --no-configure
}
- 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 }
artifacts: artifacts:
name: "$env:CI_COMMIT_REF_NAME-$env:CI_COMMIT_SHORT_SHA" name: "$env:CI_COMMIT_REF_NAME-$env:CI_COMMIT_SHORT_SHA"
expire_in: 2 week expire_in: 1 week
paths: paths:
- build-vc-*/newview/Release/build_data.json - 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 - build-vc-*/newview/Release/Singularity_*_Setup.exe
.beta_rules: &beta_rules .linux_build:
only: stage: build
- /^.*-beta$/ image: r.alchemyviewer.org/singularity/infrastructure/debian-build-image:latest
except: tags:
- branches - 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 .win32_build:
only: extends: .win_build
- /^.*-release$/ variables:
except: AUTOBUILD_ADDRSIZE: 32
- branches 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: build:master:windows32:
<<: *win_build extends:
interruptible: true - .win32_build
variables: - .master_rules
AUTOBUILD_ADDRSIZE: 32
VIEWER_CHANNEL_TYPE: Test
VIEWER_USE_CRASHPAD: "FALSE"
only:
- schedules
build:master:windows64: build:master:windows64:
<<: *win_build extends:
interruptible: true - .win64_build
variables: - .master_rules
AUTOBUILD_ADDRSIZE: 64
VIEWER_CHANNEL_TYPE: Test .build:project:linux64:
VIEWER_USE_CRASHPAD: "FALSE" extends:
only: - .linux64_build
- schedules - .project_rules
build:project:windows32: build:project:windows32:
<<: *win_build extends:
interruptible: true - .win32_build
variables: - .project_rules
AUTOBUILD_ADDRSIZE: 32
VIEWER_CHANNEL_TYPE: Project
VIEWER_USE_CRASHPAD: "FALSE"
only:
- /^project-.*$/
build:project:windows64: build:project:windows64:
<<: *win_build extends:
interruptible: true - .win64_build
variables: - .project_rules
AUTOBUILD_ADDRSIZE: 64
VIEWER_CHANNEL_TYPE: Project .build:beta:linux64:
only: extends:
- /^project-.*$/ - .linux64_build
- .beta_rules
build:beta:windows32: build:beta:windows32:
<<: *win_build extends:
variables: - .win32_build
AUTOBUILD_ADDRSIZE: 32 - .beta_rules
VIEWER_CHANNEL_TYPE: Beta
VIEWER_USE_CRASHPAD: "FALSE"
<<: *beta_rules
build:beta:windows64: build:beta:windows64:
<<: *win_build extends:
variables: - .win64_build
AUTOBUILD_ADDRSIZE: 64 - .beta_rules
VIEWER_CHANNEL_TYPE: Beta
<<: *beta_rules .build:release:linux64:
extends:
- .linux64_build
- .release_rules
build:release:windows32: build:release:windows32:
<<: *win_build extends:
variables: - .win32_build
AUTOBUILD_ADDRSIZE: 32 - .release_rules
VIEWER_CHANNEL_TYPE: Release
VIEWER_USE_CRASHPAD: "FALSE"
<<: *release_rules
build:release:windows64: build:release:windows64:
<<: *win_build extends:
variables: - .win64_build
AUTOBUILD_ADDRSIZE: 64 - .release_rules
VIEWER_CHANNEL_TYPE: Release
<<: *release_rules
.deploy_template: &deploy_template .upload_template:
stage: deploy stage: upload
tags: tags:
- autobuild - autobuild
- windows - windows
allow_failure: false
script: script:
- $BuildData = Get-Content .\build-vc-64\newview\Release\build_data.json | ConvertFrom-Json - |
- $BuildChannelVersion = $BuildData."Channel" + ' ' + $BuildData."Version" $BuildData = Get-Content .\build-vc-64\newview\Release\build_data.json | ConvertFrom-Json
- $UploadDestViewerDir = $BuildChannelVersion.ToLower().Replace(" ", "/") $BuildChannelVersion = $BuildData."Channel" + ' ' + $BuildData."Version"
- $UploadDestURL = "https://pkg.alchemyviewer.org/repository/viewer/${UploadDestViewerDir}" $UploadDestViewerDir = $BuildChannelVersion.ToLower().Replace(" ", "/")
$UploadDestURL = "https://pkg.alchemyviewer.org/repository/viewer/${UploadDestViewerDir}"
- $UploadParams = @{ UseBasicParsing = $true; $UploadParams = @{ UseBasicParsing = $true;
Method = "PUT"; Method = "PUT";
Headers = @{ Headers = @{
ContentType = "application/x-executable"; ContentType = "application/x-executable";
Authorization = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$env:AUTOBUILD_HTTP_USER`:$env:AUTOBUILD_HTTP_PASS")))"; }; Authorization = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$env:AUTOBUILD_HTTP_USER`:$env:AUTOBUILD_HTTP_PASS")))"; };
Verbose = $true; }; Verbose = $true; };
- Push-Location .\build-vc-32\newview\Release\ If (Test-Path -LiteralPath ".\build-linux-64\newview\")
- $FileNameWin32 = Get-ChildItem -Path . -Name -Include Singularity_*_Setup.exe {
- Invoke-WebRequest @UploadParams -InFile .\$FileNameWin32 -Uri "${UploadDestURL}/${FileNameWin32}" Push-Location .\build-linux-64\newview\
- Pop-Location $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\ Push-Location .\build-vc-64\newview\Release\
- $FileNameWin64 = Get-ChildItem -Path . -Name -Include Singularity_*_Setup.exe $FileNameWin64 = Get-ChildItem -Path . -Name -Include Singularity_*_Setup.exe
- Invoke-WebRequest @UploadParams -InFile .\$FileNameWin64 -Uri "${UploadDestURL}/${FileNameWin64}" Invoke-WebRequest @UploadParams -InFile .\$FileNameWin64 -Uri "${UploadDestURL}/${FileNameWin64}"
- Pop-Location
- sentry-cli releases new $BuildChannelVersion If ($env:VIEWER_USE_CRASHPAD -eq 'TRUE')
- sentry-cli releases set-commits --auto $BuildChannelVersion {
- sentry-cli releases finalize $BuildChannelVersion 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
when: manual }
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: upload:project:
<<: *deploy_template 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: environment:
name: qa name: qa
only:
- /^project-.*$/
deploy_beta: upload:beta:
<<: *deploy_template 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: environment:
name: staging name: beta
<<: *beta_rules
deploy_release: upload:release:
<<: *deploy_template 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: environment:
name: production name: release
<<: *release_rules

View File

@@ -8,7 +8,7 @@ name = "pypi"
[packages] [packages]
llbase = "*" llbase = "*"
certifi = "*" certifi = "*"
autobuild = {hg = "https://bitbucket.org/alchemyviewer/autobuild-1.1"} autobuild = {git = "https://git.alchemyviewer.org/alchemy/autobuild.git"}
[requires] [requires]
python_version = "2.7" python_version = "2.7"

View File

@@ -410,11 +410,11 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>4614b29cc98021cf1770a8290171602b</string> <string>a96fda7ad5cee967823f5c94390ba35b</string>
<key>hash_algorithm</key> <key>hash_algorithm</key>
<string>md5</string> <string>md5</string>
<key>url</key> <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> </map>
<key>name</key> <key>name</key>
<string>windows</string> <string>windows</string>
@@ -424,18 +424,18 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>d801461b7a6a40fffab828aa1e01e3e6</string> <string>5ff95ca1007ed2dc300b59de17453201</string>
<key>hash_algorithm</key> <key>hash_algorithm</key>
<string>md5</string> <string>md5</string>
<key>url</key> <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> </map>
<key>name</key> <key>name</key>
<string>windows64</string> <string>windows64</string>
</map> </map>
</map> </map>
<key>version</key> <key>version</key>
<string>ce32d093.7</string> <string>c6d76a90.194</string>
</map> </map>
<key>curl</key> <key>curl</key>
<map> <map>
@@ -664,11 +664,11 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>06746b78827e9a0c6b666bd2528d36ad</string> <string>695efb6fc548a56dc4ff34e8d9a37bfb</string>
<key>hash_algorithm</key> <key>hash_algorithm</key>
<string>md5</string> <string>md5</string>
<key>url</key> <key>url</key>
<string>https://bitbucket.org/SingularityViewer/libraries/downloads/dullahan-1.1.1320_73.1.12%252Bgee4b49f%252Bchromium-73.0.3683.75-linux64-192030536.tar.bz2</string> <string>https://bitbucket.org/router_gray/3p-dullahan/downloads/dullahan-1.3.202002250830_79.1.38_gecefb59_chromium-79.0.3945.130-linux64-200580406.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>linux64</string> <string>linux64</string>
@@ -678,9 +678,11 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>e19b664ad8cf9e7f4a7bf649d28faa76</string> <string>1b278ff2535f428ea6536683d096fdd0</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key> <key>url</key>
<string>https://bitbucket.org/SingularityViewer/libraries/downloads/dullahan-1.1.1320_73.1.12+gee4b49f+chromium-73.0.3683.75-windows-191102212.tar.bz2</string> <string>https://pkg.alchemyviewer.org/repository/autobuild-external/dullahan/windows/dullahan-1.3.201911222116_78.3.7_gea7ef34_chromium-78.0.3904.108-windows-2.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>windows</string> <string>windows</string>
@@ -690,18 +692,18 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>414190fd1ce3876ee3efc682b06ae65c</string> <string>b9346fea7643b10308c7bd9a769ef5f7</string>
<key>hash_algorithm</key> <key>hash_algorithm</key>
<string>md5</string> <string>md5</string>
<key>url</key> <key>url</key>
<string>http://depot.alchemyviewer.org/pub/packages/windows64/msvc-1920/dullahan-1.1.1320_73.1.12-gee4b49f-chromium-73.0.3683.75-windows64-190871757.tar.bz2</string> <string>https://pkg.alchemyviewer.org/repository/autobuild-external/dullahan/windows64/dullahan-1.3.201911222103_78.3.7_gea7ef34_chromium-78.0.3904.108-windows64-2.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>windows64</string> <string>windows64</string>
</map> </map>
</map> </map>
<key>version</key> <key>version</key>
<string>1.1.1320_73.1.12+gee4b49f+chromium-73.0.3683.75</string> <string>1.3.201911222103_78.3.7_gea7ef34_chromium-78.0.3904.108</string>
</map> </map>
<key>elfio</key> <key>elfio</key>
<map> <map>
@@ -816,7 +818,7 @@
<key>fmodstudio</key> <key>fmodstudio</key>
<map> <map>
<key>copyright</key> <key>copyright</key>
<string>FMOD Studio, copyright (c) Firelight Technologies Pty, Ltd., 2012-2019.</string> <string>FMOD Studio, Copyright (c) Firelight Technologies Pty Ltd.</string>
<key>description</key> <key>description</key>
<string>FMOD Studio audio system library</string> <string>FMOD Studio audio system library</string>
<key>license</key> <key>license</key>
@@ -874,11 +876,11 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>54dbd41322a08a1fc333ca6d96af5502</string> <string>7f631a7f1742a5786e1f9de1d2424350</string>
<key>hash_algorithm</key> <key>hash_algorithm</key>
<string>md5</string> <string>md5</string>
<key>url</key> <key>url</key>
<string>/opt/devel/secondlife/pkg/fmodstudio-2.00.02.191991250-linux64-191991250.tar.bz2</string> <string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/linux64/fmodstudio-2.01.04.417-linux64-417.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>linux64</string> <string>linux64</string>
@@ -888,11 +890,11 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>e0e87e0423fa42e4d2997b47b92eac6e</string> <string>50ce25e855c10d3b39f5461f34661c7f</string>
<key>hash_algorithm</key> <key>hash_algorithm</key>
<string>md5</string> <string>md5</string>
<key>url</key> <key>url</key>
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows/fmodstudio-2.00.03.192211030-windows-192211030.tar.bz2</string> <string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows/fmodstudio-2.01.04.417-windows-417.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>windows</string> <string>windows</string>
@@ -902,18 +904,18 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>c2e55e1bfef7e066a0e40867a64b4cce</string> <string>e13b156ca861c36b388e18df0e8e20fb</string>
<key>hash_algorithm</key> <key>hash_algorithm</key>
<string>md5</string> <string>md5</string>
<key>url</key> <key>url</key>
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows64/fmodstudio-2.00.03.192211029-windows64-192211029.tar.bz2</string> <string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows64/fmodstudio-2.01.04.417-windows64-417.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>windows64</string> <string>windows64</string>
</map> </map>
</map> </map>
<key>version</key> <key>version</key>
<string>2.00.03.192211300</string> <string>2.01.04.417</string>
</map> </map>
<key>fonts</key> <key>fonts</key>
<map> <map>
@@ -996,7 +998,7 @@
<key>freetype</key> <key>freetype</key>
<map> <map>
<key>copyright</key> <key>copyright</key>
<string>Copyright 2006-2017 by David Turner, Robert Wilhelm, and Werner Lemberg.</string> <string>Copyright 2006-2018 by David Turner, Robert Wilhelm, and Werner Lemberg.</string>
<key>description</key> <key>description</key>
<string>Font rendering library</string> <string>Font rendering library</string>
<key>license</key> <key>license</key>
@@ -1931,38 +1933,6 @@
<key>version</key> <key>version</key>
<string>7.11.1.297294</string> <string>7.11.1.297294</string>
</map> </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> <key>nvapi</key>
<map> <map>
<key>copyright</key> <key>copyright</key>
@@ -2506,7 +2476,7 @@
<key>vlc-bin</key> <key>vlc-bin</key>
<map> <map>
<key>copyright</key> <key>copyright</key>
<string>Copyright (C) 1998-2016 VLC authors and VideoLAN</string> <string>Copyright (C) 1998-2020 VLC authors and VideoLAN</string>
<key>license</key> <key>license</key>
<string>GPL2</string> <string>GPL2</string>
<key>license_file</key> <key>license_file</key>
@@ -2544,9 +2514,9 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>add560654a53cb1c554044a4fac3c718</string> <string>3ff1d097e4f9b8f864a639aff974a506</string>
<key>url</key> <key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12144/71458/vlc_bin-2.2.8.511703-windows-511703.tar.bz2</string> <string>https://pkg.alchemyviewer.org/repository/autobuild-external/vlc-bin/windows/vlc_bin-3.0.8.189-windows-189.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>windows</string> <string>windows</string>
@@ -2556,16 +2526,16 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>94bf04b49acc1e1bf2c06e2232f8a083</string> <string>b890b109b526cc6ad211eadefed83316</string>
<key>url</key> <key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12145/71463/vlc_bin-2.2.8.511703-windows64-511703.tar.bz2</string> <string>https://pkg.alchemyviewer.org/repository/autobuild-external/vlc-bin/windows64/vlc_bin-3.0.8.189-windows64-189.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>windows64</string> <string>windows64</string>
</map> </map>
</map> </map>
<key>version</key> <key>version</key>
<string>2.2.8.511703</string> <string>3.0.8.189</string>
</map> </map>
<key>xmlrpc-epi</key> <key>xmlrpc-epi</key>
<map> <map>

View File

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

View File

@@ -1,13 +1,13 @@
# -*- cmake -*- # -*- cmake -*-
include(Prebuilt) include(Prebuilt)
if (STANDALONE) if (LINUX)
include(FindPkgConfig) include(FindPkgConfig)
pkg_check_modules(OGG REQUIRED ogg) pkg_check_modules(OGG REQUIRED ogg)
pkg_check_modules(VORBIS REQUIRED vorbis) pkg_check_modules(VORBIS REQUIRED vorbis)
pkg_check_modules(VORBISENC REQUIRED vorbisenc) pkg_check_modules(VORBISENC REQUIRED vorbisenc)
pkg_check_modules(VORBISFILE REQUIRED vorbisfile) pkg_check_modules(VORBISFILE REQUIRED vorbisfile)
else (STANDALONE) else (LINUX)
use_prebuilt_binary(ogg_vorbis) use_prebuilt_binary(ogg_vorbis)
set(VORBIS_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) set(VORBIS_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
set(VORBISENC_INCLUDE_DIRS ${VORBIS_INCLUDE_DIRS}) set(VORBISENC_INCLUDE_DIRS ${VORBIS_INCLUDE_DIRS})
@@ -32,7 +32,7 @@ else (STANDALONE)
set(VORBISENC_LIBRARIES vorbisenc) set(VORBISENC_LIBRARIES vorbisenc)
set(VORBISFILE_LIBRARIES vorbisfile) set(VORBISFILE_LIBRARIES vorbisfile)
endif (WINDOWS) endif (WINDOWS)
endif (STANDALONE) endif (LINUX)
link_directories( link_directories(
${VORBIS_LIBRARY_DIRS} ${VORBIS_LIBRARY_DIRS}

View File

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

View File

@@ -13,10 +13,6 @@ include(LLCommon)
# set up platform specific lists of files that need to be copied # set up platform specific lists of files that need to be copied
################################################################### ###################################################################
if(WINDOWS) if(WINDOWS)
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
include(InstallRequiredSystemLibrariesAL)
set(SHARED_LIB_STAGING_DIR_DEBUG "${SHARED_LIB_STAGING_DIR}/Debug") set(SHARED_LIB_STAGING_DIR_DEBUG "${SHARED_LIB_STAGING_DIR}/Debug")
set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO "${SHARED_LIB_STAGING_DIR}/RelWithDebInfo") set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO "${SHARED_LIB_STAGING_DIR}/RelWithDebInfo")
set(SHARED_LIB_STAGING_DIR_RELEASE "${SHARED_LIB_STAGING_DIR}/Release") set(SHARED_LIB_STAGING_DIR_RELEASE "${SHARED_LIB_STAGING_DIR}/Release")
@@ -96,26 +92,6 @@ if(WINDOWS)
list(APPEND release_files fmod.dll) list(APPEND release_files fmod.dll)
endif (USE_FMODSTUDIO) endif (USE_FMODSTUDIO)
foreach(redistfullfile IN LISTS CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS)
get_filename_component(redistfilepath ${redistfullfile} DIRECTORY )
get_filename_component(redistfilename ${redistfullfile} NAME)
copy_if_different(
${redistfilepath}
"${SHARED_LIB_STAGING_DIR_RELEASE}"
out_targets
${redistfilename}
)
set(third_party_targets ${third_party_targets} ${out_targets})
copy_if_different(
${redistfilepath}
"${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}"
out_targets
${redistfilename}
)
set(third_party_targets ${third_party_targets} ${out_targets})
endforeach()
elseif(DARWIN) elseif(DARWIN)
set(SHARED_LIB_STAGING_DIR_DEBUG "${SHARED_LIB_STAGING_DIR}/Debug/Resources") set(SHARED_LIB_STAGING_DIR_DEBUG "${SHARED_LIB_STAGING_DIR}/Debug/Resources")
set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO "${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/Resources") set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO "${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/Resources")
@@ -148,10 +124,10 @@ elseif(DARWIN)
libndofdev.dylib libndofdev.dylib
) )
if (FMODSTUDIO) if (USE_FMODSTUDIO)
list(APPEND debug_files libfmodL.dylib) list(APPEND debug_files libfmodL.dylib)
list(APPEND release_files libfmod.dylib) list(APPEND release_files libfmod.dylib)
endif (FMODSTUDIO) endif (USE_FMODSTUDIO)
elseif(LINUX) elseif(LINUX)
# linux is weird, multiple side by side configurations aren't supported # linux is weird, multiple side by side configurations aren't supported
@@ -181,12 +157,9 @@ elseif(LINUX)
set(release_files set(release_files
libapr-1.so.0 libapr-1.so.0
libaprutil-1.so.0 libaprutil-1.so.0
libatk-1.0.so
libexpat.so libexpat.so
libexpat.so.1 libexpat.so.1
libGLOD.so libGLOD.so
libgmodule-2.0.so
libgobject-2.0.so
libopenal.so libopenal.so
) )

View File

@@ -1,24 +1,11 @@
# -*- cmake -*- # -*- cmake -*-
include(Prebuilt)
if (STANDALONE) if (LINUX)
include(FindPkgConfig) include(FindPkgConfig)
pkg_check_modules(DBUSGLIB REQUIRED dbus-glib-1) pkg_check_modules(DBUSGLIB REQUIRED dbus-glib-1)
elseif (LINUX) endif (LINUX)
use_prebuilt_binary(dbus-glib)
set(DBUSGLIB_FOUND ON FORCE BOOL)
set(DBUSGLIB_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include/dbus
)
# We don't need to explicitly link against dbus-glib itself, because
# the viewer probes for the system's copy at runtime.
set(DBUSGLIB_LIBRARIES
gobject-2.0
glib-2.0
)
endif (STANDALONE)
if (DBUSGLIB_FOUND) if (DBUSGLIB_FOUND)
set(DBUSGLIB ON CACHE BOOL "Build with dbus-glib message bus support.") set(DBUSGLIB ON CACHE BOOL "Build with dbus-glib message bus support.")

View File

@@ -1,741 +0,0 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
InstallRequiredSystemLibraries
------------------------------
Include this module to search for compiler-provided system runtime
libraries and add install rules for them. Some optional variables
may be set prior to including the module to adjust behavior:
``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS``
Specify additional runtime libraries that may not be detected.
After inclusion any detected libraries will be appended to this.
``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP``
Set to TRUE to skip calling the :command:`install(PROGRAMS)` command to
allow the includer to specify its own install rule, using the value of
``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS`` to get the list of libraries.
``CMAKE_INSTALL_DEBUG_LIBRARIES``
Set to TRUE to install the debug runtime libraries when available
with MSVC tools.
``CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY``
Set to TRUE to install only the debug runtime libraries with MSVC
tools even if the release runtime libraries are also available.
``CMAKE_INSTALL_UCRT_LIBRARIES``
Set to TRUE to install the Windows Universal CRT libraries for
app-local deployment (e.g. to Windows XP). This is meaningful
only with MSVC from Visual Studio 2015 or higher.
One may set a ``CMAKE_WINDOWS_KITS_10_DIR`` *environment variable*
to an absolute path to tell CMake to look for Windows 10 SDKs in
a custom location. The specified directory is expected to contain
``Redist/ucrt/DLLs/*`` directories.
``CMAKE_INSTALL_MFC_LIBRARIES``
Set to TRUE to install the MSVC MFC runtime libraries.
``CMAKE_INSTALL_OPENMP_LIBRARIES``
Set to TRUE to install the MSVC OpenMP runtime libraries
``CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION``
Specify the :command:`install(PROGRAMS)` command ``DESTINATION``
option. If not specified, the default is ``bin`` on Windows
and ``lib`` elsewhere.
``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS``
Set to TRUE to disable warnings about required library files that
do not exist. (For example, Visual Studio Express editions may
not provide the redistributable files.)
``CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT``
Specify the :command:`install(PROGRAMS)` command ``COMPONENT``
option. If not specified, no such option will be used.
#]=======================================================================]
cmake_policy(PUSH)
cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
set(_IRSL_HAVE_Intel FALSE)
set(_IRSL_HAVE_MSVC FALSE)
foreach(LANG IN ITEMS C CXX Fortran)
if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Intel")
if(NOT _IRSL_HAVE_Intel)
get_filename_component(_Intel_basedir "${CMAKE_${LANG}_COMPILER}" PATH)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_Intel_archdir intel64)
else()
set(_Intel_archdir x86)
endif()
set(_Intel_compiler_ver ${CMAKE_${LANG}_COMPILER_VERSION})
if(WIN32)
get_filename_component(_Intel_redistdir "${_Intel_basedir}/../../redist/${_Intel_archdir}/compiler" ABSOLUTE)
elseif(APPLE)
get_filename_component(_Intel_redistdir "${_Intel_basedir}/../../compiler/lib" ABSOLUTE)
else()
if(EXISTS "${_Intel_basedir}/../lib/${_Intel_archdir}_lin")
get_filename_component(_Intel_redistdir "${_Intel_basedir}/../lib/${_Intel_archdir}" ABSOLUTE)
else()
get_filename_component(_Intel_redistdir "${_Intel_basedir}/../../compiler/lib/${_Intel_archdir}_lin" ABSOLUTE)
endif()
endif()
set(_IRSL_HAVE_Intel TRUE)
endif()
elseif("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "MSVC")
set(_IRSL_HAVE_MSVC TRUE)
endif()
endforeach()
if(MSVC)
file(TO_CMAKE_PATH "$ENV{SYSTEMROOT}" SYSTEMROOT)
if(CMAKE_CL_64)
if(MSVC_VERSION GREATER 1599)
# VS 10 and later:
set(CMAKE_MSVC_ARCH x64)
else()
# VS 9 and earlier:
set(CMAKE_MSVC_ARCH amd64)
endif()
else()
set(CMAKE_MSVC_ARCH x86)
endif()
get_filename_component(devenv_dir "${CMAKE_MAKE_PROGRAM}" PATH)
get_filename_component(base_dir "${devenv_dir}/../.." ABSOLUTE)
if(MSVC_VERSION EQUAL 1300)
set(__install__libs
"${SYSTEMROOT}/system32/msvcp70.dll"
"${SYSTEMROOT}/system32/msvcr70.dll"
)
endif()
if(MSVC_VERSION EQUAL 1310)
set(__install__libs
"${SYSTEMROOT}/system32/msvcp71.dll"
"${SYSTEMROOT}/system32/msvcr71.dll"
)
endif()
if(MSVC_TOOLSET_VERSION EQUAL 80)
# Find the runtime library redistribution directory.
get_filename_component(msvc_install_dir
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0;InstallDir]" ABSOLUTE)
if(DEFINED MSVC80_REDIST_DIR AND EXISTS "${MSVC80_REDIST_DIR}")
set(MSVC_REDIST_DIR "${MSVC80_REDIST_DIR}") # use old cache entry
endif()
find_path(MSVC_REDIST_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.VC80.CRT/Microsoft.VC80.CRT.manifest
PATHS
"${msvc_install_dir}/../../VC/redist"
"${base_dir}/VC/redist"
)
mark_as_advanced(MSVC_REDIST_DIR)
set(MSVC_CRT_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC80.CRT")
# Install the manifest that allows DLLs to be loaded from the
# directory containing the executable.
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs
"${MSVC_CRT_DIR}/Microsoft.VC80.CRT.manifest"
"${MSVC_CRT_DIR}/msvcm80.dll"
"${MSVC_CRT_DIR}/msvcp80.dll"
"${MSVC_CRT_DIR}/msvcr80.dll"
)
else()
set(__install__libs)
endif()
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
set(MSVC_CRT_DIR
"${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC80.DebugCRT")
set(__install__libs ${__install__libs}
"${MSVC_CRT_DIR}/Microsoft.VC80.DebugCRT.manifest"
"${MSVC_CRT_DIR}/msvcm80d.dll"
"${MSVC_CRT_DIR}/msvcp80d.dll"
"${MSVC_CRT_DIR}/msvcr80d.dll"
)
endif()
endif()
if(MSVC_TOOLSET_VERSION EQUAL 90)
# Find the runtime library redistribution directory.
get_filename_component(msvc_install_dir
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0;InstallDir]" ABSOLUTE)
get_filename_component(msvc_express_install_dir
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\9.0;InstallDir]" ABSOLUTE)
if(DEFINED MSVC90_REDIST_DIR AND EXISTS "${MSVC90_REDIST_DIR}")
set(MSVC_REDIST_DIR "${MSVC90_REDIST_DIR}") # use old cache entry
endif()
find_path(MSVC_REDIST_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.VC90.CRT/Microsoft.VC90.CRT.manifest
PATHS
"${msvc_install_dir}/../../VC/redist"
"${msvc_express_install_dir}/../../VC/redist"
"${base_dir}/VC/redist"
)
mark_as_advanced(MSVC_REDIST_DIR)
set(MSVC_CRT_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC90.CRT")
# Install the manifest that allows DLLs to be loaded from the
# directory containing the executable.
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs
"${MSVC_CRT_DIR}/Microsoft.VC90.CRT.manifest"
"${MSVC_CRT_DIR}/msvcm90.dll"
"${MSVC_CRT_DIR}/msvcp90.dll"
"${MSVC_CRT_DIR}/msvcr90.dll"
)
else()
set(__install__libs)
endif()
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
set(MSVC_CRT_DIR
"${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC90.DebugCRT")
set(__install__libs ${__install__libs}
"${MSVC_CRT_DIR}/Microsoft.VC90.DebugCRT.manifest"
"${MSVC_CRT_DIR}/msvcm90d.dll"
"${MSVC_CRT_DIR}/msvcp90d.dll"
"${MSVC_CRT_DIR}/msvcr90d.dll"
)
endif()
endif()
set(MSVC_REDIST_NAME "")
set(_MSVC_DLL_VERSION "")
set(_MSVC_IDE_VERSION "")
if(MSVC_VERSION GREATER_EQUAL 2000)
message(WARNING "MSVC ${MSVC_VERSION} not yet supported.")
elseif(MSVC_VERSION_VERSION GREATER_EQUAL 143)
message(WARNING "MSVC toolset v${MSVC_VERSION_VERSION} not yet supported.")
elseif(MSVC_TOOLSET_VERSION EQUAL 142)
set(MSVC_REDIST_NAME VC142)
set(_MSVC_DLL_VERSION 140)
set(_MSVC_IDE_VERSION 16)
if(MSVC_VERSION EQUAL 1920)
# VS2019 named this differently prior to update 1.
set(MSVC_REDIST_NAME VC141)
endif()
elseif(MSVC_TOOLSET_VERSION EQUAL 141)
set(MSVC_REDIST_NAME VC141)
set(_MSVC_DLL_VERSION 140)
set(_MSVC_IDE_VERSION 15)
if(MSVC_VERSION EQUAL 1910)
# VS2017 named this differently prior to update 3.
set(MSVC_REDIST_NAME VC150)
endif()
elseif(MSVC_TOOLSET_VERSION)
set(MSVC_REDIST_NAME VC${MSVC_TOOLSET_VERSION})
math(EXPR _MSVC_DLL_VERSION "${MSVC_TOOLSET_VERSION} / 10 * 10")
math(EXPR _MSVC_IDE_VERSION "${MSVC_TOOLSET_VERSION} / 10")
endif()
set(_MSVCRT_DLL_VERSION "")
set(_MSVCRT_IDE_VERSION "")
if(_MSVC_IDE_VERSION GREATER_EQUAL 10)
set(_MSVCRT_DLL_VERSION "${_MSVC_DLL_VERSION}")
set(_MSVCRT_IDE_VERSION "${_MSVC_IDE_VERSION}")
endif()
if(_MSVCRT_DLL_VERSION)
set(v "${_MSVCRT_DLL_VERSION}")
set(vs "${_MSVCRT_IDE_VERSION}")
# Find the runtime library redistribution directory.
if(vs VERSION_LESS 15 AND DEFINED MSVC${vs}_REDIST_DIR AND EXISTS "${MSVC${vs}_REDIST_DIR}")
set(MSVC_REDIST_DIR "${MSVC${vs}_REDIST_DIR}") # use old cache entry
endif()
if(NOT vs VERSION_LESS 15)
set(_vs_redist_paths "")
cmake_host_system_information(RESULT _vs_dir QUERY VS_${vs}_DIR) # undocumented query
if(IS_DIRECTORY "${_vs_dir}")
file(GLOB _vs_redist_paths "${_vs_dir}/VC/Redist/MSVC/*")
endif()
unset(_vs_dir)
else()
get_filename_component(_vs_dir
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\${vs}.0;InstallDir]" ABSOLUTE)
set(programfilesx86 "ProgramFiles(x86)")
set(_vs_redist_paths
"${_vs_dir}/../../VC/redist"
"${base_dir}/VC/redist"
"$ENV{ProgramFiles}/Microsoft Visual Studio ${vs}.0/VC/redist"
"$ENV{${programfilesx86}}/Microsoft Visual Studio ${vs}.0/VC/redist"
)
unset(_vs_dir)
unset(programfilesx86)
endif()
find_path(MSVC_REDIST_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.CRT PATHS ${_vs_redist_paths})
unset(_vs_redist_paths)
mark_as_advanced(MSVC_REDIST_DIR)
set(MSVC_CRT_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.CRT")
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs
"${MSVC_CRT_DIR}/msvcp${v}.dll"
)
if(NOT vs VERSION_LESS 14)
file(GLOB __msvcr_dlls "${MSVC_CRT_DIR}/*.dll")
list(APPEND __install__libs ${__msvcr_dlls})
else()
list(APPEND __install__libs "${MSVC_CRT_DIR}/msvcr${v}.dll")
endif()
else()
set(__install__libs)
endif()
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
set(MSVC_CRT_DIR
"${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.DebugCRT")
set(__install__libs ${__install__libs}
"${MSVC_CRT_DIR}/msvcp${v}d.dll"
)
if(NOT vs VERSION_LESS 14)
list(APPEND __install__libs
"${MSVC_CRT_DIR}/vcruntime${v}d.dll"
"${MSVC_CRT_DIR}/concrt${v}d.dll"
)
else()
list(APPEND __install__libs "${MSVC_CRT_DIR}/msvcr${v}d.dll")
endif()
endif()
if(CMAKE_INSTALL_UCRT_LIBRARIES AND NOT vs VERSION_LESS 14)
# Find the Windows Kits directory.
get_filename_component(windows_kits_dir
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot10]" ABSOLUTE)
set(programfilesx86 "ProgramFiles(x86)")
if(";${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION};$ENV{UCRTVersion};$ENV{WindowsSDKVersion};" MATCHES [=[;(10\.[0-9.]+)[;\]]=])
set(__ucrt_version "${CMAKE_MATCH_1}/")
else()
set(__ucrt_version "")
endif()
find_path(WINDOWS_KITS_DIR
NAMES
Redist/${__ucrt_version}ucrt/DLLs/${CMAKE_MSVC_ARCH}/ucrtbase.dll
Redist/ucrt/DLLs/${CMAKE_MSVC_ARCH}/ucrtbase.dll
PATHS
$ENV{CMAKE_WINDOWS_KITS_10_DIR}
"${windows_kits_dir}"
"$ENV{ProgramFiles}/Windows Kits/10"
"$ENV{${programfilesx86}}/Windows Kits/10"
)
mark_as_advanced(WINDOWS_KITS_DIR)
# Glob the list of UCRT DLLs.
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
if(EXISTS "${WINDOWS_KITS_DIR}/Redist/${__ucrt_version}ucrt/DLLs/${CMAKE_MSVC_ARCH}/ucrtbase.dll")
file(GLOB __ucrt_dlls "${WINDOWS_KITS_DIR}/Redist/${__ucrt_version}ucrt/DLLs/${CMAKE_MSVC_ARCH}/*.dll")
else()
file(GLOB __ucrt_dlls "${WINDOWS_KITS_DIR}/Redist/ucrt/DLLs/${CMAKE_MSVC_ARCH}/*.dll")
endif()
list(APPEND __install__libs ${__ucrt_dlls})
endif()
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
if(EXISTS "${WINDOWS_KITS_DIR}/bin/${__ucrt_version}${CMAKE_MSVC_ARCH}/ucrt/ucrtbased.dll")
file(GLOB __ucrt_dlls "${WINDOWS_KITS_DIR}/bin/${__ucrt_version}${CMAKE_MSVC_ARCH}/ucrt/*.dll")
else()
file(GLOB __ucrt_dlls "${WINDOWS_KITS_DIR}/bin/${CMAKE_MSVC_ARCH}/ucrt/*.dll")
endif()
list(APPEND __install__libs ${__ucrt_dlls})
endif()
endif()
endif()
if(CMAKE_INSTALL_MFC_LIBRARIES)
if(MSVC_VERSION EQUAL 1300)
set(__install__libs ${__install__libs}
"${SYSTEMROOT}/system32/mfc70.dll"
)
endif()
if(MSVC_VERSION EQUAL 1310)
set(__install__libs ${__install__libs}
"${SYSTEMROOT}/system32/mfc71.dll"
)
endif()
if(MSVC_VERSION EQUAL 1400)
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
set(MSVC_MFC_DIR
"${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC80.DebugMFC")
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/Microsoft.VC80.DebugMFC.manifest"
"${MSVC_MFC_DIR}/mfc80d.dll"
"${MSVC_MFC_DIR}/mfc80ud.dll"
"${MSVC_MFC_DIR}/mfcm80d.dll"
"${MSVC_MFC_DIR}/mfcm80ud.dll"
)
endif()
set(MSVC_MFC_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC80.MFC")
# Install the manifest that allows DLLs to be loaded from the
# directory containing the executable.
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/Microsoft.VC80.MFC.manifest"
"${MSVC_MFC_DIR}/mfc80.dll"
"${MSVC_MFC_DIR}/mfc80u.dll"
"${MSVC_MFC_DIR}/mfcm80.dll"
"${MSVC_MFC_DIR}/mfcm80u.dll"
)
endif()
# include the language dll's for vs8 as well as the actual dll's
set(MSVC_MFCLOC_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC80.MFCLOC")
# Install the manifest that allows DLLs to be loaded from the
# directory containing the executable.
set(__install__libs ${__install__libs}
"${MSVC_MFCLOC_DIR}/Microsoft.VC80.MFCLOC.manifest"
"${MSVC_MFCLOC_DIR}/mfc80chs.dll"
"${MSVC_MFCLOC_DIR}/mfc80cht.dll"
"${MSVC_MFCLOC_DIR}/mfc80enu.dll"
"${MSVC_MFCLOC_DIR}/mfc80esp.dll"
"${MSVC_MFCLOC_DIR}/mfc80deu.dll"
"${MSVC_MFCLOC_DIR}/mfc80fra.dll"
"${MSVC_MFCLOC_DIR}/mfc80ita.dll"
"${MSVC_MFCLOC_DIR}/mfc80jpn.dll"
"${MSVC_MFCLOC_DIR}/mfc80kor.dll"
)
endif()
if(MSVC_VERSION EQUAL 1500)
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
set(MSVC_MFC_DIR
"${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC90.DebugMFC")
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/Microsoft.VC90.DebugMFC.manifest"
"${MSVC_MFC_DIR}/mfc90d.dll"
"${MSVC_MFC_DIR}/mfc90ud.dll"
"${MSVC_MFC_DIR}/mfcm90d.dll"
"${MSVC_MFC_DIR}/mfcm90ud.dll"
)
endif()
set(MSVC_MFC_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC90.MFC")
# Install the manifest that allows DLLs to be loaded from the
# directory containing the executable.
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/Microsoft.VC90.MFC.manifest"
"${MSVC_MFC_DIR}/mfc90.dll"
"${MSVC_MFC_DIR}/mfc90u.dll"
"${MSVC_MFC_DIR}/mfcm90.dll"
"${MSVC_MFC_DIR}/mfcm90u.dll"
)
endif()
# include the language dll's for vs9 as well as the actual dll's
set(MSVC_MFCLOC_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC90.MFCLOC")
# Install the manifest that allows DLLs to be loaded from the
# directory containing the executable.
set(__install__libs ${__install__libs}
"${MSVC_MFCLOC_DIR}/Microsoft.VC90.MFCLOC.manifest"
"${MSVC_MFCLOC_DIR}/mfc90chs.dll"
"${MSVC_MFCLOC_DIR}/mfc90cht.dll"
"${MSVC_MFCLOC_DIR}/mfc90enu.dll"
"${MSVC_MFCLOC_DIR}/mfc90esp.dll"
"${MSVC_MFCLOC_DIR}/mfc90deu.dll"
"${MSVC_MFCLOC_DIR}/mfc90fra.dll"
"${MSVC_MFCLOC_DIR}/mfc90ita.dll"
"${MSVC_MFCLOC_DIR}/mfc90jpn.dll"
"${MSVC_MFCLOC_DIR}/mfc90kor.dll"
)
endif()
set(_MFC_DLL_VERSION "")
set(_MFC_IDE_VERSION "")
if(_MSVC_IDE_VERSION GREATER_EQUAL 10)
set(_MFC_DLL_VERSION ${_MSVC_DLL_VERSION})
set(_MFC_IDE_VERSION ${_MSVC_IDE_VERSION})
endif()
if(_MFC_DLL_VERSION)
set(v "${_MFC_DLL_VERSION}")
set(vs "${_MFC_IDE_VERSION}")
# Starting with VS 15 the MFC DLLs may be in a different directory.
if (NOT vs VERSION_LESS 15)
file(GLOB _MSVC_REDIST_DIRS "${MSVC_REDIST_DIR}/../*")
find_path(MSVC_REDIST_MFC_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.MFC
PATHS ${_MSVC_REDIST_DIRS} NO_DEFAULT_PATH)
mark_as_advanced(MSVC_REDIST_MFC_DIR)
unset(_MSVC_REDIST_DIRS)
else()
set(MSVC_REDIST_MFC_DIR "${MSVC_REDIST_DIR}")
endif()
# Multi-Byte Character Set versions of MFC are available as optional
# addon since Visual Studio 12. So for version 12 or higher, check
# whether they are available and exclude them if they are not.
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
set(MSVC_MFC_DIR
"${MSVC_REDIST_MFC_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.DebugMFC")
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/mfc${v}ud.dll"
"${MSVC_MFC_DIR}/mfcm${v}ud.dll"
)
if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfc${v}d.dll")
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/mfc${v}d.dll"
)
endif()
if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfcm${v}d.dll")
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/mfcm${v}d.dll"
)
endif()
endif()
set(MSVC_MFC_DIR "${MSVC_REDIST_MFC_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.MFC")
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/mfc${v}u.dll"
"${MSVC_MFC_DIR}/mfcm${v}u.dll"
)
if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfc${v}.dll")
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/mfc${v}.dll"
)
endif()
if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfcm${v}.dll")
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/mfcm${v}.dll"
)
endif()
endif()
# include the language dll's as well as the actual dll's
set(MSVC_MFCLOC_DIR "${MSVC_REDIST_MFC_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.MFCLOC")
set(__install__libs ${__install__libs}
"${MSVC_MFCLOC_DIR}/mfc${v}chs.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}cht.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}deu.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}enu.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}esn.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}fra.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}ita.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}jpn.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}kor.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}rus.dll"
)
endif()
endif()
# MSVC 8 was the first version with OpenMP
# Furthermore, there is no debug version of this
if(CMAKE_INSTALL_OPENMP_LIBRARIES AND _IRSL_HAVE_MSVC)
set(_MSOMP_DLL_VERSION ${_MSVC_DLL_VERSION})
set(_MSOMP_IDE_VERSION ${_MSVC_IDE_VERSION})
if(_MSOMP_DLL_VERSION)
set(v "${_MSOMP_DLL_VERSION}")
set(vs "${_MSOMP_IDE_VERSION}")
set(MSVC_OPENMP_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.OPENMP")
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs ${__install__libs}
"${MSVC_OPENMP_DIR}/vcomp${v}.dll")
endif()
endif()
endif()
foreach(lib
${__install__libs}
)
if(EXISTS ${lib})
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS
${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} ${lib})
else()
if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
message(WARNING "system runtime library file does not exist: '${lib}'")
# This warning indicates an incomplete Visual Studio installation
# or a bug somewhere above here in this file.
# If you would like to avoid this warning, fix the real problem, or
# set CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS before including
# this file.
endif()
endif()
endforeach()
endif()
if(_IRSL_HAVE_Intel)
unset(__install_libs)
if(CMAKE_INSTALL_OPENMP_LIBRARIES)
if(WIN32)
list(APPEND __install_libs "${_Intel_redistdir}/libiomp5md.dll" "${_Intel_redistdir}/libiompstubs5md.dll")
elseif(APPLE)
list(APPEND __install_libs "${_Intel_redistdir}/libiomp5.dylib" "${_Intel_redistdir}/libiompstubs5.dylib")
else()
list(APPEND __install_libs "${_Intel_redistdir}/libiomp5.so" "${_Intel_redistdir}/libiompstubs5.so")
if(_Intel_compiler_ver VERSION_LESS 17)
list(APPEND __install_libs "${_Intel_redistdir}/libomp_db.so")
endif()
if(_Intel_compiler_ver VERSION_LESS 13)
list(APPEND __install_libs "${_Intel_redistdir}/libiompprof5.so")
endif()
endif()
endif()
if(WIN32)
set(__install_dirs "${_Intel_redistdir}/1033")
if(EXISTS "${_Intel_redistdir}/1041")
list(APPEND __install_dirs "${_Intel_redistdir}/1041")
endif()
if(_Intel_compiler_ver VERSION_LESS 18)
list(APPEND __install_dirs "${_Intel_redistdir}/irml" "${_Intel_redistdir}/irml_c")
endif()
foreach(__Intel_lib IN ITEMS cilkrts20.dll libchkp.dll libioffload_host.dll libirngmd.dll
libmmd.dll libmmdd.dll libmpx.dll liboffload.dll svml_dispmd.dll)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
if(CMAKE_C_COMPILER_ID STREQUAL Intel OR CMAKE_CXX_COMPILER_ID STREQUAL Intel)
list(APPEND __install_libs "${_Intel_redistdir}/libgfxoffload.dll")
endif()
if(CMAKE_Fortran_COMPILER_ID STREQUAL Intel)
foreach(__Intel_lib IN ITEMS ifdlg100.dll libicaf.dll libifcoremd.dll libifcoremdd.dll libifcorert.dll libifcorertd.dll libifportmd.dll)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
endif()
elseif(APPLE)
foreach(__Intel_lib IN ITEMS libchkp.dylib libcilkrts.5.dylib libcilkrts.dylib libimf.dylib libintlc.dylib libirc.dylib libirng.dylib libsvml.dylib)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
if(CMAKE_C_COMPILER_ID STREQUAL Intel OR CMAKE_CXX_COMPILER_ID STREQUAL Intel)
if(_Intel_compiler_ver VERSION_LESS 17)
list(APPEND __install_libs "${_Intel_redistdir}/libistrconv.dylib")
endif()
endif()
if(CMAKE_Fortran_COMPILER_ID STREQUAL Intel)
foreach(__Intel_lib IN ITEMS libifcore.dylib libifcoremt.dylib libifport.dylib libifportmt.dylib)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
endif()
else()
foreach(__Intel_lib IN ITEMS libchkp.so libcilkrts.so libcilkrts.so.5 libimf.so libintlc.so libintlc.so.5 libirc.so libpdbx.so libpdbx.so.5 libsvml.so)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
if(_Intel_compiler_ver VERSION_GREATER_EQUAL 13)
foreach(__Intel_lib IN ITEMS libirng.so liboffload.so liboffload.so.5)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
endif()
if(CMAKE_C_COMPILER_ID STREQUAL Intel OR CMAKE_CXX_COMPILER_ID STREQUAL Intel)
set(__install_dirs "${_Intel_redistdir}/irml")
list(APPEND __install_libs "${_Intel_redistdir}/cilk_db.so")
if(_Intel_compiler_ver VERSION_GREATER_EQUAL 15)
list(APPEND __install_libs "${_Intel_redistdir}/libistrconv.so" "${_Intel_redistdir}/libgfxoffload.so")
endif()
endif()
if(_Intel_compiler_ver VERSION_GREATER_EQUAL 16)
foreach(__Intel_lib IN ITEMS libioffload_host.so libioffload_host.so.5 libioffload_target.so libioffload_target.so.5 libmpx.so offload_main)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
endif()
if(_Intel_compiler_ver VERSION_LESS 15)
foreach(__Intel_lib IN ITEMS libcxaguard.so libcxaguard.so.5)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
endif()
if(CMAKE_Fortran_COMPILER_ID STREQUAL Intel)
foreach(__Intel_lib IN ITEMS libicaf.so libifcore.so libifcore.so.5 libifcoremt.so libifcoremt.so.5 libifport.so libifport.so.5)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
endif()
endif()
foreach(lib IN LISTS __install_libs)
if(EXISTS ${lib})
list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${lib})
else()
if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
message(WARNING "system runtime library file does not exist: '${lib}'")
endif()
endif()
endforeach()
foreach(dir IN LISTS __install_dirs)
if(EXISTS ${dir})
list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_DIRECTORIES ${dir})
else()
if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
message(WARNING "system runtime library file does not exist: '${dir}'")
endif()
endif()
endforeach()
endif()
if(WATCOM)
get_filename_component( CompilerPath ${CMAKE_C_COMPILER} PATH )
if(CMAKE_C_COMPILER_VERSION)
set(_compiler_version ${CMAKE_C_COMPILER_VERSION})
else()
set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION})
endif()
string(REGEX MATCHALL "[0-9]+" _watcom_version_list "${_compiler_version}")
list(GET _watcom_version_list 0 _watcom_major)
list(GET _watcom_version_list 1 _watcom_minor)
set( __install__libs
${CompilerPath}/clbr${_watcom_major}${_watcom_minor}.dll
${CompilerPath}/mt7r${_watcom_major}${_watcom_minor}.dll
${CompilerPath}/plbr${_watcom_major}${_watcom_minor}.dll )
foreach(lib
${__install__libs}
)
if(EXISTS ${lib})
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS
${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} ${lib})
else()
if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
message(WARNING "system runtime library file does not exist: '${lib}'")
# This warning indicates an incomplete Watcom installation
# or a bug somewhere above here in this file.
# If you would like to avoid this warning, fix the real problem, or
# set CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS before including
# this file.
endif()
endif()
endforeach()
endif()
# Include system runtime libraries in the installation if any are
# specified by CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS.
if(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS)
if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP)
if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION)
if(WIN32)
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION bin)
else()
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION lib)
endif()
endif()
if(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT)
set(_CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT
COMPONENT ${CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT})
endif()
install(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}
DESTINATION ${CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION}
${_CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT}
)
install(DIRECTORY ${CMAKE_INSTALL_SYSTEM_RUNTIME_DIRECTORIES}
DESTINATION ${CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION}
${_CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT}
)
endif()
endif()
cmake_policy(POP)

View File

@@ -7,6 +7,6 @@ set(LLAUDIO_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llaudio ${LIBS_OPEN_DIR}/llaudio
) )
add_definitions(-DOV_EXCLUDE_STATIC_CALLBACKS) #add_definitions(-DOV_EXCLUDE_STATIC_CALLBACKS)
set(LLAUDIO_LIBRARIES llaudio ${OPENAL_LIBRARIES}) set(LLAUDIO_LIBRARIES llaudio ${OPENAL_LIBRARIES})

View File

@@ -3,6 +3,7 @@
include(APR) include(APR)
include(Boost) include(Boost)
include(EXPAT) include(EXPAT)
include(Linking)
include(ZLIB) include(ZLIB)
if (DARWIN) if (DARWIN)
@@ -18,7 +19,9 @@ set(LLCOMMON_INCLUDE_DIRS
${Boost_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.") set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a shared library.")
if(LLCOMMON_LINK_SHARED) if(LLCOMMON_LINK_SHARED)

View File

@@ -1,9 +1,8 @@
# -*- cmake -*- # -*- cmake -*-
include(OpenGL) include(OpenGL)
include(Prebuilt)
if (STANDALONE) if (LINUX)
include(FindSDL) include(FindSDL)
# This should be done by FindSDL. Sigh. # This should be done by FindSDL. Sigh.
@@ -12,14 +11,7 @@ if (STANDALONE)
SDL_INCLUDE_DIR SDL_INCLUDE_DIR
SDL_LIBRARY SDL_LIBRARY
) )
else (STANDALONE) endif (LINUX)
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)
if (SDL_FOUND) if (SDL_FOUND)
add_definitions(-DLL_SDL=1) add_definitions(-DLL_SDL=1)

View File

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

View File

@@ -1,11 +1,9 @@
# -*- cmake -*- # -*- cmake -*-
include(Prebuilt)
include(FreeType) include(FreeType)
if (STANDALONE) if (LINUX)
include(FindPkgConfig) include(FindPkgConfig)
if (LINUX)
set(PKGCONFIG_PACKAGES set(PKGCONFIG_PACKAGES
atk atk
cairo cairo
@@ -21,8 +19,8 @@ if (STANDALONE)
pangox pangox
pangoxft pangoxft
sdl sdl
x11
) )
endif (LINUX)
foreach(pkg ${PKGCONFIG_PACKAGES}) foreach(pkg ${PKGCONFIG_PACKAGES})
pkg_check_modules(${pkg} REQUIRED ${pkg}) pkg_check_modules(${pkg} REQUIRED ${pkg})
@@ -31,39 +29,6 @@ if (STANDALONE)
list(APPEND UI_LIBRARIES ${${pkg}_LIBRARIES}) list(APPEND UI_LIBRARIES ${${pkg}_LIBRARIES})
add_definitions(${${pkg}_CFLAGS_OTHERS}) add_definitions(${${pkg}_CFLAGS_OTHERS})
endforeach(pkg) endforeach(pkg)
else (STANDALONE)
if (LINUX)
use_prebuilt_binary(gtk-atk-pango-glib)
set(UI_LIBRARIES
atk-1.0
cairo
gdk-x11-2.0
gdk_pixbuf-2.0
Xinerama
glib-2.0
gio-2.0
gmodule-2.0
gobject-2.0
gthread-2.0
gtk-x11-2.0
pango-1.0
pangoft2-1.0
pangoxft-1.0
pangocairo-1.0
pixman-1
X11
${FREETYPE_LIBRARIES}
)
endif (LINUX)
include_directories (
${LIBS_PREBUILT_DIR}/include
)
foreach(include ${${LL_ARCH}_INCLUDES})
include_directories(${LIBS_PREBUILT_DIR}/include/${include})
endforeach(include)
endif (STANDALONE)
if (LINUX)
add_definitions(-DLL_GTK=1 -DLL_X11=1) add_definitions(-DLL_GTK=1 -DLL_X11=1)
endif (LINUX) endif (LINUX)

View File

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

View File

@@ -9,16 +9,23 @@ FetchContent_Declare(
Catch2 Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v2.11.0 GIT_TAG v2.11.0
GIT_SHALLOW TRUE
) )
FetchContent_Declare( FetchContent_Declare(
fmt fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git 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( FetchContent_Declare(
absl absl
GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git
GIT_TAG 29235139149790f5afc430c11cec8f1eb1677607 GIT_TAG 768eb2ca2857342673fcd462792ce04b8bac3fa3
) )
# This is a hack because absl has dumb cmake # This is a hack because absl has dumb cmake
@@ -40,9 +47,16 @@ if (BUILD_TESTING)
endif() endif()
#Download the rest of the libraries #Download the rest of the libraries
if(WINDOWS)
FetchContent_MakeAvailable(fmt) 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_FOLDER)
unset(CMAKE_POSITION_INDEPENDENT_CODE) unset(CMAKE_POSITION_INDEPENDENT_CODE)

View File

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

View File

@@ -31,11 +31,16 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#define OPJ_SKIP_POISON
#include "opj_includes.h"
#ifdef __SSE__ #ifdef __SSE__
#include <xmmintrin.h> #include <xmmintrin.h>
#endif #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 */ /** @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> */ /* <summary> */
/* Determine maximum computed resolution level for inverse wavelet transform */ /* Determine maximum computed resolution level for inverse wavelet transform */
/* </summary> */ /* </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 mr = 1;
int w; int w;
while( --i ) { 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; v.mem = h.mem;
while( --numres) { while( --numres) {
int * restrict tiledp = tilec->data; int * OPJ_RESTRICT tiledp = tilec->data;
int j; int j;
++tr; ++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); opj_aligned_free(h.mem);
} }
static void v4dwt_interleave_h(v4dwt_t* restrict w, float* restrict a, int x, int size){ static void v4dwt_interleave_h(v4dwt_t* OPJ_RESTRICT w, float* OPJ_RESTRICT a, int x, int size) {
float* restrict bi = (float*) (w->wavelet + w->cas); float* OPJ_RESTRICT bi = (float*)(w->wavelet + w->cas);
int count = w->sn; int count = w->sn;
int i, k; int i, k;
for(k = 0; k < 2; ++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) { if (count + 3 * x < size && ((size_t)a & 0x0f) == 0 && ((size_t)bi & 0x0f) == 0 && (x & 0x0f) == 0) {
/* Fast code path */ /* Fast code path */
for(i = 0; i < count; ++i){ for (i = 0; i < count; ++i) {
int j = i; int j = i;
bi[i*8 ] = a[j]; bi[i * 8] = a[j];
j += x; j += x;
bi[i*8 + 1] = a[j]; bi[i * 8 + 1] = a[j];
j += x; j += x;
bi[i*8 + 2] = a[j]; bi[i * 8 + 2] = a[j];
j += x; j += x;
bi[i*8 + 3] = a[j]; bi[i * 8 + 3] = a[j];
} }
} else { }
else {
/* Slow code path */ /* Slow code path */
for(i = 0; i < count; ++i){ for (i = 0; i < count; ++i) {
int j = i; int j = i;
bi[i*8 ] = a[j]; bi[i * 8] = a[j];
j += x; j += x;
if(j > size) continue; if (j > size) continue;
bi[i*8 + 1] = a[j]; bi[i * 8 + 1] = a[j];
j += x; j += x;
if(j > size) continue; if (j > size) continue;
bi[i*8 + 2] = a[j]; bi[i * 8 + 2] = a[j];
j += x; j += x;
if(j > size) continue; if (j > size) continue;
bi[i*8 + 3] = a[j]; bi[i * 8 + 3] = a[j];
}
} }
} bi = (float*)(w->wavelet + 1 - w->cas);
bi = (float*) (w->wavelet + 1 - w->cas);
a += w->sn; a += w->sn;
size -= w->sn; size -= w->sn;
count = w->dn; count = w->dn;
} }
} }
static void v4dwt_interleave_v(v4dwt_t* restrict v , float* restrict a , int x){ static void v4dwt_interleave_v(v4dwt_t* OPJ_RESTRICT v , float* OPJ_RESTRICT a , int x){
v4* restrict bi = v->wavelet + v->cas; v4* OPJ_RESTRICT bi = v->wavelet + v->cas;
int i; int i;
for(i = 0; i < v->sn; ++i){ for(i = 0; i < v->sn; ++i){
memcpy(&bi[i*2], &a[i*x], 4 * sizeof(float)); 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__ #ifdef __SSE__
static void v4dwt_decode_step1_sse(v4* w, int count, const __m128 c){ 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; int i;
/* 4x unrolled loop */ /* 4x unrolled loop */
for(i = 0; i < count >> 2; ++i){ 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){ static void v4dwt_decode_step2_sse(v4* l, v4* w, int k, int m, __m128 c){
__m128* restrict vl = (__m128*) l; __m128* OPJ_RESTRICT vl = (__m128*) l;
__m128* restrict vw = (__m128*) w; __m128* OPJ_RESTRICT vw = (__m128*) w;
int i; int i;
__m128 tmp1, tmp2, tmp3; __m128 tmp1, tmp2, tmp3;
tmp1 = vl[0]; 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]; tmp2 = vw[-1];
tmp3 = vw[ 0]; tmp3 = vw[ 0];
vw[-1] = _mm_add_ps(tmp2, _mm_mul_ps(_mm_add_ps(tmp1, tmp3), c)); vw[-1] = _mm_add_ps(tmp2, _mm_mul_ps(_mm_add_ps(tmp1, tmp3), c));
tmp1 = tmp3; tmp1 = tmp3;
vw += 2; vw += 2;
} }
vl = vw - 2;
if(m >= k){ if(m >= k){
return; return;
} }
vl = vw - 2;
c = _mm_add_ps(c, c); c = _mm_add_ps(c, c);
c = _mm_mul_ps(c, vl[0]); c = _mm_mul_ps(c, vl[0]);
for(; m < k; ++m){ 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 #else
static void v4dwt_decode_step1(v4* w, int count, const float c){ 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; int i;
for(i = 0; i < count; ++i){ for(i = 0; i < count; ++i){
float tmp1 = fw[i*8 ]; 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){ static void v4dwt_decode_step2(v4* l, v4* w, int k, int m, float c){
float* restrict fl = (float*) l; float* OPJ_RESTRICT fl = (float*) l;
float* restrict fw = (float*) w; float* OPJ_RESTRICT fw = (float*) w;
int i; int i;
for(i = 0; i < m; ++i){ for(i = 0; i < m; ++i){
float tmp1_1 = fl[0]; 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> */ /* <summary> */
/* Inverse 9-7 wavelet transform in 1-D. */ /* Inverse 9-7 wavelet transform in 1-D. */
/* </summary> */ /* </summary> */
static void v4dwt_decode(v4dwt_t* restrict dwt){ static void v4dwt_decode(v4dwt_t* OPJ_RESTRICT dwt){
int a, b; int a, b;
if(dwt->cas == 0) { if(dwt->cas == 0) {
if(!((dwt->dn > 0) || (dwt->sn > 1))){ if (dwt->dn <= 0 && dwt->sn <= 1) {
return; return;
} }
a = 0; a = 0;
b = 1; b = 1;
}else{ }else{
if(!((dwt->sn > 0) || (dwt->dn > 1))) { if (dwt->sn <= 0 && dwt->dn <= 1) {
return; return;
} }
a = 1; a = 1;
b = 0; b = 0;
} }
v4* OPJ_RESTRICT waveleta = dwt->wavelet + a;
v4* OPJ_RESTRICT waveletb = dwt->wavelet + b;
#ifdef __SSE__ #ifdef __SSE__
v4dwt_decode_step1_sse(dwt->wavelet+a, dwt->sn, _mm_set1_ps(K)); v4dwt_decode_step1_sse(waveleta, dwt->sn, _mm_set1_ps(K));
v4dwt_decode_step1_sse(dwt->wavelet+b, dwt->dn, _mm_set1_ps(c13318)); v4dwt_decode_step1_sse(waveletb, 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(waveletb, waveleta + 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(waveleta, waveletb + 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(waveletb, waveleta + 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_step2_sse(waveleta, waveletb + 1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_alpha));
#else #else
v4dwt_decode_step1(dwt->wavelet+a, dwt->sn, K); v4dwt_decode_step1(waveleta, dwt->sn, K);
v4dwt_decode_step1(dwt->wavelet+b, dwt->dn, c13318); v4dwt_decode_step1(waveletb, 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(waveletb, waveleta + 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(waveleta, waveletb + 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(waveletb, waveleta + 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_step2(waveleta, waveletb + 1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_alpha);
#endif #endif
} }
/* <summary> */ /* <summary> */
/* Inverse 9-7 wavelet transform in 2-D. */ /* Inverse 9-7 wavelet transform in 2-D. */
/* </summary> */ /* </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 h;
v4dwt_t v; v4dwt_t v;
@@ -787,7 +812,7 @@ void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){
v.wavelet = h.wavelet; v.wavelet = h.wavelet;
while( --numres) { 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 bufsize = (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0);
int j; int j;

View File

@@ -29,11 +29,16 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#define OPJ_SKIP_POISON
#include "opj_includes.h"
#ifdef __SSE__ #ifdef __SSE__
#include <xmmintrin.h> #include <xmmintrin.h>
#endif #endif
#include "opj_includes.h" #if defined(__GNUC__)
#pragma GCC poison malloc calloc realloc free
#endif
/* <summary> */ /* <summary> */
/* This table contains the norms of the basis function of the reversible MCT. */ /* 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. */ /* Foward reversible MCT. */
/* </summary> */ /* </summary> */
void mct_encode( void mct_encode(
int* restrict c0, int* OPJ_RESTRICT c0,
int* restrict c1, int* OPJ_RESTRICT c1,
int* restrict c2, int* OPJ_RESTRICT c2,
int n) int n)
{ {
int i; int i = 0;
for(i = 0; i < n; ++i) { #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 r = c0[i];
int g = c1[i]; int g = c1[i];
int b = c2[i]; int b = c2[i];
int y = (r + (g * 2) + b) >> 2; int y = (r + g + g + b) >> 2;
int u = b - g; int u = b - g;
int v = r - g; int v = r - g;
c0[i] = y; c0[i] = y;
@@ -72,13 +98,32 @@ void mct_encode(
/* Inverse reversible MCT. */ /* Inverse reversible MCT. */
/* </summary> */ /* </summary> */
void mct_decode( void mct_decode(
int* restrict c0, int* OPJ_RESTRICT c0,
int* restrict c1, int* OPJ_RESTRICT c1,
int* restrict c2, int* OPJ_RESTRICT c2,
int n) int n)
{ {
int i; int i = 0;
for (i = 0; i < n; ++i) { #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 y = c0[i];
int u = c1[i]; int u = c1[i];
int v = c2[i]; int v = c2[i];
@@ -102,13 +147,119 @@ double mct_getnorm(int compno) {
/* Foward irreversible MCT. */ /* Foward irreversible MCT. */
/* </summary> */ /* </summary> */
void mct_encode_real( void mct_encode_real(
int* restrict c0, int* OPJ_RESTRICT c0,
int* restrict c1, int* OPJ_RESTRICT c1,
int* restrict c2, int* OPJ_RESTRICT c2,
int n) int n)
{ {
int i; int i = 0;
for(i = 0; i < n; ++i) { #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 r = c0[i];
int g = c1[i]; int g = c1[i];
int b = c2[i]; int b = c2[i];
@@ -125,19 +276,21 @@ void mct_encode_real(
/* Inverse irreversible MCT. */ /* Inverse irreversible MCT. */
/* </summary> */ /* </summary> */
void mct_decode_real( void mct_decode_real(
float* restrict c0, float* OPJ_RESTRICT c0,
float* restrict c1, float* OPJ_RESTRICT c1,
float* restrict c2, float* OPJ_RESTRICT c2,
int n) int n)
{ {
int i; int i;
#ifdef __SSE__ #ifdef __SSE__
int count;
__m128 vrv, vgu, vgv, vbu; __m128 vrv, vgu, vgv, vbu;
vrv = _mm_set1_ps(1.402f); vrv = _mm_set1_ps(1.402f);
vgu = _mm_set1_ps(0.34413f); vgu = _mm_set1_ps(0.34413f);
vgv = _mm_set1_ps(0.71414f); vgv = _mm_set1_ps(0.71414f);
vbu = _mm_set1_ps(1.772f); 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 vy, vu, vv;
__m128 vr, vg, vb; __m128 vr, vg, vb;
@@ -174,7 +327,7 @@ void mct_decode_real(
float u = c1[i]; float u = c1[i];
float v = c2[i]; float v = c2[i];
float r = y + (v * 1.402f); 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); float b = y + (u * 1.772f);
c0[i] = r; c0[i] = r;
c1[i] = g; 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) #if defined(OPJ_STATIC) || !defined(_WIN32)
#define OPJ_API #define OPJ_API
#define OPJ_CALLCONV #define OPJ_CALLCONV
#else #else
#define OPJ_CALLCONV __stdcall #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 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 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 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 OPJ_API functions as being imported from a DLL, whereas this DLL sees symbols
defined with this macro as being exported. defined with this macro as being exported.
*/ */
#if defined(OPJ_EXPORTS) || defined(DLL_EXPORT) # if defined(OPJ_EXPORTS) || defined(DLL_EXPORT)
#define OPJ_API __declspec(dllexport) # define OPJ_API __declspec(dllexport)
#else # else
#define OPJ_API __declspec(dllimport) # define OPJ_API __declspec(dllimport)
#endif /* OPJ_EXPORTS */ # endif /* OPJ_EXPORTS */
#endif /* !OPJ_STATIC || !_WIN32 */ #endif /* !OPJ_STATIC || !_WIN32 */
typedef int opj_bool; typedef int opj_bool;
#define OPJ_TRUE 1 #define OPJ_TRUE 1
#define OPJ_FALSE 0 #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 */ /* Avoid compile-time warning because parameter is not used */
#define OPJ_ARG_NOT_USED(x) (void)(x) #define OPJ_ARG_NOT_USED(x) (void)(x)
/*
/*
========================================================== ==========================================================
Useful constant definitions Useful constant definitions
========================================================== ==========================================================

View File

@@ -40,6 +40,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <ctype.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 */ /* Ignore GCC attributes if this is not GCC */
#ifndef __GNUC__ #ifndef __GNUC__
#define __attribute__(x) /* __attribute__(x) */ #define __attribute__(x) /* __attribute__(x) */
#endif #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) */ /* MSVC before 2013 and Borland C do not have lrintf */
#if (__STDC_VERSION__ != 199901L) #if defined(_MSC_VER)
/* Not a C99 compiler */ #include <intrin.h>
#ifdef __GNUC__ static INLINE long opj_lrintf(float f)
#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){
#ifdef _M_X64 #ifdef _M_X64
return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f)); return _mm_cvt_ss2si(_mm_load_ss(&f));
#else
/* commented out line breaks many tests */
/* return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f)); */
#elif defined(_M_IX86)
int i; int i;
_asm{ _asm{
fld f fld f
fistp i 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; return i;
#endif #endif
} }
#else
static INLINE long opj_lrintf(float f)
{
return lrintf(f);
}
#endif #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 "j2k_lib.h"
#include "opj_malloc.h" #include "opj_malloc.h"
#include "event.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) 2005, Herve Drolon, FreeImage Team
* Copyright (c) 2007, Callum Lerwick <seg@haxxed.com> * Copyright (c) 2007, Callum Lerwick <seg@haxxed.com>
* All rights reserved. * All rights reserved.
@@ -24,8 +29,10 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef __OPJ_MALLOC_H #ifndef OPJ_MALLOC_H
#define __OPJ_MALLOC_H #define OPJ_MALLOC_H
#include <stddef.h>
/** /**
@file opj_malloc.h @file opj_malloc.h
@brief Internal functions @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 */ /** @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 */ /** @name Exported functions */
/*@{*/ /*@{*/
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
@@ -45,90 +63,32 @@ Allocate an uninitialized memory block
@param size Bytes to allocate @param size Bytes to allocate
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available @return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
*/ */
#ifdef ALLOC_PERF_OPT void * opj_malloc(size_t size);
void * OPJ_CALLCONV opj_malloc(size_t size);
#else
#define opj_malloc(size) malloc(size)
#endif
/** /**
Allocate a memory block with elements initialized to 0 Allocate a memory block with elements initialized to 0
@param num Blocks to allocate @param numOfElements Blocks to allocate
@param size Bytes per block 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 @return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
*/ */
#ifdef ALLOC_PERF_OPT void * opj_calloc(size_t numOfElements, size_t sizeOfElements);
void * OPJ_CALLCONV opj_calloc(size_t _NumOfElements, size_t _SizeOfElements);
#else
#define opj_calloc(num, size) calloc(num, size)
#endif
/** /**
Allocate memory aligned to a 16 byte boundry Allocate memory aligned to a 16 byte boundary
@param size Bytes to allocate @param size Bytes to allocate
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available @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 */ void * opj_aligned_malloc(size_t size);
#ifdef _WIN32 void * opj_aligned_realloc(void *ptr, size_t size);
/* Someone should tell the mingw people that their malloc.h ought to provide _mm_malloc() */ void opj_aligned_free(void* ptr);
#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
#define opj_aligned_malloc(size) malloc(size) /**
#define opj_aligned_free(m) free(m) Allocate memory aligned to a 32 byte boundary
@param size Bytes to allocate
#ifdef HAVE_MM_MALLOC @return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
#undef opj_aligned_malloc */
#define opj_aligned_malloc(size) _mm_malloc(size, 16) void * opj_aligned_32_malloc(size_t size);
#undef opj_aligned_free void * opj_aligned_32_realloc(void *ptr, size_t size);
#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
/** /**
Reallocate memory blocks. Reallocate memory blocks.
@@ -136,23 +96,15 @@ Reallocate memory blocks.
@param s New size in bytes @param s New size in bytes
@return Returns a void pointer to the reallocated (and possibly moved) memory block @return Returns a void pointer to the reallocated (and possibly moved) memory block
*/ */
#ifdef ALLOC_PERF_OPT void * opj_realloc(void * m, size_t s);
void * OPJ_CALLCONV opj_realloc(void * m, size_t s);
#else
#define opj_realloc(m, s) realloc(m, s)
#endif
/** /**
Deallocates or frees a memory block. Deallocates or frees a memory block.
@param m Previously allocated memory block to be freed @param m Previously allocated memory block to be freed
*/ */
#ifdef ALLOC_PERF_OPT void opj_free(void * m);
void OPJ_CALLCONV opj_free(void * m);
#else
#define opj_free(m) free(m)
#endif
#ifdef __GNUC__ #if defined(__GNUC__) && !defined(OPJ_SKIP_POISON)
#pragma GCC poison malloc calloc realloc free #pragma GCC poison malloc calloc realloc free
#endif #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]; opj_tcd_resolution_t *res = &tilec->resolutions[resno];
for (bandno = 0; bandno < res->numbands; ++bandno) { 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)); int bandconst = 8192 * 8192 / ((int) floor(band->stepsize * 8192));
for (precno = 0; precno < res->pw * res->ph; ++precno) { 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) { for (cblkno = 0; cblkno < prc->cw * prc->ch; ++cblkno) {
opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno]; opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
int* restrict datap; int* OPJ_RESTRICT datap;
int* restrict tiledp; int* OPJ_RESTRICT tiledp;
int cblk_w; int cblk_w;
int cblk_h; int cblk_h;
int i, j; int i, j;
@@ -1517,14 +1517,14 @@ void t1_decode_cblks(
opj_tcd_resolution_t* res = &tilec->resolutions[resno]; opj_tcd_resolution_t* res = &tilec->resolutions[resno];
for (bandno = 0; bandno < res->numbands; ++bandno) { 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) { for (precno = 0; precno < res->pw * res->ph; ++precno) {
opj_tcd_precinct_t* precinct = &band->precincts[precno]; opj_tcd_precinct_t* precinct = &band->precincts[precno];
for (cblkno = 0; cblkno < precinct->cw * precinct->ch; ++cblkno) { for (cblkno = 0; cblkno < precinct->cw * precinct->ch; ++cblkno) {
opj_tcd_cblk_dec_t* cblk = &precinct->cblks.dec[cblkno]; opj_tcd_cblk_dec_t* cblk = &precinct->cblks.dec[cblkno];
int* restrict datap; int* OPJ_RESTRICT datap;
int cblk_w, cblk_h; int cblk_w, cblk_h;
int x, y; int x, y;
int i, j; int i, j;
@@ -1566,7 +1566,7 @@ void t1_decode_cblks(
} }
if (tccp->qmfbid == 1) { 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 (j = 0; j < cblk_h; ++j) {
for (i = 0; i < cblk_w; ++i) { for (i = 0; i < cblk_w; ++i) {
int tmp = datap[(j * cblk_w) + i]; int tmp = datap[(j * cblk_w) + i];
@@ -1574,9 +1574,9 @@ void t1_decode_cblks(
} }
} }
} else { /* if (tccp->qmfbid == 0) */ } 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) { for (j = 0; j < cblk_h; ++j) {
float* restrict tiledp2 = tiledp; float* OPJ_RESTRICT tiledp2 = tiledp;
for (i = 0; i < cblk_w; ++i) { for (i = 0; i < cblk_w; ++i) {
float tmp = *datap * band->stepsize; float tmp = *datap * band->stepsize;
*tiledp2 = tmp; *tiledp2 = tmp;

View File

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

View File

@@ -30,6 +30,7 @@
*/ */
#include "opj_includes.h" #include "opj_includes.h"
#include <assert.h>
/** @defgroup T2 T2 - Implementation of a tier-2 coding */ /** @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 precno = pi->precno; /* precinct value */
int layno = pi->layno; /* quality layer value */ int layno = pi->layno; /* quality layer value */
opj_tcd_resolution_t* res = &tile->comps[compno].resolutions[resno];
unsigned char *hd = NULL; unsigned char *hd = NULL;
int present; int present;
opj_bio_t *bio = NULL; /* BIO component */ 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) { if (layno == 0) {
for (bandno = 0; bandno < res->numbands; bandno++) { for (bandno = 0; bandno < res->numbands; bandno++) {
opj_tcd_band_t *band = &res->bands[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(j = res->y0; j < res->y1; ++j) {
for(i = res->x0; i < res->x1; ++i) { for(i = res->x0; i < res->x1; ++i) {
float tmp = ((float*)tilec->data)[i - res->x0 + (j - res->y0) * tw]; float tmp = ((float*)tilec->data)[i - res->x0 + (j - res->y0) * tw];
int v = lrintf(tmp); int v = opj_lrintf(tmp);
v += adjust; v += adjust;
imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max); imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max);
} }

View File

@@ -24,11 +24,6 @@
* $/LicenseInfo$ * $/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" #include "linden_common.h"
@@ -230,7 +225,7 @@ void LLAvatarAppearance::initInstance()
for (U32 lod = 0; lod < mesh_dict->mLOD; lod++) for (U32 lod = 0; lod < mesh_dict->mLOD; lod++)
{ {
LLAvatarJointMesh* mesh = createAvatarJointMesh(); 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 // We pre-pended an m - need to capitalize first character for camelCase
mesh_name[1] = toupper(mesh_name[1]); mesh_name[1] = toupper(mesh_name[1]);
mesh->setName(mesh_name); mesh->setName(mesh_name);

View File

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

View File

@@ -132,7 +132,7 @@ class LL_COMMON_API AIArgs
// Add another replacement. // Add another replacement.
AIArgs& operator()(char const* key, std::string const& replacement) { mArgs[key] = replacement; return *this; } AIArgs& operator()(char const* key, std::string const& replacement) { mArgs[key] = replacement; return *this; }
// The destructor may not throw. // The destructor may not throw.
~AIArgs() throw() { } ~AIArgs() noexcept { }
// Accessor. // Accessor.
LLStringUtil::format_map_t const& operator*() const { return mArgs; } LLStringUtil::format_map_t const& operator*() const { return mArgs; }
@@ -193,7 +193,7 @@ class LL_COMMON_API Line
Line(std::string const& xml_desc, AIArgs const& args, bool newline = false) : mNewline(newline), mXmlDesc(xml_desc), mArgs(args), mType(normal) { } Line(std::string const& xml_desc, AIArgs const& args, bool newline = false) : mNewline(newline), mXmlDesc(xml_desc), mArgs(args), mType(normal) { }
Line(Prefix const& prefix, bool newline = false) : mNewline(newline), mXmlDesc("AIPrefix"), mArgs("[PREFIX]", prefix.str()), mType(prefix.type()) { } Line(Prefix const& prefix, bool newline = false) : mNewline(newline), mXmlDesc("AIPrefix"), mArgs("[PREFIX]", prefix.str()), mType(prefix.type()) { }
// The destructor may not throw. // The destructor may not throw.
~Line() throw() { } ~Line() noexcept { }
// Prepend a newline before this line. // Prepend a newline before this line.
void set_newline(void) { mNewline = true; } void set_newline(void) { mNewline = true; }
@@ -225,7 +225,7 @@ class LL_COMMON_API Error : public std::exception
typedef std::deque<Line> lines_type; typedef std::deque<Line> lines_type;
// The destructor may not throw. // The destructor may not throw.
~Error() throw() { } ~Error() noexcept { }
// Accessors. // Accessors.
lines_type const& lines(void) const { return mLines; } lines_type const& lines(void) const { return mLines; }
@@ -267,7 +267,7 @@ class LL_COMMON_API ErrorCode : public Error
public: public:
// The destructor may not throw. // The destructor may not throw.
~ErrorCode() throw() { } ~ErrorCode() noexcept { }
// Accessor. // Accessor.
int getCode(void) const { return mCode; } int getCode(void) const { return mCode; }

View File

@@ -244,7 +244,6 @@ const U8 SIM_ACCESS_DOWN = 254;
const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT; const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT;
// attachment constants // attachment constants
const U32 MAX_AGENT_ATTACHMENTS = 38;
const U8 ATTACHMENT_ADD = 0x80; const U8 ATTACHMENT_ADD = 0x80;
// god levels // god levels

View File

@@ -353,8 +353,14 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
// NEW Macros for debugging, allow the passing of a string tag // 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) // 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_INFOS(...) lllog(LLError::LEVEL_INFO, false, false, ##__VA_ARGS__)
#define LL_WARNS(...) lllog(LLError::LEVEL_WARN, 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__) #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 // 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). // 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_INFOS_ONCE(...) lllog(LLError::LEVEL_INFO, true, false, ##__VA_ARGS__)
#define LL_WARNS_ONCE(...) lllog(LLError::LEVEL_WARN, true, false, ##__VA_ARGS__) #define LL_WARNS_ONCE(...) lllog(LLError::LEVEL_WARN, true, false, ##__VA_ARGS__)
// No function name // 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_INFOS_NF(...) lllog(LLError::LEVEL_INFO, false, true, ##__VA_ARGS__)
#define LL_WARNS_NF(...) lllog(LLError::LEVEL_WARN, 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__) #define LL_ERRS_NF(...) lllog(LLError::LEVEL_ERROR, false, true, ##__VA_ARGS__)

View File

@@ -412,7 +412,7 @@ public:
std::runtime_error(what), std::runtime_error(what),
mData(data) mData(data)
{} {}
virtual ~LLErrorEvent() throw() {} virtual ~LLErrorEvent() noexcept {}
LLSD getData() const { return mData; } LLSD getData() const { return mData; }

View File

@@ -381,10 +381,9 @@ std::string LLSDArgsMapper::formatlist(const LLSD& list)
{ {
std::ostringstream out; std::ostringstream out;
const char* delim = ""; const char* delim = "";
for (LLSD::array_const_iterator li(list.beginArray()), lend(list.endArray()); for (auto const& entry : list.array())
li != lend; ++li)
{ {
out << delim << li->asString(); out << delim << entry.asString();
delim = ", "; delim = ", ";
} }
return out.str(); return out.str();
@@ -494,10 +493,9 @@ struct LLEventDispatcher::MapParamsDispatchEntry: public LLEventDispatcher::Para
{ {
// Build the set of all param keys, then delete the ones that are // Build the set of all param keys, then delete the ones that are
// optional. What's left are the ones that are required. // optional. What's left are the ones that are required.
for (LLSD::array_const_iterator pi(params.beginArray()), pend(params.endArray()); for (auto const& entry : params.array())
pi != pend; ++pi)
{ {
mRequired[pi->asString()] = LLSD(); mRequired[entry.asString()] = LLSD();
} }
if (defaults.isArray() || defaults.isUndefined()) if (defaults.isArray() || defaults.isUndefined())

View File

@@ -182,10 +182,10 @@ public:
bool operator! () const { return ! mListener; } bool operator! () const { return ! mListener; }
/// explicit accessor /// explicit accessor
const LLEventListener& getListener() const { return *mListener; } const ::LLEventListener& getListener() const { return *mListener; }
/// implicit conversion to LLEventListener /// implicit conversion to LLEventListener
operator LLEventListener() const { return *mListener; } operator ::LLEventListener() const { return *mListener; }
/// allow calling directly /// allow calling directly
bool operator()(const LLSD& event) const; bool operator()(const LLSD& event) const;
@@ -277,7 +277,7 @@ namespace LLEventDetail
/// Any callable capable of connecting an LLEventListener to an /// Any callable capable of connecting an LLEventListener to an
/// LLStandardSignal to produce an LLBoundListener can be mapped to this /// LLStandardSignal to produce an LLBoundListener can be mapped to this
/// signature. /// signature.
typedef boost::function<LLBoundListener(const LLEventListener&)> ConnectFunc; typedef boost::function<LLBoundListener(const ::LLEventListener&)> ConnectFunc;
/// overload of visit_and_connect() when we have a string identifier available /// overload of visit_and_connect() when we have a string identifier available
template <typename LISTENER> template <typename LISTENER>
@@ -547,7 +547,7 @@ private:
virtual void reset(); virtual void reset();
private: private:
virtual LLBoundListener listen_impl(const std::string& name, const LLEventListener&, virtual LLBoundListener listen_impl(const std::string& name, const ::LLEventListener&,
const NameList& after, const NameList& after,
const NameList& before); const NameList& before);
std::string mName; std::string mName;
@@ -845,7 +845,7 @@ namespace LLEventDetail
* Visitor binds a reference to LLEventListener so we can track() any * Visitor binds a reference to LLEventListener so we can track() any
* shared_ptrs we find in the argument list. * shared_ptrs we find in the argument list.
*/ */
Visitor(LLEventListener& listener): Visitor(::LLEventListener& listener):
mListener(listener) mListener(listener)
{ {
} }
@@ -988,7 +988,7 @@ namespace LLEventDetail
|*==========================================================================*/ |*==========================================================================*/
/// Bind a reference to the LLEventListener to call its track() method. /// Bind a reference to the LLEventListener to call its track() method.
LLEventListener& mListener; ::LLEventListener& mListener;
}; };
/** /**
@@ -1005,7 +1005,7 @@ namespace LLEventDetail
const ConnectFunc& connect_func) const ConnectFunc& connect_func)
{ {
// Capture the listener // Capture the listener
LLEventListener listener(raw_listener); ::LLEventListener listener(raw_listener);
// Define our Visitor, binding the listener so we can call // Define our Visitor, binding the listener so we can call
// listener.track() if we discover any shared_ptr<Foo>. // listener.track() if we discover any shared_ptr<Foo>.
LLEventDetail::Visitor visitor(listener); LLEventDetail::Visitor visitor(listener);

View File

@@ -54,6 +54,7 @@ std::string LLFile::strerr(int errn)
{ {
char buffer[256]; char buffer[256];
strerror_s(buffer, errn); // infers sizeof(buffer) -- love it! strerror_s(buffer, errn); // infers sizeof(buffer) -- love it!
buffer[255] = 0;
return buffer; return buffer;
} }
@@ -281,6 +282,11 @@ int LLFile::rename_nowarn(const std::string& filename, const std::string& newnam
int rc = _wrename(utf16filename.c_str(),utf16newname.c_str()); int rc = _wrename(utf16filename.c_str(),utf16newname.c_str());
#else #else
int rc = ::rename(filename.c_str(),newname.c_str()); int rc = ::rename(filename.c_str(),newname.c_str());
if (rc == -1 && errno == EXDEV)
{
rc = std::system(("mv '" + filename + "' '" + newname + '\'').data());
errno = 0;
}
#endif #endif
return rc; return rc;
} }

View File

@@ -34,6 +34,16 @@
#ifndef LL_LLFORMAT_H #ifndef LL_LLFORMAT_H
#define 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: // Use as follows:
// LL_INFOS() << llformat("Test:%d (%.2f %.2f)", idx, x, y) << LL_ENDL; // LL_INFOS() << llformat("Test:%d (%.2f %.2f)", idx, x, y) << LL_ENDL;
// //

View File

@@ -126,9 +126,9 @@ public:
virtual Date asDate() const { return LLDate(); } virtual Date asDate() const { return LLDate(); }
virtual URI asURI() const { return LLURI(); } virtual URI asURI() const { return LLURI(); }
virtual const Binary& asBinary() const { static const std::vector<U8> empty; return empty; } virtual const Binary& asBinary() const { static const std::vector<U8> empty; return empty; }
virtual const String& asStringRef() const { static const std::string empty; return empty; }
virtual const String& asStringRef() const { static const std::string empty; return empty; }
virtual bool has(const String&) const { return false; } virtual bool has(const String&) const { return false; }
virtual LLSD get(const String&) const { return LLSD(); } virtual LLSD get(const String&) const { return LLSD(); }
virtual LLSD getKeys() const { return LLSD::emptyArray(); } virtual LLSD getKeys() const { return LLSD::emptyArray(); }
@@ -140,10 +140,14 @@ public:
virtual void erase(Integer) { } virtual void erase(Integer) { }
virtual const LLSD& ref(Integer) const { return undef(); } virtual const LLSD& ref(Integer) const { return undef(); }
virtual LLSD::map_const_iterator beginMap() const { return endMap(); } virtual const std::map<String, LLSD>& map() const { static const std::map<String, LLSD> empty; return empty; }
virtual LLSD::map_const_iterator endMap() const { static const std::map<String, LLSD> empty; return empty.end(); } virtual std::map<String, LLSD>& map() { static std::map<String, LLSD> empty; return empty; }
virtual LLSD::array_const_iterator beginArray() const { return endArray(); } LLSD::map_const_iterator beginMap() const { return map().begin(); }
virtual LLSD::array_const_iterator endArray() const { static const std::vector<LLSD> empty; return empty.end(); } LLSD::map_const_iterator endMap() const { return map().end(); }
virtual const std::vector<LLSD>& array() const { static const std::vector<LLSD> empty; return empty; }
virtual std::vector<LLSD>& array() { static std::vector<LLSD> empty; return empty; }
LLSD::array_const_iterator beginArray() const { return array().begin(); }
LLSD::array_const_iterator endArray() const { return array().end(); }
virtual void dumpStats() const; virtual void dumpStats() const;
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const; virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
@@ -183,10 +187,11 @@ namespace
public: public:
ImplBase(DataRef value) : mValue(value) { } ImplBase(DataRef value) : mValue(value) { }
virtual LLSD::Type type() const { return T; } LLSD::Type type() const override { return T; }
using LLSD::Impl::assign; // Unhiding base class virtuals... using LLSD::Impl::assign; // Unhiding base class virtuals...
virtual void assign(LLSD::Impl*& var, DataRef value) { void assign(LLSD::Impl*& var, DataRef value) override
{
if (shared()) if (shared())
{ {
Impl::assign(var, value); Impl::assign(var, value);
@@ -199,16 +204,16 @@ namespace
}; };
class ImplBoolean class ImplBoolean final
: public ImplBase<LLSD::TypeBoolean, LLSD::Boolean> : public ImplBase<LLSD::TypeBoolean, LLSD::Boolean>
{ {
public: public:
ImplBoolean(LLSD::Boolean v) : Base(v) { } ImplBoolean(LLSD::Boolean v) : Base(v) { }
virtual LLSD::Boolean asBoolean() const { return mValue; } LLSD::Boolean asBoolean() const override { return mValue; }
virtual LLSD::Integer asInteger() const { return mValue ? 1 : 0; } LLSD::Integer asInteger() const override { return mValue ? 1 : 0; }
virtual LLSD::Real asReal() const { return mValue ? 1 : 0; } LLSD::Real asReal() const override { return mValue ? 1 : 0; }
virtual LLSD::String asString() const; LLSD::String asString() const override;
}; };
LLSD::String ImplBoolean::asString() const LLSD::String ImplBoolean::asString() const
@@ -220,32 +225,32 @@ namespace
{ return mValue ? "true" : ""; } { return mValue ? "true" : ""; }
class ImplInteger class ImplInteger final
: public ImplBase<LLSD::TypeInteger, LLSD::Integer> : public ImplBase<LLSD::TypeInteger, LLSD::Integer>
{ {
public: public:
ImplInteger(LLSD::Integer v) : Base(v) { } ImplInteger(LLSD::Integer v) : Base(v) { }
virtual LLSD::Boolean asBoolean() const { return mValue != 0; } LLSD::Boolean asBoolean() const override { return mValue != 0; }
virtual LLSD::Integer asInteger() const { return mValue; } LLSD::Integer asInteger() const override { return mValue; }
virtual LLSD::Real asReal() const { return mValue; } LLSD::Real asReal() const override { return mValue; }
virtual LLSD::String asString() const; LLSD::String asString() const override;
}; };
LLSD::String ImplInteger::asString() const LLSD::String ImplInteger::asString() const
{ return llformat("%d", mValue); } { return llformat("%d", mValue); }
class ImplReal class ImplReal final
: public ImplBase<LLSD::TypeReal, LLSD::Real> : public ImplBase<LLSD::TypeReal, LLSD::Real>
{ {
public: public:
ImplReal(LLSD::Real v) : Base(v) { } ImplReal(LLSD::Real v) : Base(v) { }
virtual LLSD::Boolean asBoolean() const; LLSD::Boolean asBoolean() const override;
virtual LLSD::Integer asInteger() const; LLSD::Integer asInteger() const override;
virtual LLSD::Real asReal() const { return mValue; } LLSD::Real asReal() const override { return mValue; }
virtual LLSD::String asString() const; LLSD::String asString() const override;
}; };
LLSD::Boolean ImplReal::asBoolean() const LLSD::Boolean ImplReal::asBoolean() const
@@ -258,21 +263,21 @@ namespace
{ return llformat("%lg", mValue); } { return llformat("%lg", mValue); }
class ImplString class ImplString final
: public ImplBase<LLSD::TypeString, LLSD::String, const LLSD::String&> : public ImplBase<LLSD::TypeString, LLSD::String, const LLSD::String&>
{ {
public: public:
ImplString(const LLSD::String& v) : Base(v) { } ImplString(const LLSD::String& v) : Base(v) { }
virtual LLSD::Boolean asBoolean() const { return !mValue.empty(); } LLSD::Boolean asBoolean() const override { return !mValue.empty(); }
virtual LLSD::Integer asInteger() const; LLSD::Integer asInteger() const override;
virtual LLSD::Real asReal() const; LLSD::Real asReal() const override;
virtual LLSD::String asString() const { return mValue; } LLSD::String asString() const override { return mValue; }
virtual LLSD::UUID asUUID() const { return LLUUID(mValue); } LLSD::UUID asUUID() const override { return LLUUID(mValue); }
virtual LLSD::Date asDate() const { return LLDate(mValue); } LLSD::Date asDate() const override { return LLDate(mValue); }
virtual LLSD::URI asURI() const { return LLURI(mValue); } LLSD::URI asURI() const override { return LLURI(mValue); }
virtual int size() const { return mValue.size(); } int size() const override { return mValue.size(); }
virtual const LLSD::String& asStringRef() const { return mValue; } const LLSD::String& asStringRef() const override { return mValue; }
}; };
LLSD::Integer ImplString::asInteger() const LLSD::Integer ImplString::asInteger() const
@@ -302,18 +307,18 @@ namespace
} }
class ImplUUID class ImplUUID final
: public ImplBase<LLSD::TypeUUID, LLSD::UUID, const LLSD::UUID&> : public ImplBase<LLSD::TypeUUID, LLSD::UUID, const LLSD::UUID&>
{ {
public: public:
ImplUUID(const LLSD::UUID& v) : Base(v) { } ImplUUID(const LLSD::UUID& v) : Base(v) { }
virtual LLSD::String asString() const{ return mValue.asString(); } LLSD::String asString() const override { return mValue.asString(); }
virtual LLSD::UUID asUUID() const { return mValue; } LLSD::UUID asUUID() const override { return mValue; }
}; };
class ImplDate class ImplDate final
: public ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&> : public ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&>
{ {
public: public:
@@ -321,41 +326,42 @@ namespace
: ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&>(v) : ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&>(v)
{ } { }
virtual LLSD::Integer asInteger() const LLSD::Integer asInteger() const override
{ {
return (LLSD::Integer)(mValue.secondsSinceEpoch()); return (LLSD::Integer)(mValue.secondsSinceEpoch());
} }
virtual LLSD::Real asReal() const LLSD::Real asReal() const override
{ {
return mValue.secondsSinceEpoch(); return mValue.secondsSinceEpoch();
} }
virtual LLSD::String asString() const{ return mValue.asString(); }
virtual LLSD::Date asDate() const { return mValue; } LLSD::String asString() const override { return mValue.asString(); }
LLSD::Date asDate() const override { return mValue; }
}; };
class ImplURI class ImplURI final
: public ImplBase<LLSD::TypeURI, LLSD::URI, const LLSD::URI&> : public ImplBase<LLSD::TypeURI, LLSD::URI, const LLSD::URI&>
{ {
public: public:
ImplURI(const LLSD::URI& v) : Base(v) { } ImplURI(const LLSD::URI& v) : Base(v) { }
virtual LLSD::String asString() const{ return mValue.asString(); } LLSD::String asString() const override { return mValue.asString(); }
virtual LLSD::URI asURI() const { return mValue; } LLSD::URI asURI() const override { return mValue; }
}; };
class ImplBinary class ImplBinary final
: public ImplBase<LLSD::TypeBinary, LLSD::Binary, const LLSD::Binary&> : public ImplBase<LLSD::TypeBinary, LLSD::Binary, const LLSD::Binary&>
{ {
public: public:
ImplBinary(const LLSD::Binary& v) : Base(v) { } ImplBinary(const LLSD::Binary& v) : Base(v) { }
virtual const LLSD::Binary& asBinary() const{ return mValue; } const LLSD::Binary& asBinary() const override { return mValue; }
}; };
class ImplMap : public LLSD::Impl class ImplMap final : public LLSD::Impl
{ {
private: private:
typedef std::map<LLSD::String, LLSD> DataMap; typedef std::map<LLSD::String, LLSD> DataMap;
@@ -368,33 +374,31 @@ namespace
public: public:
ImplMap() { } ImplMap() { }
virtual ImplMap& makeMap(LLSD::Impl*&); ImplMap& makeMap(LLSD::Impl*&) override;
virtual LLSD::Type type() const { return LLSD::TypeMap; } LLSD::Type type() const override { return LLSD::TypeMap; }
virtual LLSD::Boolean asBoolean() const { return !mData.empty(); } LLSD::Boolean asBoolean() const override { return !mData.empty(); }
virtual bool has(const LLSD::String&) const; bool has(const LLSD::String&) const override;
using LLSD::Impl::get; // Unhiding get(LLSD::Integer) using LLSD::Impl::get; // Unhiding get(LLSD::Integer)
using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer) using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer)
using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer) using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer)
virtual LLSD get(const LLSD::String&) const; LLSD get(const LLSD::String&) const override;
virtual LLSD getKeys() const; LLSD getKeys() const override;
void insert(const LLSD::String& k, const LLSD& v); void insert(const LLSD::String& k, const LLSD& v);
virtual void erase(const LLSD::String&); void erase(const LLSD::String&) override;
LLSD& ref(const LLSD::String&); LLSD& ref(const LLSD::String&);
virtual const LLSD& ref(const LLSD::String&) const; const LLSD& ref(const LLSD::String&) const override;
virtual int size() const { return mData.size(); } int size() const override { return mData.size(); }
LLSD::map_iterator beginMap() { return mData.begin(); } DataMap& map() final override { return mData; }
LLSD::map_iterator endMap() { return mData.end(); } const DataMap& map() const final override { return mData; }
virtual LLSD::map_const_iterator beginMap() const { return mData.begin(); }
virtual LLSD::map_const_iterator endMap() const { return mData.end(); }
virtual void dumpStats() const; void dumpStats() const override;
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const; void calcStats(S32 type_counts[], S32 share_counts[]) const override;
}; };
ImplMap& ImplMap::makeMap(LLSD::Impl*& var) ImplMap& ImplMap::makeMap(LLSD::Impl*& var)
@@ -481,7 +485,7 @@ namespace
{ {
//std::cout << " " << (*iter).first << ": " << (*iter).second << std::endl; //std::cout << " " << (*iter).first << ": " << (*iter).second << std::endl;
Impl::calcStats((*iter).second, type_counts, share_counts); Impl::calcStats((*iter).second, type_counts, share_counts);
iter++; ++iter;
} }
// Add in the values for this map // Add in the values for this map
@@ -489,7 +493,7 @@ namespace
} }
class ImplArray : public LLSD::Impl class ImplArray final : public LLSD::Impl
{ {
private: private:
typedef std::vector<LLSD> DataVector; typedef std::vector<LLSD> DataVector;
@@ -502,32 +506,28 @@ namespace
public: public:
ImplArray() { } ImplArray() { }
virtual ImplArray& makeArray(Impl*&); ImplArray& makeArray(Impl*&) override;
virtual LLSD::Type type() const { return LLSD::TypeArray; } LLSD::Type type() const override { return LLSD::TypeArray; }
virtual LLSD::Boolean asBoolean() const { return !mData.empty(); } LLSD::Boolean asBoolean() const override { return !mData.empty(); }
using LLSD::Impl::get; // Unhiding get(LLSD::String) using LLSD::Impl::get; // Unhiding get(LLSD::String)
using LLSD::Impl::erase; // Unhiding erase(LLSD::String) using LLSD::Impl::erase; // Unhiding erase(LLSD::String)
using LLSD::Impl::ref; // Unhiding ref(LLSD::String) using LLSD::Impl::ref; // Unhiding ref(LLSD::String)
virtual int size() const; int size() const override;
virtual LLSD get(LLSD::Integer) const; LLSD get(LLSD::Integer) const override;
void set(LLSD::Integer, const LLSD&); void set(LLSD::Integer, const LLSD&);
void insert(LLSD::Integer, const LLSD&); void insert(LLSD::Integer, const LLSD&);
LLSD& append(const LLSD&); LLSD& append(const LLSD&);
virtual void erase(LLSD::Integer); void erase(LLSD::Integer) override;
LLSD& ref(LLSD::Integer); LLSD& ref(LLSD::Integer);
virtual const LLSD& ref(LLSD::Integer) const; const LLSD& ref(LLSD::Integer) const override;
LLSD::array_iterator beginArray() { return mData.begin(); } DataVector& array() final override { return mData; }
LLSD::array_iterator endArray() { return mData.end(); } const DataVector& array() const final override { return mData; }
LLSD::reverse_array_iterator rbeginArray() { return mData.rbegin(); }
LLSD::reverse_array_iterator rendArray() { return mData.rend(); }
virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); }
virtual LLSD::array_const_iterator endArray() const { return mData.end(); }
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const; void calcStats(S32 type_counts[], S32 share_counts[]) const override;
}; };
ImplArray& ImplArray::makeArray(Impl*& var) ImplArray& ImplArray::makeArray(Impl*& var)
@@ -631,7 +631,7 @@ namespace
while (iter != endArray()) while (iter != endArray())
{ // Add values for all items held in the array { // Add values for all items held in the array
Impl::calcStats((*iter), type_counts, share_counts); Impl::calcStats((*iter), type_counts, share_counts);
iter++; ++iter;
} }
// Add in the values for this array // Add in the values for this array
@@ -703,7 +703,7 @@ void LLSD::Impl::assign(Impl*& var, const Impl* other)
void LLSD::Impl::assignUndefined(Impl*& var) void LLSD::Impl::assignUndefined(Impl*& var)
{ {
reset(var, 0); reset(var, nullptr);
} }
void LLSD::Impl::assign(Impl*& var, LLSD::Boolean v) void LLSD::Impl::assign(Impl*& var, LLSD::Boolean v)
@@ -779,7 +779,7 @@ void LLSD::Impl::calcStats(S32 type_counts[], S32 share_counts[]) const
S32 tp = S32(type()); S32 tp = S32(type());
if (0 <= tp && tp < LLSD::TypeLLSDNumTypes) if (0 <= tp && tp < LLSD::TypeLLSDNumTypes)
{ {
type_counts[tp]++; type_counts[tp]++;
if (shared()) if (shared())
{ {
share_counts[tp]++; share_counts[tp]++;
@@ -813,10 +813,10 @@ namespace
} }
LLSD::LLSD() : impl(0) { ALLOC_LLSD_OBJECT; } LLSD::LLSD() : impl(nullptr) { ALLOC_LLSD_OBJECT; }
LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, 0); } LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, nullptr); }
LLSD::LLSD(const LLSD& other) : impl(0) { ALLOC_LLSD_OBJECT; assign(other); } LLSD::LLSD(const LLSD& other) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(other); }
void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); } void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); }
@@ -825,17 +825,17 @@ void LLSD::clear() { Impl::assignUndefined(impl); }
LLSD::Type LLSD::type() const { return safe(impl).type(); } LLSD::Type LLSD::type() const { return safe(impl).type(); }
// Scalar Constructors // Scalar Constructors
LLSD::LLSD(Boolean v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } LLSD::LLSD(Boolean v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(Integer v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } LLSD::LLSD(Integer v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(Real v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } LLSD::LLSD(Real v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const UUID& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } LLSD::LLSD(const UUID& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const String& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } LLSD::LLSD(const String& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const Date& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } LLSD::LLSD(const Date& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const URI& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } LLSD::LLSD(const URI& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const Binary& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } LLSD::LLSD(const Binary& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
// Convenience Constructors // Convenience Constructors
LLSD::LLSD(F32 v) : impl(0) { ALLOC_LLSD_OBJECT; assign((Real)v); } LLSD::LLSD(F32 v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign((Real)v); }
// Scalar Assignment // Scalar Assignment
void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); } void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); }
@@ -860,7 +860,7 @@ const LLSD::Binary& LLSD::asBinary() const { return safe(impl).asBinary(); }
const LLSD::String& LLSD::asStringRef() const { return safe(impl).asStringRef(); } const LLSD::String& LLSD::asStringRef() const { return safe(impl).asStringRef(); }
// const char * helpers // const char * helpers
LLSD::LLSD(const char* v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } LLSD::LLSD(const char* v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
void LLSD::assign(const char* v) void LLSD::assign(const char* v)
{ {
if(v) assign(std::string(v)); if(v) assign(std::string(v));
@@ -927,7 +927,7 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
// sStorage will point to the result of the last call. This will actually // sStorage will point to the result of the last call. This will actually
// be one leak, but since this is used only when running under the // be one leak, but since this is used only when running under the
// debugger, it should not be an issue. // debugger, it should not be an issue.
static char *sStorage = NULL; static char *sStorage = nullptr;
delete[] sStorage; delete[] sStorage;
std::string out_string; std::string out_string;
{ {
@@ -938,7 +938,7 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
out << LLSDNotationStreamer(llsd); out << LLSDNotationStreamer(llsd);
out_string = out.str(); out_string = out.str();
} }
int len = out_string.length(); size_t len = out_string.length();
sStorage = new char[len + 1]; sStorage = new char[len + 1];
memcpy(sStorage, out_string.c_str(), len); memcpy(sStorage, out_string.c_str(), len);
sStorage[len] = '\0'; sStorage[len] = '\0';
@@ -957,18 +957,24 @@ const char *LLSD::dump(const LLSD &llsd)
return llsd_dump(llsd, false); return llsd_dump(llsd, false);
} }
LLSD::map_iterator LLSD::beginMap() { return makeMap(impl).beginMap(); } std::map<LLSD::String, LLSD>& LLSD::map() { return makeMap(impl).map(); }
LLSD::map_iterator LLSD::endMap() { return makeMap(impl).endMap(); } const std::map<LLSD::String, LLSD>& LLSD::map() const { return safe(impl).map(); }
LLSD::map_const_iterator LLSD::beginMap() const { return safe(impl).beginMap(); }
LLSD::map_const_iterator LLSD::endMap() const { return safe(impl).endMap(); }
LLSD::array_iterator LLSD::beginArray() { return makeArray(impl).beginArray(); } LLSD::map_iterator LLSD::beginMap() { return map().begin(); }
LLSD::array_iterator LLSD::endArray() { return makeArray(impl).endArray(); } LLSD::map_iterator LLSD::endMap() { return map().end(); }
LLSD::array_const_iterator LLSD::beginArray() const{ return safe(impl).beginArray(); } LLSD::map_const_iterator LLSD::beginMap() const { return map().cbegin(); }
LLSD::array_const_iterator LLSD::endArray() const { return safe(impl).endArray(); } LLSD::map_const_iterator LLSD::endMap() const { return map().cend(); }
LLSD::reverse_array_iterator LLSD::rbeginArray() { return makeArray(impl).rbeginArray(); } std::vector<LLSD>& LLSD::array() { return makeArray(impl).array(); }
LLSD::reverse_array_iterator LLSD::rendArray() { return makeArray(impl).rendArray(); } const std::vector<LLSD>& LLSD::array() const { return safe(impl).array(); }
LLSD::array_iterator LLSD::beginArray() { return array().begin(); }
LLSD::array_iterator LLSD::endArray() { return array().end(); }
LLSD::array_const_iterator LLSD::beginArray() const{ return array().cbegin(); }
LLSD::array_const_iterator LLSD::endArray() const { return array().cend(); }
LLSD::reverse_array_iterator LLSD::rbeginArray() { return array().rbegin(); }
LLSD::reverse_array_iterator LLSD::rendArray() { return array().rend(); }
namespace llsd namespace llsd
{ {

View File

@@ -320,6 +320,8 @@ public:
typedef std::map<String, LLSD>::iterator map_iterator; typedef std::map<String, LLSD>::iterator map_iterator;
typedef std::map<String, LLSD>::const_iterator map_const_iterator; typedef std::map<String, LLSD>::const_iterator map_const_iterator;
std::map<String, LLSD>& map();
const std::map<String, LLSD>& map() const;
map_iterator beginMap(); map_iterator beginMap();
map_iterator endMap(); map_iterator endMap();
map_const_iterator beginMap() const; map_const_iterator beginMap() const;
@@ -329,6 +331,8 @@ public:
typedef std::vector<LLSD>::const_iterator array_const_iterator; typedef std::vector<LLSD>::const_iterator array_const_iterator;
typedef std::vector<LLSD>::reverse_iterator reverse_array_iterator; typedef std::vector<LLSD>::reverse_iterator reverse_array_iterator;
std::vector<LLSD>& array();
const std::vector<LLSD>& array() const;
array_iterator beginArray(); array_iterator beginArray();
array_iterator endArray(); array_iterator endArray();
array_const_iterator beginArray() const; array_const_iterator beginArray() const;

View File

@@ -79,6 +79,17 @@ LLSD LlsdFromJson(const nlohmann::json &val)
return result; return result;
} }
LLSD LlsdFromJsonString(const std::string& str)
{
auto json = nlohmann::json::parse(str, nullptr, false);
if (json.is_discarded())
{
LL_WARNS() << "Cannot parse invalid json string:\n" << str << LL_ENDL;
return LLSD();
}
return LlsdFromJson(json);
}
//========================================================================= //=========================================================================
nlohmann::json LlsdToJson(const LLSD &val) nlohmann::json LlsdToJson(const LLSD &val)
{ {
@@ -111,9 +122,9 @@ nlohmann::json LlsdToJson(const LLSD &val)
} }
break; break;
case LLSD::TypeArray: case LLSD::TypeArray:
for (LLSD::array_const_iterator it = val.beginArray(); it != val.endArray(); ++it) for (auto const& entry : val.array())
{ {
result.push_back(LlsdToJson(*it)); result.push_back(LlsdToJson(entry));
} }
break; break;
case LLSD::TypeBinary: case LLSD::TypeBinary:

View File

@@ -54,6 +54,7 @@
/// For maps and arrays child entries will be converted and added to the structure. /// For maps and arrays child entries will be converted and added to the structure.
/// Order is preserved for an array but not for objects. /// Order is preserved for an array but not for objects.
LLSD LlsdFromJson(const nlohmann::json &val); LLSD LlsdFromJson(const nlohmann::json &val);
LLSD LlsdFromJsonString(const std::string& body);
/// Convert an LLSD object into Parsed JSON object maintaining member names and /// Convert an LLSD object into Parsed JSON object maintaining member names and
/// array indexs. /// array indexs.

View File

@@ -267,12 +267,10 @@ void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd, LLI
} }
else if (sd.isArray()) else if (sd.isArray())
{ {
for (LLSD::array_const_iterator it = sd.beginArray(); for (auto const& entry : sd.array())
it != sd.endArray();
++it)
{ {
stack.push_back(make_pair(std::string(), true)); stack.push_back(make_pair(std::string(), true));
readSDValues(cb, *it, stack); readSDValues(cb, entry, stack);
stack.pop_back(); stack.pop_back();
} }
} }

View File

@@ -1072,8 +1072,8 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
// the size, and read it. // the size, and read it.
U32 size_nbo = 0; U32 size_nbo = 0;
read(istr, (char*)&size_nbo, sizeof(U32)); /*Flawfinder: ignore*/ read(istr, (char*)&size_nbo, sizeof(U32)); /*Flawfinder: ignore*/
S32 size = (S32)ntohl(size_nbo); S32 size = (S32)ntohl(size_nbo); // Can return negative size if > 2^31.
if(mCheckLimits && (size > mMaxBytesLeft)) if(size < 0 || mCheckLimits && (size > mMaxBytesLeft))
{ {
parse_count = PARSE_FAILURE; parse_count = PARSE_FAILURE;
} }
@@ -1113,7 +1113,11 @@ S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map) const
map = LLSD::emptyMap(); map = LLSD::emptyMap();
U32 value_nbo = 0; U32 value_nbo = 0;
read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/ 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 parse_count = 0;
S32 count = 0; S32 count = 0;
char c = get(istr); char c = get(istr);
@@ -1167,7 +1171,11 @@ S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array) const
array = LLSD::emptyArray(); array = LLSD::emptyArray();
U32 value_nbo = 0; U32 value_nbo = 0;
read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/ 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 // *FIX: This would be a good place to reserve some space in the
// array... // array...
@@ -1208,8 +1216,8 @@ bool LLSDBinaryParser::parseString(
// *FIX: This is memory inefficient. // *FIX: This is memory inefficient.
U32 value_nbo = 0; U32 value_nbo = 0;
read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/ 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(mCheckLimits && (size > mMaxBytesLeft)) return false; if(size < 0 || mCheckLimits && (size > mMaxBytesLeft)) return false;
std::vector<char> buf; std::vector<char> buf;
if(size) if(size)
{ {
@@ -1322,13 +1330,11 @@ S32 LLSDNotationFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32
{ {
ostr << post << pre << "["; ostr << post << pre << "[";
bool need_comma = false; bool need_comma = false;
auto iter = data.beginArray(); for (const auto& entry : data.array())
auto end = data.endArray();
for(; iter != end; ++iter)
{ {
if(need_comma) ostr << ","; if (need_comma) ostr << ",";
need_comma = true; need_comma = true;
format_count += format_impl(*iter, ostr, options, level + 1); format_count += format_impl(entry, ostr, options, level + 1);
} }
ostr << "]"; ostr << "]";
break; break;
@@ -1461,11 +1467,9 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option
ostr.put('['); ostr.put('[');
U32 size_nbo = htonl(data.size()); U32 size_nbo = htonl(data.size());
ostr.write(reinterpret_cast<const char*>(&size_nbo), sizeof(U32)); ostr.write(reinterpret_cast<const char*>(&size_nbo), sizeof(U32));
auto iter = data.beginArray(); for (const auto& entry : data.array())
auto end = data.endArray();
for(; iter != end; ++iter)
{ {
format_count += format(*iter, ostr); format_count += format(entry, ostr);
} }
ostr.put(']'); ostr.put(']');
break; break;

View File

@@ -116,11 +116,9 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 opti
else else
{ {
ostr << pre << "<array>" << post; ostr << pre << "<array>" << post;
LLSD::array_const_iterator iter = data.beginArray(); for (const auto& entry : data.array())
LLSD::array_const_iterator end = data.endArray();
for(; iter != end; ++iter)
{ {
format_count += format_impl(*iter, ostr, options, level + 1); format_count += format_impl(entry, ostr, options, level + 1);
} }
ostr << pre << "</array>" << post; ostr << pre << "</array>" << post;
} }

View File

@@ -891,9 +891,9 @@ LLSD llsd_clone(LLSD value, LLSD filter)
break; break;
case LLSD::TypeArray: case LLSD::TypeArray:
clone = LLSD::emptyArray(); clone = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita) for (auto const& entry : value.array())
{ {
clone.append(llsd_clone(*ita, filter)); clone.append(llsd_clone(entry, filter));
} }
break; break;
@@ -943,9 +943,9 @@ LLSD llsd_shallow(LLSD value, LLSD filter)
else if (value.isArray()) else if (value.isArray())
{ {
shallow = LLSD::emptyArray(); shallow = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita) for (auto const& entry : value.array())
{ {
shallow.append(*ita); shallow.append(entry);
} }
} }
else else

View File

@@ -1340,7 +1340,8 @@ void LLStringUtil::formatNumber(std::string& numStr, std::string decimals)
// std::locale() throws if the locale is unknown! (EXT-7926) // std::locale() throws if the locale is unknown! (EXT-7926)
try try
{ {
strStream.imbue(std::locale(sLocale.c_str())); std::locale locale(sLocale.c_str());
strStream.imbue(locale);
} catch (const std::exception &) } catch (const std::exception &)
{ {
LL_WARNS_ONCE("Locale") << "Cannot set locale to " << sLocale << LL_ENDL; LL_WARNS_ONCE("Locale") << "Cannot set locale to " << sLocale << LL_ENDL;
@@ -1353,8 +1354,7 @@ void LLStringUtil::formatNumber(std::string& numStr, std::string decimals)
if (convertToS32(numStr, intStr)) if (convertToS32(numStr, intStr))
{ {
strStream << intStr; numStr = fmt::to_string(intStr);
numStr = strStream.str();
} }
} }
else else
@@ -1434,14 +1434,14 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,
{ {
struct tm * gmt = gmtime (&loc_seconds); struct tm * gmt = gmtime (&loc_seconds);
LLStringUtil::format_map_t args; LLStringUtil::format_map_t args;
args["[MDAY]"] = llformat ("%d", gmt->tm_mday); args["[MDAY]"] = fmt::to_string(gmt->tm_mday);
replacement = LLStringOps::sDayFormat; replacement = LLStringOps::sDayFormat;
LLStringUtil::format(replacement, args); LLStringUtil::format(replacement, args);
} }
else if (code == "%-d") else if (code == "%-d")
{ {
struct tm * gmt = gmtime (&loc_seconds); 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" ) else if( !LLStringOps::sAM.empty() && !LLStringOps::sPM.empty() && code == "%p" )
{ {

View File

@@ -29,6 +29,16 @@
#include <boost/optional/optional.hpp> #include <boost/optional/optional.hpp>
#include <string> #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 <cstdio>
//#include <locale> //#include <locale>
#include <iomanip> #include <iomanip>
@@ -243,7 +253,7 @@ public:
bool operator<(const LLFormatMapString& rhs) const { return mString < rhs.mString; } bool operator<(const LLFormatMapString& rhs) const { return mString < rhs.mString; }
std::size_t length() const { return mString.length(); } std::size_t length() const { return mString.length(); }
// The destructor may not throw. // The destructor may not throw.
~LLFormatMapString() throw() { } ~LLFormatMapString() noexcept { }
private: private:
std::string mString; std::string mString;

View File

@@ -1274,7 +1274,7 @@ BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile)
const S32 UNCOMPRESS_BUFFER_SIZE = 32768; const S32 UNCOMPRESS_BUFFER_SIZE = 32768;
BOOL retval = FALSE; BOOL retval = FALSE;
gzFile src = NULL; gzFile src = NULL;
U8 buffer[UNCOMPRESS_BUFFER_SIZE]; std::array<U8, UNCOMPRESS_BUFFER_SIZE> buffer;
LLFILE *dst = NULL; LLFILE *dst = NULL;
S32 bytes = 0; S32 bytes = 0;
tmpfile = dstfile + ".t"; tmpfile = dstfile + ".t";
@@ -1288,8 +1288,8 @@ BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile)
if (! dst) goto err; if (! dst) goto err;
do do
{ {
bytes = gzread(src, buffer, UNCOMPRESS_BUFFER_SIZE); bytes = gzread(src, buffer.data(), buffer.size());
size_t nwrit = fwrite(buffer, sizeof(U8), bytes, dst); size_t nwrit = fwrite(buffer.data(), sizeof(U8), bytes, dst);
if (nwrit < (size_t) bytes) if (nwrit < (size_t) bytes)
{ {
LL_WARNS() << "Short write on " << tmpfile << ": Wrote " << nwrit << " of " << bytes << " bytes." << LL_ENDL; LL_WARNS() << "Short write on " << tmpfile << ": Wrote " << nwrit << " of " << bytes << " bytes." << LL_ENDL;
@@ -1311,7 +1311,7 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile)
const S32 COMPRESS_BUFFER_SIZE = 32768; const S32 COMPRESS_BUFFER_SIZE = 32768;
std::string tmpfile; std::string tmpfile;
BOOL retval = FALSE; BOOL retval = FALSE;
U8 buffer[COMPRESS_BUFFER_SIZE]; std::array<U8, COMPRESS_BUFFER_SIZE> buffer;
gzFile dst = NULL; gzFile dst = NULL;
LLFILE *src = NULL; LLFILE *src = NULL;
S32 bytes = 0; S32 bytes = 0;
@@ -1325,9 +1325,9 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile)
src = LLFile::fopen(srcfile, "rb"); /* Flawfinder: ignore */ src = LLFile::fopen(srcfile, "rb"); /* Flawfinder: ignore */
if (! src) goto err; if (! src) goto err;
while ((bytes = (S32)fread(buffer, sizeof(U8), COMPRESS_BUFFER_SIZE, src)) > 0) while ((bytes = (S32)fread(buffer.data(), sizeof(U8), buffer.size(), src)) > 0)
{ {
if (gzwrite(dst, buffer, bytes) <= 0) if (gzwrite(dst, buffer.data(), bytes) <= 0)
{ {
LL_WARNS() << "gzwrite failed: " << gzerror(dst, NULL) << LL_ENDL; LL_WARNS() << "gzwrite failed: " << gzerror(dst, NULL) << LL_ENDL;
goto err; goto err;

View File

@@ -17,7 +17,6 @@ include_directories(
set(llinventory_SOURCE_FILES set(llinventory_SOURCE_FILES
llcategory.cpp llcategory.cpp
lleconomy.cpp
llfoldertype.cpp llfoldertype.cpp
llinventory.cpp llinventory.cpp
llinventorydefines.cpp llinventorydefines.cpp
@@ -40,7 +39,6 @@ set(llinventory_HEADER_FILES
CMakeLists.txt CMakeLists.txt
llcategory.h llcategory.h
lleconomy.h
llfoldertype.h llfoldertype.h
llinventory.h llinventory.h
llinventorydefines.h llinventorydefines.h

View File

@@ -1,288 +0,0 @@
/**
* @file lleconomy.cpp
*
* $LicenseInfo:firstyear=2002&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 "lleconomy.h"
#include "llerror.h"
#include "message.h"
#include "v3math.h"
LLGlobalEconomy::LLGlobalEconomy()
: mObjectCount( -1 ),
mObjectCapacity( -1 ),
mPriceObjectClaim( -1 ),
mPricePublicObjectDecay( -1 ),
mPricePublicObjectDelete( -1 ),
mPriceEnergyUnit( -1 ),
mPriceUpload( -1 ),
mPriceRentLight( -1 ),
mTeleportMinPrice( -1 ),
mTeleportPriceExponent( -1 ),
mPriceGroupCreate( -1 )
{ }
LLGlobalEconomy::~LLGlobalEconomy()
{ }
void LLGlobalEconomy::addObserver(LLEconomyObserver* observer)
{
mObservers.push_back(observer);
}
void LLGlobalEconomy::removeObserver(LLEconomyObserver* observer)
{
std::list<LLEconomyObserver*>::iterator it =
std::find(mObservers.begin(), mObservers.end(), observer);
if (it != mObservers.end())
{
mObservers.erase(it);
}
}
void LLGlobalEconomy::notifyObservers()
{
for (std::list<LLEconomyObserver*>::iterator it = mObservers.begin();
it != mObservers.end();
++it)
{
(*it)->onEconomyDataChange();
}
}
// static
void LLGlobalEconomy::processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data)
{
S32 i;
F32 f;
msg->getS32Fast(_PREHASH_Info, _PREHASH_ObjectCapacity, i);
econ_data->setObjectCapacity(i);
msg->getS32Fast(_PREHASH_Info, _PREHASH_ObjectCount, i);
econ_data->setObjectCount(i);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceEnergyUnit, i);
econ_data->setPriceEnergyUnit(i);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceObjectClaim, i);
econ_data->setPriceObjectClaim(i);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PricePublicObjectDecay, i);
econ_data->setPricePublicObjectDecay(i);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PricePublicObjectDelete, i);
econ_data->setPricePublicObjectDelete(i);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceUpload, i);
econ_data->setPriceUpload(i);
#if LL_LINUX
// We can optionally fake the received upload price for testing.
// Note that the server is within its rights to not obey our fake
// price. :)
const char* fakeprice_str = getenv("LL_FAKE_UPLOAD_PRICE");
if (fakeprice_str)
{
S32 fakeprice = (S32)atoi(fakeprice_str);
LL_WARNS() << "LL_FAKE_UPLOAD_PRICE: Faking upload price as L$" << fakeprice << LL_ENDL;
econ_data->setPriceUpload(fakeprice);
}
#endif
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceRentLight, i);
econ_data->setPriceRentLight(i);
msg->getS32Fast(_PREHASH_Info, _PREHASH_TeleportMinPrice, i);
econ_data->setTeleportMinPrice(i);
msg->getF32Fast(_PREHASH_Info, _PREHASH_TeleportPriceExponent, f);
econ_data->setTeleportPriceExponent(f);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceGroupCreate, i);
econ_data->setPriceGroupCreate(i);
econ_data->notifyObservers();
}
S32 LLGlobalEconomy::calculateTeleportCost(F32 distance) const
{
S32 min_cost = getTeleportMinPrice();
F32 exponent = getTeleportPriceExponent();
F32 divisor = 100.f * pow(3.f, exponent);
S32 cost = (U32)(distance * pow(log10(distance), exponent) / divisor);
if (cost < 0)
{
cost = 0;
}
else if (cost < min_cost)
{
cost = min_cost;
}
return cost;
}
S32 LLGlobalEconomy::calculateLightRent(const LLVector3& object_size) const
{
F32 intensity_mod = llmax(object_size.magVec(), 1.f);
return (S32)(intensity_mod * getPriceRentLight());
}
void LLGlobalEconomy::print()
{
LL_INFOS() << "Global Economy Settings: " << LL_ENDL;
LL_INFOS() << "Object Capacity: " << mObjectCapacity << LL_ENDL;
LL_INFOS() << "Object Count: " << mObjectCount << LL_ENDL;
LL_INFOS() << "Claim Price Per Object: " << mPriceObjectClaim << LL_ENDL;
LL_INFOS() << "Claim Price Per Public Object: " << mPricePublicObjectDecay << LL_ENDL;
LL_INFOS() << "Delete Price Per Public Object: " << mPricePublicObjectDelete << LL_ENDL;
LL_INFOS() << "Release Price Per Public Object: " << getPricePublicObjectRelease() << LL_ENDL;
LL_INFOS() << "Price Per Energy Unit: " << mPriceEnergyUnit << LL_ENDL;
LL_INFOS() << "Price Per Upload: " << mPriceUpload << LL_ENDL;
LL_INFOS() << "Light Base Price: " << mPriceRentLight << LL_ENDL;
LL_INFOS() << "Teleport Min Price: " << mTeleportMinPrice << LL_ENDL;
LL_INFOS() << "Teleport Price Exponent: " << mTeleportPriceExponent << LL_ENDL;
LL_INFOS() << "Price for group creation: " << mPriceGroupCreate << LL_ENDL;
}
LLRegionEconomy::LLRegionEconomy()
: LLGlobalEconomy(),
mPriceObjectRent( -1.f ),
mPriceObjectScaleFactor( -1.f ),
mEnergyEfficiency( -1.f ),
mBasePriceParcelClaimDefault(-1),
mBasePriceParcelClaimActual(-1),
mPriceParcelClaimFactor(-1.f),
mBasePriceParcelRent(-1),
mAreaOwned(-1.f),
mAreaTotal(-1.f)
{ }
LLRegionEconomy::~LLRegionEconomy()
{ }
BOOL LLRegionEconomy::hasData() const
{
return (mBasePriceParcelRent != -1);
}
// static
void LLRegionEconomy::processEconomyData(LLMessageSystem *msg, void** user_data)
{
S32 i;
F32 f;
LLRegionEconomy *this_ptr = (LLRegionEconomy*)user_data;
LLGlobalEconomy::processEconomyData(msg, this_ptr);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceParcelClaim, i);
this_ptr->setBasePriceParcelClaimDefault(i);
msg->getF32(_PREHASH_Info, _PREHASH_PriceParcelClaimFactor, f);
this_ptr->setPriceParcelClaimFactor(f);
msg->getF32Fast(_PREHASH_Info, _PREHASH_EnergyEfficiency, f);
this_ptr->setEnergyEfficiency(f);
msg->getF32Fast(_PREHASH_Info, _PREHASH_PriceObjectRent, f);
this_ptr->setPriceObjectRent(f);
msg->getF32Fast(_PREHASH_Info, _PREHASH_PriceObjectScaleFactor, f);
this_ptr->setPriceObjectScaleFactor(f);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceParcelRent, i);
this_ptr->setBasePriceParcelRent(i);
}
// static
void LLRegionEconomy::processEconomyDataRequest(LLMessageSystem *msg, void **user_data)
{
LLRegionEconomy *this_ptr = (LLRegionEconomy*)user_data;
if (!this_ptr->hasData())
{
LL_WARNS() << "Dropping EconomyDataRequest, because EconomyData message "
<< "has not been processed" << LL_ENDL;
}
msg->newMessageFast(_PREHASH_EconomyData);
msg->nextBlockFast(_PREHASH_Info);
msg->addS32Fast(_PREHASH_ObjectCapacity, this_ptr->getObjectCapacity());
msg->addS32Fast(_PREHASH_ObjectCount, this_ptr->getObjectCount());
msg->addS32Fast(_PREHASH_PriceEnergyUnit, this_ptr->getPriceEnergyUnit());
msg->addS32Fast(_PREHASH_PriceObjectClaim, this_ptr->getPriceObjectClaim());
msg->addS32Fast(_PREHASH_PricePublicObjectDecay, this_ptr->getPricePublicObjectDecay());
msg->addS32Fast(_PREHASH_PricePublicObjectDelete, this_ptr->getPricePublicObjectDelete());
msg->addS32Fast(_PREHASH_PriceParcelClaim, this_ptr->mBasePriceParcelClaimActual);
msg->addF32Fast(_PREHASH_PriceParcelClaimFactor, this_ptr->mPriceParcelClaimFactor);
msg->addS32Fast(_PREHASH_PriceUpload, this_ptr->getPriceUpload());
msg->addS32Fast(_PREHASH_PriceRentLight, this_ptr->getPriceRentLight());
msg->addS32Fast(_PREHASH_TeleportMinPrice, this_ptr->getTeleportMinPrice());
msg->addF32Fast(_PREHASH_TeleportPriceExponent, this_ptr->getTeleportPriceExponent());
msg->addF32Fast(_PREHASH_EnergyEfficiency, this_ptr->getEnergyEfficiency());
msg->addF32Fast(_PREHASH_PriceObjectRent, this_ptr->getPriceObjectRent());
msg->addF32Fast(_PREHASH_PriceObjectScaleFactor, this_ptr->getPriceObjectScaleFactor());
msg->addS32Fast(_PREHASH_PriceParcelRent, this_ptr->getPriceParcelRent());
msg->addS32Fast(_PREHASH_PriceGroupCreate, this_ptr->getPriceGroupCreate());
msg->sendReliable(msg->getSender());
}
S32 LLRegionEconomy::getPriceParcelClaim() const
{
//return (S32)((F32)mBasePriceParcelClaim * (mAreaTotal / (mAreaTotal - mAreaOwned)));
return (S32)((F32)mBasePriceParcelClaimActual * mPriceParcelClaimFactor);
}
S32 LLRegionEconomy::getPriceParcelRent() const
{
return mBasePriceParcelRent;
}
void LLRegionEconomy::print()
{
this->LLGlobalEconomy::print();
LL_INFOS() << "Region Economy Settings: " << LL_ENDL;
LL_INFOS() << "Land (square meters): " << mAreaTotal << LL_ENDL;
LL_INFOS() << "Owned Land (square meters): " << mAreaOwned << LL_ENDL;
LL_INFOS() << "Daily Object Rent: " << mPriceObjectRent << LL_ENDL;
LL_INFOS() << "Daily Land Rent (per meter): " << getPriceParcelRent() << LL_ENDL;
LL_INFOS() << "Energey Efficiency: " << mEnergyEfficiency << LL_ENDL;
}
void LLRegionEconomy::setBasePriceParcelClaimDefault(S32 val)
{
mBasePriceParcelClaimDefault = val;
if(mBasePriceParcelClaimActual == -1)
{
mBasePriceParcelClaimActual = val;
}
}
void LLRegionEconomy::setBasePriceParcelClaimActual(S32 val)
{
mBasePriceParcelClaimActual = val;
}
void LLRegionEconomy::setPriceParcelClaimFactor(F32 val)
{
mPriceParcelClaimFactor = val;
}
void LLRegionEconomy::setBasePriceParcelRent(S32 val)
{
mBasePriceParcelRent = val;
}

View File

@@ -1,159 +0,0 @@
/**
* @file lleconomy.h
*
* $LicenseInfo:firstyear=2002&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_LLECONOMY_H
#define LL_LLECONOMY_H
#include "llsingleton.h"
class LLMessageSystem;
class LLVector3;
/**
* Register an observer to be notified of economy data updates coming from server.
*/
class LLEconomyObserver
{
public:
virtual ~LLEconomyObserver() {}
virtual void onEconomyDataChange() = 0;
};
class LLGlobalEconomy
{
public:
LLGlobalEconomy();
virtual ~LLGlobalEconomy();
// This class defines its singleton internally as a typedef instead of inheriting from
// LLSingleton like most others because the LLRegionEconomy sub-class might also
// become a singleton and this pattern will more easily disambiguate them.
typedef LLSingleton<LLGlobalEconomy> Singleton;
void initSingleton() { }
virtual void print();
void addObserver(LLEconomyObserver* observer);
void removeObserver(LLEconomyObserver* observer);
void notifyObservers();
static void processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data);
S32 calculateTeleportCost(F32 distance) const;
S32 calculateLightRent(const LLVector3& object_size) const;
S32 getObjectCount() const { return mObjectCount; }
S32 getObjectCapacity() const { return mObjectCapacity; }
S32 getPriceObjectClaim() const { return mPriceObjectClaim; }
S32 getPricePublicObjectDecay() const { return mPricePublicObjectDecay; }
S32 getPricePublicObjectDelete() const { return mPricePublicObjectDelete; }
S32 getPricePublicObjectRelease() const { return mPriceObjectClaim - mPricePublicObjectDelete; }
S32 getPriceEnergyUnit() const { return mPriceEnergyUnit; }
S32 getPriceUpload() const { return mPriceUpload; }
S32 getPriceRentLight() const { return mPriceRentLight; }
S32 getTeleportMinPrice() const { return mTeleportMinPrice; }
F32 getTeleportPriceExponent() const { return mTeleportPriceExponent; }
S32 getPriceGroupCreate() const { return mPriceGroupCreate; }
void setObjectCount(S32 val) { mObjectCount = val; }
void setObjectCapacity(S32 val) { mObjectCapacity = val; }
void setPriceObjectClaim(S32 val) { mPriceObjectClaim = val; }
void setPricePublicObjectDecay(S32 val) { mPricePublicObjectDecay = val; }
void setPricePublicObjectDelete(S32 val) { mPricePublicObjectDelete = val; }
void setPriceEnergyUnit(S32 val) { mPriceEnergyUnit = val; }
void setPriceUpload(S32 val) { mPriceUpload = val; }
void setPriceRentLight(S32 val) { mPriceRentLight = val; }
void setTeleportMinPrice(S32 val) { mTeleportMinPrice = val; }
void setTeleportPriceExponent(F32 val) { mTeleportPriceExponent = val; }
void setPriceGroupCreate(S32 val) { mPriceGroupCreate = val; }
private:
S32 mObjectCount;
S32 mObjectCapacity;
S32 mPriceObjectClaim; // per primitive
S32 mPricePublicObjectDecay; // per primitive
S32 mPricePublicObjectDelete; // per primitive
S32 mPriceEnergyUnit;
S32 mPriceUpload;
S32 mPriceRentLight;
S32 mTeleportMinPrice;
F32 mTeleportPriceExponent;
S32 mPriceGroupCreate;
std::list<LLEconomyObserver*> mObservers;
};
class LLRegionEconomy : public LLGlobalEconomy
{
public:
LLRegionEconomy();
~LLRegionEconomy();
static void processEconomyData(LLMessageSystem *msg, void **user_data);
static void processEconomyDataRequest(LLMessageSystem *msg, void **user_data);
void print();
BOOL hasData() const;
F32 getPriceObjectRent() const { return mPriceObjectRent; }
F32 getPriceObjectScaleFactor() const {return mPriceObjectScaleFactor;}
F32 getEnergyEfficiency() const { return mEnergyEfficiency; }
S32 getPriceParcelClaim() const;
S32 getPriceParcelRent() const;
F32 getAreaOwned() const { return mAreaOwned; }
F32 getAreaTotal() const { return mAreaTotal; }
S32 getBasePriceParcelClaimActual() const { return mBasePriceParcelClaimActual; }
void setPriceObjectRent(F32 val) { mPriceObjectRent = val; }
void setPriceObjectScaleFactor(F32 val) { mPriceObjectScaleFactor = val; }
void setEnergyEfficiency(F32 val) { mEnergyEfficiency = val; }
void setBasePriceParcelClaimDefault(S32 val);
void setBasePriceParcelClaimActual(S32 val);
void setPriceParcelClaimFactor(F32 val);
void setBasePriceParcelRent(S32 val);
void setAreaOwned(F32 val) { mAreaOwned = val; }
void setAreaTotal(F32 val) { mAreaTotal = val; }
private:
F32 mPriceObjectRent;
F32 mPriceObjectScaleFactor;
F32 mEnergyEfficiency;
S32 mBasePriceParcelClaimDefault;
S32 mBasePriceParcelClaimActual;
F32 mPriceParcelClaimFactor;
S32 mBasePriceParcelRent;
F32 mAreaOwned;
F32 mAreaTotal;
};
#endif

View File

@@ -40,6 +40,8 @@
#include "llsdutil_math.h" #include "llsdutil_math.h"
#include "message.h" #include "message.h"
#include "u64.h" #include "u64.h"
#include "llregionflags.h"
#include <boost/range/adaptor/map.hpp>
static const F32 SOME_BIG_NUMBER = 1000.0f; static const F32 SOME_BIG_NUMBER = 1000.0f;
static const F32 SOME_BIG_NEG_NUMBER = -1000.0f; static const F32 SOME_BIG_NEG_NUMBER = -1000.0f;
@@ -742,8 +744,8 @@ void LLParcel::unpackMessage(LLMessageSystem* msg)
void LLParcel::packAccessEntries(LLMessageSystem* msg, void LLParcel::packAccessEntries(LLMessageSystem* msg,
const std::map<LLUUID,LLAccessEntry>& list) const std::map<LLUUID,LLAccessEntry>& list)
{ {
access_map_const_iterator cit = list.begin(); LLAccessEntry::map::const_iterator cit = list.begin();
access_map_const_iterator end = list.end(); LLAccessEntry::map::const_iterator end = list.end();
if (cit == end) if (cit == end)
{ {
@@ -794,9 +796,28 @@ void LLParcel::unpackAccessEntries(LLMessageSystem* msg,
} }
void LLParcel::unpackExperienceEntries(LLMessageSystem* msg, U32 type)
{
LLUUID id;
S32 i;
S32 count = msg->getNumberOfBlocksFast(_PREHASH_List);
for (i = 0; i < count; i++)
{
msg->getUUIDFast(_PREHASH_List, _PREHASH_ID, id, i);
if (id.notNull())
{
mExperienceKeys[id] = type;
}
}
}
void LLParcel::expirePasses(S32 now) void LLParcel::expirePasses(S32 now)
{ {
access_map_iterator itor = mAccessList.begin(); LLAccessEntry::map::iterator itor = mAccessList.begin();
while (itor != mAccessList.end()) while (itor != mAccessList.end())
{ {
const LLAccessEntry& entry = (*itor).second; const LLAccessEntry& entry = (*itor).second;
@@ -886,7 +907,7 @@ BOOL LLParcel::addToAccessList(const LLUUID& agent_id, S32 time)
// Can't add owner to these lists // Can't add owner to these lists
return FALSE; return FALSE;
} }
access_map_iterator itor = mAccessList.begin(); LLAccessEntry::map::iterator itor = mAccessList.begin();
while (itor != mAccessList.end()) while (itor != mAccessList.end())
{ {
const LLAccessEntry& entry = (*itor).second; const LLAccessEntry& entry = (*itor).second;
@@ -931,7 +952,7 @@ BOOL LLParcel::addToBanList(const LLUUID& agent_id, S32 time)
return FALSE; return FALSE;
} }
access_map_iterator itor = mBanList.begin(); LLAccessEntry::map::iterator itor = mBanList.begin();
while (itor != mBanList.end()) while (itor != mBanList.end())
{ {
const LLAccessEntry& entry = (*itor).second; const LLAccessEntry& entry = (*itor).second;
@@ -970,7 +991,7 @@ BOOL remove_from_access_array(std::map<LLUUID,LLAccessEntry>* list,
const LLUUID& agent_id) const LLUUID& agent_id)
{ {
BOOL removed = FALSE; BOOL removed = FALSE;
access_map_iterator itor = list->begin(); LLAccessEntry::map::iterator itor = list->begin();
while (itor != list->end()) while (itor != list->end())
{ {
const LLAccessEntry& entry = (*itor).second; const LLAccessEntry& entry = (*itor).second;
@@ -1091,7 +1112,7 @@ void LLParcel::startSale(const LLUUID& buyer_id, BOOL is_buyer_group)
mSaleTimerExpires.start(); mSaleTimerExpires.start();
mSaleTimerExpires.setTimerExpirySec(U64Microseconds(DEFAULT_USEC_SALE_TIMEOUT)); mSaleTimerExpires.setTimerExpirySec(U64Microseconds(DEFAULT_USEC_SALE_TIMEOUT));
mStatus = OS_LEASE_PENDING; mStatus = OS_LEASE_PENDING;
mClaimDate = time(NULL); mClaimDate = time(nullptr);
setAuctionID(0); setAuctionID(0);
// clear the autoreturn whenever land changes hands // clear the autoreturn whenever land changes hands
setCleanOtherTime(0); setCleanOtherTime(0);
@@ -1313,3 +1334,58 @@ LLParcel::ECategory category_ui_string_to_category(const std::string& s)
// is a distinct option from "None" and "Other" // is a distinct option from "None" and "Other"
return LLParcel::C_ANY; return LLParcel::C_ANY;
} }
LLAccessEntry::map LLParcel::getExperienceKeysByType(U32 type) const
{
LLAccessEntry::map access;
LLAccessEntry entry;
xp_type_map_t::const_iterator it = mExperienceKeys.begin();
for(/**/; it != mExperienceKeys.end(); ++it)
{
if(it->second == type)
{
entry.mID = it->first;
access[entry.mID] = entry;
}
}
return access;
}
void LLParcel::clearExperienceKeysByType(U32 type)
{
xp_type_map_t::iterator it = mExperienceKeys.begin();
while(it != mExperienceKeys.end())
{
if(it->second == type)
{
mExperienceKeys.erase(it++);
}
else
{
++it;
}
}
}
void LLParcel::setExperienceKeyType(const LLUUID& experience_key, U32 type)
{
if (type == EXPERIENCE_KEY_TYPE_NONE)
{
mExperienceKeys.erase(experience_key);
}
else
{
if (countExperienceKeyType(type) < PARCEL_MAX_EXPERIENCE_LIST)
{
mExperienceKeys[experience_key] = type;
}
}
}
U32 LLParcel::countExperienceKeyType(U32 type)
{
return std::count_if(
boost::begin(mExperienceKeys | boost::adaptors::map_values),
boost::end(mExperienceKeys | boost::adaptors::map_values),
std::bind2nd(std::equal_to<U32>(), type));
}

View File

@@ -60,6 +60,9 @@ const S32 PARCEL_MAX_ACCESS_LIST = 300;
//for access/ban lists. //for access/ban lists.
const F32 PARCEL_MAX_ENTRIES_PER_PACKET = 48.f; const F32 PARCEL_MAX_ENTRIES_PER_PACKET = 48.f;
// Maximum number of experiences
const S32 PARCEL_MAX_EXPERIENCE_LIST = 24;
// Weekly charge for listing a parcel in the directory // Weekly charge for listing a parcel in the directory
const S32 PARCEL_DIRECTORY_FEE = 30; const S32 PARCEL_DIRECTORY_FEE = 30;
@@ -141,9 +144,11 @@ class LLSD;
class LLAccessEntry class LLAccessEntry
{ {
public: public:
typedef std::map<LLUUID,LLAccessEntry> map;
LLAccessEntry() LLAccessEntry()
: mID(), : mTime(0),
mTime(0),
mFlags(0) mFlags(0)
{} {}
@@ -152,8 +157,6 @@ public:
U32 mFlags; // Not used - currently should always be zero U32 mFlags; // Not used - currently should always be zero
}; };
typedef std::map<LLUUID,LLAccessEntry>::iterator access_map_iterator;
typedef std::map<LLUUID,LLAccessEntry>::const_iterator access_map_const_iterator;
class LLParcel class LLParcel
{ {
@@ -331,6 +334,9 @@ public:
void unpackAccessEntries(LLMessageSystem* msg, void unpackAccessEntries(LLMessageSystem* msg,
std::map<LLUUID,LLAccessEntry>* list); std::map<LLUUID,LLAccessEntry>* list);
void unpackExperienceEntries(LLMessageSystem* msg, U32 type);
void setAABBMin(const LLVector3& min) { mAABBMin = min; } void setAABBMin(const LLVector3& min) { mAABBMin = min; }
void setAABBMax(const LLVector3& max) { mAABBMax = max; } void setAABBMax(const LLVector3& max) { mAABBMax = max; }
@@ -707,6 +713,17 @@ public:
std::map<LLUUID,LLAccessEntry> mTempBanList; std::map<LLUUID,LLAccessEntry> mTempBanList;
std::map<LLUUID,LLAccessEntry> mTempAccessList; std::map<LLUUID,LLAccessEntry> mTempAccessList;
typedef std::map<LLUUID, U32> xp_type_map_t;
void setExperienceKeyType(const LLUUID& experience_key, U32 type);
U32 countExperienceKeyType(U32 type);
U32 getExperienceKeyType(const LLUUID& experience_key)const;
LLAccessEntry::map getExperienceKeysByType(U32 type)const;
void clearExperienceKeysByType(U32 type);
private:
xp_type_map_t mExperienceKeys;
}; };

View File

@@ -1,31 +1,25 @@
/** /**
* @file llparcelflags.h * @file llparcelflags.h
* *
* $LicenseInfo:firstyear=2002&license=viewergpl$ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
@@ -97,8 +91,10 @@ const U32 PF_DEFAULT = PF_ALLOW_FLY
| PF_USE_ESTATE_VOICE_CHAN; | PF_USE_ESTATE_VOICE_CHAN;
// Access list flags // Access list flags
const U32 AL_ACCESS = (1 << 0); const U32 AL_ACCESS = (1 << 0);
const U32 AL_BAN = (1 << 1); const U32 AL_BAN = (1 << 1);
const U32 AL_ALLOW_EXPERIENCE = (1 << 3);
const U32 AL_BLOCK_EXPERIENCE = (1 << 4);
//const U32 AL_RENTER = (1 << 2); //const U32 AL_RENTER = (1 << 2);
// Block access return values. BA_ALLOWED is the only success case // Block access return values. BA_ALLOWED is the only success case

View File

@@ -103,9 +103,9 @@ LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) cons
break; break;
case LLSD::TypeArray: case LLSD::TypeArray:
newSettings[key_name] = LLSD::emptyArray(); newSettings[key_name] = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita) for (auto const& entry : value.array())
{ {
newSettings[key_name].append(*ita); newSettings[key_name].append(entry);
} }
break; break;
//case LLSD::TypeInteger: //case LLSD::TypeInteger:
@@ -137,9 +137,9 @@ LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) cons
break; break;
case LLSD::TypeArray: case LLSD::TypeArray:
newSettings[key_name] = LLSD::emptyArray(); newSettings[key_name] = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita) for (auto const& entry : value.array())
{ {
newSettings[key_name].append(*ita); newSettings[key_name].append(entry);
} }
break; break;
//case LLSD::TypeInteger: //case LLSD::TypeInteger:

View File

@@ -240,16 +240,16 @@ bool LLSettingsDay::initialize(bool validate_frames)
{ {
mDayTracks[i].clear(); mDayTracks[i].clear();
LLSD curtrack = tracks[i]; LLSD curtrack = tracks[i];
for (LLSD::array_const_iterator it = curtrack.beginArray(); it != curtrack.endArray(); ++it) for (const auto& entry : curtrack.array())
{ {
LLSettingsBase::TrackPosition keyframe = LLSettingsBase::TrackPosition((*it)[SETTING_KEYKFRAME].asReal()); LLSettingsBase::TrackPosition keyframe = LLSettingsBase::TrackPosition(entry[SETTING_KEYKFRAME].asReal());
keyframe = llclamp(keyframe, 0.0f, 1.0f); keyframe = llclamp(keyframe, 0.0f, 1.0f);
LLSettingsBase::ptr_t setting; LLSettingsBase::ptr_t setting;
if ((*it).has(SETTING_KEYNAME)) if (entry.has(SETTING_KEYNAME))
{ {
std::string key_name = (*it)[SETTING_KEYNAME]; std::string key_name = entry[SETTING_KEYNAME];
if (i == TRACK_WATER) if (i == TRACK_WATER)
{ {
setting = used[key_name]; setting = used[key_name];
@@ -469,36 +469,36 @@ namespace
S32 framecount(0); S32 framecount(0);
for (LLSD::array_iterator track = value.beginArray(); track != value.endArray(); ++track) for (auto& entry : value.array())
{ {
S32 index = 0; S32 index = 0;
while (index < (*track).size()) while (index < entry.size())
{ {
LLSD& elem = (*track)[index]; LLSD& elem = entry[index];
++framecount; ++framecount;
if (index >= LLSettingsDay::FRAME_MAX) if (index >= LLSettingsDay::FRAME_MAX)
{ {
(*track).erase(index); entry.erase(index);
continue; continue;
} }
if (!elem.has(LLSettingsDay::SETTING_KEYKFRAME)) if (!elem.has(LLSettingsDay::SETTING_KEYKFRAME))
{ {
(*track).erase(index); entry.erase(index);
continue; continue;
} }
if (!elem[LLSettingsDay::SETTING_KEYKFRAME].isReal()) if (!elem[LLSettingsDay::SETTING_KEYKFRAME].isReal())
{ {
(*track).erase(index); entry.erase(index);
continue; continue;
} }
if (!elem.has(LLSettingsDay::SETTING_KEYNAME) && if (!elem.has(LLSettingsDay::SETTING_KEYNAME) &&
!elem.has(LLSettingsDay::SETTING_KEYID)) !elem.has(LLSettingsDay::SETTING_KEYID))
{ {
(*track).erase(index); entry.erase(index);
continue; continue;
} }

View File

@@ -126,9 +126,12 @@ public:
// Returns true if this rotation is orthonormal with det ~= 1 // Returns true if this rotation is orthonormal with det ~= 1
inline bool isOkRotation() const; inline bool isOkRotation() const;
} LL_ALIGN_POSTFIX(16); } 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_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_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_trivial<LLRotation>::value, "LLRotation must be a trivial type");
static_assert(std::is_standard_layout<LLRotation>::value, "LLRotation must be a standard layout type"); static_assert(std::is_standard_layout<LLRotation>::value, "LLRotation must be a standard layout type");
#endif #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); 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_trivial<LLMatrix4a>::value, "LLMatrix4a must be a trivial type");
static_assert(std::is_standard_layout<LLMatrix4a>::value, "LLMatrix4a must be a standard layout type"); static_assert(std::is_standard_layout<LLMatrix4a>::value, "LLMatrix4a must be a standard layout type");
#endif #endif
#endif

View File

@@ -45,6 +45,7 @@
#endif #endif
extern U32 gOctreeMaxCapacity; extern U32 gOctreeMaxCapacity;
extern float gOctreeMinSize;
extern U32 gOctreeReserveCapacity; extern U32 gOctreeReserveCapacity;
#if LL_DEBUG #if LL_DEBUG
#define LL_OCTREE_PARANOIA_CHECK 0 #define LL_OCTREE_PARANOIA_CHECK 0
@@ -404,7 +405,7 @@ public:
F32 size = mSize[0]; F32 size = mSize[0];
F32 p_size = size * 2.f; F32 p_size = size * 2.f;
return (radius <= 0.001f && size <= 0.001f) || return (radius <= gOctreeMinSize && size <= gOctreeMinSize) ||
(radius <= p_size && radius > size); (radius <= p_size && radius > size);
} }
@@ -425,7 +426,7 @@ public:
} }
void accept(oct_traveler* visitor) { visitor->visit(this); } void accept(oct_traveler* visitor) { visitor->visit(this); }
virtual bool isLeaf() const { return mChildCount == 0; } bool isLeaf() const { return mChildCount == 0; }
U32 getElementCount() const { return mData.size(); } U32 getElementCount() const { return mData.size(); }
bool isEmpty() const { return mData.size() == 0; } bool isEmpty() const { return mData.size() == 0; }
@@ -498,7 +499,7 @@ public:
return node; return node;
} }
virtual bool insert(T* data) bool insert(T* data) override
{ {
OctreeGuard::checkGuarded(this); OctreeGuard::checkGuarded(this);
if (data == NULL || data->getBinIndex() != -1) if (data == NULL || data->getBinIndex() != -1)
@@ -511,7 +512,7 @@ public:
//is it here? //is it here?
if (isInside(data->getPositionGroup())) 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))) (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
{ //it belongs here { //it belongs here
/*mElementCount++; /*mElementCount++;
@@ -537,7 +538,7 @@ public:
OctreeStats::getInstance()->realloc(old_cap,mData.capacity()); OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
#endif #endif
BaseType::insert(data); LLOctreeNode<T>::notifyAddition(data);
return true; return true;
} }
else else
@@ -566,8 +567,9 @@ public:
LLVector4a val; LLVector4a val;
val.setSub(center, getCenter()); val.setSub(center, getCenter());
val.setAbs(val); val.setAbs(val);
LLVector4a min_diff(gOctreeMinSize);
S32 lt = val.lessThan(LLVector4a::getEpsilon()).getGatheredBits() & 0x7;
S32 lt = val.lessThan(min_diff).getGatheredBits() & 0x7;
if( lt == 0x7 ) if( lt == 0x7 )
{ {
@@ -593,7 +595,7 @@ public:
OctreeStats::getInstance()->realloc(old_cap,mData.capacity()); OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
#endif #endif
BaseType::insert(data); LLOctreeNode<T>::notifyAddition(data);
return true; return true;
} }
@@ -616,6 +618,7 @@ public:
} }
#endif #endif
llassert(size[0] >= gOctreeMinSize*0.5f);
//make the new kid //make the new kid
child = new LLOctreeNode<T>(center, size, this); child = new LLOctreeNode<T>(center, size, this);
addChild(child); addChild(child);
@@ -623,10 +626,7 @@ public:
child->insert(data); child->insert(data);
} }
} }
// Singu note: now that we allow wider range in octree, discard them here else if (parent)
// if they fall out of range
#if 0
else
{ {
//it's not in here, give it to the root //it's not in here, give it to the root
OCT_ERRS << "Octree insertion failed, starting over from root!" << LL_ENDL; OCT_ERRS << "Octree insertion failed, starting over from root!" << LL_ENDL;
@@ -639,12 +639,15 @@ public:
parent = node->getOctParent(); 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; return false;
} }
@@ -708,7 +711,7 @@ public:
checkAlive(); checkAlive();
} }
bool remove(T* data) bool remove(T* data) final override
{ {
OctreeGuard::checkGuarded(this); OctreeGuard::checkGuarded(this);
S32 i = data->getBinIndex(); S32 i = data->getBinIndex();
@@ -849,10 +852,9 @@ public:
if (!silent) if (!silent)
{ {
for (U32 i = 0; i < this->getListenerCount(); i++) for (auto& entry : this->mListeners)
{ {
oct_listener* listener = getOctListener(i); ((oct_listener*)entry.get())->handleChildAddition(this, child);
listener->handleChildAddition(this, child);
} }
} }
} }
@@ -861,16 +863,17 @@ public:
{ {
OctreeGuard::checkGuarded(this); OctreeGuard::checkGuarded(this);
for (U32 i = 0; i < this->getListenerCount(); i++) oct_node* child = getChild(index);
for (auto& entry : this->mListeners)
{ {
oct_listener* listener = getOctListener(i); ((oct_listener*)entry.get())->handleChildRemoval(this, child);
listener->handleChildRemoval(this, getChild(index));
} }
if (destroy) if (destroy)
{ {
mChild[index]->destroy(); child->destroy();
delete mChild[index]; delete child;
} }
--mChildCount; --mChildCount;
@@ -1012,7 +1015,7 @@ public:
} }
// LLOctreeRoot::insert // LLOctreeRoot::insert
bool insert(T* data) bool insert(T* data) final override
{ {
if (data == NULL) if (data == NULL)
{ {
@@ -1050,10 +1053,15 @@ public:
{ {
LLOctreeNode<T>::insert(data); LLOctreeNode<T>::insert(data);
} }
else else if (node->isInside(data->getPositionGroup()))
{ {
node->insert(data); 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) else if (this->getChildCount() == 0)
{ {
@@ -1088,6 +1096,8 @@ public:
this->setSize(size2); this->setSize(size2);
this->updateMinMax(); this->updateMinMax();
llassert(size[0] >= gOctreeMinSize);
//copy our children to a new branch //copy our children to a new branch
LLOctreeNode<T>* newnode = new LLOctreeNode<T>(center, size, this); LLOctreeNode<T>* newnode = new LLOctreeNode<T>(center, size, this);

View File

@@ -104,7 +104,8 @@ private:
LL_ALIGN_16(LLVector4a mV); LL_ALIGN_16(LLVector4a mV);
} LL_ALIGN_POSTFIX(16); } 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_trivial<LLPlane>::value, "LLPlane must be a trivial type");
static_assert(std::is_standard_layout<LLPlane>::value, "LLPlane must be a standard layout type"); static_assert(std::is_standard_layout<LLPlane>::value, "LLPlane must be a standard layout type");
#endif
#endif // LL_LLPLANE_H #endif // LL_LLPLANE_H

View File

@@ -105,7 +105,9 @@ protected:
} LL_ALIGN_POSTFIX(16); } 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_trivial<LLQuaternion2>::value, "LLQuaternion2 must be a trivial type");
static_assert(std::is_standard_layout<LLQuaternion2>::value, "LLQuaternion2 must be a standard layout type"); static_assert(std::is_standard_layout<LLQuaternion2>::value, "LLQuaternion2 must be a standard layout type");
#endif
#endif #endif

View File

@@ -44,7 +44,6 @@ public:
virtual void handleInsertion(const LLTreeNode<T>* node, T* data) = 0; virtual void handleInsertion(const LLTreeNode<T>* node, T* data) = 0;
virtual void handleRemoval(const LLTreeNode<T>* node, T* data) = 0; virtual void handleRemoval(const LLTreeNode<T>* node, T* data) = 0;
virtual void handleDestruction(const LLTreeNode<T>* node) = 0; virtual void handleDestruction(const LLTreeNode<T>* node) = 0;
virtual void handleStateChange(const LLTreeNode<T>* node) = 0;
}; };
template <class T> template <class T>
@@ -53,11 +52,15 @@ class LLTreeNode
public: public:
virtual ~LLTreeNode(); virtual ~LLTreeNode();
virtual bool insert(T* data); virtual bool insert(T* data) = 0;
virtual bool remove(T* data); virtual bool remove(T* data) = 0;
virtual void notifyRemoval(T* data); bool notifyAddition(T* data);
virtual U32 getListenerCount() { return mListeners.size(); } void notifyRemoval(T* data);
virtual LLTreeListener<T>* getListener(U32 index) const U32 getListenerCount() const
{
return mListeners.size();
}
LLTreeListener<T>* getListener(U32 index) const
{ {
if(index < mListeners.size()) if(index < mListeners.size())
{ {
@@ -65,7 +68,10 @@ public:
} }
return NULL; return NULL;
} }
virtual void addListener(LLTreeListener<T>* listener) { mListeners.push_back(listener); } void addListener(LLTreeListener<T>* listener)
{
mListeners.push_back(listener);
}
protected: protected:
void destroyListeners() void destroyListeners()
@@ -97,7 +103,7 @@ LLTreeNode<T>::~LLTreeNode()
}; };
template <class T> template <class T>
bool LLTreeNode<T>::insert(T* data) bool LLTreeNode<T>::notifyAddition(T* data)
{ {
for (U32 i = 0; i < mListeners.size(); i++) for (U32 i = 0; i < mListeners.size(); i++)
{ {
@@ -106,12 +112,6 @@ bool LLTreeNode<T>::insert(T* data)
return true; return true;
}; };
template <class T>
bool LLTreeNode<T>::remove(T* data)
{
return true;
};
template <class T> template <class T>
void LLTreeNode<T>::notifyRemoval(T* data) void LLTreeNode<T>::notifyRemoval(T* data)
{ {

View File

@@ -350,6 +350,8 @@ inline std::ostream& operator<<(std::ostream& s, const LLVector4a& v)
return s; 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_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"); static_assert(std::is_standard_layout<LLVector4a>::value, "LLVector4a must be a standard layout type");
#endif #endif
#endif

View File

@@ -38,7 +38,7 @@ class LLVolumeParams;
class LLProfile; class LLProfile;
class LLPath; class LLPath;
template <class T> class LLOctreeNode; template <class T> class LLOctreeRoot;
class LLVolumeFace; class LLVolumeFace;
class LLVolume; class LLVolume;
@@ -964,7 +964,7 @@ public:
// vertices per joint. // vertices per joint.
LLJointRiggingInfoTab mJointRiggingInfoTab; LLJointRiggingInfoTab mJointRiggingInfoTab;
LLOctreeNode<LLVolumeTriangle>* mOctree; LLOctreeRoot<LLVolumeTriangle>* mOctree;
//whether or not face has been cache optimized //whether or not face has been cache optimized
BOOL mOptimized; BOOL mOptimized;

View File

@@ -112,14 +112,13 @@ public:
} }
//LISTENER FUNCTIONS //LISTENER FUNCTIONS
virtual void handleChildAddition(const LLOctreeNode<LLVolumeTriangle>* parent, void handleChildAddition(const LLOctreeNode<LLVolumeTriangle>* parent,
LLOctreeNode<LLVolumeTriangle>* child); LLOctreeNode<LLVolumeTriangle>* child) final override;
virtual void handleStateChange(const LLTreeNode<LLVolumeTriangle>* node) { } void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle>* parent,
virtual void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle>* parent, const LLOctreeNode<LLVolumeTriangle>* child) final override { }
const LLOctreeNode<LLVolumeTriangle>* child) { } void handleInsertion(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) final override { }
virtual void handleInsertion(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { } void handleRemoval(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) final override { }
virtual void handleRemoval(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { } void handleDestruction(const LLTreeNode<LLVolumeTriangle>* node) final override { }
virtual void handleDestruction(const LLTreeNode<LLVolumeTriangle>* node) { }
public: public:

View File

@@ -45,6 +45,7 @@ set(llmessage_SOURCE_FILES
llclassifiedflags.cpp llclassifiedflags.cpp
lldatapacker.cpp lldatapacker.cpp
lldispatcher.cpp lldispatcher.cpp
llexperiencecache.cpp
llfiltersd2xmlrpc.cpp llfiltersd2xmlrpc.cpp
llhost.cpp llhost.cpp
llhttpclient.cpp llhttpclient.cpp
@@ -63,7 +64,6 @@ set(llmessage_SOURCE_FILES
llmessagetemplate.cpp llmessagetemplate.cpp
llmessagetemplateparser.cpp llmessagetemplateparser.cpp
llmessagethrottle.cpp llmessagethrottle.cpp
llmime.cpp
llnamevalue.cpp llnamevalue.cpp
llnullcipher.cpp llnullcipher.cpp
llpacketack.cpp llpacketack.cpp
@@ -133,11 +133,13 @@ set(llmessage_HEADER_FILES
llcipher.h llcipher.h
llcircuit.h llcircuit.h
llclassifiedflags.h llclassifiedflags.h
llcororesponder.h
llcurl.h llcurl.h
lldatapacker.h lldatapacker.h
lldbstrings.h lldbstrings.h
lldispatcher.h lldispatcher.h
lleventflags.h lleventflags.h
llexperiencecache.h
llfiltersd2xmlrpc.h llfiltersd2xmlrpc.h
llfollowcamparams.h llfollowcamparams.h
llhost.h llhost.h
@@ -160,7 +162,6 @@ set(llmessage_HEADER_FILES
llmessagetemplate.h llmessagetemplate.h
llmessagetemplateparser.h llmessagetemplateparser.h
llmessagethrottle.h llmessagethrottle.h
llmime.h
llmsgvariabletype.h llmsgvariabletype.h
llnamevalue.h llnamevalue.h
llnullcipher.h llnullcipher.h
@@ -238,7 +239,6 @@ if (LL_TESTS)
include(Tut) include(Tut)
SET(llmessage_TEST_SOURCE_FILES SET(llmessage_TEST_SOURCE_FILES
llmime.cpp
llnamevalue.cpp llnamevalue.cpp
lltrustedmessageservice.cpp lltrustedmessageservice.cpp
lltemplatemessagedispatcher.cpp lltemplatemessagedispatcher.cpp

View File

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

View File

@@ -335,7 +335,7 @@ void LLAvatarNameCache::requestNamesViaCapability()
while(!sAskQueue.empty()) while(!sAskQueue.empty())
{ {
it = sAskQueue.begin(); it = sAskQueue.begin();
const LLUUID& agent_id = *it; const LLUUID agent_id = *it;
sAskQueue.erase(it); sAskQueue.erase(it);
if (url.empty()) if (url.empty())

View File

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

View File

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

View File

@@ -0,0 +1,63 @@
/**
* @file llcororesponder.h
* @brief A responder purposed to call coro functions, to ease transition to LLCoro
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
*
* Copyright (C) 2020, Liru Færs
*
* 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 <functional>
#include "llhttpclient.h"
struct LLCoroResponderBase : public LLHTTPClient::ResponderWithCompleted
{
const AIHTTPReceivedHeaders& getHeaders() const { return mReceivedHeaders; }
const LLSD& getContent() const { return mContent; }
char const* getName() const override final { return "LLCoroResponder"; }
protected:
LLCoroResponderBase() {}
};
struct LLCoroResponder final : public LLCoroResponderBase
{
typedef std::function<void(const LLCoroResponder&)> cb_t;
LLCoroResponder(const cb_t& cb) : mCB(cb) {}
void httpCompleted() override { mCB(*this); }
private:
const cb_t mCB;
};
struct LLCoroResponderRaw final : public LLCoroResponderBase
{
typedef std::function<void(const LLCoroResponderRaw&, const std::string&)> cb_t;
LLCoroResponderRaw(const cb_t& cb) : mCB(cb) {}
void completedRaw(const LLChannelDescriptors& channels, const buffer_ptr_t& buffer) override
{
std::string content;
decode_raw_body(channels, buffer, content);
mCB(*this, content);
}
private:
const cb_t mCB;
};

View File

@@ -0,0 +1,921 @@
/**
* @file llexperiencecache.cpp
* @brief llexperiencecache and related class definitions
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2012, 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 "llexperiencecache.h"
#include "llavatarname.h"
#include "llcororesponder.h"
#include "llsdserialize.h"
#include "lleventfilter.h"
#include "lldir.h"
#include <set>
#include <map>
#include <boost/tokenizer.hpp>
#include <boost/concept_check.hpp>
#include <boost/smart_ptr/make_shared.hpp>
//=========================================================================
namespace LLExperienceCacheImpl
{
void mapKeys(const LLSD& legacyKeys);
F64 getErrorRetryDeltaTime(S32 status, const AIHTTPReceivedHeaders& headers);
bool maxAgeFromCacheControl(const std::string& cache_control, S32 *max_age);
static const std::string PRIVATE_KEY = "private_id";
static const std::string EXPERIENCE_ID = "public_id";
static const std::string MAX_AGE("max-age");
static const boost::char_separator<char> EQUALS_SEPARATOR("=");
static const boost::char_separator<char> COMMA_SEPARATOR(",");
// *TODO$: this seems to be tied to mapKeys which is used by bootstrap.... but I don't think that bootstrap is used.
typedef std::map<LLUUID, LLUUID> KeyMap;
KeyMap privateToPublicKeyMap;
}
//=========================================================================
const std::string LLExperienceCache::PRIVATE_KEY = "private_id";
const std::string LLExperienceCache::MISSING = "DoesNotExist";
const std::string LLExperienceCache::AGENT_ID = "agent_id";
const std::string LLExperienceCache::GROUP_ID = "group_id";
const std::string LLExperienceCache::EXPERIENCE_ID = "public_id";
const std::string LLExperienceCache::NAME = "name";
const std::string LLExperienceCache::PROPERTIES = "properties";
const std::string LLExperienceCache::EXPIRES = "expiration";
const std::string LLExperienceCache::DESCRIPTION = "description";
const std::string LLExperienceCache::QUOTA = "quota";
const std::string LLExperienceCache::MATURITY = "maturity";
const std::string LLExperienceCache::METADATA = "extended_metadata";
const std::string LLExperienceCache::SLURL = "slurl";
// should be in sync with experience-api/experiences/models.py
const int LLExperienceCache::PROPERTY_INVALID = 1 << 0;
const int LLExperienceCache::PROPERTY_PRIVILEGED = 1 << 3;
const int LLExperienceCache::PROPERTY_GRID = 1 << 4;
const int LLExperienceCache::PROPERTY_PRIVATE = 1 << 5;
const int LLExperienceCache::PROPERTY_DISABLED = 1 << 6;
const int LLExperienceCache::PROPERTY_SUSPENDED = 1 << 7;
// default values
const F64 LLExperienceCache::DEFAULT_EXPIRATION = 600.0;
const S32 LLExperienceCache::DEFAULT_QUOTA = 128; // this is megabytes
const int LLExperienceCache::SEARCH_PAGE_SIZE = 30;
//=========================================================================
LLExperienceCache::LLExperienceCache():
mShutdown(false)
{
}
LLExperienceCache::~LLExperienceCache()
{
}
void LLExperienceCache::initSingleton()
{
mCacheFileName = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "experience_cache.xml");
LL_INFOS("ExperienceCache") << "Loading " << mCacheFileName << LL_ENDL;
llifstream cache_stream(mCacheFileName.c_str());
if (cache_stream.is_open())
{
cache_stream >> (*this);
}
}
void LLExperienceCache::cleanup()
{
LL_INFOS("ExperienceCache") << "Saving " << mCacheFileName << LL_ENDL;
llofstream cache_stream(mCacheFileName.c_str());
if (cache_stream.is_open())
{
cache_stream << (*this);
}
mShutdown = true;
}
//-------------------------------------------------------------------------
void LLExperienceCache::importFile(std::istream& istr)
{
LLSD data;
S32 parse_count = LLSDSerialize::fromXMLDocument(data, istr);
if (parse_count < 1) return;
LLSD experiences = data["experiences"];
LLUUID public_key;
for (const auto& it : experiences.map())
{
public_key.set(it.first);
mCache[public_key] = it.second;
}
LL_DEBUGS("ExperienceCache") << "importFile() loaded " << mCache.size() << LL_ENDL;
}
void LLExperienceCache::exportFile(std::ostream& ostr) const
{
LLSD experiences;
cache_t::const_iterator it = mCache.begin();
for (; it != mCache.end(); ++it)
{
if (!it->second.has(EXPERIENCE_ID) || it->second[EXPERIENCE_ID].asUUID().isNull() ||
it->second.has("DoesNotExist") || (it->second.has(PROPERTIES) && it->second[PROPERTIES].asInteger() & PROPERTY_INVALID))
continue;
experiences[it->first.asString()] = it->second;
}
LLSD data;
data["experiences"] = experiences;
LLSDSerialize::toPrettyXML(data, ostr);
}
// *TODO$: Rider: This method does not seem to be used... it may be useful in testing.
void LLExperienceCache::bootstrap(const LLSD& legacyKeys, int initialExpiration)
{
LLExperienceCacheImpl::mapKeys(legacyKeys);
for (auto experience : legacyKeys.array())
{
if (experience.has(EXPERIENCE_ID))
{
if (!experience.has(EXPIRES))
{
experience[EXPIRES] = initialExpiration;
}
processExperience(experience[EXPERIENCE_ID].asUUID(), experience);
}
else
{
LL_WARNS("ExperienceCache")
<< "Skipping bootstrap entry which is missing " << EXPERIENCE_ID
<< LL_ENDL;
}
}
}
LLUUID LLExperienceCache::getExperienceId(const LLUUID& private_key, bool null_if_not_found)
{
if (private_key.isNull())
return LLUUID::null;
LLExperienceCacheImpl::KeyMap::const_iterator it = LLExperienceCacheImpl::privateToPublicKeyMap.find(private_key);
if (it == LLExperienceCacheImpl::privateToPublicKeyMap.end())
{
if (null_if_not_found)
{
return LLUUID::null;
}
return private_key;
}
LL_WARNS("LLExperience") << "converted private key " << private_key << " to experience_id " << it->second << LL_ENDL;
return it->second;
}
//=========================================================================
void LLExperienceCache::processExperience(const LLUUID& public_key, const LLSD& experience)
{
LL_INFOS("ExperienceCache") << "Processing experience \"" << experience[NAME] << "\" with key " << public_key.asString() << LL_ENDL;
mCache[public_key]=experience;
LLSD & row = mCache[public_key];
if(row.has(EXPIRES))
{
row[EXPIRES] = row[EXPIRES].asReal() + LLFrameTimer::getTotalSeconds();
}
if(row.has(EXPERIENCE_ID))
{
mPendingQueue.erase(row[EXPERIENCE_ID].asUUID());
}
//signal
signal_map_t::iterator sig_it = mSignalMap.find(public_key);
if (sig_it != mSignalMap.end())
{
signal_ptr signal = sig_it->second;
(*signal)(experience);
mSignalMap.erase(public_key);
}
}
const LLExperienceCache::cache_t& LLExperienceCache::getCached()
{
return mCache;
}
void LLExperienceCache::requestExperiencesCoro(const LLCoroResponder& responder, RequestQueue_t requests)
{
//LL_INFOS("requestExperiencesCoro") << "url: " << url << LL_ENDL;
LLSD result = responder.getContent();
auto status = responder.getStatus();
if (!responder.isGoodStatus(status))
{
F64 now = LLFrameTimer::getTotalSeconds();
auto headers = responder.getHeaders();
// build dummy entries for the failed requests
for (auto request : requests)
{
LLSD exp = get(request);
//leave the properties alone if we already have a cache entry for this xp
if (exp.isUndefined())
{
exp[PROPERTIES] = PROPERTY_INVALID;
}
exp[EXPIRES] = now + LLExperienceCacheImpl::getErrorRetryDeltaTime(status, headers);
exp[EXPERIENCE_ID] = request;
exp["key_type"] = EXPERIENCE_ID;
exp["uuid"] = request;
exp["error"] = status;
exp[QUOTA] = DEFAULT_QUOTA;
processExperience(request, exp);
}
return;
}
LLSD experiences = result["experience_keys"];
for (const auto& row : experiences.array())
{
LLUUID public_key = row[EXPERIENCE_ID].asUUID();
LL_DEBUGS("ExperienceCache") << "Received result for " << public_key
<< " display '" << row[LLExperienceCache::NAME].asString() << "'" << LL_ENDL;
processExperience(public_key, row);
}
LLSD error_ids = result["error_ids"];
for (const auto& err : error_ids.array())
{
LLUUID id = err.asUUID();
LLSD exp;
exp[EXPIRES] = DEFAULT_EXPIRATION;
exp[EXPERIENCE_ID] = id;
exp[PROPERTIES] = PROPERTY_INVALID;
exp[MISSING] = true;
exp[QUOTA] = DEFAULT_QUOTA;
processExperience(id, exp);
LL_WARNS("ExperienceCache") << "LLExperienceResponder::result() error result for " << id << LL_ENDL;
}
}
void LLExperienceCache::requestExperiences()
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
std::string urlBase = mCapability("GetExperienceInfo");
if (urlBase.empty())
{
LL_DEBUGS("ExperienceCache") << "No Experience capability." << LL_ENDL;
return;
}
if (*urlBase.rbegin() != '/')
{
urlBase += "/";
}
urlBase += "id/";
F64 now = LLFrameTimer::getTotalSeconds();
const U32 EXP_URL_SEND_THRESHOLD = 3000;
constexpr U32 EXP_PAGE_SIZE = EXP_URL_SEND_THRESHOLD / UUID_STR_LENGTH;
std::ostringstream ostr;
ostr << urlBase << "?page_size=" << EXP_PAGE_SIZE;
RequestQueue_t requests;
while (!mRequestQueue.empty())
{
RequestQueue_t::iterator it = mRequestQueue.begin();
LLUUID key = (*it);
mRequestQueue.erase(it);
requests.insert(key);
ostr << "&" << EXPERIENCE_ID << "=" << key.asString();
mPendingQueue[key] = now;
if (mRequestQueue.empty() || (ostr.tellp() > EXP_URL_SEND_THRESHOLD))
{ // request is placed in the coprocedure pool for the ExpCache cache. Throttling is done by the pool itself.
LLHTTPClient::get(ostr.str(), new LLCoroResponder(
boost::bind(&LLExperienceCache::requestExperiencesCoro, this, _1, requests) ));
ostr.str(std::string());
ostr << urlBase << "?page_size=" << EXP_PAGE_SIZE;
requests.clear();
}
}
}
bool LLExperienceCache::isRequestPending(const LLUUID& public_key)
{
bool isPending = false;
const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0;
PendingQueue_t::const_iterator it = mPendingQueue.find(public_key);
if(it != mPendingQueue.end())
{
F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS;
isPending = (it->second > expire_time);
}
return isPending;
}
void LLExperienceCache::setCapabilityQuery(LLExperienceCache::CapabilityQuery_t queryfn)
{
mCapability = queryfn;
}
void LLExperienceCache::idleCoro()
{
const F32 SECS_BETWEEN_REQUESTS = 0.5f;
const F32 ERASE_EXPIRED_TIMEOUT = 60.f; // seconds
{
static LLFrameTimer sRequestTimer;
if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS)) return;
if (mEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT))
{
eraseExpired();
}
if (!mRequestQueue.empty())
{
requestExperiences();
}
}
// The coroutine system will likely be shut down by the time we get to this point
// (or at least no further cycling will occur on it since the user has decided to quit.)
}
void LLExperienceCache::erase(const LLUUID& key)
{
cache_t::iterator it = mCache.find(key);
if(it != mCache.end())
{
mCache.erase(it);
}
}
void LLExperienceCache::eraseExpired()
{
F64 now = LLFrameTimer::getTotalSeconds();
cache_t::iterator it = mCache.begin();
while (it != mCache.end())
{
cache_t::iterator cur = it;
LLSD& exp = cur->second;
++it;
//LL_INFOS("ExperienceCache") << "Testing experience \"" << exp[NAME] << "\" with exp time " << exp[EXPIRES].asReal() << "(now = " << now << ")" << LL_ENDL;
if(exp.has(EXPIRES) && exp[EXPIRES].asReal() < now)
{
if(!exp.has(EXPERIENCE_ID))
{
LL_WARNS("ExperienceCache") << "Removing experience with no id " << LL_ENDL ;
mCache.erase(cur);
}
else
{
LLUUID id = exp[EXPERIENCE_ID].asUUID();
LLUUID private_key = exp.has(LLExperienceCache::PRIVATE_KEY) ? exp[LLExperienceCache::PRIVATE_KEY].asUUID():LLUUID::null;
if(private_key.notNull() || !exp.has("DoesNotExist"))
{
fetch(id, true);
}
else
{
LL_WARNS("ExperienceCache") << "Removing invalid experience " << id << LL_ENDL ;
mCache.erase(cur);
}
}
}
}
}
bool LLExperienceCache::fetch(const LLUUID& key, bool refresh/* = true*/)
{
if(!key.isNull() && !isRequestPending(key) && (refresh || mCache.find(key)==mCache.end()))
{
LL_DEBUGS("ExperienceCache") << " queue request for " << EXPERIENCE_ID << " " << key << LL_ENDL;
mRequestQueue.insert(key);
return true;
}
return false;
}
void LLExperienceCache::insert(const LLSD& experience_data)
{
if(experience_data.has(EXPERIENCE_ID))
{
processExperience(experience_data[EXPERIENCE_ID].asUUID(), experience_data);
}
else
{
LL_WARNS("ExperienceCache") << ": Ignoring cache insert of experience which is missing " << EXPERIENCE_ID << LL_ENDL;
}
}
const LLSD& LLExperienceCache::get(const LLUUID& key)
{
static const LLSD empty;
if(key.isNull())
return empty;
cache_t::const_iterator it = mCache.find(key);
if (it != mCache.end())
{
return it->second;
}
fetch(key);
return empty;
}
void LLExperienceCache::get(const LLUUID& key, LLExperienceCache::ExperienceGetFn_t slot)
{
if(key.isNull())
return;
cache_t::const_iterator it = mCache.find(key);
if (it != mCache.end())
{
// ...name already exists in cache, fire callback now
callback_signal_t signal;
signal.connect(slot);
signal(it->second);
return;
}
fetch(key);
signal_ptr signal = boost::make_shared<callback_signal_t>();
std::pair<signal_map_t::iterator, bool> result = mSignalMap.insert(signal_map_t::value_type(key, signal));
if (!result.second)
signal = (*result.first).second;
signal->connect(slot);
}
//=========================================================================
void LLExperienceCache::fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, std::string url, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
if (url.empty())
{
url = mCapability("GetMetadata");
if (url.empty())
{
LL_WARNS("ExperienceCache") << "No Metadata capability." << LL_ENDL;
return;
}
}
LLSD fields;
fields.append("experience");
LLSD data;
data["object-id"] = objectId;
data["item-id"] = itemId;
data["fields"] = fields;
LLHTTPClient::post(url, data, new LLCoroResponder(
boost::bind(&LLExperienceCache::fetchAssociatedExperienceCoro, this, _1, fn)));
}
void LLExperienceCache::fetchAssociatedExperienceCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
{
LLSD result = responder.getContent();
auto status = responder.getStatus();
if (!responder.isGoodStatus(status) || !result.has("experience"))
{
LLSD failure;
if (!status)
{
failure["error"] = status;
failure["message"] = responder.getReason();
}
else
{
failure["error"] = -1;
failure["message"] = "no experience";
}
if (fn != nullptr)
fn(failure);
return;
}
LLUUID expId = result["experience"].asUUID();
get(expId, fn);
}
//-------------------------------------------------------------------------
void LLExperienceCache::findExperienceByName(const std::string text, int page, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
std::ostringstream url;
url << mCapability("FindExperienceByName") << "?page=" << page << "&page_size=" << SEARCH_PAGE_SIZE << "&query=" << LLURI::escape(text);
LLHTTPClient::get(url.str(), new LLCoroResponder(
boost::bind(&LLExperienceCache::findExperienceByNameCoro, this, _1, fn)));
}
void LLExperienceCache::findExperienceByNameCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
{
LLSD result = responder.getContent();
if (!responder.isGoodStatus(responder.getStatus()))
{
fn(LLSD());
return;
}
const LLSD& experiences = result["experience_keys"];
for (const auto& it : experiences.array())
{
insert(it);
}
fn(result);
}
//-------------------------------------------------------------------------
void LLExperienceCache::getGroupExperiences(const LLUUID &groupId, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
// search for experiences owned by the current group
std::string url = mCapability("GroupExperiences");
if (url.empty())
{
LL_WARNS("ExperienceCache") << "No Group Experiences capability" << LL_ENDL;
return;
}
url += "?" + groupId.asString();
LLHTTPClient::get(url, new LLCoroResponder(
boost::bind(&LLExperienceCache::getGroupExperiencesCoro, this, _1, fn)));
}
void LLExperienceCache::getGroupExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
{
LLSD result = responder.getContent();
if (!responder.isGoodStatus(responder.getStatus()))
{
fn(LLSD());
return;
}
const LLSD& experienceIds = result["experience_ids"];
fn(experienceIds);
}
//-------------------------------------------------------------------------
void LLExperienceCache::getRegionExperiences(CapabilityQuery_t regioncaps, ExperienceGetFn_t fn)
{
regionExperiences(regioncaps, LLSD(), false, fn);
}
void LLExperienceCache::setRegionExperiences(CapabilityQuery_t regioncaps, const LLSD &experiences, ExperienceGetFn_t fn)
{
regionExperiences(regioncaps, experiences, true, fn);
}
void LLExperienceCache::regionExperiences(CapabilityQuery_t regioncaps, const LLSD &experiences, bool update, ExperienceGetFn_t fn)
{
// search for experiences owned by the current group
std::string url = regioncaps("RegionExperiences");
if (url.empty())
{
LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL;
return;
}
auto httpRequest = new LLCoroResponder(
boost::bind(&LLExperienceCache::regionExperiencesCoro, this, _1, fn));
LLSD result;
if (update)
LLHTTPClient::post(url, experiences, httpRequest);
else
LLHTTPClient::get(url, httpRequest);
}
void LLExperienceCache::regionExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
{
LLSD result = responder.getContent();
if (!responder.isGoodStatus(responder.getStatus()))
{
// fn(LLSD());
return;
}
fn(result);
}
//-------------------------------------------------------------------------
void LLExperienceCache::getExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
std::string url = mCapability("ExperiencePreferences") + "?" + experienceId.asString();
LLHTTPClient::get(url, new LLCoroResponder(
boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, fn)));
}
void LLExperienceCache::setExperiencePermission(const LLUUID &experienceId, const std::string &permission, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
std::string url = mCapability("ExperiencePreferences");
if (url.empty())
return;
LLSD permData;
LLSD data;
permData["permission"] = permission;
data[experienceId.asString()] = permData;
LLHTTPClient::put(url, data, new LLCoroResponder(
boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, fn)));
}
void LLExperienceCache::forgetExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
std::string url = mCapability("ExperiencePreferences") + "?" + experienceId.asString();
LLHTTPClient::del(url, new LLCoroResponder(
boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, fn)));
}
void LLExperienceCache::experiencePermissionCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
{
// search for experiences owned by the current group
LLSD result = responder.getContent();
if (responder.isGoodStatus(responder.getStatus()))
{
fn(result);
}
}
//-------------------------------------------------------------------------
void LLExperienceCache::getExperienceAdmin(const LLUUID &experienceId, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
std::string url = mCapability("IsExperienceAdmin");
if (url.empty())
{
LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL;
return;
}
url += "?experience_id=" + experienceId.asString();
LLHTTPClient::get(url, new LLCoroResponder(
boost::bind(fn, boost::bind(&LLCoroResponder::getContent, _1))));
}
//-------------------------------------------------------------------------
void LLExperienceCache::updateExperience(LLSD updateData, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
std::string url = mCapability("UpdateExperience");
if (url.empty())
{
LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL;
return;
}
updateData.erase(LLExperienceCache::QUOTA);
updateData.erase(LLExperienceCache::EXPIRES);
updateData.erase(LLExperienceCache::AGENT_ID);
LLHTTPClient::post(url, updateData, new LLCoroResponder(
boost::bind(fn, boost::bind(&LLCoroResponder::getContent, _1))));
}
//=========================================================================
void LLExperienceCacheImpl::mapKeys(const LLSD& legacyKeys)
{
for (const auto& exp : legacyKeys.array())
{
if (exp.has(LLExperienceCacheImpl::EXPERIENCE_ID) && exp.has(LLExperienceCacheImpl::PRIVATE_KEY))
{
LLExperienceCacheImpl::privateToPublicKeyMap[exp[LLExperienceCacheImpl::PRIVATE_KEY].asUUID()] =
exp[LLExperienceCacheImpl::EXPERIENCE_ID].asUUID();
}
}
}
// Return time to retry a request that generated an error, based on
// error type and headers. Return value is seconds-since-epoch.
F64 LLExperienceCacheImpl::getErrorRetryDeltaTime(S32 status, const AIHTTPReceivedHeaders& headers)
{
// Retry-After takes priority
std::string retry_afters;
if (headers.getFirstValue("retry-after", retry_afters))
{
LLSD retry_after(retry_afters);
// We only support the delta-seconds type
S32 delta_seconds = retry_after.asInteger();
if (delta_seconds > 0)
{
// ...valid delta-seconds
return F64(delta_seconds);
}
}
// If no Retry-After, look for Cache-Control max-age
// Allow the header to override the default
std::string cache_control;
if (headers.getFirstValue("cache-control", cache_control))
{
S32 max_age = 0;
if (LLExperienceCacheImpl::maxAgeFromCacheControl(cache_control, &max_age))
{
LL_WARNS("ExperienceCache")
<< "got EXPIRES from headers, max_age " << max_age
<< LL_ENDL;
return (F64)max_age;
}
}
// No information in header, make a guess
if (status == 503)
{
// ...service unavailable, retry soon
const F64 SERVICE_UNAVAILABLE_DELAY = 600.0; // 10 min
return SERVICE_UNAVAILABLE_DELAY;
}
else if (status == 499)
{
// ...we were probably too busy, retry quickly
const F64 BUSY_DELAY = 10.0; // 10 seconds
return BUSY_DELAY;
}
else
{
// ...other unexpected error
const F64 DEFAULT_DELAY = 3600.0; // 1 hour
return DEFAULT_DELAY;
}
}
bool LLExperienceCacheImpl::maxAgeFromCacheControl(const std::string& cache_control, S32 *max_age)
{
// Split the string on "," to get a list of directives
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
tokenizer directives(cache_control, COMMA_SEPARATOR);
tokenizer::iterator token_it = directives.begin();
for ( ; token_it != directives.end(); ++token_it)
{
// Tokens may have leading or trailing whitespace
std::string token = *token_it;
LLStringUtil::trim(token);
if (token.compare(0, MAX_AGE.size(), MAX_AGE) == 0)
{
// ...this token starts with max-age, so let's chop it up by "="
tokenizer subtokens(token, EQUALS_SEPARATOR);
tokenizer::iterator subtoken_it = subtokens.begin();
// Must have a token
if (subtoken_it == subtokens.end()) return false;
std::string subtoken = *subtoken_it;
// Must exactly equal "max-age"
LLStringUtil::trim(subtoken);
if (subtoken != MAX_AGE) return false;
// Must have another token
++subtoken_it;
if (subtoken_it == subtokens.end()) return false;
subtoken = *subtoken_it;
// Must be a valid integer
// *NOTE: atoi() returns 0 for invalid values, so we have to
// check the string first.
// *TODO: Do servers ever send "0000" for zero? We don't handle it
LLStringUtil::trim(subtoken);
if (subtoken == "0")
{
*max_age = 0;
return true;
}
S32 val = atoi( subtoken.c_str() );
if (val > 0 && val < S32_MAX)
{
*max_age = val;
return true;
}
return false;
}
}
return false;
}

View File

@@ -0,0 +1,181 @@
/**
* @file llexperiencecache.h
* @brief Caches information relating to experience keys
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2012, 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_LLEXPERIENCECACHE_H
#define LL_LLEXPERIENCECACHE_H
#include "linden_common.h"
#include "llsingleton.h"
#include "llframetimer.h"
#include "llsd.h"
#include <boost/signals2.hpp>
struct LLCoroResponder;
class LLSD;
class LLUUID;
class LLExperienceCache final : public LLSingleton < LLExperienceCache >
{
friend class LLSingleton<LLExperienceCache>;
LLExperienceCache();
public:
typedef std::function<std::string(const std::string &)> CapabilityQuery_t;
typedef std::function<void(const LLSD &)> ExperienceGetFn_t;
void idleCoro();
void setCapabilityQuery(CapabilityQuery_t queryfn);
void cleanup();
//-------------------------------------------
// Cache methods
void erase(const LLUUID& key);
bool fetch(const LLUUID& key, bool refresh = false);
void insert(const LLSD& experience_data);
const LLSD& get(const LLUUID& key);
void get(const LLUUID& key, ExperienceGetFn_t slot); // If name information is in cache, callback will be called immediately.
bool isRequestPending(const LLUUID& public_key);
//-------------------------------------------
void fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, ExperienceGetFn_t fn) { fetchAssociatedExperience(objectId, itemId, LLStringUtil::null, fn); }
void fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, std::string url, ExperienceGetFn_t fn);
void findExperienceByName(const std::string text, int page, ExperienceGetFn_t fn);
void getGroupExperiences(const LLUUID &groupId, ExperienceGetFn_t fn);
// the Get/Set Region Experiences take a CapabilityQuery to get the capability since
// the region being queried may not be the region that the agent is standing on.
void getRegionExperiences(CapabilityQuery_t regioncaps, ExperienceGetFn_t fn);
void setRegionExperiences(CapabilityQuery_t regioncaps, const LLSD &experiences, ExperienceGetFn_t fn);
void getExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn);
void setExperiencePermission(const LLUUID &experienceId, const std::string &permission, ExperienceGetFn_t fn);
void forgetExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn);
void getExperienceAdmin(const LLUUID &experienceId, ExperienceGetFn_t fn);
void updateExperience(LLSD updateData, ExperienceGetFn_t fn);
//-------------------------------------------
static const std::string NAME; // "name"
static const std::string EXPERIENCE_ID; // "public_id"
static const std::string AGENT_ID; // "agent_id"
static const std::string GROUP_ID; // "group_id"
static const std::string PROPERTIES; // "properties"
static const std::string EXPIRES; // "expiration"
static const std::string DESCRIPTION; // "description"
static const std::string QUOTA; // "quota"
static const std::string MATURITY; // "maturity"
static const std::string METADATA; // "extended_metadata"
static const std::string SLURL; // "slurl"
static const std::string MISSING; // "DoesNotExist"
// should be in sync with experience-api/experiences/models.py
static const int PROPERTY_INVALID; // 1 << 0
static const int PROPERTY_PRIVILEGED; // 1 << 3
static const int PROPERTY_GRID; // 1 << 4
static const int PROPERTY_PRIVATE; // 1 << 5
static const int PROPERTY_DISABLED; // 1 << 6
static const int PROPERTY_SUSPENDED; // 1 << 7
private:
virtual ~LLExperienceCache();
void initSingleton() override;
// Callback types for get()
typedef boost::signals2::signal < void(const LLSD &) > callback_signal_t;
typedef boost::shared_ptr<callback_signal_t> signal_ptr;
// May have multiple callbacks for a single ID, which are
// represented as multiple slots bound to the signal.
// Avoid copying signals via pointers.
typedef std::map<LLUUID, signal_ptr> signal_map_t;
typedef std::map<LLUUID, LLSD> cache_t;
typedef uuid_set_t RequestQueue_t;
typedef std::map<LLUUID, F64> PendingQueue_t;
//--------------------------------------------
static const std::string PRIVATE_KEY; // "private_id"
// default values
static const F64 DEFAULT_EXPIRATION; // 600.0
static const S32 DEFAULT_QUOTA; // 128 this is megabytes
static const int SEARCH_PAGE_SIZE;
//--------------------------------------------
void processExperience(const LLUUID& public_key, const LLSD& experience);
//--------------------------------------------
cache_t mCache;
signal_map_t mSignalMap;
RequestQueue_t mRequestQueue;
PendingQueue_t mPendingQueue;
LLFrameTimer mEraseExpiredTimer; // Periodically clean out expired entries from the cache
CapabilityQuery_t mCapability;
std::string mCacheFileName;
bool mShutdown;
void eraseExpired();
void requestExperiencesCoro(const LLCoroResponder& responder, RequestQueue_t);
void requestExperiences();
void fetchAssociatedExperienceCoro(const LLCoroResponder& responder, ExperienceGetFn_t);
void findExperienceByNameCoro(const LLCoroResponder& responder, ExperienceGetFn_t);
void getGroupExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t);
void regionExperiences(CapabilityQuery_t regioncaps, const LLSD& experiences, bool update, ExperienceGetFn_t fn);
void regionExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn);
void experiencePermissionCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn);
void bootstrap(const LLSD& legacyKeys, int initialExpiration);
void exportFile(std::ostream& ostr) const;
void importFile(std::istream& istr);
//
const cache_t& getCached();
// maps an experience private key to the experience id
LLUUID getExperienceId(const LLUUID& private_key, bool null_if_not_found=false);
//=====================================================================
inline friend std::ostream &operator << (std::ostream &os, const LLExperienceCache &cache)
{
cache.exportFile(os);
return os;
}
inline friend std::istream &operator >> (std::istream &is, LLExperienceCache &cache)
{
cache.importFile(is);
return is;
}
};
#endif // LL_LLEXPERIENCECACHE_H

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 std::string INTERACTIVE_SYSTEM_FROM("F387446C-37C4-45f2-A438-D99CBDBB563B");
const S32 IM_TTL = 1; 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( void pack_instant_message(
LLMessageSystem* msg, LLMessageSystem* msg,
const LLUUID& from_id, const LLUUID& from_id,
@@ -264,124 +167,3 @@ void pack_instant_message_block(
} }
msg->addBinaryDataFast(_PREHASH_BinaryBucket, bb, binary_bucket_size); 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. // Number of retry attempts on sending the im.
extern const S32 IM_TTL; 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( void pack_instant_message(
LLMessageSystem* msgsystem, LLMessageSystem* msgsystem,
const LLUUID& from_id, 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 "llnamevalue.h"
#include "u64.h"
#include "llstring.h" #include "llstring.h"
#include "llstringtable.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")) else if (!strcmp(mStringType, "U64"))
{ {
mType = NVT_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")) else if (!strcmp(mStringType, "VEC3"))
{ {
@@ -919,9 +918,7 @@ std::string LLNameValue::printData() const
break; break;
case NVT_U64: case NVT_U64:
{ {
char u64_string[U64_BUFFER_LEN]; /* Flawfinder: ignore */ buffer = fmt::to_string(*mNameValueReference.u64);
U64_to_str(*mNameValueReference.u64, u64_string, sizeof(u64_string));
buffer = u64_string;
} }
break; break;
case NVT_VEC3: case NVT_VEC3:
@@ -952,11 +949,7 @@ std::ostream& operator<<(std::ostream& s, const LLNameValue &a)
s << *(a.mNameValueReference.u32); s << *(a.mNameValueReference.u32);
break; break;
case NVT_U64: case NVT_U64:
{ s << (*a.mNameValueReference.u64);
char u64_string[U64_BUFFER_LEN]; /* Flawfinder: ignore */
U64_to_str(*a.mNameValueReference.u64, u64_string, sizeof(u64_string));
s << u64_string;
}
break; break;
case NVT_VEC3: case NVT_VEC3:
s << *(a.mNameValueReference.vec3); s << *(a.mNameValueReference.vec3);

View File

@@ -168,19 +168,20 @@ const U32 ESTATE_ACCESS_ALL = ESTATE_ACCESS_ALLOWED_AGENTS
| ESTATE_ACCESS_BANNED_AGENTS | ESTATE_ACCESS_BANNED_AGENTS
| ESTATE_ACCESS_MANAGERS; | ESTATE_ACCESS_MANAGERS;
// for EstateOwnerRequest, estateaccessdelta message // for EstateOwnerRequest, estateaccessdelta, estateexperiencedelta messages
const U32 ESTATE_ACCESS_APPLY_TO_ALL_ESTATES = 1 << 0; const U32 ESTATE_ACCESS_APPLY_TO_ALL_ESTATES = 1U << 0;
const U32 ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES = 1 << 1; const U32 ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES = 1U << 1;
const U32 ESTATE_ACCESS_ALLOWED_AGENT_ADD = 1 << 2; const U32 ESTATE_ACCESS_ALLOWED_AGENT_ADD = 1U << 2;
const U32 ESTATE_ACCESS_ALLOWED_AGENT_REMOVE = 1 << 3; const U32 ESTATE_ACCESS_ALLOWED_AGENT_REMOVE = 1U << 3;
const U32 ESTATE_ACCESS_ALLOWED_GROUP_ADD = 1 << 4; const U32 ESTATE_ACCESS_ALLOWED_GROUP_ADD = 1U << 4;
const U32 ESTATE_ACCESS_ALLOWED_GROUP_REMOVE = 1 << 5; const U32 ESTATE_ACCESS_ALLOWED_GROUP_REMOVE = 1U << 5;
const U32 ESTATE_ACCESS_BANNED_AGENT_ADD = 1 << 6; const U32 ESTATE_ACCESS_BANNED_AGENT_ADD = 1U << 6;
const U32 ESTATE_ACCESS_BANNED_AGENT_REMOVE = 1 << 7; const U32 ESTATE_ACCESS_BANNED_AGENT_REMOVE = 1U << 7;
const U32 ESTATE_ACCESS_MANAGER_ADD = 1 << 8; const U32 ESTATE_ACCESS_MANAGER_ADD = 1U << 8;
const U32 ESTATE_ACCESS_MANAGER_REMOVE = 1 << 9; const U32 ESTATE_ACCESS_MANAGER_REMOVE = 1U << 9;
const U32 ESTATE_ACCESS_NO_REPLY = 1 << 10; const U32 ESTATE_ACCESS_NO_REPLY = 1U << 10;
const U32 ESTATE_ACCESS_FAILED_BAN_ESTATE_MANAGER = 1U << 11;
const S32 ESTATE_MAX_MANAGERS = 15; const S32 ESTATE_MAX_MANAGERS = 15;
const S32 ESTATE_MAX_ACCESS_IDS = 500; // max for access, banned const S32 ESTATE_MAX_ACCESS_IDS = 500; // max for access, banned
@@ -191,6 +192,26 @@ const U32 SWD_OTHERS_LAND_ONLY = (1 << 0);
const U32 SWD_ALWAYS_RETURN_OBJECTS = (1 << 1); const U32 SWD_ALWAYS_RETURN_OBJECTS = (1 << 1);
const U32 SWD_SCRIPTED_ONLY = (1 << 2); const U32 SWD_SCRIPTED_ONLY = (1 << 2);
// Controls experience key validity in the estate
const U32 EXPERIENCE_KEY_TYPE_NONE = 0;
const U32 EXPERIENCE_KEY_TYPE_BLOCKED = 1;
const U32 EXPERIENCE_KEY_TYPE_ALLOWED = 2;
const U32 EXPERIENCE_KEY_TYPE_TRUSTED = 3;
const U32 EXPERIENCE_KEY_TYPE_FIRST = EXPERIENCE_KEY_TYPE_BLOCKED;
const U32 EXPERIENCE_KEY_TYPE_LAST = EXPERIENCE_KEY_TYPE_TRUSTED;
//
const U32 ESTATE_EXPERIENCE_TRUSTED_ADD = 1U << 2;
const U32 ESTATE_EXPERIENCE_TRUSTED_REMOVE = 1U << 3;
const U32 ESTATE_EXPERIENCE_ALLOWED_ADD = 1U << 4;
const U32 ESTATE_EXPERIENCE_ALLOWED_REMOVE = 1U << 5;
const U32 ESTATE_EXPERIENCE_BLOCKED_ADD = 1U << 6;
const U32 ESTATE_EXPERIENCE_BLOCKED_REMOVE = 1U << 7;
const S32 ESTATE_MAX_EXPERIENCE_IDS = 8;
#endif #endif

View File

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

View File

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

View File

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

View File

@@ -1393,6 +1393,8 @@ char const* const _PREHASH_AppearanceVersion = LLMessageStringTable::getInstance
char const* const _PREHASH_CofVersion = LLMessageStringTable::getInstance()->getString("CofVersion"); char const* const _PREHASH_CofVersion = LLMessageStringTable::getInstance()->getString("CofVersion");
char const* const _PREHASH_AppearanceHover = LLMessageStringTable::getInstance()->getString("AppearanceHover"); char const* const _PREHASH_AppearanceHover = LLMessageStringTable::getInstance()->getString("AppearanceHover");
char const* const _PREHASH_HoverHeight = LLMessageStringTable::getInstance()->getString("HoverHeight"); char const* const _PREHASH_HoverHeight = LLMessageStringTable::getInstance()->getString("HoverHeight");
char const* const _PREHASH_Experience = LLMessageStringTable::getInstance()->getString("Experience");
char const* const _PREHASH_ExperienceID = LLMessageStringTable::getInstance()->getString("ExperienceID");
// <FS:CR> Aurora Sim // <FS:CR> Aurora Sim
char const* const _PREHASH_RegionSizeX = LLMessageStringTable::getInstance()->getString("RegionSizeX"); char const* const _PREHASH_RegionSizeX = LLMessageStringTable::getInstance()->getString("RegionSizeX");

View File

@@ -1393,6 +1393,8 @@ extern char const* const _PREHASH_AppearanceVersion;
extern char const* const _PREHASH_CofVersion; extern char const* const _PREHASH_CofVersion;
extern char const* const _PREHASH_AppearanceHover; extern char const* const _PREHASH_AppearanceHover;
extern char const* const _PREHASH_HoverHeight; extern char const* const _PREHASH_HoverHeight;
extern char const* const _PREHASH_Experience;
extern char const* const _PREHASH_ExperienceID;
// <FS:CR> Aurora Sim // <FS:CR> Aurora Sim
extern char const* const _PREHASH_RegionSizeX; extern char const* const _PREHASH_RegionSizeX;

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<>()
{
}
*/
}

View File

@@ -19,7 +19,7 @@ include_directories(
set(llplugin_SOURCE_FILES set(llplugin_SOURCE_FILES
llpluginclassbasic.cpp llpluginclassbasic.cpp
llpluginclassmedia.cpp llpluginclassmedia.cpp
llplugincookiestore.cpp #llplugincookiestore.cpp
llplugininstance.cpp llplugininstance.cpp
llpluginmessage.cpp llpluginmessage.cpp
llpluginmessagepipe.cpp llpluginmessagepipe.cpp
@@ -34,7 +34,7 @@ set(llplugin_HEADER_FILES
llpluginclassbasic.h llpluginclassbasic.h
llpluginclassmedia.h llpluginclassmedia.h
llpluginclassmediaowner.h llpluginclassmediaowner.h
llplugincookiestore.h #llplugincookiestore.h
llplugininstance.h llplugininstance.h
llpluginmessage.h llpluginmessage.h
llpluginmessageclasses.h llpluginmessageclasses.h

View File

@@ -623,12 +623,14 @@ bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifie
return result; return result;
} }
void LLPluginClassMedia::scrollEvent(int x, int y, MASK modifiers) void LLPluginClassMedia::scrollEvent(int x, int y, int clicks_x, int clicks_y, MASK modifiers)
{ {
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "scroll_event"); LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "scroll_event");
message.setValueS32("x", x); message.setValueS32("x", x);
message.setValueS32("y", y); message.setValueS32("y", y);
message.setValueS32("clicks_x", clicks_x);
message.setValueS32("clicks_y", clicks_y);
message.setValue("modifiers", translateModifiers(modifiers)); message.setValue("modifiers", translateModifiers(modifiers));
sendMessage(message); sendMessage(message);
@@ -711,9 +713,9 @@ void LLPluginClassMedia::sendPickFileResponse(const std::vector<std::string> fil
} }
LLSD file_list = LLSD::emptyArray(); LLSD file_list = LLSD::emptyArray();
for (std::vector<std::string>::const_iterator in_iter = files.begin(); in_iter != files.end(); ++in_iter) for (const auto& file : files)
{ {
file_list.append(LLSD::String(*in_iter)); file_list.append(LLSD::String(file));
} }
message.setValueLLSD("file_list", file_list); message.setValueLLSD("file_list", file_list);

View File

@@ -75,7 +75,7 @@ public:
void setAutoScale(bool auto_scale); void setAutoScale(bool auto_scale);
void setZoomFactor(F64 zoom_factor) { mZoomFactor = zoom_factor; } void setZoomFactor(F64 zoom_factor) { mZoomFactor = zoom_factor; }
void setBackgroundColor(LLColor4 color) { mBackgroundColor = color; }; void setBackgroundColor(const LLColor4& color) { mBackgroundColor = color; };
void setOwner(LLPluginClassMediaOwner *owner) { mOwner = owner; }; void setOwner(LLPluginClassMediaOwner *owner) { mOwner = owner; };
@@ -107,7 +107,7 @@ public:
bool keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data); bool keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data);
void scrollEvent(int x, int y, MASK modifiers); void scrollEvent(int x, int y, int clicks_x, int clicks_y, MASK modifiers);
// enable/disable media plugin debugging messages and info spam // enable/disable media plugin debugging messages and info spam
void enableMediaPluginDebugging( bool enable ); void enableMediaPluginDebugging( bool enable );

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -99,7 +99,7 @@ public:
S32 mLod; S32 mLod;
LLMatrix4 mTransform; LLMatrix4 mTransform, mBindTransform;
BOOL mFirstTransform; BOOL mFirstTransform;
LLVector3 mExtents[2]; LLVector3 mExtents[2];
@@ -180,7 +180,7 @@ public:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// isNodeAJoint() // isNodeAJoint()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool isNodeAJoint(const char* name) bool isNodeAJoint(const char* name) const
{ {
return name != NULL && mJointMap.find(name) != mJointMap.end(); 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 (mNewContext.lineWidth != line_width || mDirty)
{ {
if (mMode == LLRender::LINES || LLRender::LINE_STRIP) if (mMode == LLRender::LINES || mMode == LLRender::LINE_STRIP)
{ {
flush(); flush();
} }
@@ -2483,16 +2483,17 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count)
mTexcoordsp[mCount] = mTexcoordsp[mCount - 1]; mTexcoordsp[mCount] = mTexcoordsp[mCount - 1];
} }
mVerticesp.copyArray(mCount, verts, vert_count);
for (S32 i = 0; i < vert_count; i++) for (S32 i = 0; i < vert_count; i++)
{ {
mVerticesp[mCount] = verts[i];
mCount++; mCount++;
mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
mColorsp[mCount] = mColorsp[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; mPrimitiveReset = false;
} }
@@ -2520,17 +2521,20 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32
mTexcoordsp[mCount] = mTexcoordsp[mCount - 1]; 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++) for (S32 i = 0; i < vert_count; i++)
{ {
mVerticesp[mCount] = verts[i];
mTexcoordsp[mCount] = uvs[i];
mCount++; mCount++;
mColorsp[mCount] = mColorsp[mCount-1]; mColorsp[mCount] = mColorsp[mCount-1];
} }
mVerticesp[mCount] = mVerticesp[mCount-1]; if (mCount > 0)
mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; {
mVerticesp[mCount] = mVerticesp[mCount - 1];
mTexcoordsp[mCount] = mTexcoordsp[mCount - 1];
}
mPrimitiveReset = false; mPrimitiveReset = false;
} }
@@ -2564,9 +2568,12 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLCo
mColorsp.copyArray(mCount, colors, vert_count); mColorsp.copyArray(mCount, colors, vert_count);
mCount += vert_count; mCount += vert_count;
mVerticesp[mCount] = mVerticesp[mCount-1]; if (mCount > 0)
mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; {
mColorsp[mCount] = mColorsp[mCount-1]; mVerticesp[mCount] = mVerticesp[mCount - 1];
mTexcoordsp[mCount] = mTexcoordsp[mCount - 1];
mColorsp[mCount] = mColorsp[mCount - 1];
}
mPrimitiveReset = false; mPrimitiveReset = false;
} }

View File

@@ -1197,6 +1197,10 @@ void LLVertexBuffer::genBuffer(U32 size)
{ {
mMappedData = sDynamicVBOPool.allocate(mGLBuffer, mSize); mMappedData = sDynamicVBOPool.allocate(mGLBuffer, mSize);
} }
if ((sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB) && !mMappedData)
{
LL_ERRS() << "mMappedData allocation failedd" << LL_ENDL;
}
sGLCount++; sGLCount++;
} }
@@ -1213,6 +1217,10 @@ void LLVertexBuffer::genIndices(U32 size)
{ {
mMappedIndexData = sDynamicIBOPool.allocate(mGLIndices, mIndicesSize); mMappedIndexData = sDynamicIBOPool.allocate(mGLIndices, mIndicesSize);
} }
if ((sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB) && !mMappedIndexData)
{
LL_ERRS() << "mMappedIndexData allocation failedd" << LL_ENDL;
}
sGLCount++; 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; LL_ERRS() << "Attempted to map a specific range of a buffer that was already mapped." << LL_ENDL;
} }
bool was_locked = mIndexLocked;
if (!mIndexLocked) if (!mIndexLocked)
{ {
mIndexLocked = true; 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; 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 else
{ {
LL_ERRS() << "memory allocation for Index data failed. " << LL_ENDL; LL_ERRS() << "memory allocation for Index data failed. " << LL_ENDL;

View File

@@ -37,6 +37,7 @@ set(llui_SOURCE_FILES
lldraghandle.cpp lldraghandle.cpp
lleditmenuhandler.cpp lleditmenuhandler.cpp
llfiltereditor.cpp llfiltereditor.cpp
llflatlistview.cpp
llfloater.cpp llfloater.cpp
llflyoutbutton.cpp llflyoutbutton.cpp
llfocusmgr.cpp llfocusmgr.cpp
@@ -116,6 +117,7 @@ set(llui_HEADER_FILES
lldraghandle.h lldraghandle.h
lleditmenuhandler.h lleditmenuhandler.h
llfiltereditor.h llfiltereditor.h
llflatlistview.h
llfloater.h llfloater.h
llflyoutbutton.h llflyoutbutton.h
llfocusmgr.h llfocusmgr.h

View File

@@ -27,6 +27,7 @@ const std::array<const std::string, LFIDBearer::COUNT> LFIDBearer::sMenuStrings
"menu_avs_list.xml" // 0 "menu_avs_list.xml" // 0
, "menu_groups_list.xml" // 1 , "menu_groups_list.xml" // 1
, "menu_objects_list.xml" // 2 , "menu_objects_list.xml" // 2
, "menu_experiences.xml" // 3
}; };
std::array<LLMenuGL*, LFIDBearer::COUNT> LFIDBearer::sMenus {}; std::array<LLMenuGL*, LFIDBearer::COUNT> LFIDBearer::sMenus {};

View File

@@ -34,6 +34,7 @@ struct LFIDBearer
AVATAR = 0, AVATAR = 0,
GROUP, GROUP,
OBJECT, OBJECT,
EXPERIENCE,
COUNT COUNT
}; };

View File

@@ -446,8 +446,7 @@ void LLComboBox::setLabel(const LLStringExplicit& name)
if (!mAllowTextEntry) if (!mAllowTextEntry)
{ {
mButton->setLabelUnselected(name); mButton->setLabel(name);
mButton->setLabelSelected(name);
} }
} }
@@ -465,9 +464,7 @@ void LLComboBox::updateLabel()
// the combo button label. // the combo button label.
if (!mAllowTextEntry) if (!mAllowTextEntry)
{ {
std::string label = getSelectedItemLabel(); mButton->setLabel(getSelectedItemLabel());
mButton->setLabelUnselected(label);
mButton->setLabelSelected(label);
} }
} }
@@ -513,13 +510,16 @@ void LLComboBox::onFocusLost()
void LLComboBox::setButtonVisible(BOOL visible) void LLComboBox::setButtonVisible(BOOL visible)
{ {
static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0);
mButton->setVisible(visible); mButton->setVisible(visible);
if (mTextEntry) if (mTextEntry)
{ {
LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
if (visible) if (visible)
{ {
text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;
} }
//mTextEntry->setRect(text_entry_rect); //mTextEntry->setRect(text_entry_rect);
mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE); mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE);
@@ -558,18 +558,21 @@ S32 LLComboBox::getCurrentIndex() const
void LLComboBox::updateLayout() void LLComboBox::updateLayout()
{ {
static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0);
LLRect rect = getLocalRect(); LLRect rect = getLocalRect();
if (mAllowTextEntry) if (mAllowTextEntry)
{ {
S32 shadow_size = LLUI::sConfigGroup->getS32("DropShadowButton"); S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
mButton->setRect(LLRect( getRect().getWidth() - llmax(8,mArrowImage->getWidth()) - 2 * shadow_size, S32 shadow_size = drop_shadow_button;
mButton->setRect(LLRect( getRect().getWidth() - llmax(8,arrow_width) - 2 * shadow_size,
rect.mTop, rect.mRight, rect.mBottom)); rect.mTop, rect.mRight, rect.mBottom));
mButton->setTabStop(FALSE); mButton->setTabStop(FALSE);
mButton->setHAlign(LLFontGL::HCENTER);
if (!mTextEntry) if (!mTextEntry)
{ {
LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * shadow_size; text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;
// clear label on button // clear label on button
std::string cur_label = mButton->getLabelSelected(); std::string cur_label = mButton->getLabelSelected();
mTextEntry = new LLLineEditor(std::string("combo_text_entry"), mTextEntry = new LLLineEditor(std::string("combo_text_entry"),
@@ -718,6 +721,7 @@ void LLComboBox::showList()
mList->setVisible(TRUE); mList->setVisible(TRUE);
setUseBoundingRect(TRUE); setUseBoundingRect(TRUE);
// updateBoundingRect();
} }
void LLComboBox::hideList() void LLComboBox::hideList()
@@ -744,6 +748,7 @@ void LLComboBox::hideList()
{ {
gFocusMgr.setTopCtrl(NULL); gFocusMgr.setTopCtrl(NULL);
} }
// updateBoundingRect();
} }
} }
@@ -1029,9 +1034,7 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor)
void LLComboBox::updateSelection() void LLComboBox::updateSelection()
{ {
if(mSuppressAutoComplete) { if(mSuppressAutoComplete) return;
return;
}
LLWString left_wstring = mTextEntry->getWText().substr(0, mTextEntry->getCursor()); LLWString left_wstring = mTextEntry->getWText().substr(0, mTextEntry->getCursor());
// user-entered portion of string, based on assumption that any selected // user-entered portion of string, based on assumption that any selected
@@ -1242,3 +1245,25 @@ BOOL LLComboBox::selectItemRange( S32 first, S32 last )
return mList->selectItemRange(first, last); return mList->selectItemRange(first, last);
} }
/* Singu Note: This isn't very necessary for now, let's not bother.
static LLRegisterWidget<LLIconsComboBox> register_icons_combo_box("icons_combo_box");
LLIconsComboBox::Params::Params()
: icon_column("icon_column", ICON_COLUMN),
label_column("label_column", LABEL_COLUMN)
{}
LLIconsComboBox::LLIconsComboBox(const LLIconsComboBox::Params& p)
: LLComboBox(p),
mIconColumnIndex(p.icon_column),
mLabelColumnIndex(p.label_column)
{}
const std::string LLIconsComboBox::getSelectedItemLabel(S32 column) const
{
mButton->setImageOverlay(LLComboBox::getSelectedItemLabel(mIconColumnIndex), mButton->getImageOverlayHAlign());
return LLComboBox::getSelectedItemLabel(mLabelColumnIndex);
}
*/

File diff suppressed because it is too large Load Diff

540
indra/llui/llflatlistview.h Normal file
View File

@@ -0,0 +1,540 @@
/**
* @file llflatlistview.h
* @brief LLFlatListView base class and extension to support messages for several cases of an empty list.
*
* $LicenseInfo:firstyear=2009&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_LLFLATLISTVIEW_H
#define LL_LLFLATLISTVIEW_H
#include "llpanel.h"
#include "llscrollcontainer.h"
#include "lltextbox.h"
/**
* LLFlatListView represents a flat list ui control that operates on items in a form of LLPanel's.
* LLSD can be associated with each added item, it can keep data from an item in digested form.
* Associated LLSD's can be of any type (singular, a map etc.).
* Items (LLPanel's subclasses) can be of different height.
* The list is LLPanel created in itself and grows in height while new items are added.
*
* The control can manage selection of its items when the flag "allow_select" is set. Also ability to select
* multiple items (by using CTRL) is enabled through setting the flag "multi_select" - if selection is not allowed that flag
* is ignored. The option "keep_one_selected" forces at least one item to be selected at any time (only for mouse events on items)
* since any item of the list was selected.
*
* Examples of using this control are presented in Picks panel (My Profile and Profile View), where this control is used to
* manage the list of pick items.
*
* ASSUMPTIONS AND STUFF
* - NULL pointers and undefined LLSD's are not accepted by any method of this class unless specified otherwise
* - Order of returned selected items are not guaranteed
* - The control assumes that all items being added are unique.
*/
class LLFlatListView : public LLScrollContainer, public LLEditMenuHandler
{
LOG_CLASS(LLFlatListView);
public:
/**
* Abstract comparator for comparing flat list items in a form of LLPanel
*/
class ItemComparator
{
public:
ItemComparator() {};
virtual ~ItemComparator() {};
/** Returns true if item1 < item2, false otherwise */
virtual bool compare(const LLPanel* item1, const LLPanel* item2) const = 0;
};
/**
* Represents reverse comparator which acts as a decorator for a comparator that need to be reversed
*/
class ItemReverseComparator : public ItemComparator
{
public:
ItemReverseComparator(const ItemComparator& comparator) : mComparator(comparator) {};
virtual ~ItemReverseComparator() {};
bool compare(const LLPanel* item1, const LLPanel* item2) const override
{
return mComparator.compare(item2, item1);
}
private:
const ItemComparator& mComparator;
};
struct Params : public LLInitParam::Block<Params, LLScrollContainer::Params>
{
/** turning on/off selection support */
Optional<bool> allow_select;
/** turning on/off multiple selection (works while clicking and holding CTRL)*/
Optional<bool> multi_select;
/** don't allow to deselect all selected items (for mouse events on items only) */
Optional<bool> keep_one_selected;
/** try to keep selection visible after reshape */
Optional<bool> keep_selection_visible_on_reshape;
/** padding between items */
Optional<U32> item_pad;
/** textbox with info message when list is empty*/
Optional<LLTextBox::Params> no_items_text;
Params();
};
// disable traversal when finding widget to hand focus off to
/*virtual*/ BOOL canFocusChildren() const override { return FALSE; }
/**
* Connects callback to signal called when Return key is pressed.
*/
boost::signals2::connection setReturnCallback( const commit_signal_t::slot_type& cb ) { return mOnReturnSignal.connect(cb); }
/** Overridden LLPanel's reshape, height is ignored, the list sets its height to accommodate all items */
void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
/** Returns full rect of child panel */
const LLRect& getItemsRect() const;
LLRect getRequiredRect() override { return getItemsRect(); }
/** Returns distance between items */
const S32 getItemsPad() const { return mItemPad; }
/**
* Adds and item and LLSD value associated with it to the list at specified position
* @return true if the item was added, false otherwise
*/
virtual bool addItem(LLPanel * item, const LLSD& value = LLUUID::null, EAddPosition pos = ADD_BOTTOM, bool rearrange = true);
/**
* Insert item_to_add along with associated value to the list right after the after_item.
* @return true if the item was successfully added, false otherwise
*/
virtual bool insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, const LLSD& value = LLUUID::null);
/**
* Remove specified item
* @return true if the item was removed, false otherwise
*/
virtual bool removeItem(LLPanel* item, bool rearrange = true);
/**
* Remove an item specified by value
* @return true if the item was removed, false otherwise
*/
virtual bool removeItemByValue(const LLSD& value, bool rearrange = true);
/**
* Remove an item specified by uuid
* @return true if the item was removed, false otherwise
*/
virtual bool removeItemByUUID(const LLUUID& uuid, bool rearrange = true);
/**
* Get an item by value
* @return the item as LLPanel if associated with value, NULL otherwise
*/
virtual LLPanel* getItemByValue(const LLSD& value) const;
/**
* Check for item by value in list
* @return bool whether item exists by value or not
*/
virtual bool valueExists(const LLSD& value) const;
template<class T>
T* getTypedItemByValue(const LLSD& value) const
{
return dynamic_cast<T*>(getItemByValue(value));
}
/**
* Select or deselect specified item based on select
* @return true if succeed, false otherwise
*/
virtual bool selectItem(LLPanel* item, bool select = true);
/**
* Select or deselect an item by associated value based on select
* @return true if succeed, false otherwise
*/
virtual bool selectItemByValue(const LLSD& value, bool select = true);
/**
* Select or deselect an item by associated uuid based on select
* @return true if succeed, false otherwise
*/
virtual bool selectItemByUUID(const LLUUID& uuid, bool select = true);
/**
* Get all panels stored in the list.
*/
virtual void getItems(std::vector<LLPanel*>& items) const;
/**
* Get all items values.
*/
virtual void getValues(std::vector<LLSD>& values) const;
/**
* Get LLSD associated with the first selected item
*/
virtual LLSD getSelectedValue() const;
/**
* Get LLSD's associated with selected items.
* @param selected_values std::vector being populated with LLSD associated with selected items
*/
virtual void getSelectedValues(std::vector<LLSD>& selected_values) const;
/**
* Get LLUUID associated with selected item
* @return LLUUID if such was associated with selected item
*/
virtual LLUUID getSelectedUUID() const;
/**
* Get LLUUIDs associated with selected items
* @param selected_uuids An std::vector being populated with LLUUIDs associated with selected items
*/
virtual void getSelectedUUIDs(uuid_vec_t& selected_uuids) const;
/** Get the top selected item */
virtual LLPanel* getSelectedItem() const;
/**
* Get selected items
* @param selected_items An std::vector being populated with pointers to selected items
*/
virtual void getSelectedItems(std::vector<LLPanel*>& selected_items) const;
/**
* Resets selection of items.
*
* It calls onCommit callback if setCommitOnSelectionChange(bool b) was called with "true"
* argument for current Flat List.
* @param no_commit_on_deselection - if true onCommit callback will not be called
*/
virtual void resetSelection(bool no_commit_on_deselection = false);
/**
* Sets comment text which will be shown in the list is it is empty.
*
* Textbox to hold passed text is created while this method is called at the first time.
*
* @param comment_text - string to be shown as a comment.
*/
void setNoItemsCommentText( const std::string& comment_text);
/** Turn on/off multiple selection support */
void setAllowMultipleSelection(bool allow) { mMultipleSelection = allow; }
/** Turn on/off selection support */
void setAllowSelection(bool can_select) { mAllowSelection = can_select; }
/** Sets flag whether onCommit should be fired if selection was changed */
// FIXME: this should really be a separate signal, since "Commit" implies explicit user action, and selection changes can happen more indirectly.
void setCommitOnSelectionChange(bool b) { mCommitOnSelectionChange = b; }
/** Get number of selected items in the list */
U32 numSelected() const {return mSelectedItemPairs.size(); }
/** Get number of (visible) items in the list */
U32 size(const bool only_visible_items = true) const;
/** Removes all items from the list */
void clear() override;
/**
* Removes all items that can be detached from the list but doesn't destroy
* them, caller responsible to manage items after they are detached.
* Detachable item should accept "detach" action via notify() method,
* where it disconnect all callbacks, does other valuable routines and
* return 1.
*/
void detachItems(std::vector<LLPanel*>& detached_items);
/**
* Set comparator to use for future sorts.
*
* This class does NOT manage lifetime of the comparator
* but assumes that the comparator is always alive.
*/
void setComparator(const ItemComparator* comp) { mItemComparator = comp; }
void sort();
bool updateValue(const LLSD& old_value, const LLSD& new_value);
void scrollToShowFirstSelectedItem();
void selectFirstItem ();
void selectLastItem ();
S32 notify(const LLSD& info) override;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); // <singu> Old-style
virtual ~LLFlatListView();
protected:
/** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */
typedef std::pair<LLPanel*, LLSD> item_pair_t;
typedef std::list<item_pair_t*> pairs_list_t;
typedef pairs_list_t::iterator pairs_iterator_t;
typedef pairs_list_t::const_iterator pairs_const_iterator_t;
/** An adapter for a ItemComparator */
struct ComparatorAdaptor
{
ComparatorAdaptor(const ItemComparator& comparator) : mComparator(comparator) {};
bool operator()(const item_pair_t* item_pair1, const item_pair_t* item_pair2) const
{
return mComparator.compare(item_pair1->first, item_pair2->first);
}
const ItemComparator& mComparator;
};
friend class LLUICtrlFactory;
LLFlatListView(const std::string& name, const LLRect& rect, bool opaque, const LLColor4& color, const S32& item_pad, bool allow_select, bool multi_select, bool keep_one_selected, bool keep_selection_visible_on_reshape, const std::string& no_items_text);
/** Manage selection on mouse events */
void onItemMouseClick(item_pair_t* item_pair, MASK mask);
void onItemRightMouseClick(item_pair_t* item_pair, MASK mask);
/**
* Updates position of items.
* It does not take into account invisible items.
*/
virtual void rearrangeItems();
virtual item_pair_t* getItemPair(LLPanel* item) const;
virtual item_pair_t* getItemPair(const LLSD& value) const;
virtual bool selectItemPair(item_pair_t* item_pair, bool select);
virtual bool selectNextItemPair(bool is_up_direction, bool reset_selection);
BOOL canSelectAll() const override;
void selectAll() override;
virtual bool isSelected(item_pair_t* item_pair) const;
virtual bool removeItemPair(item_pair_t* item_pair, bool rearrange);
bool addItemPairs(pairs_list_t panel_list, bool rearrange = true);
/**
* Notify parent about changed size of internal controls with "size_changes" action
*
* Size includes Items Rect width and either Items Rect height or comment text height.
* Comment text height is included if comment text is set and visible.
* List border size is also included into notified size.
*/
void notifyParentItemsRectChanged();
BOOL handleKeyHere(KEY key, MASK mask) override;
BOOL postBuild() override;
void onFocusReceived() override;
void onFocusLost() override;
void draw() override;
LLRect getLastSelectedItemRect();
void ensureSelectedVisible();
private:
void setItemsNoScrollWidth(S32 new_width) {mItemsNoScrollWidth = new_width - 2 * mBorderThickness;}
void setNoItemsCommentVisible(bool visible) const;
protected:
/** Comparator to use when sorting the list. */
const ItemComparator* mItemComparator;
private:
LLPanel* mItemsPanel;
S32 mItemsNoScrollWidth;
S32 mBorderThickness;
/** Items padding */
S32 mItemPad;
/** Selection support flag */
bool mAllowSelection;
/** Multiselection support flag, ignored if selection is not supported */
bool mMultipleSelection;
/**
* Flag specified whether onCommit be called if selection is changed in the list.
*
* Can be ignored in the resetSelection() method.
* @see resetSelection()
*/
bool mCommitOnSelectionChange;
bool mKeepOneItemSelected;
bool mIsConsecutiveSelection;
bool mKeepSelectionVisibleOnReshape;
/** All pairs of the list */
pairs_list_t mItemPairs;
/** Selected pairs for faster access */
pairs_list_t mSelectedItemPairs;
/**
* Rectangle contained previous size of items parent notified last time.
* Is used to reduce amount of parentNotify() calls if size was not changed.
*/
LLRect mPrevNotifyParentRect;
LLTextBox* mNoItemsCommentTextbox;
LLViewBorder* mSelectedItemsBorder;
commit_signal_t mOnReturnSignal;
};
/**
* Extends LLFlatListView functionality to show different messages when there are no items in the
* list depend on whether they are filtered or not.
*
* Class provides one message per case of empty list.
* It also provides protected updateNoItemsMessage() method to be called each time when derived list
* is changed to update base mNoItemsCommentTextbox value.
*
* It is implemented to avoid duplication of this functionality in concrete implementations of the
* lists. It is intended to be used as a base class for lists which should support two different
* messages for empty state. Can be improved to support more than two messages via state-to-message map.
*/
class LLFlatListViewEx : public LLFlatListView
{
public:
LOG_CLASS(LLFlatListViewEx);
struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
{
/**
* Contains a message for empty list when it does not contain any items at all.
*/
Optional<std::string> no_items_msg;
/**
* Contains a message for empty list when its items are removed by filtering.
*/
Optional<std::string> no_filtered_items_msg;
Params();
};
// *WORKAROUND: two methods to overload appropriate Params due to localization issue:
// no_items_msg & no_filtered_items_msg attributes are not defined as translatable in VLT. See EXT-5931
void setNoItemsMsg(const std::string& msg) { mNoItemsMsg = msg; }
void setNoFilteredItemsMsg(const std::string& msg) { mNoFilteredItemsMsg = msg; }
bool getForceShowingUnmatchedItems();
void setForceShowingUnmatchedItems(bool show);
/**
* Sets up new filter string and filters the list.
*/
void setFilterSubString(const std::string& filter_str);
std::string getFilterSubString() const { return mFilterSubString; }
/**
* Filters the list, rearranges and notifies parent about shape changes.
* Derived classes may want to overload rearrangeItems() to exclude repeated separators after filtration.
*/
void filterItems();
/**
* Returns true if last call of filterItems() found at least one matching item
*/
bool hasMatchedItems();
protected:
LLFlatListViewEx(const Params& p);
/**
* Applies a message for empty list depend on passed argument.
*
* @param filter_string - if is not empty, message for filtered items will be set, otherwise for
* completely empty list. Value of filter string will be passed as search_term in SLURL.
*/
void updateNoItemsMessage(const std::string& filter_string);
/**
* Applies visibility acording to action and LLFlatListView settings.
*
* @param item - item we are changing
* @param item - action - parameters to determin visibility from
*/
void updateItemVisibility(LLPanel* item, const LLSD &action);
private:
std::string mNoFilteredItemsMsg;
std::string mNoItemsMsg;
std::string mFilterSubString;
/**
* Show list items that don't match current filter
*/
bool mForceShowingUnmatchedItems;
/**
* True if last call of filterItems() found at least one matching item
*/
bool mHasMatchedItems;
};
#endif

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