Example #1
0
ZTupleValue ZUtil_BitTorrent::sTupleValueFromStream(const ZStreamU& s)
	{
	ZTupleValue theTV;
	const uint8 type = s.ReadUInt8();
	switch (type)
		{
		case 'd':
			{
			// Dictionary
			ZTuple& theTuple = theTV.SetMutableTuple();
			for (;;)
				{
				if (sTryRead_Byte(s, 'e'))
					break;
				string name = sReadString(s);
				theTuple.SetValue(name, sTupleValueFromStream(s));
				}
			break;
			}
		case 'l':
			{
			// List
			vector<ZTupleValue>& theVector = theTV.SetMutableVector();
			for (;;)
				{
				if (sTryRead_Byte(s, 'e'))
					break;
				theVector.push_back(sTupleValueFromStream(s));
				}
			break;
			}
		case 'i':
			{
			// Integer
			theTV = sReadInteger(s);
			uint8 terminator = s.ReadUInt8();
			if (terminator != 'e')
				throw runtime_error("Expected 'e' terminator for integer");
			break;
			}
		default:
			{
			s.Unread();
			// It must be a 'string'. It could be valid UTF-8, or could be
			// arbitrary bytes, so we call sReadStringish.
			theTV = sReadStringish(s);
			break;
			}
		}
	return theTV;
	}
Example #2
0
static bool sFromStrim_TupleValue(const ZStrimU& iStrimU, ZTupleValue& oTupleValue)
{
    using namespace ZUtil_Strim;

    sSkip_WSAndCPlusPlusComments(iStrimU);

    if (sTryRead_CP(iStrimU, '['))
    {
        sFromStrim_BodyOfVector(iStrimU, oTupleValue.SetMutableVector());

        sSkip_WSAndCPlusPlusComments(iStrimU);

        if (!sTryRead_CP(iStrimU, ']'))
            throw ParseException("Expected ']' to close a vector");
    }
    else if (sTryRead_CP(iStrimU, '{'))
    {
        // It's a tuple.
        sFromStrim_BodyOfTuple(iStrimU, oTupleValue.SetMutableTuple());

        sSkip_WSAndCPlusPlusComments(iStrimU);

        if (!sTryRead_CP(iStrimU, '}'))
            throw ParseException("Expected '}' to close a tuple");
    }
    else if (sTryRead_CP(iStrimU, '"'))
    {
        // It's a string, delimited by ".
        sReadQuotedString_Quote(iStrimU, oTupleValue);
    }
    else if (sTryRead_CP(iStrimU, '\''))
    {
        // It's a string, delimited by '.
        sReadQuotedString_Apos(iStrimU, oTupleValue);
    }
    else if (sTryRead_CP(iStrimU, '('))
    {
        // It's a raw.
        ZMemoryBlock theMemoryBlock;
        ZStreamR_HexStrim(iStrimU).CopyAllTo(ZStreamRWPos_MemoryBlock(theMemoryBlock));
        sSkip_WSAndCPlusPlusComments(iStrimU);

        if (!sTryRead_CP(iStrimU, ')'))
            throw ParseException("Expected ')' to close a raw");
        oTupleValue.SetRaw(theMemoryBlock);
    }
    else
    {
        string theTypeLC, theType;
        if (!ZUtil_Tuple::sRead_Identifier(iStrimU, &theTypeLC, &theType))
        {
            // We couldn't find any of the special characters, nor could
            // we read a type designator, so we fail to read a tuplevalue,
            // which is not a parse error at this stage -- it might be for our caller.
            return false;
        }

        if (theTypeLC == "null")
        {
            oTupleValue.SetNull();
        }
        else if (theTypeLC == "false")
        {
            oTupleValue.SetBool(false);
        }
        else if (theTypeLC == "true")
        {
            oTupleValue.SetBool(true);
        }
        else
        {
            sSkip_WSAndCPlusPlusComments(iStrimU);
            if (!sTryRead_CP(iStrimU, '('))
                throw ParseException("Expected '(' following a type designator");

            sSkip_WSAndCPlusPlusComments(iStrimU);

            if (theTypeLC == "type")
            {
                string typeValueLC, typeValue;
                if (!ZUtil_Tuple::sRead_Identifier(iStrimU, &typeValueLC, &typeValue))
                    throw ParseException("Expected a type name");

                if (typeValueLC == "null") oTupleValue.SetType(eZType_Null);
                else if (typeValueLC == "string") oTupleValue.SetType(eZType_String);
                else if (typeValueLC == "cstring") oTupleValue.SetType(eZType_CString);
                else if (typeValueLC == "int8") oTupleValue.SetType(eZType_Int8);
                else if (typeValueLC == "int16") oTupleValue.SetType(eZType_Int16);
                else if (typeValueLC == "int32") oTupleValue.SetType(eZType_Int32);
                else if (typeValueLC == "int64") oTupleValue.SetType(eZType_Int64);
                else if (typeValueLC == "float") oTupleValue.SetType(eZType_Float);
                else if (typeValueLC == "double") oTupleValue.SetType(eZType_Double);
                else if (typeValueLC == "time") oTupleValue.SetType(eZType_Time);
                else if (typeValueLC == "bool") oTupleValue.SetType(eZType_Bool);
                else if (typeValueLC == "pointer") oTupleValue.SetType(eZType_Pointer);
                else if (typeValueLC == "raw") oTupleValue.SetType(eZType_Raw);
                else if (typeValueLC == "tuple") oTupleValue.SetType(eZType_Tuple);
                else if (typeValueLC == "refcounted") oTupleValue.SetType(eZType_RefCounted);
                else if (typeValueLC == "rect") oTupleValue.SetType(eZType_Rect);
                else if (typeValueLC == "point") oTupleValue.SetType(eZType_Point);
                else if (typeValueLC == "region") oTupleValue.SetType(eZType_Region);
                else if (typeValueLC == "id") oTupleValue.SetType(eZType_ID);
                else if (typeValueLC == "vector") oTupleValue.SetType(eZType_Vector);
                else if (typeValueLC == "type") oTupleValue.SetType(eZType_Type);
                else if (typeValueLC == "time") oTupleValue.SetType(eZType_Time);
                else
                    throw ParseException("Unknown type name '" + typeValue + "'");
            }
            else if (theTypeLC == "id")
            {
                oTupleValue.SetID(sMustRead_GenericInteger(iStrimU));
            }
            else if (theTypeLC == "int8")
            {
                oTupleValue.SetInt8(sMustRead_GenericInteger(iStrimU));
            }
            else if (theTypeLC == "int16")
            {
                oTupleValue.SetInt16(sMustRead_GenericInteger(iStrimU));
            }
            else if (theTypeLC == "int32")
            {
                oTupleValue.SetInt32(sMustRead_GenericInteger(iStrimU));
            }
            else if (theTypeLC == "int64")
            {
                oTupleValue.SetInt64(sMustRead_GenericInteger(iStrimU));
            }
            else if (theTypeLC == "bool")
            {
                string theBool;
                if (!ZUtil_Tuple::sRead_Identifier(iStrimU, &theBool, nil))
                    throw ParseException("Expected 'false' or 'true'");

                if (theBool == "true")
                    oTupleValue.SetBool(true);
                else if (theBool == "false")
                    oTupleValue.SetBool(false);
                else
                    throw ParseException("Expected 'false' or 'true'");
            }
            else if (theTypeLC == "float")
            {
                double theDouble;
                if (!sTryRead_SignedDouble(iStrimU, theDouble))
                    throw ParseException("Expected a floating point number");
                oTupleValue.SetFloat(theDouble);
            }
            else if (theTypeLC == "double")
            {
                double theDouble;
                if (!sTryRead_SignedDouble(iStrimU, theDouble))
                    throw ParseException("Expected a floating point number");
                oTupleValue.SetDouble(theDouble);
            }
            else if (theTypeLC == "time")
            {
                if (sTryRead_CP(iStrimU, ')'))
                {
                    // It's a time with no content, hence an invalid time.
                    oTupleValue.SetTime(ZTime());

                    // We'll take an early exit so the normal code that
                    // looks for a closing parenthesis doesn't choke.
                    return true;
                }
                // Try to read a double, which is how we're representing
                // times in text streams for now.
                double theDouble;
                if (!sTryRead_SignedDouble(iStrimU, theDouble))
                    throw ParseException("Expected a floating point time");
                oTupleValue.SetTime(theDouble);
            }
            else if (theTypeLC == "rect")
            {
                ZRectPOD theRect;

                theRect.left = sMustRead_GenericInteger(iStrimU);

                sMustRead_WSCommaWS(iStrimU);

                theRect.top = sMustRead_GenericInteger(iStrimU);

                sMustRead_WSCommaWS(iStrimU);

                theRect.right = sMustRead_GenericInteger(iStrimU);

                sMustRead_WSCommaWS(iStrimU);

                theRect.bottom = sMustRead_GenericInteger(iStrimU);

                oTupleValue.SetRect(theRect);
            }
            else if (theTypeLC == "point")
            {
                ZPointPOD thePoint;

                thePoint.h = sMustRead_GenericInteger(iStrimU);

                sMustRead_WSCommaWS(iStrimU);

                thePoint.v = sMustRead_GenericInteger(iStrimU);

                oTupleValue.SetPoint(thePoint);
            }
            else
            {
                throw ParseException("Unknown type designator '" + theType + "'");
            }

            sSkip_WSAndCPlusPlusComments(iStrimU);

            if (!sTryRead_CP(iStrimU, ')'))
                throw ParseException("Expected ')' to close a value");
        }
    }
    return true;
}