LLSD LLMaterialID::asLLSD() const
{
	LLSD::Binary materialIDBinary;

	materialIDBinary.resize(MATERIAL_ID_SIZE * sizeof(U8));
	memcpy(materialIDBinary.data(), mID, MATERIAL_ID_SIZE * sizeof(U8));

	LLSD materialID = materialIDBinary;
	return materialID;
}
Exemple #2
0
	// The lexical param types here intentionally diverge from the declaration
	// in our header file. In lltut.h, LLSD is only a forward-declared type;
	// we have no access to its LLSD::Binary nested type, and so must restate
	// it explicitly to declare this overload. However, an overload that does
	// NOT match LLSD::Binary does us no good whatsoever: it would never be
	// engaged. Stating LLSD::Binary for this definition at least means that
	// if the LLSD::Binary type ever diverges from what we expect in lltut.h,
	// that divergence will produce an error: no definition will match that
	// declaration.
	void ensure_equals(const std::string& msg,
		const LLSD::Binary& actual, const LLSD::Binary& expected)
	{
		ensure_equals(msg + " size", actual.size(), expected.size());
		
		LLSD::Binary::const_iterator i, j;
		int k;
		for (i = actual.begin(), j = expected.begin(), k = 0;
			i != actual.end();
			++i, ++j, ++k)
		{
			ensure_equals(msg + " field", *i, *j);
		}
	}
bool LLCrashLogger::readMinidump(std::string minidump_path)
{
	size_t length=0;

	std::ifstream minidump_stream(minidump_path.c_str(), std::ios_base::in | std::ios_base::binary);
	if(minidump_stream.is_open())
	{
		minidump_stream.seekg(0, std::ios::end);
		length = (size_t)minidump_stream.tellg();
		minidump_stream.seekg(0, std::ios::beg);
		
		LLSD::Binary data;
		data.resize(length);
		
		minidump_stream.read(reinterpret_cast<char *>(&(data[0])),length);
		minidump_stream.close();
		
		mCrashInfo["Minidump"] = data;
	}
	return (length>0?true:false);
}
void LLPathfindingNavMeshZone::NavMeshLocation::handleNavMesh(LLPathfindingNavMesh::ENavMeshRequestStatus pNavMeshRequestStatus, const LLPathfindingNavMeshStatus &pNavMeshStatus, const LLSD::Binary &pNavMeshData)
{
	llassert(mRegionUUID == pNavMeshStatus.getRegionUUID());

	if ((pNavMeshRequestStatus == LLPathfindingNavMesh::kNavMeshRequestCompleted) &&
		(!mHasNavMesh || (mNavMeshVersion != pNavMeshStatus.getVersion())))
	{
		llassert(!pNavMeshData.empty());
		mHasNavMesh = true;
		mNavMeshVersion = pNavMeshStatus.getVersion();
		llassert(LLPathingLib::getInstance() != NULL);
		if (LLPathingLib::getInstance() != NULL)
		{
			LLPathingLib::getInstance()->extractNavMeshSrcFromLLSD(pNavMeshData, mDirection);
		}
	}

	mRequestStatus = pNavMeshRequestStatus;
	mNavMeshStatus = pNavMeshStatus.getStatus();
	mLocationCallback();
}
void LLFilterSD2XMLRPC::streamOut(std::ostream& ostr, const LLSD& sd)
{
	ostr << "<value>";
	switch(sd.type())
	{
	case LLSD::TypeMap:
	{
#if LL_SPEW_STREAM_OUT_DEBUGGING
		llinfos << "streamOut(map) BEGIN" << llendl;
#endif
		ostr << "<struct>";
		if(ostr.fail())
		{
			llinfos << "STREAM FAILURE writing struct" << llendl;
		}
		LLSD::map_const_iterator it = sd.beginMap();
		LLSD::map_const_iterator end = sd.endMap();
		for(; it != end; ++it)
		{
			ostr << "<member><name>" << xml_escape_string((*it).first)
				<< "</name>";
			streamOut(ostr, (*it).second);
			if(ostr.fail())
			{
				llinfos << "STREAM FAILURE writing '" << (*it).first
						<< "' with sd type " << (*it).second.type() << llendl;
			}
			ostr << "</member>";
		}
		ostr << "</struct>";
#if LL_SPEW_STREAM_OUT_DEBUGGING
		llinfos << "streamOut(map) END" << llendl;
#endif
		break;
	}
	case LLSD::TypeArray:
	{
#if LL_SPEW_STREAM_OUT_DEBUGGING
		llinfos << "streamOut(array) BEGIN" << llendl;
#endif
		ostr << "<array><data>";
		LLSD::array_const_iterator it = sd.beginArray();
		LLSD::array_const_iterator end = sd.endArray();
		for(; it != end; ++it)
		{
			streamOut(ostr, *it);
			if(ostr.fail())
			{
				llinfos << "STREAM FAILURE writing array element sd type "
						<< (*it).type() << llendl;
			}
		}
#if LL_SPEW_STREAM_OUT_DEBUGGING
		llinfos << "streamOut(array) END" << llendl;
#endif
		ostr << "</data></array>";
		break;
	}
	case LLSD::TypeUndefined:
		// treat undefined as a bool with a false value.
	case LLSD::TypeBoolean:
#if LL_SPEW_STREAM_OUT_DEBUGGING
		llinfos << "streamOut(bool)" << llendl;
#endif
		ostr << "<boolean>" << (sd.asBoolean() ? "1" : "0") << "</boolean>";
		break;
	case LLSD::TypeInteger:
#if LL_SPEW_STREAM_OUT_DEBUGGING
		llinfos << "streamOut(int)" << llendl;
#endif
		ostr << "<i4>" << sd.asInteger() << "</i4>";
		break;
	case LLSD::TypeReal:
#if LL_SPEW_STREAM_OUT_DEBUGGING
		llinfos << "streamOut(real)" << llendl;
#endif
		ostr << "<double>" << sd.asReal() << "</double>";
		break;
	case LLSD::TypeString:
#if LL_SPEW_STREAM_OUT_DEBUGGING
		llinfos << "streamOut(string)" << llendl;
#endif
		ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>";
		break;
	case LLSD::TypeUUID:
#if LL_SPEW_STREAM_OUT_DEBUGGING
		llinfos << "streamOut(uuid)" << llendl;
#endif
		// serialize it as a string
		ostr << "<string>" << sd.asString() << "</string>";
		break;
	case LLSD::TypeURI:
	{
#if LL_SPEW_STREAM_OUT_DEBUGGING
		llinfos << "streamOut(uri)" << llendl;
#endif
		// serialize it as a string
		ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>";
		break;
	}
	case LLSD::TypeBinary:
	{
#if LL_SPEW_STREAM_OUT_DEBUGGING
		llinfos << "streamOut(binary)" << llendl;
#endif
		// this is pretty inefficient, but we'll deal with that
		// problem when it becomes one.
		ostr << "<base64>";
		LLSD::Binary buffer = sd.asBinary();
		if(!buffer.empty())
		{
			// *TODO: convert to LLBase64
			int b64_buffer_length = apr_base64_encode_len(buffer.size());
			char* b64_buffer = new char[b64_buffer_length];
			b64_buffer_length = apr_base64_encode_binary(
				b64_buffer,
				&buffer[0],
				buffer.size());
			ostr.write(b64_buffer, b64_buffer_length - 1);
			delete[] b64_buffer;
		}
		ostr << "</base64>";
		break;
	}
	case LLSD::TypeDate:
#if LL_SPEW_STREAM_OUT_DEBUGGING
		llinfos << "streamOut(date)" << llendl;
#endif
		// no need to escape this since it will be alpha-numeric.
		ostr << "<dateTime.iso8601>" << sd.asString() << "</dateTime.iso8601>";
		break;
	default:
		// unhandled type
		llwarns << "Unhandled structured data type: " << sd.type()
			<< llendl;
		break;
	}
	ostr << "</value>";
}
void LLMaterialID::parseFromBinary (const LLSD::Binary& pMaterialID)
{
	llassert(pMaterialID.size() == (MATERIAL_ID_SIZE * sizeof(U8)));
	memcpy(mID, &pMaterialID[0], MATERIAL_ID_SIZE * sizeof(U8));
}
S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const
{
	S32 format_count = 1;
	std::string pre;
	std::string post;

	if (options & LLSDFormatter::OPTIONS_PRETTY)
	{
		for (U32 i = 0; i < level; i++)
		{
			pre += "    ";
		}
		post = "\n";
	}

	switch(data.type())
	{
	case LLSD::TypeMap:
		if (0 == data.size())
		{
			ostr << pre << "<map />" << post;
		}
		else
		{
			ostr << pre << "<map>" << post;
			LLSD::map_const_iterator iter = data.beginMap();
			LLSD::map_const_iterator end = data.endMap();
			for (; iter != end; ++iter)
			{
				ostr << pre << "<key>" << escapeString((*iter).first) << "</key>" << post;
				format_count += format_impl((*iter).second, ostr, options, level + 1);
			}
			ostr << pre <<  "</map>" << post;
		}
		break;

	case LLSD::TypeArray:
		if (0 == data.size())
		{
			ostr << pre << "<array />" << post;
		}
		else
		{
			ostr << pre << "<array>" << post;
			LLSD::array_const_iterator iter = data.beginArray();
			LLSD::array_const_iterator end = data.endArray();
			for(; iter != end; ++iter)
			{
				format_count += format_impl(*iter, ostr, options, level + 1);
			}
			ostr << pre << "</array>" << post;
		}
		break;

	case LLSD::TypeUndefined:
		ostr << pre << "<undef />" << post;
		break;

	case LLSD::TypeBoolean:
		ostr << pre << "<boolean>";
		if (mBoolAlpha || (ostr.flags() & std::ios::boolalpha))
		{
			ostr << (data.asBoolean() ? "true" : "false");
		}
		else
		{
			ostr << (data.asBoolean() ? 1 : 0);
		}
		ostr << "</boolean>" << post;
		break;

	case LLSD::TypeInteger:
		ostr << pre << "<integer>" << data.asInteger() << "</integer>" << post;
		break;

	case LLSD::TypeReal:
		ostr << pre << "<real>";
		if (mRealFormat.empty())
		{
			ostr << data.asReal();
		}
		else
		{
			formatReal(data.asReal(), ostr);
		}
		ostr << "</real>" << post;
		break;

	case LLSD::TypeUUID:
		if (data.asUUID().isNull())
		{
			ostr << pre << "<uuid />" << post;
		}
		else
		{
			ostr << pre << "<uuid>" << data.asUUID() << "</uuid>" << post;
		}
		break;

	case LLSD::TypeString:
		if (data.asString().empty()) ostr << pre << "<string />" << post;
		else ostr << pre << "<string>" << escapeString(data.asString()) <<"</string>" << post;
		break;

	case LLSD::TypeDate:
		ostr << pre << "<date>" << data.asDate() << "</date>" << post;
		break;

	case LLSD::TypeURI:
		ostr << pre << "<uri>" << escapeString(data.asString()) << "</uri>" << post;
		break;

	case LLSD::TypeBinary:
	{
		LLSD::Binary buffer = data.asBinary();
		if (buffer.empty())
		{
			ostr << pre << "<binary />" << post;
		}
		else
		{
			// *FIX: memory inefficient.
			// *TODO: convert to use LLBase64
			ostr << pre << "<binary encoding=\"base64\">";
			int b64_buffer_length = apr_base64_encode_len(buffer.size());
			char* b64_buffer = new char[b64_buffer_length];
			b64_buffer_length = apr_base64_encode_binary(b64_buffer,
														 &buffer[0],
														 buffer.size());
			ostr.write(b64_buffer, b64_buffer_length - 1);
			delete[] b64_buffer;
			ostr << "</binary>" << post;
		}
		break;
	}

	default:
		// *NOTE: This should never happen.
		ostr << pre << "<undef />" << post;
		break;
	}
	return format_count;
}
void LLMaterialMgr::processPutQueue()
{
	typedef std::map<LLViewerRegion*, LLSD> regionput_request_map;
	regionput_request_map requests;

	put_queue_t::iterator loopQueue = mPutQueue.begin();
	while (mPutQueue.end() != loopQueue)
	{
		put_queue_t::iterator itQueue = loopQueue++;

		const LLUUID& object_id = itQueue->first;
		const LLViewerObject* objectp = gObjectList.findObject(object_id);
		if ( !objectp )
		{
			LL_WARNS("Materials") << "Object is NULL" << LL_ENDL;
			mPutQueue.erase(itQueue);
		}
		else
		{
			LLViewerRegion* regionp = objectp->getRegion();
			if ( !regionp )
		{
				LL_WARNS("Materials") << "Object region is NULL" << LL_ENDL;
				mPutQueue.erase(itQueue);
		}
			else if ( regionp->capabilitiesReceived() && !regionp->materialsCapThrottled())
			{
		LLSD& facesData = requests[regionp];

		facematerial_map_t& face_map = itQueue->second;
				U32 max_entries = regionp->getMaxMaterialsPerTransaction();
		facematerial_map_t::iterator itFace = face_map.begin();
				while ( (face_map.end() != itFace) && (facesData.size() < (int)max_entries) )
		{
			LLSD faceData = LLSD::emptyMap();
			faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
			faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID());
			if (!itFace->second.isNull())
			{
				faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD();
			}
			facesData.append(faceData);
			face_map.erase(itFace++);
		}
		if (face_map.empty())
		{
			mPutQueue.erase(itQueue);
		}
	}
		}
	}

	for (regionput_request_map::const_iterator itRequest = requests.begin(); itRequest != requests.end(); ++itRequest)
	{
		LLViewerRegion* regionp = itRequest->first;
		std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
		if (capURL.empty())
		{
			LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
				<< "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
			continue;
		}

		LLSD materialsData = LLSD::emptyMap();
		materialsData[MATERIALS_CAP_FULL_PER_FACE_FIELD] = itRequest->second;

		std::string materialString = zip_llsd(materialsData);

		S32 materialSize = materialString.size();

		if (materialSize > 0)
		{
			LLSD::Binary materialBinary;
			materialBinary.resize(materialSize);
			memcpy(materialBinary.data(), materialString.data(), materialSize);

			LLSD putData = LLSD::emptyMap();
			putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;

			LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL;
			LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2));
			LLHTTPClient::put(capURL, putData, materialsResponder);
			regionp->resetMaterialsCapThrottle();
		}
		else
		{
			LL_ERRS("debugMaterials") << "cannot zip LLSD binary content" << LL_ENDL;
		}
	}
}
void LLMaterialMgr::processGetQueue()
{
	get_queue_t::iterator loopRegionQueue = mGetQueue.begin();
	while (mGetQueue.end() != loopRegionQueue)
	{
		get_queue_t::iterator itRegionQueue = loopRegionQueue++;

		const LLUUID& region_id = itRegionQueue->first;
		if (isGetAllPending(region_id))
		{
			continue;
		}

		LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
		if (!regionp)
		{
			LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
			mGetQueue.erase(itRegionQueue);
			continue;
		}
		else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())
		{
			continue;
		}
		else if (mGetAllRequested.end() == mGetAllRequested.find(region_id))
		{
			LL_DEBUGS("Materials") << "calling getAll for " << regionp->getName() << LL_ENDL;
			getAll(region_id);
			continue;
		}

		const std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
		if (capURL.empty())
		{
			LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
				<< "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
			mGetQueue.erase(itRegionQueue);
			continue;
		}

		LLSD materialsData = LLSD::emptyArray();

		material_queue_t& materials = itRegionQueue->second;
		U32 max_entries = regionp->getMaxMaterialsPerTransaction();
		material_queue_t::iterator loopMaterial = materials.begin();
		while ( (materials.end() != loopMaterial) && (materialsData.size() < (int)max_entries) )
		{
			material_queue_t::iterator itMaterial = loopMaterial++;
			materialsData.append((*itMaterial).asLLSD());
			materials.erase(itMaterial);
			markGetPending(region_id, *itMaterial);
		}
		if (materials.empty())
		{
			mGetQueue.erase(itRegionQueue);
		}
		
		std::string materialString = zip_llsd(materialsData);

		S32 materialSize = materialString.size();
		if (materialSize <= 0)
		{
			LL_ERRS("Materials") << "cannot zip LLSD binary content" << LL_ENDL;
			return;
		}

		LLSD::Binary materialBinary;
		materialBinary.resize(materialSize);
		memcpy(materialBinary.data(), materialString.data(), materialSize);

		LLSD postData = LLSD::emptyMap();
		postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;

		LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("POST", capURL, boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id));
		LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials." 
			<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
		LLHTTPClient::post(capURL, postData, materialsResponder);
		regionp->resetMaterialsCapThrottle();
	}
}