/indra/llprimitive/llmediaentry.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 596 lines · 443 code · 64 blank · 89 comment · 101 complexity · bd7cbfdb06edb77da17383ac0513fa20 MD5 · raw file

  1. /**
  2. * @file llmediaentry.cpp
  3. * @brief This is a single instance of media data related to the face of a prim
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "linden_common.h"
  27. #include "llmediaentry.h"
  28. #include "lllslconstants.h"
  29. #include <boost/regex.hpp>
  30. // LLSD key defines
  31. // DO NOT REORDER OR REMOVE THESE!
  32. // Some LLSD keys. Do not change!
  33. #define MEDIA_ALT_IMAGE_ENABLE_KEY_STR "alt_image_enable"
  34. #define MEDIA_CONTROLS_KEY_STR "controls"
  35. #define MEDIA_CURRENT_URL_KEY_STR "current_url"
  36. #define MEDIA_HOME_URL_KEY_STR "home_url"
  37. #define MEDIA_AUTO_LOOP_KEY_STR "auto_loop"
  38. #define MEDIA_AUTO_PLAY_KEY_STR "auto_play"
  39. #define MEDIA_AUTO_SCALE_KEY_STR "auto_scale"
  40. #define MEDIA_AUTO_ZOOM_KEY_STR "auto_zoom"
  41. #define MEDIA_FIRST_CLICK_INTERACT_KEY_STR "first_click_interact"
  42. #define MEDIA_WIDTH_PIXELS_KEY_STR "width_pixels"
  43. #define MEDIA_HEIGHT_PIXELS_KEY_STR "height_pixels"
  44. // "security" fields
  45. #define MEDIA_WHITELIST_ENABLE_KEY_STR "whitelist_enable"
  46. #define MEDIA_WHITELIST_KEY_STR "whitelist"
  47. // "permissions" fields
  48. #define MEDIA_PERMS_INTERACT_KEY_STR "perms_interact"
  49. #define MEDIA_PERMS_CONTROL_KEY_STR "perms_control"
  50. // "general" fields
  51. const char* LLMediaEntry::ALT_IMAGE_ENABLE_KEY = MEDIA_ALT_IMAGE_ENABLE_KEY_STR;
  52. const char* LLMediaEntry::CONTROLS_KEY = MEDIA_CONTROLS_KEY_STR;
  53. const char* LLMediaEntry::CURRENT_URL_KEY = MEDIA_CURRENT_URL_KEY_STR;
  54. const char* LLMediaEntry::HOME_URL_KEY = MEDIA_HOME_URL_KEY_STR;
  55. const char* LLMediaEntry::AUTO_LOOP_KEY = MEDIA_AUTO_LOOP_KEY_STR;
  56. const char* LLMediaEntry::AUTO_PLAY_KEY = MEDIA_AUTO_PLAY_KEY_STR;
  57. const char* LLMediaEntry::AUTO_SCALE_KEY = MEDIA_AUTO_SCALE_KEY_STR;
  58. const char* LLMediaEntry::AUTO_ZOOM_KEY = MEDIA_AUTO_ZOOM_KEY_STR;
  59. const char* LLMediaEntry::FIRST_CLICK_INTERACT_KEY = MEDIA_FIRST_CLICK_INTERACT_KEY_STR;
  60. const char* LLMediaEntry::WIDTH_PIXELS_KEY = MEDIA_WIDTH_PIXELS_KEY_STR;
  61. const char* LLMediaEntry::HEIGHT_PIXELS_KEY = MEDIA_HEIGHT_PIXELS_KEY_STR;
  62. // "security" fields
  63. const char* LLMediaEntry::WHITELIST_ENABLE_KEY = MEDIA_WHITELIST_ENABLE_KEY_STR;
  64. const char* LLMediaEntry::WHITELIST_KEY = MEDIA_WHITELIST_KEY_STR;
  65. // "permissions" fields
  66. const char* LLMediaEntry::PERMS_INTERACT_KEY = MEDIA_PERMS_INTERACT_KEY_STR;
  67. const char* LLMediaEntry::PERMS_CONTROL_KEY = MEDIA_PERMS_CONTROL_KEY_STR;
  68. #define DEFAULT_URL_PREFIX "http://"
  69. // Constructor(s)
  70. LLMediaEntry::LLMediaEntry() :
  71. mAltImageEnable(false),
  72. mControls(STANDARD),
  73. mCurrentURL(""),
  74. mHomeURL(""),
  75. mAutoLoop(false),
  76. mAutoPlay(false),
  77. mAutoScale(false),
  78. mAutoZoom(false),
  79. mFirstClickInteract(false),
  80. mWidthPixels(0),
  81. mHeightPixels(0),
  82. mWhiteListEnable(false),
  83. // mWhiteList
  84. mPermsInteract(PERM_ALL),
  85. mPermsControl(PERM_ALL),
  86. mMediaIDp(NULL)
  87. {
  88. }
  89. LLMediaEntry::LLMediaEntry(const LLMediaEntry &rhs) :
  90. mMediaIDp(NULL)
  91. {
  92. // "general" fields
  93. mAltImageEnable = rhs.mAltImageEnable;
  94. mControls = rhs.mControls;
  95. mCurrentURL = rhs.mCurrentURL;
  96. mHomeURL = rhs.mHomeURL;
  97. mAutoLoop = rhs.mAutoLoop;
  98. mAutoPlay = rhs.mAutoPlay;
  99. mAutoScale = rhs.mAutoScale;
  100. mAutoZoom = rhs.mAutoZoom;
  101. mFirstClickInteract = rhs.mFirstClickInteract;
  102. mWidthPixels = rhs.mWidthPixels;
  103. mHeightPixels = rhs.mHeightPixels;
  104. // "security" fields
  105. mWhiteListEnable = rhs.mWhiteListEnable;
  106. mWhiteList = rhs.mWhiteList;
  107. // "permissions" fields
  108. mPermsInteract = rhs.mPermsInteract;
  109. mPermsControl = rhs.mPermsControl;
  110. }
  111. LLMediaEntry::~LLMediaEntry()
  112. {
  113. if (NULL != mMediaIDp)
  114. {
  115. delete mMediaIDp;
  116. }
  117. }
  118. LLSD LLMediaEntry::asLLSD() const
  119. {
  120. LLSD sd;
  121. asLLSD(sd);
  122. return sd;
  123. }
  124. //
  125. // LLSD functions
  126. //
  127. void LLMediaEntry::asLLSD(LLSD& sd) const
  128. {
  129. // "general" fields
  130. sd[ALT_IMAGE_ENABLE_KEY] = mAltImageEnable;
  131. sd[CONTROLS_KEY] = (LLSD::Integer)mControls;
  132. sd[CURRENT_URL_KEY] = mCurrentURL;
  133. sd[HOME_URL_KEY] = mHomeURL;
  134. sd[AUTO_LOOP_KEY] = mAutoLoop;
  135. sd[AUTO_PLAY_KEY] = mAutoPlay;
  136. sd[AUTO_SCALE_KEY] = mAutoScale;
  137. sd[AUTO_ZOOM_KEY] = mAutoZoom;
  138. sd[FIRST_CLICK_INTERACT_KEY] = mFirstClickInteract;
  139. sd[WIDTH_PIXELS_KEY] = mWidthPixels;
  140. sd[HEIGHT_PIXELS_KEY] = mHeightPixels;
  141. // "security" fields
  142. sd[WHITELIST_ENABLE_KEY] = mWhiteListEnable;
  143. sd.erase(WHITELIST_KEY);
  144. for (U32 i=0; i<mWhiteList.size(); i++)
  145. {
  146. sd[WHITELIST_KEY].append(mWhiteList[i]);
  147. }
  148. // "permissions" fields
  149. sd[PERMS_INTERACT_KEY] = mPermsInteract;
  150. sd[PERMS_CONTROL_KEY] = mPermsControl;
  151. }
  152. // static
  153. bool LLMediaEntry::checkLLSD(const LLSD& sd)
  154. {
  155. if (sd.isUndefined()) return true;
  156. LLMediaEntry temp;
  157. return temp.fromLLSDInternal(sd, true);
  158. }
  159. void LLMediaEntry::fromLLSD(const LLSD& sd)
  160. {
  161. (void)fromLLSDInternal(sd, true);
  162. }
  163. void LLMediaEntry::mergeFromLLSD(const LLSD& sd)
  164. {
  165. (void)fromLLSDInternal(sd, false);
  166. }
  167. // *NOTE: returns true if NO failures to set occurred, false otherwise.
  168. // However, be aware that if a failure to set does occur, it does
  169. // not stop setting fields from the LLSD!
  170. bool LLMediaEntry::fromLLSDInternal(const LLSD& sd, bool overwrite)
  171. {
  172. // *HACK: we sort of cheat here and assume that status is a
  173. // bit field. We "or" into status and instead of returning
  174. // it, we return whether it finishes off as LSL_STATUS_OK or not.
  175. U32 status = LSL_STATUS_OK;
  176. // "general" fields
  177. if ( overwrite || sd.has(ALT_IMAGE_ENABLE_KEY) )
  178. {
  179. status |= setAltImageEnable( sd[ALT_IMAGE_ENABLE_KEY] );
  180. }
  181. if ( overwrite || sd.has(CONTROLS_KEY) )
  182. {
  183. status |= setControls( (MediaControls)(LLSD::Integer)sd[CONTROLS_KEY] );
  184. }
  185. if ( overwrite || sd.has(CURRENT_URL_KEY) )
  186. {
  187. // Don't check whitelist
  188. status |= setCurrentURLInternal( sd[CURRENT_URL_KEY], false );
  189. }
  190. if ( overwrite || sd.has(HOME_URL_KEY) )
  191. {
  192. status |= setHomeURL( sd[HOME_URL_KEY] );
  193. }
  194. if ( overwrite || sd.has(AUTO_LOOP_KEY) )
  195. {
  196. status |= setAutoLoop( sd[AUTO_LOOP_KEY] );
  197. }
  198. if ( overwrite || sd.has(AUTO_PLAY_KEY) )
  199. {
  200. status |= setAutoPlay( sd[AUTO_PLAY_KEY] );
  201. }
  202. if ( overwrite || sd.has(AUTO_SCALE_KEY) )
  203. {
  204. status |= setAutoScale( sd[AUTO_SCALE_KEY] );
  205. }
  206. if ( overwrite || sd.has(AUTO_ZOOM_KEY) )
  207. {
  208. status |= setAutoZoom( sd[AUTO_ZOOM_KEY] );
  209. }
  210. if ( overwrite || sd.has(FIRST_CLICK_INTERACT_KEY) )
  211. {
  212. status |= setFirstClickInteract( sd[FIRST_CLICK_INTERACT_KEY] );
  213. }
  214. if ( overwrite || sd.has(WIDTH_PIXELS_KEY) )
  215. {
  216. status |= setWidthPixels( (LLSD::Integer)sd[WIDTH_PIXELS_KEY] );
  217. }
  218. if ( overwrite || sd.has(HEIGHT_PIXELS_KEY) )
  219. {
  220. status |= setHeightPixels( (LLSD::Integer)sd[HEIGHT_PIXELS_KEY] );
  221. }
  222. // "security" fields
  223. if ( overwrite || sd.has(WHITELIST_ENABLE_KEY) )
  224. {
  225. status |= setWhiteListEnable( sd[WHITELIST_ENABLE_KEY] );
  226. }
  227. if ( overwrite || sd.has(WHITELIST_KEY) )
  228. {
  229. status |= setWhiteList( sd[WHITELIST_KEY] );
  230. }
  231. // "permissions" fields
  232. if ( overwrite || sd.has(PERMS_INTERACT_KEY) )
  233. {
  234. status |= setPermsInteract( 0xff & (LLSD::Integer)sd[PERMS_INTERACT_KEY] );
  235. }
  236. if ( overwrite || sd.has(PERMS_CONTROL_KEY) )
  237. {
  238. status |= setPermsControl( 0xff & (LLSD::Integer)sd[PERMS_CONTROL_KEY] );
  239. }
  240. return LSL_STATUS_OK == status;
  241. }
  242. LLMediaEntry& LLMediaEntry::operator=(const LLMediaEntry &rhs)
  243. {
  244. if (this != &rhs)
  245. {
  246. // "general" fields
  247. mAltImageEnable = rhs.mAltImageEnable;
  248. mControls = rhs.mControls;
  249. mCurrentURL = rhs.mCurrentURL;
  250. mHomeURL = rhs.mHomeURL;
  251. mAutoLoop = rhs.mAutoLoop;
  252. mAutoPlay = rhs.mAutoPlay;
  253. mAutoScale = rhs.mAutoScale;
  254. mAutoZoom = rhs.mAutoZoom;
  255. mFirstClickInteract = rhs.mFirstClickInteract;
  256. mWidthPixels = rhs.mWidthPixels;
  257. mHeightPixels = rhs.mHeightPixels;
  258. // "security" fields
  259. mWhiteListEnable = rhs.mWhiteListEnable;
  260. mWhiteList = rhs.mWhiteList;
  261. // "permissions" fields
  262. mPermsInteract = rhs.mPermsInteract;
  263. mPermsControl = rhs.mPermsControl;
  264. }
  265. return *this;
  266. }
  267. bool LLMediaEntry::operator==(const LLMediaEntry &rhs) const
  268. {
  269. return (
  270. // "general" fields
  271. mAltImageEnable == rhs.mAltImageEnable &&
  272. mControls == rhs.mControls &&
  273. mCurrentURL == rhs.mCurrentURL &&
  274. mHomeURL == rhs.mHomeURL &&
  275. mAutoLoop == rhs.mAutoLoop &&
  276. mAutoPlay == rhs.mAutoPlay &&
  277. mAutoScale == rhs.mAutoScale &&
  278. mAutoZoom == rhs.mAutoZoom &&
  279. mFirstClickInteract == rhs.mFirstClickInteract &&
  280. mWidthPixels == rhs.mWidthPixels &&
  281. mHeightPixels == rhs.mHeightPixels &&
  282. // "security" fields
  283. mWhiteListEnable == rhs.mWhiteListEnable &&
  284. mWhiteList == rhs.mWhiteList &&
  285. // "permissions" fields
  286. mPermsInteract == rhs.mPermsInteract &&
  287. mPermsControl == rhs.mPermsControl
  288. );
  289. }
  290. bool LLMediaEntry::operator!=(const LLMediaEntry &rhs) const
  291. {
  292. return (
  293. // "general" fields
  294. mAltImageEnable != rhs.mAltImageEnable ||
  295. mControls != rhs.mControls ||
  296. mCurrentURL != rhs.mCurrentURL ||
  297. mHomeURL != rhs.mHomeURL ||
  298. mAutoLoop != rhs.mAutoLoop ||
  299. mAutoPlay != rhs.mAutoPlay ||
  300. mAutoScale != rhs.mAutoScale ||
  301. mAutoZoom != rhs.mAutoZoom ||
  302. mFirstClickInteract != rhs.mFirstClickInteract ||
  303. mWidthPixels != rhs.mWidthPixels ||
  304. mHeightPixels != rhs.mHeightPixels ||
  305. // "security" fields
  306. mWhiteListEnable != rhs.mWhiteListEnable ||
  307. mWhiteList != rhs.mWhiteList ||
  308. // "permissions" fields
  309. mPermsInteract != rhs.mPermsInteract ||
  310. mPermsControl != rhs.mPermsControl
  311. );
  312. }
  313. U32 LLMediaEntry::setWhiteList( const std::vector<std::string> &whitelist )
  314. {
  315. // *NOTE: This code is VERY similar to the setWhitelist below.
  316. // IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER!
  317. U32 size = 0;
  318. U32 count = 0;
  319. // First count to make sure the size constraint is not violated
  320. std::vector<std::string>::const_iterator iter = whitelist.begin();
  321. std::vector<std::string>::const_iterator end = whitelist.end();
  322. for ( ; iter < end; ++iter)
  323. {
  324. const std::string &entry = (*iter);
  325. size += entry.length() + 1; // Include one for \0
  326. count ++;
  327. if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT)
  328. {
  329. return LSL_STATUS_BOUNDS_ERROR;
  330. }
  331. }
  332. // Next clear the vector
  333. mWhiteList.clear();
  334. // Then re-iterate and copy entries
  335. iter = whitelist.begin();
  336. for ( ; iter < end; ++iter)
  337. {
  338. const std::string &entry = (*iter);
  339. mWhiteList.push_back(entry);
  340. }
  341. return LSL_STATUS_OK;
  342. }
  343. U32 LLMediaEntry::setWhiteList( const LLSD &whitelist )
  344. {
  345. // If whitelist is undef, the whitelist is cleared
  346. if (whitelist.isUndefined())
  347. {
  348. mWhiteList.clear();
  349. return LSL_STATUS_OK;
  350. }
  351. // However, if the whitelist is an empty array, erase it.
  352. if (whitelist.isArray())
  353. {
  354. // *NOTE: This code is VERY similar to the setWhitelist above.
  355. // IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER!
  356. U32 size = 0;
  357. U32 count = 0;
  358. // First check to make sure the size and count constraints are not violated
  359. LLSD::array_const_iterator iter = whitelist.beginArray();
  360. LLSD::array_const_iterator end = whitelist.endArray();
  361. for ( ; iter < end; ++iter)
  362. {
  363. const std::string &entry = (*iter).asString();
  364. size += entry.length() + 1; // Include one for \0
  365. count ++;
  366. if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT)
  367. {
  368. return LSL_STATUS_BOUNDS_ERROR;
  369. }
  370. }
  371. // Next clear the vector
  372. mWhiteList.clear();
  373. // Then re-iterate and copy entries
  374. iter = whitelist.beginArray();
  375. for ( ; iter < end; ++iter)
  376. {
  377. const std::string &entry = (*iter).asString();
  378. mWhiteList.push_back(entry);
  379. }
  380. return LSL_STATUS_OK;
  381. }
  382. else
  383. {
  384. return LSL_STATUS_MALFORMED_PARAMS;
  385. }
  386. }
  387. static void prefix_with(std::string &str, const char *chars, const char *prefix)
  388. {
  389. // Given string 'str', prefix all instances of any character in 'chars'
  390. // with 'prefix'
  391. size_t found = str.find_first_of(chars);
  392. size_t prefix_len = strlen(prefix);
  393. while (found != std::string::npos)
  394. {
  395. str.insert(found, prefix, prefix_len);
  396. found = str.find_first_of(chars, found+prefix_len+1);
  397. }
  398. }
  399. static bool pattern_match(const std::string &candidate_str, const std::string &pattern)
  400. {
  401. // If the pattern is empty, it matches
  402. if (pattern.empty()) return true;
  403. // 'pattern' is a glob pattern, we only accept '*' chars
  404. // copy it
  405. std::string expression = pattern;
  406. // Escape perl's regexp chars with a backslash, except all "*" chars
  407. prefix_with(expression, ".[{()\\+?|^$", "\\");
  408. prefix_with(expression, "*", ".");
  409. // case-insensitive matching:
  410. boost::regex regexp(expression, boost::regex::perl|boost::regex::icase);
  411. return boost::regex_match(candidate_str, regexp);
  412. }
  413. bool LLMediaEntry::checkCandidateUrl(const std::string& url) const
  414. {
  415. if (getWhiteListEnable())
  416. {
  417. return checkUrlAgainstWhitelist(url, getWhiteList());
  418. }
  419. else
  420. {
  421. return true;
  422. }
  423. }
  424. // static
  425. bool LLMediaEntry::checkUrlAgainstWhitelist(const std::string& url,
  426. const std::vector<std::string> &whitelist)
  427. {
  428. bool passes = true;
  429. // *NOTE: no entries? Don't check
  430. if (whitelist.size() > 0)
  431. {
  432. passes = false;
  433. // Case insensitive: the reason why we toUpper both this and the
  434. // filter
  435. std::string candidate_url = url;
  436. // Use lluri to see if there is a path part in the candidate URL. No path? Assume "/"
  437. LLURI candidate_uri(candidate_url);
  438. std::vector<std::string>::const_iterator iter = whitelist.begin();
  439. std::vector<std::string>::const_iterator end = whitelist.end();
  440. for ( ; iter < end; ++iter )
  441. {
  442. std::string filter = *iter;
  443. LLURI filter_uri(filter);
  444. bool scheme_passes = pattern_match( candidate_uri.scheme(), filter_uri.scheme() );
  445. if (filter_uri.scheme().empty())
  446. {
  447. filter_uri = LLURI(DEFAULT_URL_PREFIX + filter);
  448. }
  449. bool authority_passes = pattern_match( candidate_uri.authority(), filter_uri.authority() );
  450. bool path_passes = pattern_match( candidate_uri.escapedPath(), filter_uri.escapedPath() );
  451. if (scheme_passes && authority_passes && path_passes)
  452. {
  453. passes = true;
  454. break;
  455. }
  456. }
  457. }
  458. return passes;
  459. }
  460. U32 LLMediaEntry::setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit )
  461. {
  462. if ( value.length() > limit )
  463. {
  464. return LSL_STATUS_BOUNDS_ERROR;
  465. }
  466. else
  467. {
  468. field = value;
  469. return LSL_STATUS_OK;
  470. }
  471. }
  472. U32 LLMediaEntry::setControls(LLMediaEntry::MediaControls controls)
  473. {
  474. if (controls == STANDARD ||
  475. controls == MINI)
  476. {
  477. mControls = controls;
  478. return LSL_STATUS_OK;
  479. }
  480. return LSL_STATUS_BOUNDS_ERROR;
  481. }
  482. U32 LLMediaEntry::setPermsInteract( U8 val )
  483. {
  484. mPermsInteract = val & PERM_MASK;
  485. return LSL_STATUS_OK;
  486. }
  487. U32 LLMediaEntry::setPermsControl( U8 val )
  488. {
  489. mPermsControl = val & PERM_MASK;
  490. return LSL_STATUS_OK;
  491. }
  492. U32 LLMediaEntry::setCurrentURL(const std::string& current_url)
  493. {
  494. return setCurrentURLInternal( current_url, true );
  495. }
  496. U32 LLMediaEntry::setCurrentURLInternal(const std::string& current_url, bool check_whitelist)
  497. {
  498. if ( ! check_whitelist || checkCandidateUrl(current_url))
  499. {
  500. return setStringFieldWithLimit( mCurrentURL, current_url, MAX_URL_LENGTH );
  501. }
  502. else
  503. {
  504. return LSL_STATUS_WHITELIST_FAILED;
  505. }
  506. }
  507. U32 LLMediaEntry::setHomeURL(const std::string& home_url)
  508. {
  509. return setStringFieldWithLimit( mHomeURL, home_url, MAX_URL_LENGTH );
  510. }
  511. U32 LLMediaEntry::setWidthPixels(U16 width)
  512. {
  513. if (width > MAX_WIDTH_PIXELS) return LSL_STATUS_BOUNDS_ERROR;
  514. mWidthPixels = width;
  515. return LSL_STATUS_OK;
  516. }
  517. U32 LLMediaEntry::setHeightPixels(U16 height)
  518. {
  519. if (height > MAX_HEIGHT_PIXELS) return LSL_STATUS_BOUNDS_ERROR;
  520. mHeightPixels = height;
  521. return LSL_STATUS_OK;
  522. }
  523. const LLUUID &LLMediaEntry::getMediaID() const
  524. {
  525. // Lazily generate media ID
  526. if (NULL == mMediaIDp)
  527. {
  528. mMediaIDp = new LLUUID();
  529. mMediaIDp->generate();
  530. }
  531. return *mMediaIDp;
  532. }