예제 #1
0
void ZTupleIndex_General::WriteDescription(const ZStrimW& s)
	{
	s << "ZTupleIndex_General. ";
	s.Writef("%d entries, indexing on ", fSet.size());
	for (size_t x = 0; x < fPropNameCount; ++x)
		s << fPropNames[x].AsString() << ", ";
	}
예제 #2
0
void ZTupleIndex_String::WriteDescription(const ZStrimW& s)
	{
	s << "ZTupleIndex_String. ";
	s.Writef("%zu entries, ", fSet.size());
	s << "indexing on " << string8(fPropName);
	}
예제 #3
0
static void sWriteIndent(const ZStrimW& iStrimW, int iIndent)
	{
	ZAssert(iIndent >= 0);
	for (int x = 0; x < iIndent; ++x)
		iStrimW.WriteCP('\t');
	}
예제 #4
0
static void sWriteLFIndent(const ZStrimW& iStrimW,
                           size_t iCount, const ZUtil_Tuple::Options& iOptions)
{
    iStrimW.Write(iOptions.fEOLString);
    sWriteIndent(iStrimW, iCount, iOptions);
}
예제 #5
0
static void sToStrim_Tuple(const ZStrimW& s, const ZTuple& iTuple,
                           size_t iLevel, const ZUtil_Tuple::Options& iOptions, bool iMayNeedInitialLF)
{
    if (iTuple.Empty())
    {
        // We've got an empty tuple.
        s.Write("{}");
        return;
    }

    const ZTuple::const_iterator theBegin = iTuple.begin();
    const ZTuple::const_iterator theEnd = iTuple.end();
    bool needsIndentation = false;
    if (iOptions.DoIndentation())
    {
        for (ZTuple::const_iterator i = theBegin; i != theEnd; ++i)
        {
            if (sIsComplex(iOptions, iTuple.GetValue(i)))
            {
                needsIndentation = true;
                break;
            }
        }
    }

    if (needsIndentation)
    {
        if (iMayNeedInitialLF)
        {
            // We're going to be indenting, but need to start
            // a fresh line to have our { and contents line up.
            sWriteLFIndent(s, iLevel, iOptions);
        }
        s.Write("{");
        for (ZTuple::const_iterator i = theBegin; i != theEnd; ++i)
        {
            sWriteLFIndent(s, iLevel, iOptions);

            ZUtil_Tuple::sWrite_PropName(s, iTuple.NameOf(i));

            s << " = ";

            sToStrim_TupleValue(s, iTuple.GetValue(i), iLevel + 1, iOptions, true);
            s.Write(";");
        }

        sWriteLFIndent(s, iLevel, iOptions);

        s.Write("}");
    }
    else
    {
        s.Write("{");
        for (ZTuple::const_iterator i = theBegin; i != theEnd; ++i)
        {
            s.Write(" ");

            ZUtil_Tuple::sWrite_PropName(s, iTuple.NameOf(i));

            s << " = ";

            sToStrim_TupleValue(s, iTuple.GetValue(i), iLevel + 1, iOptions, true);
            s.Write(";");
        }

        s.Write(" }");
    }
}
예제 #6
0
static void sWriteIndent(const ZStrimW& iStrimW,
                         size_t iCount, const ZUtil_Tuple::Options& iOptions)
{
    while (iCount--)
        iStrimW.Write(iOptions.fIndentString);
}
예제 #7
0
static void sToStrim_Vector(const ZStrimW& s, const vector<ZTupleValue>& iVector,
                            size_t iLevel, const ZUtil_Tuple::Options& iOptions, bool iMayNeedInitialLF)
{
    if (iVector.empty())
    {
        // We've got an empty vector.
        s.Write("[]");
        return;
    }

    vector<ZTupleValue>::const_iterator theBegin = iVector.begin();
    vector<ZTupleValue>::const_iterator theEnd = iVector.end();
    bool needsIndentation = false;
    if (iOptions.DoIndentation())
    {
        // We're supposed to be indenting if we're complex, ie if any element is:
        // 1. A non-empty vector.
        // 2. A non-empty tuple.
        // or if iOptions.fBreakStrings is true, any element is a string with embedded
        // line breaks or more than iOptions.fStringLineLength characters.
        for (vector<ZTupleValue>::const_iterator i = theBegin; i != theEnd; ++i)
        {
            if (sIsComplex(iOptions, *i))
            {
                needsIndentation = true;
                break;
            }
        }
    }

    if (needsIndentation)
    {
        // We need to indent.
        if (iMayNeedInitialLF)
        {
            // We were invoked by a tuple which has already issued the property
            // name and equals sign, so we need to start a fresh line.
            sWriteLFIndent(s, iLevel, iOptions);
        }

        s.Write("[");
        for (vector<ZTupleValue>::const_iterator i = theBegin;;)
        {
            sWriteLFIndent(s, iLevel, iOptions);
            sToStrim_TupleValue(s, *i, iLevel, iOptions, false);
            ++i;
            if (i == theEnd)
                break;
            s.Write(", ");
        }
        sWriteLFIndent(s, iLevel, iOptions);
        s.Write("]");
    }
    else
    {
        // We're not indenting, so we can just dump everything out on
        // one line, with just some spaces to keep things legible.
        s.Write("[");
        for (vector<ZTupleValue>::const_iterator i = theBegin;;)
        {
            sToStrim_TupleValue(s, *i, iLevel, iOptions, false);
            ++i;
            if (i == theEnd)
                break;
            s.Write(", ");
        }
        s.Write("]");
    }
}
예제 #8
0
static void sToStrim_TupleValue(const ZStrimW& s, const ZTupleValue& iTV,
                                size_t iLevel, const ZUtil_Tuple::Options& iOptions, bool iMayNeedInitialLF)
{
    switch (iTV.TypeOf())
    {
    case eZType_Vector:
    {
        sToStrim_Vector(s, iTV.GetVector(), iLevel, iOptions, iMayNeedInitialLF);
        break;
    }
    case eZType_Tuple:
    {
        sToStrim_Tuple(s, iTV.GetTuple(), iLevel, iOptions, iMayNeedInitialLF);
        break;
    }
    case eZType_Raw:
    {
        const void* theData;
        size_t theSize;
        iTV.GetRawAttributes(&theData, &theSize);
        if (theSize == 0)
        {
            // we've got an empty Raw
            s.Write("()");
        }
        else
        {
            ZStreamRPos_Memory dataStream(theData, theSize);

            if (iOptions.DoIndentation() && theSize > iOptions.fRawChunkSize)
            {
                if (iMayNeedInitialLF)
                    sWriteLFIndent(s, iLevel, iOptions);

                s.Writef("( // %d bytes", theSize);
                sWriteLFIndent(s, iLevel, iOptions);
                if (iOptions.fRawAsASCII)
                {
                    for (;;)
                    {
                        uint64 lastPos = dataStream.GetPosition();
                        uint64 countCopied;
                        ZStreamW_HexStrim(iOptions.fRawByteSeparator, "", 0, s)
                        .CopyFrom(dataStream, iOptions.fRawChunkSize, &countCopied, nil);

                        if (countCopied == 0)
                            break;

                        dataStream.SetPosition(lastPos);
                        if (size_t extraSpaces = iOptions.fRawChunkSize - countCopied)
                        {
                            // We didn't write a complete line of bytes, so pad it out.
                            while (extraSpaces--)
                            {
                                // Two spaces for the two nibbles
                                s.Write("  ");
                                // And then the separator sequence
                                s.Write(iOptions.fRawByteSeparator);
                            }
                        }

                        s.Write(" // ");
                        while (countCopied--)
                        {
                            char theChar = dataStream.ReadInt8();
                            if (theChar < 0x20 || theChar > 0x7E)
                                s.WriteCP('.');
                            else
                                s.WriteCP(theChar);
                        }
                        sWriteLFIndent(s, iLevel, iOptions);
                    }
                }
                else
                {
                    string eol = iOptions.fEOLString;
                    for (size_t x = 0; x < iLevel; ++x)
                        eol += iOptions.fIndentString;

                    ZStreamW_HexStrim(iOptions.fRawByteSeparator,
                                      eol, iOptions.fRawChunkSize, s).CopyAllFrom(dataStream);

                    sWriteLFIndent(s, iLevel, iOptions);
                }

                s.Write(")");
            }
            else
            {
                s.Write("(");

                ZStreamW_HexStrim(iOptions.fRawByteSeparator, "", 0, s)
                .CopyAllFrom(dataStream);

                if (iOptions.fRawAsASCII)
                {
                    dataStream.SetPosition(0);
                    s.Write(" /* ");
                    while (theSize--)
                    {
                        char theChar = dataStream.ReadInt8();
                        if (theChar < 0x20 || theChar > 0x7E)
                            s.WriteCP('.');
                        else
                            s.WriteCP(theChar);
                    }
                    s.Write(" */");
                }
                s.Write(")");
            }
        }
        break;
    }
    default:
    {
        // We've got something other than a tuple or a vector.
        sSimpleTupleValueToStrim(s, iTV, iLevel, iOptions);
        break;
    }
    }
}
예제 #9
0
static void sSimpleTupleValueToStrim(const ZStrimW& s, const ZTupleValue& iTV,
                                     size_t iLevel, const ZUtil_Tuple::Options& iOptions)
{
    switch (iTV.TypeOf())
    {
    case eZType_Null:
        s.Write("Null");
        break;
    case eZType_Type:
    {
        s.Write("Type(");
        s.Write(ZTypeAsString(iTV.GetType()));
        s.Write(")");
        break;
    }
    case eZType_ID:
    {
        s.Writef("ID(0x%0llX)", iTV.GetID());
        if (iOptions.fIDsHaveDecimalVersionComment)
            s.Writef(" /* %lld */", iTV.GetID());
        break;
    }
    case eZType_Int8:
        s.Writef("int8(%d)", iTV.GetInt8());
        break;
    case eZType_Int16:
        s.Writef("int16(%d)", iTV.GetInt16());
        break;
    case eZType_Int32:
        s.Writef("int32(%d)", iTV.GetInt32());
        break;
    case eZType_Int64:
        s.Writef("int64(0x%0llX)", iTV.GetInt64());
        break;
    case eZType_Bool:
    {
        if (iTV.GetBool())
            s.Write("true");
        else
            s.Write("false");
        break;
    }
    case eZType_Float:
    {
        // 9 decimal digits are necessary and sufficient for single precision IEEE 754.
        // "What Every Computer Scientist Should Know About Floating Point", Goldberg, 1991.
        // <http://docs.sun.com/source/806-3568/ncg_goldberg.html>
        s.Writef("float(%.9g)", iTV.GetFloat());
        break;
    }
    case eZType_Double:
    {
        // 17 decimal digits are necessary and sufficient for double precision IEEE 754.
        s.Writef("double(%.17g)", iTV.GetDouble());
        break;
    }
    case eZType_Time:
    {
        // For the moment I'm just writing times as a count of seconds, putting
        // the broken-out Gregorian version in a comment. Later we can improve
        // the parsing of dates, and then we can write them in human readable form.
        if (ZTime theTime = iTV.GetTime())
        {
            s.Writef("time(%.17g)", theTime.fVal);
            if (iOptions.fTimesHaveUserLegibleComment)
            {
                s << " /*" << ZUtil_Time::sAsStringUTC(theTime, "%Y-%m-%dZ%H:%M:");
                // We've got about 10 significant digits in year (-10,000 to +10,000),
                // month, day, hour, minutes, and seconds, and no more than 17 in a double.
                // To get a leading zero in the seconds' tens column we add 100
                // to the count of seconds, so to get up to 7 digits in the fraction we
                // need to allow ten digits overall.
                s << ZString::sFormat("%.10g", 100.0 + fmod(theTime.fVal, 60)).substr(1);
                s << "*/";
            };
        }
        else
        {
            // We're now allowing empty parens to represent invalid times.
            s.Write("time()");
        }
        break;
    }
    case eZType_Pointer:
        s.Writef("pointer(%08X)", iTV.GetPointer());
        break;
    case eZType_Rect:
    {
        const ZRectPOD& theRect = iTV.GetRect();
        s.Writef("Rect(%d, %d, %d, %d)",
                 theRect.left,
                 theRect.top,
                 theRect.right,
                 theRect.bottom);
        break;
    }
    case eZType_Point:
    {
        const ZPointPOD& thePoint = iTV.GetPoint();
        s.Writef("Point(%d, %d)",
                 thePoint.h,
                 thePoint.v);
        break;
    }
    case eZType_String:
    {
        const string& theString = iTV.GetString();
        if (iOptions.fBreakStrings && iOptions.DoIndentation())
        {
            if (string::npos != theString.find_first_of("\n\r"))
            {
                // We put a newline after the opening """, which will be
                // ignored by sFromStrim, so the first line of theString
                // will be in column zero.
                s << "\"\"\"\n";
                ZStrimU_String strim_String(theString);
                ZStrimR_Boundary strim_Boundary("\"\"\"", strim_String);
                for (;;)
                {
                    s.CopyAllFrom(strim_Boundary);
                    if (!strim_Boundary.HitBoundary())
                    {
                        // We've returned without having hit the boundary, so we're done.
                        break;
                    }
                    strim_Boundary.Reset();

                    // Close the triple quotes.
                    s << "\"\"\"";
                    // A space to separate the triple-quote from the single quote
                    s << " ";
                    // An open quote
                    s << "\"";
                    // Three escaped quotes.
                    s << "\\\"\\\"\\\"";
                    // A close quote.
                    s << "\"";
                    // Another space, for symmetry
                    s << " ";
                    // And re-open triple quotes again.
                    s << "\"\"\"";
                    // With a newline, so the text will again
                    // start in column zero.
                    s << "\n";
                }
                s << "\"\"\"";
                break;
            }
        }
        string delimiter = "\"";
        bool quoteQuotes = true;
        if (string::npos != theString.find('"') && string::npos == theString.find('\''))
        {
            delimiter = "'";
            quoteQuotes = false;
        }

        s.Write(delimiter);

        ZStrimW_Escapify::Options theOptions;
        theOptions.fQuoteQuotes = quoteQuotes;
        theOptions.fEscapeHighUnicode = false;

        ZStrimW_Escapify(theOptions, s).Write(theString);

        s.Write(delimiter);
        break;
    }
    case eZType_RefCounted:
        s.Writef("RefCounted(%08X)", iTV.GetRefCounted().GetObject());
        break;
    case eZType_Raw:
    case eZType_Tuple:
    case eZType_Vector:
    {
        ZDebugStopf(0,
                    ("sSimpleTupleValueToStrim should only be called on simple tuple values"));
        break;
    }
    default:
    {
        ZDebugStopf(0, ("Unrecognized type %d", iTV.TypeOf()));
        break;
    }
    }
}