Ejemplo n.º 1
0
	/*! DRAGONS: We use the current UTF16String GetString trait to ensure that we always have the correct handling,
	 *           even if the user wants these strings handled differently (i.e. we do it their way!)
	 */
	std::list<std::string> SplitStringArray(const MDObjectPtr &Array)
	{
		std::list<std::string> Ret;

		// Quit early if an invalid parameter
		if(!Array) return Ret;

		// Build a working string
		static MDTypePtr ValType = MDType::Find("UTF16String");
		MDObjectPtr Value = ValType ? new MDObject(ValType) : NULL;
		if(!Value)
		{
			error("Can't build UTF16String value required by SplitStringArray() - need this type to be defined in the dictionary file\n");
			return Ret;
		}

		// Assemble the data value (which may be an array of sub-values)
		DataChunkPtr Data = Array->PutData();

		// Get a pointer to the start of the data
		UInt8 *pData = Data->Data;

		// The number of bytes of data to split
		size_t BytesLeft = Data->Size;

		while(BytesLeft > 1)
		{
			// Find the end of the current string
			size_t Len = 0;
			UInt8 *p = pData;
			while(BytesLeft > 1)
			{
				BytesLeft -= 2;
				Len += 2;
				UInt16 Char = GetU16(p);
				p += 2;

				// End when we find a null
				if(Char == 0) break;
			}

			// Copy this string to the working value
			Value->SetValue(pData, Len);

			// Read out the traits-formatted version of the string
			Ret.push_back(Value->GetString());

			// Move the pointer forward to the next value after the string terminator
			pData = p;
		}

		return Ret;
	}
Ejemplo n.º 2
0
	/*! DRAGONS: We use the current UTF16String SetString trait to ensure that we always have the correct handling,
	 *           even if the user wants these strings handled differently (i.e. we do it their way!)
	 */
	void SetStringArray(MDObjectPtr &Array, const std::list<std::string> &Strings)
	{
		// Abort if we are send a NULL pointer
		if(!Array) return;

		// Don't bother if we have nothing to do
		if(Strings.empty()) return;

		// Build a working string
		static MDTypePtr ValType = MDType::Find("UTF16String");
		MDObjectPtr Value = ValType ? new MDObject(ValType) : NULL;
		if(!Value)
		{
			error("Can't build UTF16String value required by SetStringArray() - need this type to be defined in the dictionary file\n");
			return;
		}

		// Get a buffer in which to build the final string array, make it quite granular as it will keep growing
		DataChunkPtr Buffer = new DataChunk();
		Buffer->SetGranularity(16 * 1024);

		std::list<std::string>::const_iterator it = Strings.begin();
		while(it != Strings.end())
		{
			Value->SetString(*it);
			DataChunkPtr ThisString = Value->PutData();
			Buffer->Append(ThisString);
			
			// Add terminator if required, i.e. if the sub-string we just added did not end in a zero
			UInt8 *p = &ThisString->Data[ThisString->Size];

			// Terminate if either of the last two bytes in the current buffer is non-zero - or if the string was too short to have a terminator
			if((ThisString->Size) < 2 || ((*(--p) != 0) || (*(--p) != 0)))
			{
				const UInt8 Term[2] = { 0, 0};
				Buffer->Set(2, Term, Buffer->Size);
			}

			it++;
		}

		// Set the value from this buffer
		Array->SetValue(Buffer);
	}