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() << ", "; }
void ZTupleIndex_String::WriteDescription(const ZStrimW& s) { s << "ZTupleIndex_String. "; s.Writef("%zu entries, ", fSet.size()); s << "indexing on " << string8(fPropName); }
static void sWriteIndent(const ZStrimW& iStrimW, int iIndent) { ZAssert(iIndent >= 0); for (int x = 0; x < iIndent; ++x) iStrimW.WriteCP('\t'); }
static void sWriteLFIndent(const ZStrimW& iStrimW, size_t iCount, const ZUtil_Tuple::Options& iOptions) { iStrimW.Write(iOptions.fEOLString); sWriteIndent(iStrimW, iCount, iOptions); }
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(" }"); } }
static void sWriteIndent(const ZStrimW& iStrimW, size_t iCount, const ZUtil_Tuple::Options& iOptions) { while (iCount--) iStrimW.Write(iOptions.fIndentString); }
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("]"); } }
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; } } }
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; } } }