llsdutil.cpp

Go to the documentation of this file.
00001 
00034 #include "linden_common.h"
00035 
00036 #include "llsdutil.h"
00037 
00038 #if LL_WINDOWS
00039 #       define WIN32_LEAN_AND_MEAN
00040 #       include <winsock2.h>    // for htonl
00041 #elif LL_LINUX || LL_SOLARIS
00042 #       include <netinet/in.h>
00043 #elif LL_DARWIN
00044 #       include <arpa/inet.h>
00045 #endif
00046 
00047 #include "llsdserialize.h"
00048 
00049 // vector3
00050 LLSD ll_sd_from_vector3(const LLVector3& vec)
00051 {
00052         LLSD rv;
00053         rv.append((F64)vec.mV[VX]);
00054         rv.append((F64)vec.mV[VY]);
00055         rv.append((F64)vec.mV[VZ]);
00056         return rv;
00057 }
00058 
00059 LLVector3 ll_vector3_from_sd(const LLSD& sd, S32 start_index)
00060 {
00061         LLVector3 rv;
00062         rv.mV[VX] = (F32)sd[start_index].asReal();
00063         rv.mV[VY] = (F32)sd[++start_index].asReal();
00064         rv.mV[VZ] = (F32)sd[++start_index].asReal();
00065         return rv;
00066 }
00067 
00068 // vector4
00069 LLSD ll_sd_from_vector4(const LLVector4& vec)
00070 {
00071         LLSD rv;
00072         rv.append((F64)vec.mV[VX]);
00073         rv.append((F64)vec.mV[VY]);
00074         rv.append((F64)vec.mV[VZ]);
00075         rv.append((F64)vec.mV[VW]);
00076         return rv;
00077 }
00078 
00079 LLVector4 ll_vector4_from_sd(const LLSD& sd, S32 start_index)
00080 {
00081         LLVector4 rv;
00082         rv.mV[VX] = (F32)sd[start_index].asReal();
00083         rv.mV[VY] = (F32)sd[++start_index].asReal();
00084         rv.mV[VZ] = (F32)sd[++start_index].asReal();
00085         rv.mV[VW] = (F32)sd[++start_index].asReal();
00086         return rv;
00087 }
00088 
00089 // vector3d
00090 LLSD ll_sd_from_vector3d(const LLVector3d& vec)
00091 {
00092         LLSD rv;
00093         rv.append(vec.mdV[VX]);
00094         rv.append(vec.mdV[VY]);
00095         rv.append(vec.mdV[VZ]);
00096         return rv;
00097 }
00098 
00099 LLVector3d ll_vector3d_from_sd(const LLSD& sd, S32 start_index)
00100 {
00101         LLVector3d rv;
00102         rv.mdV[VX] = sd[start_index].asReal();
00103         rv.mdV[VY] = sd[++start_index].asReal();
00104         rv.mdV[VZ] = sd[++start_index].asReal();
00105         return rv;
00106 }
00107 
00108 //vector2
00109 LLSD ll_sd_from_vector2(const LLVector2& vec)
00110 {
00111         LLSD rv;
00112         rv.append((F64)vec.mV[VX]);
00113         rv.append((F64)vec.mV[VY]);
00114         return rv;
00115 }
00116 
00117 LLVector2 ll_vector2_from_sd(const LLSD& sd)
00118 {
00119         LLVector2 rv;
00120         rv.mV[VX] = (F32)sd[0].asReal();
00121         rv.mV[VY] = (F32)sd[1].asReal();
00122         return rv;
00123 }
00124 
00125 // Quaternion
00126 LLSD ll_sd_from_quaternion(const LLQuaternion& quat)
00127 {
00128         LLSD rv;
00129         rv.append((F64)quat.mQ[VX]);
00130         rv.append((F64)quat.mQ[VY]);
00131         rv.append((F64)quat.mQ[VZ]);
00132         rv.append((F64)quat.mQ[VW]);
00133         return rv;
00134 }
00135 
00136 LLQuaternion ll_quaternion_from_sd(const LLSD& sd)
00137 {
00138         LLQuaternion quat;
00139         quat.mQ[VX] = (F32)sd[0].asReal();
00140         quat.mQ[VY] = (F32)sd[1].asReal();
00141         quat.mQ[VZ] = (F32)sd[2].asReal();
00142         quat.mQ[VW] = (F32)sd[3].asReal();
00143         return quat;
00144 }
00145 
00146 // color4
00147 LLSD ll_sd_from_color4(const LLColor4& c)
00148 {
00149         LLSD rv;
00150         rv.append(c.mV[0]);
00151         rv.append(c.mV[1]);
00152         rv.append(c.mV[2]);
00153         rv.append(c.mV[3]);
00154         return rv;
00155 }
00156 
00157 LLColor4 ll_color4_from_sd(const LLSD& sd)
00158 {
00159         LLColor4 c;
00160         c.mV[0] = (F32)sd[0].asReal();
00161         c.mV[1] = (F32)sd[1].asReal();
00162         c.mV[2] = (F32)sd[2].asReal();
00163         c.mV[3] = (F32)sd[3].asReal();
00164         return c;
00165 }
00166 
00167 // U32
00168 LLSD ll_sd_from_U32(const U32 val)
00169 {
00170         std::vector<U8> v;
00171         U32 net_order = htonl(val);
00172 
00173         v.resize(4);
00174         memcpy(&(v[0]), &net_order, 4);         /* Flawfinder: ignore */
00175 
00176         return LLSD(v);
00177 }
00178 
00179 U32 ll_U32_from_sd(const LLSD& sd)
00180 {
00181         U32 ret;
00182         std::vector<U8> v = sd.asBinary();
00183         if (v.size() < 4)
00184         {
00185                 return 0;
00186         }
00187         memcpy(&ret, &(v[0]), 4);               /* Flawfinder: ignore */
00188         ret = ntohl(ret);
00189         return ret;
00190 }
00191 
00192 //U64
00193 LLSD ll_sd_from_U64(const U64 val)
00194 {
00195         std::vector<U8> v;
00196         U32 high, low;
00197 
00198         high = (U32)(val >> 32);
00199         low = (U32)val;
00200         high = htonl(high);
00201         low = htonl(low);
00202 
00203         v.resize(8);
00204         memcpy(&(v[0]), &high, 4);              /* Flawfinder: ignore */
00205         memcpy(&(v[4]), &low, 4);               /* Flawfinder: ignore */
00206 
00207         return LLSD(v);
00208 }
00209 
00210 U64 ll_U64_from_sd(const LLSD& sd)
00211 {
00212         U32 high, low;
00213         std::vector<U8> v = sd.asBinary();
00214 
00215         if (v.size() < 8)
00216         {
00217                 return 0;
00218         }
00219 
00220         memcpy(&high, &(v[0]), 4);              /* Flawfinder: ignore */
00221         memcpy(&low, &(v[4]), 4);               /* Flawfinder: ignore */
00222         high = ntohl(high);
00223         low = ntohl(low);
00224 
00225         return ((U64)high) << 32 | low;
00226 }
00227 
00228 // IP Address (stored in net order in a U32, so don't need swizzling)
00229 LLSD ll_sd_from_ipaddr(const U32 val)
00230 {
00231         std::vector<U8> v;
00232 
00233         v.resize(4);
00234         memcpy(&(v[0]), &val, 4);               /* Flawfinder: ignore */
00235 
00236         return LLSD(v);
00237 }
00238 
00239 U32 ll_ipaddr_from_sd(const LLSD& sd)
00240 {
00241         U32 ret;
00242         std::vector<U8> v = sd.asBinary();
00243         if (v.size() < 4)
00244         {
00245                 return 0;
00246         }
00247         memcpy(&ret, &(v[0]), 4);               /* Flawfinder: ignore */
00248         return ret;
00249 }
00250 
00251 // Converts an LLSD binary to an LLSD string
00252 LLSD ll_string_from_binary(const LLSD& sd)
00253 {
00254         std::vector<U8> value = sd.asBinary();
00255         std::string str;
00256         str.resize(value.size());
00257         memcpy(&str[0], &value[0], value.size());
00258         return str;
00259 }
00260 
00261 // Converts an LLSD string to an LLSD binary
00262 LLSD ll_binary_from_string(const LLSD& sd)
00263 {
00264         std::vector<U8> binary_value;
00265 
00266         LLString string_value = sd.asString();
00267         const char* string_p = string_value.c_str();
00268         while (*string_p)
00269         {
00270                 binary_value.push_back(*string_p);
00271                 string_p++;
00272         }
00273 
00274         binary_value.push_back('\0');
00275 
00276         return binary_value;
00277 }
00278 
00279 char* ll_print_sd(const LLSD& sd)
00280 {
00281         const U32 bufferSize = 10 * 1024;
00282         static char buffer[bufferSize];
00283         std::ostringstream stream;
00284         //stream.rdbuf()->pubsetbuf(buffer, bufferSize);
00285         stream << LLSDOStreamer<LLSDXMLFormatter>(sd);
00286         stream << std::ends;
00287         strncpy(buffer, stream.str().c_str(), bufferSize);
00288         buffer[bufferSize - 1] = '\0';
00289         return buffer;
00290 }
00291 
00292 char* ll_pretty_print_sd(const LLSD& sd)
00293 {
00294         const U32 bufferSize = 10 * 1024;
00295         static char buffer[bufferSize];
00296         std::ostringstream stream;
00297         //stream.rdbuf()->pubsetbuf(buffer, bufferSize);
00298         stream << LLSDOStreamer<LLSDXMLFormatter>(sd, LLSDFormatter::OPTIONS_PRETTY);
00299         stream << std::ends;
00300         strncpy(buffer, stream.str().c_str(), bufferSize);
00301         buffer[bufferSize - 1] = '\0';
00302         return buffer;
00303 }
00304 
00305 //compares the structure of an LLSD to a template LLSD and stores the
00306 //"valid" values in a 3rd LLSD.  Default values are stored in the template
00307 //
00308 //If the llsd to test has a specific key to a map and the values
00309 //are not of the same type, false is returned or if the LLSDs are not
00310 //of the same value.  Ordering of arrays matters
00311 //Otherwise, returns true
00312 BOOL compare_llsd_with_template(
00313         const LLSD& llsd_to_test,
00314         const LLSD& template_llsd,
00315         LLSD& resultant_llsd)
00316 {
00317         if (
00318                 llsd_to_test.isUndefined() &&
00319                 template_llsd.isDefined() )
00320         {
00321                 resultant_llsd = template_llsd;
00322                 return TRUE;
00323         }
00324         else if ( llsd_to_test.type() != template_llsd.type() )
00325         {
00326                 resultant_llsd = LLSD();
00327                 return FALSE;
00328         }
00329 
00330         if ( llsd_to_test.isArray() )
00331         {
00332                 //they are both arrays
00333                 //we loop over all the items in the template
00334                 //verifying that the to_test has a subset (in the same order)
00335                 //any shortcoming in the testing_llsd are just taken
00336                 //to be the rest of the template
00337                 LLSD data;
00338                 LLSD::array_const_iterator test_iter;
00339                 LLSD::array_const_iterator template_iter;
00340 
00341                 resultant_llsd = LLSD::emptyArray();
00342                 test_iter = llsd_to_test.beginArray();
00343 
00344                 for (
00345                         template_iter = template_llsd.beginArray();
00346                         (template_iter != template_llsd.endArray() &&
00347                          test_iter != llsd_to_test.endArray());
00348                         ++template_iter)
00349                 {
00350                         if ( !compare_llsd_with_template(
00351                                          *test_iter,
00352                                          *template_iter,
00353                                          data) )
00354                         {
00355                                 resultant_llsd = LLSD();
00356                                 return FALSE;
00357                         }
00358                         else
00359                         {
00360                                 resultant_llsd.append(data);
00361                         }
00362 
00363                         ++test_iter;
00364                 }
00365 
00366                 //so either the test or the template ended
00367                 //we do another loop now to the end of the template
00368                 //grabbing the default values
00369                 for (;
00370                          template_iter != template_llsd.endArray();
00371                          ++template_iter)
00372                 {
00373                         resultant_llsd.append(*template_iter);
00374                 }
00375         }
00376         else if ( llsd_to_test.isMap() )
00377         {
00378                 //now we loop over the keys of the two maps
00379                 //any excess is taken from the template
00380                 //excess is ignored in the test
00381                 LLSD value;
00382                 LLSD::map_const_iterator template_iter;
00383 
00384                 resultant_llsd = LLSD::emptyMap();
00385                 for (
00386                         template_iter = template_llsd.beginMap();
00387                         template_iter != template_llsd.endMap();
00388                         ++template_iter)
00389                 {
00390                         if ( llsd_to_test.has(template_iter->first) )
00391                         {
00392                                 //the test LLSD has the same key
00393                                 if ( !compare_llsd_with_template(
00394                                                  llsd_to_test[template_iter->first],
00395                                                  template_iter->second,
00396                                                  value) )
00397                                 {
00398                                         resultant_llsd = LLSD();
00399                                         return FALSE;
00400                                 }
00401                                 else
00402                                 {
00403                                         resultant_llsd[template_iter->first] = value;
00404                                 }
00405                         }
00406                         else
00407                         {
00408                                 //test llsd doesn't have it...take the
00409                                 //template as default value
00410                                 resultant_llsd[template_iter->first] =
00411                                         template_iter->second;
00412                         }
00413                 }
00414         }
00415         else
00416         {
00417                 //of same type...take the test llsd's value
00418                 resultant_llsd = llsd_to_test;
00419         }
00420 
00421 
00422         return TRUE;
00423 }

Generated on Fri May 16 08:32:08 2008 for SecondLife by  doxygen 1.5.5