diff options
Diffstat (limited to 'indra/llinventory')
| -rw-r--r-- | indra/llinventory/llfoldertype.cpp | 19 | ||||
| -rw-r--r-- | indra/llinventory/llfoldertype.h | 2 | ||||
| -rw-r--r-- | indra/llinventory/llinventory.cpp | 197 | ||||
| -rw-r--r-- | indra/llinventory/llinventory.h | 9 | ||||
| -rw-r--r-- | indra/llinventory/llparcel.h | 105 | ||||
| -rw-r--r-- | indra/llinventory/llpermissions.cpp | 120 | ||||
| -rw-r--r-- | indra/llinventory/llpermissions.h | 3 | ||||
| -rw-r--r-- | indra/llinventory/llsaleinfo.cpp | 9 | ||||
| -rw-r--r-- | indra/llinventory/llsaleinfo.h | 1 | ||||
| -rw-r--r-- | indra/llinventory/llsettingsbase.cpp | 6 | ||||
| -rw-r--r-- | indra/llinventory/llsettingsbase.h | 2 | ||||
| -rw-r--r-- | indra/llinventory/llsettingssky.cpp | 11 | ||||
| -rw-r--r-- | indra/llinventory/tests/inventorymisc_test.cpp | 56 | 
13 files changed, 402 insertions, 138 deletions
diff --git a/indra/llinventory/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp index 7e1be17ecc..670405e9b5 100644 --- a/indra/llinventory/llfoldertype.cpp +++ b/indra/llinventory/llfoldertype.cpp @@ -29,6 +29,7 @@  #include "llfoldertype.h"  #include "lldictionary.h"  #include "llmemory.h" +#include "llsd.h"  #include "llsingleton.h"  ///---------------------------------------------------------------------------- @@ -220,3 +221,21 @@ const std::string &LLFolderType::badLookup()      static const std::string sBadLookup = "llfoldertype_bad_lookup";      return sBadLookup;  } + +LLSD LLFolderType::getTypeNames() +{ +    LLSD type_names; +    for (S32 type = FT_TEXTURE; type < FT_COUNT; ++type) +    { +        if (lookupIsEnsembleType((LLFolderType::EType)type)) +            continue; + +        const FolderEntry* entry = LLFolderDictionary::getInstance()->lookup((LLFolderType::EType)type); +        // skip llfoldertype_bad_lookup +        if (entry) +        { +            type_names.append(entry->mName); +        } +    } +    return type_names; +} diff --git a/indra/llinventory/llfoldertype.h b/indra/llinventory/llfoldertype.h index 46a1b92a96..dd12693f66 100644 --- a/indra/llinventory/llfoldertype.h +++ b/indra/llinventory/llfoldertype.h @@ -115,6 +115,8 @@ public:      static const std::string&   badLookup(); // error string when a lookup fails +    static LLSD getTypeNames(); +  protected:      LLFolderType() {}      ~LLFolderType() {} diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 075abf9536..3defad8f3b 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -46,6 +46,7 @@ static const std::string INV_ITEM_ID_LABEL("item_id");  static const std::string INV_FOLDER_ID_LABEL("cat_id");  static const std::string INV_PARENT_ID_LABEL("parent_id");  static const std::string INV_THUMBNAIL_LABEL("thumbnail"); +static const std::string INV_FAVORITE_LABEL("favorite");  static const std::string INV_THUMBNAIL_ID_LABEL("thumbnail_id");  static const std::string INV_ASSET_TYPE_LABEL("type");  static const std::string INV_PREFERRED_TYPE_LABEL("preferred_type"); @@ -59,6 +60,7 @@ static const std::string INV_LINKED_ID_LABEL("linked_id");  static const std::string INV_SALE_INFO_LABEL("sale_info");  static const std::string INV_FLAGS_LABEL("flags");  static const std::string INV_CREATION_DATE_LABEL("created_at"); +static const std::string INV_TOGGLED_LABEL("toggled");  // key used by agent-inventory-service  static const std::string INV_ASSET_TYPE_LABEL_WS("type_default"); @@ -82,14 +84,16 @@ LLInventoryObject::LLInventoryObject(const LLUUID& uuid,      mParentUUID(parent_uuid),      mType(type),      mName(name), -    mCreationDate(0) +    mCreationDate(0), +    mFavorite(false)  {      correctInventoryName(mName);  }  LLInventoryObject::LLInventoryObject()  :   mType(LLAssetType::AT_NONE), -    mCreationDate(0) +    mCreationDate(0), +    mFavorite(false)  {  } @@ -104,6 +108,7 @@ void LLInventoryObject::copyObject(const LLInventoryObject* other)      mType = other->mType;      mName = other->mName;      mThumbnailUUID = other->mThumbnailUUID; +    mFavorite = other->mFavorite;  }  const LLUUID& LLInventoryObject::getUUID() const @@ -121,6 +126,11 @@ const LLUUID& LLInventoryObject::getThumbnailUUID() const      return mThumbnailUUID;  } +bool LLInventoryObject::getIsFavorite() const +{ +    return mFavorite; +} +  const std::string& LLInventoryObject::getName() const  {      return mName; @@ -175,6 +185,11 @@ void LLInventoryObject::setThumbnailUUID(const LLUUID& thumbnail_uuid)      mThumbnailUUID = thumbnail_uuid;  } +void LLInventoryObject::setFavorite(bool favorite) +{ +    mFavorite = favorite; +} +  void LLInventoryObject::setType(LLAssetType::EType type)  {      mType = type; @@ -247,6 +262,23 @@ bool LLInventoryObject::importLegacyStream(std::istream& input_stream)              {                  setThumbnailUUID(LLUUID::null);              } + +            if (metadata.has("favorite")) +            { +                const LLSD& favorite = metadata["favorite"]; +                if (favorite.has("toggled")) +                { +                    setFavorite(favorite["toggled"].asBoolean()); +                } +                else +                { +                    setFavorite(false); +                } +            } +            else +            { +                setFavorite(false); +            }          }          else if(0 == strcmp("name", keyword))          { @@ -735,6 +767,23 @@ bool LLInventoryItem::importLegacyStream(std::istream& input_stream)              {                  setThumbnailUUID(LLUUID::null);              } + +            if (metadata.has("favorite")) +            { +                const LLSD& favorite = metadata["favorite"]; +                if (favorite.has("toggled")) +                { +                    setFavorite(favorite["toggled"].asBoolean()); +                } +                else +                { +                    setFavorite(false); +                } +            } +            else +            { +                setFavorite(false); +            }          }          else if(0 == strcmp("inv_type", keyword))          { @@ -879,7 +928,7 @@ bool LLInventoryItem::exportLegacyStream(std::ostream& output_stream, bool inclu  LLSD LLInventoryItem::asLLSD() const  { -    LLSD sd = LLSD(); +    LLSD sd;      asLLSD(sd);      return sd;  } @@ -888,13 +937,18 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const  {      sd[INV_ITEM_ID_LABEL] = mUUID;      sd[INV_PARENT_ID_LABEL] = mParentUUID; -    sd[INV_PERMISSIONS_LABEL] = ll_create_sd_from_permissions(mPermissions); +    ll_fill_sd_from_permissions(sd[INV_PERMISSIONS_LABEL], mPermissions);      if (mThumbnailUUID.notNull())      {          sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);      } +    if (mFavorite) +    { +        sd[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite); +    } +      U32 mask = mPermissions.getMaskBase();      if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)          || (mAssetUUID.isNull())) @@ -909,19 +963,22 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const          cipher.encrypt(shadow_id.mData, UUID_BYTES);          sd[INV_SHADOW_ID_LABEL] = shadow_id;      } -    sd[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType); -    sd[INV_INVENTORY_TYPE_LABEL] = mInventoryType; +    sd[INV_ASSET_TYPE_LABEL] = std::string(LLAssetType::lookup(mType));      const std::string inv_type_str = LLInventoryType::lookup(mInventoryType);      if(!inv_type_str.empty())      {          sd[INV_INVENTORY_TYPE_LABEL] = inv_type_str;      } +    else +    { +        sd[INV_INVENTORY_TYPE_LABEL] = (LLSD::Integer)mInventoryType; +    }      //sd[INV_FLAGS_LABEL] = (S32)mFlags;      sd[INV_FLAGS_LABEL] = ll_sd_from_U32(mFlags); -    sd[INV_SALE_INFO_LABEL] = mSaleInfo.asLLSD(); +    mSaleInfo.asLLSD(sd[INV_SALE_INFO_LABEL]);      sd[INV_NAME_LABEL] = mName;      sd[INV_DESC_LABEL] = mDescription; -    sd[INV_CREATION_DATE_LABEL] = (S32) mCreationDate; +    sd[INV_CREATION_DATE_LABEL] = (LLSD::Integer)mCreationDate;  }  bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new) @@ -937,6 +994,8 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)      // TODO - figure out if this should be moved into the noclobber fields above      mThumbnailUUID.setNull(); +    mFavorite = false; +    mPermissions.init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);      // iterate as map to avoid making unnecessary temp copies of everything      LLSD::map_const_iterator i, end; @@ -982,9 +1041,20 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)              continue;          } +        if (i->first == INV_FAVORITE_LABEL) +        { +            const LLSD& favorite_map = i->second; +            const std::string w = INV_TOGGLED_LABEL; +            if (favorite_map.has(w)) +            { +                mFavorite = favorite_map[w].asBoolean(); +            } +            continue; +        } +          if (i->first == INV_PERMISSIONS_LABEL)          { -            mPermissions = ll_permissions_from_sd(i->second); +            mPermissions.importLLSD(i->second);              continue;          } @@ -1177,6 +1247,11 @@ LLSD LLInventoryCategory::asLLSD() const          sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);      } +    if (mFavorite) +    { +        sd[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite); +    } +      return sd;  } @@ -1188,11 +1263,17 @@ LLSD LLInventoryCategory::asAISCreateCatLLSD() const      S8 type                 = static_cast<S8>(mPreferredType);      sd[INV_ASSET_TYPE_LABEL_WS] = type;      sd[INV_NAME_LABEL] = mName; +      if (mThumbnailUUID.notNull())      {          sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);      } +    if (mFavorite) +    { +        sd[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite); +    } +      return sd;  } @@ -1240,6 +1321,17 @@ bool LLInventoryCategory::fromLLSD(const LLSD& sd)              mThumbnailUUID = sd[w];          }      } +    mFavorite = false; +    w = INV_FAVORITE_LABEL; +    if (sd.has(w)) +    { +        const LLSD& favorite_map = sd[w]; +        w = INV_TOGGLED_LABEL; +        if (favorite_map.has(w)) +        { +            mFavorite = favorite_map[w].asBoolean(); +        } +    }      w = INV_ASSET_TYPE_LABEL;      if (sd.has(w))      { @@ -1362,6 +1454,23 @@ bool LLInventoryCategory::importLegacyStream(std::istream& input_stream)              {                  setThumbnailUUID(LLUUID::null);              } + +            if (metadata.has("favorite")) +            { +                const LLSD& favorite = metadata["favorite"]; +                if (favorite.has("toggled")) +                { +                    setFavorite(favorite["toggled"].asBoolean()); +                } +                else +                { +                    setFavorite(false); +                } +            } +            else +            { +                setFavorite(false); +            }          }          else          { @@ -1396,12 +1505,11 @@ bool LLInventoryCategory::exportLegacyStream(std::ostream& output_stream, bool)      return true;  } -LLSD LLInventoryCategory::exportLLSD() const +void LLInventoryCategory::exportLLSD(LLSD& cat_data) const  { -    LLSD cat_data;      cat_data[INV_FOLDER_ID_LABEL] = mUUID;      cat_data[INV_PARENT_ID_LABEL] = mParentUUID; -    cat_data[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType); +    cat_data[INV_ASSET_TYPE_LABEL] = std::string(LLAssetType::lookup(mType));      cat_data[INV_PREFERRED_TYPE_LABEL] = LLFolderType::lookup(mPreferredType);      cat_data[INV_NAME_LABEL] = mName; @@ -1409,49 +1517,76 @@ LLSD LLInventoryCategory::exportLLSD() const      {          cat_data[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);      } +    if (mFavorite) +    { +        cat_data[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite); +    } +} -    return cat_data; +bool LLInventoryCategory::importLLSDMap(const LLSD& cat_data) +{ +    LLSD::map_const_iterator i, end; +    end = cat_data.endMap(); +    for ( i = cat_data.beginMap(); i != end; ++i) +    { +        importLLSD(i->first, i->second); +    } +    return true;  } -bool LLInventoryCategory::importLLSD(const LLSD& cat_data) +bool LLInventoryCategory::importLLSD(const std::string& label, const LLSD& value)  { -    if (cat_data.has(INV_FOLDER_ID_LABEL)) +    if (label == INV_FOLDER_ID_LABEL)      { -        setUUID(cat_data[INV_FOLDER_ID_LABEL].asUUID()); +        setUUID(value.asUUID()); +        return true;      } -    if (cat_data.has(INV_PARENT_ID_LABEL)) +    else if (label == INV_PARENT_ID_LABEL)      { -        setParent(cat_data[INV_PARENT_ID_LABEL].asUUID()); +        setParent(value.asUUID()); +        return true;      } -    if (cat_data.has(INV_ASSET_TYPE_LABEL)) +    else if (label == INV_ASSET_TYPE_LABEL)      { -        setType(LLAssetType::lookup(cat_data[INV_ASSET_TYPE_LABEL].asString())); +        setType(LLAssetType::lookup(value.asString())); +        return true;      } -    if (cat_data.has(INV_PREFERRED_TYPE_LABEL)) +    else if (label == INV_PREFERRED_TYPE_LABEL)      { -        setPreferredType(LLFolderType::lookup(cat_data[INV_PREFERRED_TYPE_LABEL].asString())); +        setPreferredType(LLFolderType::lookup(value.asString())); +        return true;      } -    if (cat_data.has(INV_THUMBNAIL_LABEL)) +    else if (label == INV_THUMBNAIL_LABEL)      {          LLUUID thumbnail_uuid; -        const LLSD &thumbnail_data = cat_data[INV_THUMBNAIL_LABEL]; -        if (thumbnail_data.has(INV_ASSET_ID_LABEL)) +        if (value.has(INV_ASSET_ID_LABEL))          { -            thumbnail_uuid = thumbnail_data[INV_ASSET_ID_LABEL].asUUID(); +            thumbnail_uuid = value[INV_ASSET_ID_LABEL].asUUID();          }          setThumbnailUUID(thumbnail_uuid); +        return true; +    } +    if (label == INV_FAVORITE_LABEL) +    { +        bool favorite = false; +        if (value.has(INV_TOGGLED_LABEL)) +        { +            favorite = value[INV_TOGGLED_LABEL].asBoolean(); +        } +        setFavorite(favorite);      } -    if (cat_data.has(INV_NAME_LABEL)) +    else if (label == INV_NAME_LABEL)      { -        mName = cat_data[INV_NAME_LABEL].asString(); +        mName = value.asString();          LLStringUtil::replaceNonstandardASCII(mName, ' ');          LLStringUtil::replaceChar(mName, '|', ' '); +        return true;      } - -    return true; +    return false;  } +  ///---------------------------------------------------------------------------- -/// Local function definitions +/// Local function definitions for testing purposes  ///----------------------------------------------------------------------------  LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item) diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index e63f2deba7..181c46226c 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -71,6 +71,7 @@ public:      virtual const LLUUID& getLinkedUUID() const; // inventoryID that this item points to, else this item's inventoryID      const LLUUID& getParentUUID() const;      virtual const LLUUID& getThumbnailUUID() const; +    virtual bool getIsFavorite() const;      virtual const std::string& getName() const;      virtual LLAssetType::EType getType() const;      LLAssetType::EType getActualType() const; // bypasses indirection for linked items @@ -86,6 +87,7 @@ public:      virtual void rename(const std::string& new_name);      void setParent(const LLUUID& new_parent);      virtual void setThumbnailUUID(const LLUUID& thumbnail_uuid); +    virtual void setFavorite(bool favorite);      void setType(LLAssetType::EType type);      virtual void setCreationDate(time_t creation_date_utc); // only stored for items @@ -111,6 +113,7 @@ protected:      LLUUID mUUID;      LLUUID mParentUUID; // Parent category.  Root categories have LLUUID::NULL.      LLUUID mThumbnailUUID; +    bool mFavorite;      LLAssetType::EType mType;      std::string mName;      time_t mCreationDate; // seconds from 1/1/1970, UTC @@ -270,8 +273,9 @@ public:      virtual bool importLegacyStream(std::istream& input_stream);      virtual bool exportLegacyStream(std::ostream& output_stream, bool include_asset_key = true) const; -    LLSD exportLLSD() const; -    bool importLLSD(const LLSD& cat_data); +    virtual void exportLLSD(LLSD& sd) const; +    bool importLLSDMap(const LLSD& cat_data); +    virtual bool importLLSD(const std::string& label, const LLSD& value);      //--------------------------------------------------------------------      // Member Variables      //-------------------------------------------------------------------- @@ -285,6 +289,7 @@ protected:  //  //   These functions convert between structured data and an inventory  //   item, appropriate for serialization. +//   Not up to date (no favorites, nor thumbnails), for testing purposes  //-----------------------------------------------------------------------------  LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item);  LLSD ll_create_sd_from_inventory_category(LLPointer<LLInventoryCategory> cat); diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 67d713db1f..ac50b428bf 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -37,98 +37,98 @@  #include "llsettingsdaycycle.h"  // Grid out of which parcels taken is stepped every 4 meters. -const F32 PARCEL_GRID_STEP_METERS   = 4.f; +constexpr F32 PARCEL_GRID_STEP_METERS   = 4.f;  // Area of one "square" of parcel -const S32 PARCEL_UNIT_AREA          = 16; +constexpr S32 PARCEL_UNIT_AREA          = 16;  // Height _above_ground_ that parcel boundary ends -const F32 PARCEL_HEIGHT = 50.f; +constexpr F32 PARCEL_HEIGHT = 50.f;  //Height above ground which parcel boundries exist for explicitly banned avatars -const F32 BAN_HEIGHT = 5000.f; +constexpr F32 BAN_HEIGHT = 5000.f;  // Maximum number of entries in an access list -const S32 PARCEL_MAX_ACCESS_LIST = 300; +constexpr S32 PARCEL_MAX_ACCESS_LIST = 300;  //Maximum number of entires in an update packet  //for access/ban lists. -const F32 PARCEL_MAX_ENTRIES_PER_PACKET = 48.f; +constexpr F32 PARCEL_MAX_ENTRIES_PER_PACKET = 48.f;  // Maximum number of experiences -const S32 PARCEL_MAX_EXPERIENCE_LIST = 24; +constexpr S32 PARCEL_MAX_EXPERIENCE_LIST = 24;  // Weekly charge for listing a parcel in the directory -const S32 PARCEL_DIRECTORY_FEE = 30; +constexpr S32 PARCEL_DIRECTORY_FEE = 30; -const S32 PARCEL_PASS_PRICE_DEFAULT = 10; -const F32 PARCEL_PASS_HOURS_DEFAULT = 1.f; +constexpr S32 PARCEL_PASS_PRICE_DEFAULT = 10; +constexpr F32 PARCEL_PASS_HOURS_DEFAULT = 1.f;  // Number of "chunks" in which parcel overlay data is sent  // Chunk 0 = southern rows, entire width -const S32 PARCEL_OVERLAY_CHUNKS = 4; +constexpr S32 PARCEL_OVERLAY_CHUNKS = 4;  // Bottom three bits are a color index for the land overlay -const U8 PARCEL_COLOR_MASK  = 0x07; -const U8 PARCEL_PUBLIC      = 0x00; -const U8 PARCEL_OWNED       = 0x01; -const U8 PARCEL_GROUP       = 0x02; -const U8 PARCEL_SELF        = 0x03; -const U8 PARCEL_FOR_SALE    = 0x04; -const U8 PARCEL_AUCTION     = 0x05; +constexpr U8 PARCEL_COLOR_MASK  = 0x07; +constexpr U8 PARCEL_PUBLIC      = 0x00; +constexpr U8 PARCEL_OWNED       = 0x01; +constexpr U8 PARCEL_GROUP       = 0x02; +constexpr U8 PARCEL_SELF        = 0x03; +constexpr U8 PARCEL_FOR_SALE    = 0x04; +constexpr U8 PARCEL_AUCTION     = 0x05;  // unused 0x06  // unused 0x07  // flag, unused 0x08 -const U8 PARCEL_HIDDENAVS   = 0x10; // avatars not visible outside of parcel.  Used for 'see avs' feature, but must be off for compatibility -const U8 PARCEL_SOUND_LOCAL = 0x20; -const U8 PARCEL_WEST_LINE   = 0x40; // flag, property line on west edge -const U8 PARCEL_SOUTH_LINE  = 0x80; // flag, property line on south edge +constexpr U8 PARCEL_HIDDENAVS   = 0x10; // avatars not visible outside of parcel.  Used for 'see avs' feature, but must be off for compatibility +constexpr U8 PARCEL_SOUND_LOCAL = 0x20; +constexpr U8 PARCEL_WEST_LINE   = 0x40; // flag, property line on west edge +constexpr U8 PARCEL_SOUTH_LINE  = 0x80; // flag, property line on south edge  // Transmission results for parcel properties -const S32 PARCEL_RESULT_NO_DATA = -1; -const S32 PARCEL_RESULT_SUCCESS = 0;    // got exactly one parcel -const S32 PARCEL_RESULT_MULTIPLE = 1;   // got multiple parcels - -const S32 SELECTED_PARCEL_SEQ_ID = -10000; -const S32 COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID =  -20000; -const S32 COLLISION_BANNED_PARCEL_SEQ_ID = -30000; -const S32 COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID =  -40000; -const S32 HOVERED_PARCEL_SEQ_ID =  -50000; - -const U32 RT_NONE   = 0x1 << 0; -const U32 RT_OWNER  = 0x1 << 1; -const U32 RT_GROUP  = 0x1 << 2; -const U32 RT_OTHER  = 0x1 << 3; -const U32 RT_LIST   = 0x1 << 4; -const U32 RT_SELL   = 0x1 << 5; - -const S32 INVALID_PARCEL_ID = -1; - -const S32 INVALID_PARCEL_ENVIRONMENT_VERSION = -2; +constexpr S32 PARCEL_RESULT_NO_DATA = -1; +constexpr S32 PARCEL_RESULT_SUCCESS = 0;    // got exactly one parcel +constexpr S32 PARCEL_RESULT_MULTIPLE = 1;   // got multiple parcels + +constexpr S32 SELECTED_PARCEL_SEQ_ID = -10000; +constexpr S32 COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID =  -20000; +constexpr S32 COLLISION_BANNED_PARCEL_SEQ_ID = -30000; +constexpr S32 COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID =  -40000; +constexpr S32 HOVERED_PARCEL_SEQ_ID =  -50000; + +constexpr U32 RT_NONE   = 0x1 << 0; +constexpr U32 RT_OWNER  = 0x1 << 1; +constexpr U32 RT_GROUP  = 0x1 << 2; +constexpr U32 RT_OTHER  = 0x1 << 3; +constexpr U32 RT_LIST   = 0x1 << 4; +constexpr U32 RT_SELL   = 0x1 << 5; + +constexpr S32 INVALID_PARCEL_ID = -1; + +constexpr S32 INVALID_PARCEL_ENVIRONMENT_VERSION = -2;  // if Region settings are used, parcel env. version is -1 -const S32 UNSET_PARCEL_ENVIRONMENT_VERSION = -1; +constexpr S32 UNSET_PARCEL_ENVIRONMENT_VERSION = -1;  // Timeouts for parcels  // default is 21 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 1814400000000 -const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000); +constexpr U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000);  // ***** TESTING is 10 minutes  //const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(600000000);  // group is 60 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 5184000000000 -const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(5184000000000); +constexpr U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(5184000000000);  // ***** TESTING is 10 minutes  //const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(600000000);  // default sale timeout is 2 days -> 172800000000 -const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(172800000000); +constexpr U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(172800000000);  // ***** TESTING is 10 minutes  //const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(600000000);  // more grace period extensions. -const U64 SEVEN_DAYS_IN_USEC = U64L(604800000000); +constexpr U64 SEVEN_DAYS_IN_USEC = U64L(604800000000);  // if more than 100,000s before sale revert, and no extra extension  // has been given, go ahead and extend it more. That's about 1.2 days. -const S32 EXTEND_GRACE_IF_MORE_THAN_SEC = 100000; +constexpr S32 EXTEND_GRACE_IF_MORE_THAN_SEC = 100000; @@ -250,9 +250,9 @@ public:      void setMediaURL(const std::string& url);      void setMediaType(const std::string& type);      void setMediaDesc(const std::string& desc); -    void    setMediaID(const LLUUID& id) { mMediaID = id; } -    void    setMediaAutoScale ( U8 flagIn ) { mMediaAutoScale = flagIn; } -    void    setMediaLoop (U8 loop) { mMediaLoop = loop; } +    void setMediaID(const LLUUID& id) { mMediaID = id; } +    void setMediaAutoScale ( U8 flagIn ) { mMediaAutoScale = flagIn; } +    void setMediaLoop(U8 loop) { mMediaLoop = loop; }      void setMediaWidth(S32 width);      void setMediaHeight(S32 height);      void setMediaCurrentURL(const std::string& url); @@ -262,6 +262,8 @@ public:      void setMediaURLResetTimer(F32 time);      virtual void    setLocalID(S32 local_id); +    void setRegionID(const LLUUID& id) { mRegionID = id; } +    const LLUUID& getRegionID() const { return mRegionID; }      // blow away all the extra stuff lurking in parcels, including urls, access lists, etc      void clearParcel(); @@ -651,6 +653,7 @@ public:      S32                 mLocalID;      LLUUID              mBanListTransactionID;      LLUUID              mAccessListTransactionID; +    LLUUID              mRegionID;      std::map<LLUUID,LLAccessEntry>  mAccessList;      std::map<LLUUID,LLAccessEntry>  mBanList;      std::map<LLUUID,LLAccessEntry>  mTempBanList; diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp index c8963881df..ebf7445c65 100644 --- a/indra/llinventory/llpermissions.cpp +++ b/indra/llinventory/llpermissions.cpp @@ -704,6 +704,79 @@ bool LLPermissions::exportLegacyStream(std::ostream& output_stream) const      return true;  } +static const std::string PERM_CREATOR_ID_LABEL("creator_id"); +static const std::string PERM_OWNER_ID_LABEL("owner_id"); +static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id"); +static const std::string PERM_GROUP_ID_LABEL("group_id"); +static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group"); +static const std::string PERM_BASE_MASK_LABEL("base_mask"); +static const std::string PERM_OWNER_MASK_LABEL("owner_mask"); +static const std::string PERM_GROUP_MASK_LABEL("group_mask"); +static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask"); +static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask"); + +void LLPermissions::importLLSD(const LLSD& sd_perm) +{ +    LLSD::map_const_iterator i, end; +    end = sd_perm.endMap(); +    for (i = sd_perm.beginMap(); i != end; ++i) +    { +        const std::string& label = i->first; +        if (label == PERM_CREATOR_ID_LABEL) +        { +            mCreator = i->second.asUUID(); +            continue; +        } +        if (label == PERM_OWNER_ID_LABEL) +        { +            mOwner = i->second.asUUID(); +            continue; +        } +        if (label == PERM_LAST_OWNER_ID_LABEL) +        { +            mLastOwner = i->second.asUUID(); +            continue; +        } +        if (label == PERM_GROUP_ID_LABEL) +        { +            mGroup = i->second.asUUID(); +            continue; +        } +        if (label == PERM_BASE_MASK_LABEL) +        { +            PermissionMask mask = i->second.asInteger(); +            mMaskBase = mask; +            continue; +        } +        if (label == PERM_OWNER_MASK_LABEL) +        { +            PermissionMask mask = i->second.asInteger(); +            mMaskOwner = mask; +            continue; +        } +        if (label == PERM_EVERYONE_MASK_LABEL) +        { +            PermissionMask mask = i->second.asInteger(); +            mMaskEveryone = mask; +            continue; +        } +        if (label == PERM_GROUP_MASK_LABEL) +        { +            PermissionMask mask = i->second.asInteger(); +            mMaskGroup = mask; +            continue; +        } +        if (label == PERM_NEXT_OWNER_MASK_LABEL) +        { +            PermissionMask mask = i->second.asInteger(); +            mMaskNextOwner = mask; +            continue; +        } +    } + +    fix(); +} +  bool LLPermissions::operator==(const LLPermissions &rhs) const  {      return @@ -998,55 +1071,30 @@ std::string mask_to_string(U32 mask)  ///----------------------------------------------------------------------------  /// exported functions  ///---------------------------------------------------------------------------- -static const std::string PERM_CREATOR_ID_LABEL("creator_id"); -static const std::string PERM_OWNER_ID_LABEL("owner_id"); -static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id"); -static const std::string PERM_GROUP_ID_LABEL("group_id"); -static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group"); -static const std::string PERM_BASE_MASK_LABEL("base_mask"); -static const std::string PERM_OWNER_MASK_LABEL("owner_mask"); -static const std::string PERM_GROUP_MASK_LABEL("group_mask"); -static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask"); -static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask");  LLSD ll_create_sd_from_permissions(const LLPermissions& perm)  {      LLSD rv; +    ll_fill_sd_from_permissions(rv, perm); +    return rv; +} +void ll_fill_sd_from_permissions(LLSD& rv, const LLPermissions& perm) +{      rv[PERM_CREATOR_ID_LABEL] = perm.getCreator();      rv[PERM_OWNER_ID_LABEL] = perm.getOwner();      rv[PERM_LAST_OWNER_ID_LABEL] = perm.getLastOwner();      rv[PERM_GROUP_ID_LABEL] = perm.getGroup();      rv[PERM_IS_OWNER_GROUP_LABEL] = perm.isGroupOwned(); -    rv[PERM_BASE_MASK_LABEL] = (S32)perm.getMaskBase(); -    rv[PERM_OWNER_MASK_LABEL] = (S32)perm.getMaskOwner(); -    rv[PERM_GROUP_MASK_LABEL] = (S32)perm.getMaskGroup(); -    rv[PERM_EVERYONE_MASK_LABEL] = (S32)perm.getMaskEveryone(); -    rv[PERM_NEXT_OWNER_MASK_LABEL] = (S32)perm.getMaskNextOwner(); -    return rv; +    rv[PERM_BASE_MASK_LABEL] = (LLSD::Integer)perm.getMaskBase(); +    rv[PERM_OWNER_MASK_LABEL] = (LLSD::Integer)perm.getMaskOwner(); +    rv[PERM_GROUP_MASK_LABEL] = (LLSD::Integer)perm.getMaskGroup(); +    rv[PERM_EVERYONE_MASK_LABEL] = (LLSD::Integer)perm.getMaskEveryone(); +    rv[PERM_NEXT_OWNER_MASK_LABEL] = (LLSD::Integer)perm.getMaskNextOwner();  }  LLPermissions ll_permissions_from_sd(const LLSD& sd_perm)  {      LLPermissions rv; -    rv.init( -        sd_perm[PERM_CREATOR_ID_LABEL].asUUID(), -        sd_perm[PERM_OWNER_ID_LABEL].asUUID(), -        sd_perm[PERM_LAST_OWNER_ID_LABEL].asUUID(), -        sd_perm[PERM_GROUP_ID_LABEL].asUUID()); - -    // We do a cast to U32 here since LLSD does not attempt to -    // represent unsigned ints. -    PermissionMask mask; -    mask = (U32)(sd_perm[PERM_BASE_MASK_LABEL].asInteger()); -    rv.setMaskBase(mask); -    mask = (U32)(sd_perm[PERM_OWNER_MASK_LABEL].asInteger()); -    rv.setMaskOwner(mask); -    mask = (U32)(sd_perm[PERM_EVERYONE_MASK_LABEL].asInteger()); -    rv.setMaskEveryone(mask); -    mask = (U32)(sd_perm[PERM_GROUP_MASK_LABEL].asInteger()); -    rv.setMaskGroup(mask); -    mask = (U32)(sd_perm[PERM_NEXT_OWNER_MASK_LABEL].asInteger()); -    rv.setMaskNext(mask); -    rv.fix(); +    rv.importLLSD(sd_perm);      return rv;  } diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h index a68abcfa34..82cdc03727 100644 --- a/indra/llinventory/llpermissions.h +++ b/indra/llinventory/llpermissions.h @@ -299,6 +299,8 @@ public:      bool    importLegacyStream(std::istream& input_stream);      bool    exportLegacyStream(std::ostream& output_stream) const; +    void importLLSD(const LLSD& sd_perm); +      bool operator==(const LLPermissions &rhs) const;      bool operator!=(const LLPermissions &rhs) const; @@ -435,6 +437,7 @@ protected:  // like 'creator_id', 'owner_id', etc, with the value copied from the  // permission object.  LLSD ll_create_sd_from_permissions(const LLPermissions& perm); +void ll_fill_sd_from_permissions(LLSD& rv, const LLPermissions& perm);  LLPermissions ll_permissions_from_sd(const LLSD& sd_perm);  #endif diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp index 35bbc1dbb1..b4d64bb4fb 100644 --- a/indra/llinventory/llsaleinfo.cpp +++ b/indra/llinventory/llsaleinfo.cpp @@ -90,15 +90,20 @@ bool LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const  LLSD LLSaleInfo::asLLSD() const  {      LLSD sd; +    asLLSD(sd); +    return sd; +} + +void LLSaleInfo::asLLSD(LLSD& sd) const +{      const char* type = lookup(mSaleType);      if (!type)      {          LL_WARNS_ONCE() << "Unknown sale type: " << mSaleType << LL_ENDL;          type = lookup(LLSaleInfo::FS_NOT);      } -    sd["sale_type"] = type; +    sd["sale_type"] = std::string(type);      sd["sale_price"] = mSalePrice; -    return sd;  }  bool LLSaleInfo::fromLLSD(const LLSD& sd, bool& has_perm_mask, U32& perm_mask) diff --git a/indra/llinventory/llsaleinfo.h b/indra/llinventory/llsaleinfo.h index 44eb841641..7186e8ab49 100644 --- a/indra/llinventory/llsaleinfo.h +++ b/indra/llinventory/llsaleinfo.h @@ -86,6 +86,7 @@ public:      bool exportLegacyStream(std::ostream& output_stream) const;      LLSD asLLSD() const; +    void asLLSD(LLSD &sd) const;      operator LLSD() const { return asLLSD(); }      bool fromLLSD(const LLSD& sd, bool& has_perm_mask, U32& perm_mask);      bool importLegacyStream(std::istream& input_stream, bool& has_perm_mask, U32& perm_mask); diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index d483b33288..d7a94d61a5 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -361,14 +361,12 @@ LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD                  new_array = q.getValue();              }              else -            {   // TODO: We could expand this to inspect the type and do a deep lerp based on type. -                // for now assume a heterogeneous array of reals. +            {                  size_t len = std::max(value.size(), other_value.size());                  for (size_t i = 0; i < len; ++i)                  { - -                    new_array[i] = lerp((F32)value[i].asReal(), (F32)other_value[i].asReal(), (F32)mix); +                    new_array[i] = interpolateSDValue(key_name, value[i], other_value[i], defaults, mix, skip, slerps);                  }              } diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h index 7de71588ef..bea6fdec97 100644 --- a/indra/llinventory/llsettingsbase.h +++ b/indra/llinventory/llsettingsbase.h @@ -398,7 +398,7 @@ protected:  private:      bool        mLLSDDirty; -    bool        mDirty; +    bool        mDirty; // gates updateSettings      bool        mReplaced; // super dirty!      static LLSD combineSDMaps(const LLSD &first, const LLSD &other); diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index ff28c30563..4957cf3c02 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -657,15 +657,16 @@ void LLSettingsSky::blend(LLSettingsBase::ptr_t &end, F64 blendf)          mHasLegacyHaze |= lerp_legacy_float(mHazeDensity, mLegacyHazeDensity, other->mHazeDensity, other->mLegacyHazeDensity, 0.7f, (F32)blendf);          mHasLegacyHaze |= lerp_legacy_float(mDistanceMultiplier, mLegacyDistanceMultiplier, other->mDistanceMultiplier, other->mLegacyDistanceMultiplier, 0.8f, (F32)blendf);          mHasLegacyHaze |= lerp_legacy_float(mDensityMultiplier, mLegacyDensityMultiplier, other->mDensityMultiplier, other->mLegacyDensityMultiplier, 0.0001f, (F32)blendf); +        mHasLegacyHaze |= lerp_legacy_color(mAmbientColor, mLegacyAmbientColor, other->mAmbientColor, other->mLegacyAmbientColor, LLColor3(0.25f, 0.25f, 0.25f), (F32)blendf);          mHasLegacyHaze |= lerp_legacy_color(mBlueHorizon, mLegacyBlueHorizon, other->mBlueHorizon, other->mLegacyBlueHorizon, LLColor3(0.4954f, 0.4954f, 0.6399f), (F32)blendf);          mHasLegacyHaze |= lerp_legacy_color(mBlueDensity, mLegacyBlueDensity, other->mBlueDensity, other->mLegacyBlueDensity, LLColor3(0.2447f, 0.4487f, 0.7599f), (F32)blendf);          parammapping_t defaults = other->getParameterMap();          stringset_t skip = getSkipInterpolateKeys();          stringset_t slerps = getSlerpKeys(); -        mAbsorptionConfigs = interpolateSDMap(mAbsorptionConfigs, other->mAbsorptionConfigs, defaults, blendf, skip, slerps); -        mMieConfigs = interpolateSDMap(mMieConfigs, other->mMieConfigs, defaults, blendf, skip, slerps); -        mRayleighConfigs = interpolateSDMap(mRayleighConfigs, other->mRayleighConfigs, defaults, blendf, skip, slerps); +        mAbsorptionConfigs = interpolateSDValue("absorption_config", mAbsorptionConfigs, other->mAbsorptionConfigs, defaults, blendf, skip, slerps); +        mMieConfigs = interpolateSDValue("mie_config", mMieConfigs, other->mMieConfigs, defaults, blendf, skip, slerps); +        mRayleighConfigs = interpolateSDValue("rayleigh_config", mRayleighConfigs, other->mRayleighConfigs, defaults, blendf, skip, slerps);          setDirtyFlag(true);          setReplaced(); @@ -1932,6 +1933,7 @@ LLUUID LLSettingsSky::getCloudNoiseTextureId() const  void LLSettingsSky::setCloudNoiseTextureId(const LLUUID &id)  {      mCloudTextureId = id; +    setDirtyFlag(true);      setLLSDDirty();  } @@ -1976,6 +1978,7 @@ LLVector2 LLSettingsSky::getCloudScrollRate() const  void LLSettingsSky::setCloudScrollRate(const LLVector2 &val)  {      mScrollRate = val; +    setDirtyFlag(true);      setLLSDDirty();  } @@ -2134,6 +2137,7 @@ LLUUID LLSettingsSky::getMoonTextureId() const  void LLSettingsSky::setMoonTextureId(LLUUID id)  {      mMoonTextureId = id; +    setDirtyFlag(true);      setLLSDDirty();  } @@ -2218,6 +2222,7 @@ LLUUID LLSettingsSky::getSunTextureId() const  void LLSettingsSky::setSunTextureId(LLUUID id)  {      mSunTextureId = id; +    setDirtyFlag(true);      setLLSDDirty();  } diff --git a/indra/llinventory/tests/inventorymisc_test.cpp b/indra/llinventory/tests/inventorymisc_test.cpp index 9779cb8fbc..f11a4c3bf7 100644 --- a/indra/llinventory/tests/inventorymisc_test.cpp +++ b/indra/llinventory/tests/inventorymisc_test.cpp @@ -39,6 +39,34 @@  #pragma warning(disable: 4702)  #endif +void set_random_inventory_metadata(LLInventoryObject* obj) +{ +    S32 extra = rand() % 4; +    switch (extra) +    { +    case 0: +    { +        LLUUID thumbnail_id; +        thumbnail_id.generate(); +        obj->setThumbnailUUID(thumbnail_id); +        break; +    } +    case 1: +        obj->setFavorite(true); +        break; +    case 2: +    { +        LLUUID thumbnail_id; +        thumbnail_id.generate(); +        obj->setThumbnailUUID(thumbnail_id); +        obj->setFavorite(true); +        break; +    } +    default: +        break; +    } +} +  LLPointer<LLInventoryItem> create_random_inventory_item()  {      LLUUID item_id; @@ -75,6 +103,7 @@ LLPointer<LLInventoryItem> create_random_inventory_item()          sale_info,          flags,          creation); +    set_random_inventory_metadata(item);      return item;  } @@ -90,6 +119,7 @@ LLPointer<LLInventoryCategory> create_random_inventory_cat()          parent_id,          LLFolderType::FT_NONE,          std::string("Sample category")); +    set_random_inventory_metadata(cat);      return cat;  } @@ -290,6 +320,7 @@ namespace tut          src->setCreationDate(new_creation);          // test a save/load cycle to LLSD and back again +        // Note: ll_create_sd_from_inventory_item does not support metadata          LLSD sd = ll_create_sd_from_inventory_item(src);          LLPointer<LLInventoryItem> dst = new LLInventoryItem;          bool successful_parse = dst->fromLLSD(sd); @@ -329,7 +360,9 @@ namespace tut          }          LLPointer<LLInventoryItem> src1 = create_random_inventory_item(); -        fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->asLLSD()) << std::endl; +        LLSD sd; +        src1->asLLSD(sd); +        fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl;          fileXML.close(); @@ -364,13 +397,13 @@ namespace tut          ensure_equals("8.name::getName() failed", src1->getName(), src2->getName());          ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription());          ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate()); - +        ensure_equals("13.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID()); +        ensure_equals("14.favorites::getIsFavorite() failed", src1->getIsFavorite(), src2->getIsFavorite());      }      template<> template<>      void inventory_object::test<8>()      { -          LLPointer<LLInventoryItem> src1 = create_random_inventory_item();          std::ostringstream ostream; @@ -390,8 +423,8 @@ namespace tut          ensure_equals("8.name::getName() failed", src1->getName(), src2->getName());          ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription());          ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate()); - - +        ensure_equals("11.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID()); +        ensure_equals("12.favorites::getIsFavorite() failed", false, src2->getIsFavorite()); // not supposed to carry over      }      template<> template<> @@ -421,6 +454,8 @@ namespace tut          ensure_equals("10.name::getName() failed", src1->getName(), src2->getName());          ensure_equals("11.description::getDescription() failed", src1->getDescription(), src2->getDescription());          ensure_equals("12.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate()); +        ensure_equals("13.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID()); +        ensure_equals("14.favorites::getIsFavorite() failed", src1->getIsFavorite(), src2->getIsFavorite());      }  //******class LLInventoryCategory*******// @@ -458,7 +493,9 @@ namespace tut          }          LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat(); -        fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->exportLLSD()) << std::endl; +        LLSD sd; +        src1->exportLLSD(sd); +        fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl;          fileXML.close();          llifstream file(filename.c_str()); @@ -481,13 +518,15 @@ namespace tut          file.close();          LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory(); -        src2->importLLSD(s_item); +        src2->importLLSDMap(s_item);          ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());          ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());          ensure_equals("3.type::getType() failed", src1->getType(), src2->getType());          ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType());          ensure_equals("5.name::getName() failed", src1->getName(), src2->getName()); +        ensure_equals("6.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID()); +        ensure_equals("7.favorites::getIsFavorite() failed", src1->getIsFavorite(), src2->getIsFavorite());      }      template<> template<> @@ -507,6 +546,7 @@ namespace tut          ensure_equals("3.type::getType() failed", src1->getType(), src2->getType());          ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType());          ensure_equals("5.name::getName() failed", src1->getName(), src2->getName()); - +        ensure_equals("13.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID()); +        ensure_equals("14.favorites::getIsFavorite() failed", false, src2->getIsFavorite()); // currently not supposed to carry over      }  }  | 
