@@ -1002,171 +1002,186 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
10021002 end = sd.endMap ();
10031003 for (i = sd.beginMap (); i != end; ++i)
10041004 {
1005- if (i->first == INV_ITEM_ID_LABEL )
1006- {
1007- mUUID = i->second ;
1008- continue ;
1009- }
1010-
1011- if (i->first == INV_PARENT_ID_LABEL )
1012- {
1013- mParentUUID = i->second ;
1014- continue ;
1015- }
1005+ // Use string length as a fast pre-filter before string comparison
1006+ const std::string& key = i->first ;
1007+ const LLSD & value = i->second ;
1008+ const size_t key_len = key.length ();
10161009
1017- if (i-> first == INV_THUMBNAIL_LABEL )
1010+ switch (key_len )
10181011 {
1019- const LLSD &thumbnail_map = i->second ;
1020- if (thumbnail_map.has (INV_ASSET_ID_LABEL ))
1021- {
1022- mThumbnailUUID = thumbnail_map[INV_ASSET_ID_LABEL ];
1023- }
1024- /* Example:
1025- <key> asset_id </key>
1026- <uuid> acc0ec86 - 17f2 - 4b92 - ab41 - 6718b1f755f7 </uuid>
1027- <key> perms </key>
1028- <integer> 8 </integer>
1029- <key>service</key>
1030- <integer> 3 </integer>
1031- <key>version</key>
1032- <integer> 1 </key>
1033- */
1034- continue ;
1035- }
1036-
1037- if (i->first == INV_THUMBNAIL_ID_LABEL )
1038- {
1039- mThumbnailUUID = i->second .asUUID ();
1040- continue ;
1041- }
1042-
1043- if (i->first == INV_FAVORITE_LABEL )
1044- {
1045- const LLSD & favorite_map = i->second ;
1046- if (favorite_map.has (INV_TOGGLED_LABEL ))
1047- {
1048- mFavorite = favorite_map[INV_TOGGLED_LABEL ].asBoolean ();
1049- }
1050- continue ;
1051- }
1052-
1053- if (i->first == INV_PERMISSIONS_LABEL )
1054- {
1055- mPermissions .importLLSD (i->second );
1056- continue ;
1057- }
1058-
1059- if (i->first == INV_SALE_INFO_LABEL )
1060- {
1061- // Sale info used to contain next owner perm. It is now in
1062- // the permissions. Thus, we read that out, and fix legacy
1063- // objects. It's possible this op would fail, but it
1064- // should pick up the vast majority of the tasks.
1065- bool has_perm_mask = false ;
1066- U32 perm_mask = 0 ;
1067- if (!mSaleInfo .fromLLSD (i->second , has_perm_mask, perm_mask))
1068- {
1069- return false ;
1070- }
1071- if (has_perm_mask)
1072- {
1073- if (perm_mask == PERM_NONE )
1012+ case 4 : // "name", "desc", "type"
1013+ if (key == INV_NAME_LABEL ) // "name"
10741014 {
1075- perm_mask = mPermissions .getMaskOwner ();
1015+ mName = value.asString ();
1016+ LLStringUtil::replaceNonstandardASCII (mName , ' ' );
1017+ LLStringUtil::replaceChar (mName , ' |' , ' ' );
1018+ continue ;
10761019 }
1077- // fair use fix.
1078- if (!(perm_mask & PERM_COPY ))
1020+ if (key == INV_DESC_LABEL ) // "desc"
10791021 {
1080- perm_mask |= PERM_TRANSFER ;
1022+ mDescription = value.asString ();
1023+ LLStringUtil::replaceNonstandardASCII (mDescription , ' ' );
1024+ continue ;
10811025 }
1082- mPermissions .setMaskNext (perm_mask);
1083- }
1084- continue ;
1085- }
1086-
1087- if (i->first == INV_SHADOW_ID_LABEL )
1088- {
1089- mAssetUUID = i->second ;
1090- LLXORCipher cipher (MAGIC_ID .mData , UUID_BYTES );
1091- cipher.decrypt (mAssetUUID .mData , UUID_BYTES );
1092- continue ;
1093- }
1026+ if (key == INV_ASSET_TYPE_LABEL ) // "type"
1027+ {
1028+ if (value.isString ())
1029+ {
1030+ mType = LLAssetType::lookup (value.asStringRef ().c_str ());
1031+ }
1032+ else if (value.isInteger ())
1033+ {
1034+ S8 type = (U8 )value.asInteger ();
1035+ mType = static_cast <LLAssetType::EType>(type);
1036+ }
1037+ continue ;
1038+ }
1039+ break ;
10941040
1095- if (i->first == INV_ASSET_ID_LABEL )
1096- {
1097- mAssetUUID = i->second ;
1098- continue ;
1099- }
1041+ case 5 : // "flags"
1042+ if (key == INV_FLAGS_LABEL )
1043+ {
1044+ if (value.isBinary ())
1045+ {
1046+ mFlags = ll_U32_from_sd (value);
1047+ }
1048+ else if (value.isInteger ())
1049+ {
1050+ mFlags = value.asInteger ();
1051+ }
1052+ continue ;
1053+ }
1054+ break ;
11001055
1101- if (i->first == INV_LINKED_ID_LABEL )
1102- {
1103- mAssetUUID = i->second ;
1104- continue ;
1105- }
1056+ case 7 : // "item_id"
1057+ if (key == INV_ITEM_ID_LABEL )
1058+ {
1059+ mUUID = value;
1060+ continue ;
1061+ }
1062+ break ;
11061063
1107- if (i->first == INV_ASSET_TYPE_LABEL )
1108- {
1109- LLSD const &label = i->second ;
1110- if (label.isString ())
1111- {
1112- mType = LLAssetType::lookup (label.asStringRef ().c_str ());
1113- }
1114- else if (label.isInteger ())
1115- {
1116- S8 type = (U8 ) label.asInteger ();
1117- mType = static_cast <LLAssetType::EType>(type);
1118- }
1119- continue ;
1120- }
1064+ case 8 : // "asset_id", "inv_type"
1065+ if (key == INV_ASSET_ID_LABEL )
1066+ {
1067+ mAssetUUID = value;
1068+ continue ;
1069+ }
1070+ if (key == INV_INVENTORY_TYPE_LABEL ) // "inv_type"
1071+ {
1072+ if (value.isString ())
1073+ {
1074+ mInventoryType = LLInventoryType::lookup (value.asStringRef ().c_str ());
1075+ }
1076+ else if (value.isInteger ())
1077+ {
1078+ S8 type = (U8 )value.asInteger ();
1079+ mInventoryType = static_cast <LLInventoryType::EType>(type);
1080+ }
1081+ continue ;
1082+ }
1083+ if (key == INV_FAVORITE_LABEL ) // "favorite"
1084+ {
1085+ if (value.has (INV_TOGGLED_LABEL ))
1086+ {
1087+ mFavorite = value[INV_TOGGLED_LABEL ].asBoolean ();
1088+ }
1089+ continue ;
1090+ }
1091+ break ;
11211092
1122- if (i->first == INV_INVENTORY_TYPE_LABEL )
1123- {
1124- LLSD const &label = i->second ;
1125- if (label.isString ())
1126- {
1127- mInventoryType = LLInventoryType::lookup (label.asStringRef ().c_str ());
1128- }
1129- else if (label.isInteger ())
1130- {
1131- S8 type = (U8 ) label.asInteger ();
1132- mInventoryType = static_cast <LLInventoryType::EType>(type);
1133- }
1134- continue ;
1135- }
1093+ case 9 : // "parent_id", "shadow_id", "linked_id", "sale_info"
1094+ if (key == INV_PARENT_ID_LABEL )
1095+ {
1096+ mParentUUID = value;
1097+ continue ;
1098+ }
1099+ if (key == INV_SHADOW_ID_LABEL )
1100+ {
1101+ mAssetUUID = value;
1102+ LLXORCipher cipher (MAGIC_ID .mData , UUID_BYTES );
1103+ cipher.decrypt (mAssetUUID .mData , UUID_BYTES );
1104+ continue ;
1105+ }
1106+ if (key == INV_LINKED_ID_LABEL )
1107+ {
1108+ mAssetUUID = value;
1109+ continue ;
1110+ }
1111+ if (key == INV_SALE_INFO_LABEL )
1112+ {
1113+ // Sale info used to contain next owner perm. It is now in
1114+ // the permissions. Thus, we read that out, and fix legacy
1115+ // objects. It's possible this op would fail, but it
1116+ // should pick up the vast majority of the tasks.
1117+ bool has_perm_mask = false ;
1118+ U32 perm_mask = 0 ;
1119+ if (!mSaleInfo .fromLLSD (value, has_perm_mask, perm_mask))
1120+ {
1121+ return false ;
1122+ }
1123+ if (has_perm_mask)
1124+ {
1125+ if (perm_mask == PERM_NONE )
1126+ {
1127+ perm_mask = mPermissions .getMaskOwner ();
1128+ }
1129+ // fair use fix.
1130+ if (!(perm_mask & PERM_COPY ))
1131+ {
1132+ perm_mask |= PERM_TRANSFER ;
1133+ }
1134+ mPermissions .setMaskNext (perm_mask);
1135+ }
1136+ continue ;
1137+ }
1138+ break ;
11361139
1137- if (i->first == INV_FLAGS_LABEL )
1138- {
1139- LLSD const &label = i->second ;
1140- if (label.isBinary ())
1141- {
1142- mFlags = ll_U32_from_sd (label);
1143- }
1144- else if (label.isInteger ())
1145- {
1146- mFlags = label.asInteger ();
1147- }
1148- continue ;
1149- }
1140+ case 10 : // "created_at", "thumbnail"
1141+ if (key == INV_CREATION_DATE_LABEL )
1142+ {
1143+ mCreationDate = value.asInteger ();
1144+ continue ;
1145+ }
1146+ if (key == INV_THUMBNAIL_LABEL )
1147+ {
1148+ if (value.has (INV_ASSET_ID_LABEL ))
1149+ {
1150+ mThumbnailUUID = value[INV_ASSET_ID_LABEL ];
1151+ }
1152+ /* Example:
1153+ <key> asset_id </key>
1154+ <uuid> acc0ec86 - 17f2 - 4b92 - ab41 - 6718b1f755f7 </uuid>
1155+ <key> perms </key>
1156+ <integer> 8 </integer>
1157+ <key>service</key>
1158+ <integer> 3 </integer>
1159+ <key>version</key>
1160+ <integer> 1 </key>
1161+ */
1162+ continue ;
1163+ }
1164+ break ;
11501165
1151- if (i-> first == INV_NAME_LABEL )
1152- {
1153- mName = i-> second . asString ();
1154- LLStringUtil::replaceNonstandardASCII ( mName , ' ' );
1155- LLStringUtil::replaceChar ( mName , ' | ' , ' ' ) ;
1156- continue ;
1157- }
1166+ case 11 : // "permissions"
1167+ if (key == INV_PERMISSIONS_LABEL )
1168+ {
1169+ mPermissions . importLLSD (value );
1170+ continue ;
1171+ }
1172+ break ;
11581173
1159- if (i->first == INV_DESC_LABEL )
1160- {
1161- mDescription = i->second .asString ();
1162- LLStringUtil::replaceNonstandardASCII (mDescription , ' ' );
1163- continue ;
1164- }
1174+ case 12 : // "thumbnail_id"
1175+ if (key == INV_THUMBNAIL_ID_LABEL )
1176+ {
1177+ mThumbnailUUID = value.asUUID ();
1178+ continue ;
1179+ }
1180+ break ;
11651181
1166- if (i->first == INV_CREATION_DATE_LABEL )
1167- {
1168- mCreationDate = i->second .asInteger ();
1169- continue ;
1182+ default :
1183+ // Unknown field - skip
1184+ break ;
11701185 }
11711186 }
11721187
0 commit comments