static void sHandle_PROPFIND_Some(const ZTrail& iPrefix, const ZNode& iRoot, const ZNode& iNode, int iDepth, const vector<string>& iPropNames, ZTuple& ioTuple) { for (DAVIter i = DAVIter(iNode, iDepth); i; i.Advance()) { ZNode theNode = i.Current(); if (theNode.Exists()) { ZTuple goodT, badT; sGetProperties(theNode, iPropNames, goodT, badT); ZTuple responseT; responseT.SetString("D:href", sMakeHREF(iPrefix, iRoot, theNode)); if (goodT) { goodT.SetString("D:status", "HTTP/1.1 200 OK"); responseT.AppendTuple("D:propstat", goodT); } if (badT) { badT.SetString("D:status", "HTTP/1.1 404 Not Found"); responseT.AppendTuple("D:propstat", badT); } ioTuple.AppendTuple("D:response", responseT); } } }
static void sHandle_PROPFIND_All(const ZTrail& iPrefix, const ZNode& iRoot, const ZNode& iNode, int iDepth, ZTuple& ioTuple) { vector<string> thePropNames; thePropNames.push_back("D:resourcetype"); thePropNames.push_back("D:getcontenttype"); thePropNames.push_back("D:creationdate"); thePropNames.push_back("D:getlastmodified"); thePropNames.push_back("D:getcontentlength"); for (DAVIter i = DAVIter(iNode, iDepth); i; i.Advance()) { ZNode theNode = i.Current(); if (theNode.Exists()) { ZTuple goodT, badT; sGetProperties(theNode, thePropNames, goodT, badT); ZTuple responseT; responseT.SetString("D:href", sMakeHREF(iPrefix, iRoot, theNode)); if (goodT) { goodT.SetString("D:status", "HTTP/1.1 200 OK"); responseT.AppendTuple("D:propstat", goodT); } ioTuple.AppendTuple("D:response", responseT); } } }
static ZTuple sCriterionUnionToTuple(const ZTBSpec::CriterionUnion& iCriterionUnion) { ZTuple result; vector<ZTupleValue>& outerVector = result.SetMutableVector("Criteria"); outerVector.reserve(iCriterionUnion.size()); outerVector.resize(iCriterionUnion.size()); vector<ZTupleValue>::iterator outerIter = outerVector.begin(); for (ZTBSpec::CriterionUnion::const_iterator critListIter = iCriterionUnion.begin(), critListEnd = iCriterionUnion.end(); critListIter != critListEnd; ++critListIter, ++outerIter) { vector<ZTupleValue>& innerVector = (*outerIter).SetMutableVector(); for (ZTBSpec::CriterionSect::const_iterator i = (*critListIter).begin(), theEnd = (*critListIter).end(); i != theEnd; ++i) { ZTuple aTuple = (*i).AsTuple(); innerVector.push_back(aTuple); } } return result; }
ZTuple ZTBQueryNode_ID_Constant::AsTuple() { ZTuple theTuple; theTuple.SetString("Kind", "ID_Constant"); theTuple.SetVector_T("IDs", fIDs.begin(), fIDs.end()); return theTuple; }
bool ZUITextEngine::MenuMessage(const ZMessage& inMessage) { switch (inMessage.GetInt32("menuCommand")) { case mcCopy: case mcCut: { size_t selectStart, selectLength; this->GetSelection(selectStart, selectLength); if (selectLength != 0) { if (inMessage.GetInt32("menuCommand") == mcCopy || this->IsRangeEditable(selectStart, selectLength)) { ZTuple theTuple = this->GetTuple(selectStart, selectLength); ZClipboard::sSet(theTuple); if (inMessage.GetInt32("menuCommand") == mcCut) this->DeleteText(selectStart, selectLength); } } return true; break; } case mcClear: { size_t selectStart, selectLength; this->GetSelection(selectStart, selectLength); if (selectLength != 0 && this->IsRangeEditable(selectStart, selectLength)) { this->DeleteText(selectStart, selectLength); return true; } return true; break; } case mcPaste: { size_t selectStart, selectLength; this->GetSelection(selectStart, selectLength); if (this->IsRangeEditable(selectStart, selectLength)) { ZTuple theTuple = ZClipboard::sGet(); if (theTuple.Has("text/plain")) { this->ReplaceSelection(theTuple.GetString("text/plain")); return true; } } return true; break; } case mcSelectAll: { this->SetSelection(0, this->GetTextLength()); return true; } } return false; }
ZTuple ZTBQueryNode_First::AsTuple() { ZTuple theTuple; theTuple.SetString("Kind", "First"); theTuple.SetString("PropName", fPropName.AsString()); if (fSourceNode) theTuple.SetTuple("SourceNode", fSourceNode->AsTuple()); return theTuple; }
ZTuple ZTBQueryNode_Combo::Intersection::AsTuple() const { ZTuple result; result.SetTuple("Filter", fFilter.AsTuple()); vector<ZTupleValue>& destVec = result.SetMutableVector("Nodes"); for (vector<ZRef<ZTBQueryNode> >::const_iterator i = fNodes.begin(); i != fNodes.end(); ++i) destVec.push_back(sTupleFromNode(*i)); return result; }
ZTuple ZTBQueryNode_ID_FromSource::AsTuple() { ZTuple theTuple; theTuple.SetString("Kind", "ID_FromSource"); theTuple.SetString("SourcePropName", fSourcePropName.AsString()); if (fSourceNode) theTuple.SetTuple("SourceNode", fSourceNode->AsTuple()); return theTuple; }
ZTuple ZTBQueryNode_Difference::AsTuple() { ZTuple theTuple; theTuple.SetString("Kind", "Difference"); if (fLeftNode) theTuple.SetTuple("LeftNode", fLeftNode->AsTuple()); if (fRightNode) theTuple.SetTuple("RightNode", fRightNode->AsTuple()); return theTuple; }
ZTBQueryNode_Combo::Intersection::Intersection(const ZTuple& iTuple) { fFilter = ZTBSpec(iTuple.GetTuple("Filter")); const vector<ZTupleValue>& nodes = iTuple.GetVector("Nodes"); for (vector<ZTupleValue>::const_iterator i = nodes.begin(); i != nodes.end(); ++i) { if (ZRef<ZTBQueryNode> aNode = sNodeFromTuple((*i).GetTuple())) fNodes.push_back(aNode); } }
static void sGetProperties(const ZNode& iNode, const vector<string>& iPropNames, ZTuple& oGoodT, ZTuple& oBadT) { for (vector<string>::const_iterator i = iPropNames.begin(); i != iPropNames.end(); ++i) { if (ZTuple propT = sGetProp(iNode, *i)) oGoodT.AppendTuple("D:prop", propT); else oBadT.AppendTuple("D:prop", ZTuple().SetNull(*i)); } }
static bool sGetStringAt(const ZTuple& iTuple, const string& iName, string& oString) { if (iTuple.GetString(iName, oString)) return true; const vector<ZTupleValue>& theVector = iTuple.GetVector(iName); if (!theVector.empty()) return theVector[0].GetString(oString); return false; }
bool ZUITextEngine::AcceptsDragDrop(const ZDragDropBase& inDragDrop) { bool gotIt = inDragDrop.GetDragSource() == this; for (size_t currentTupleIndex = 0; !gotIt && currentTupleIndex < inDragDrop.CountTuples(); ++currentTupleIndex) { ZTuple currentTuple = inDragDrop.GetTuple(currentTupleIndex); if (currentTuple.Has("text/plain")) gotIt = true; } return gotIt; }
ZTuple ZTBSpec::Criterion::Rep::AsTuple() const { ZTuple result; result.SetString("PropName", fPropName.AsString()); result.SetString("Rel", sStringFromRel(fComparator.fRel)); if (fComparator.fStrength) result.SetInt32("Strength", fComparator.fStrength); if (fTupleValue) result.SetValue("Value", fTupleValue); return result; }
void ZApp::InvalidateAllMenuBars() { // We don't need to be locked to broadcast this message ZTuple theTuple; theTuple.SetString("what", "zoolib:InvalidateAllMenuBars"); ZMessage envelope; envelope.SetString("what", "zoolib:Owner"); envelope.SetTuple("message", theTuple); fOSApp->BroadcastMessageToAllWindows(envelope); }
void ZTS_Umbrella::pTranslate_LocalToGlobal(size_t iChildIndex, ZTuple& ioTuple) { for (ZTuple::const_iterator i = ioTuple.begin(), theEnd = ioTuple.end(); i != theEnd; ++i) { switch (ioTuple.TypeOf(i)) { case eZType_ID: { uint64 globalID = this->pLocalToGlobal(iChildIndex, ioTuple.GetID(i)); ioTuple.SetID(i, globalID); break; } case eZType_Tuple: { this->pTranslate_LocalToGlobal(iChildIndex, ioTuple.GetMutableTuple(i)); break; } case eZType_Vector: { vector<ZTupleValue>& theVector = ioTuple.GetMutableVector(i); for (vector<ZTupleValue>::iterator j = theVector.begin(); j != theVector.end(); ++j) { if (eZType_ID == (*j).TypeOf()) { uint64 globalID = this->pLocalToGlobal(iChildIndex, ioTuple.GetID(i)); (*j).SetID(globalID); } } } } } }
bool ZWebDAV::sHandle_PROPFIND(const ZTrail& iPrefix, ZNode iRoot, const ZStreamR& iStreamR, const ZStreamW& iStreamW, const ZTuple& iHeader, const ZTrail& iTrail, const ZTuple& iParam) { int depth = sGetDepth(iHeader); ZRef<ZStrimmerR> theStrimmerR = sMakeStrimmer(iHeader, iStreamR); const ZStrimR& theStrimR = theStrimmerR->GetStrimR(); ZHTTP::Response r; r.Set("Date", sAsString_WebDAV(ZTime::sNow())); ZNode theNode = iRoot.Trail(iTrail); if (!theNode.Exists()) { theStrimR.SkipAll(); r.Set("Content-Length", 0); r.SetResult(404); r.Send(iStreamW); } else { ZTuple t = sReadTuple(theStrimR); ZTuple results; if (t.Empty() || t.Has("D:allprop")) { sHandle_PROPFIND_All(iPrefix, iRoot, theNode, depth, results); } else { ZTuple propT = t.GetTuple("D:prop"); vector<string> thePropNames; for (ZTuple::const_iterator i = propT.begin(); i != propT.end(); ++i) thePropNames.push_back(propT.NameOf(i)); sHandle_PROPFIND_Some(iPrefix, iRoot, theNode, depth, thePropNames, results); } if (const ZLog::S& s = ZLog::S(ZLog::eDebug, "ZWebDAV")) { s << "PropFind Request:" << t << "\n"; s << "PropFind Results:" << results << "\n"; } r.SetResult(207, "Multi-Status"); r.Set("Content-Type", "text/xml; charset=\"utf-8\""); r.Set("Transfer-Encoding", "chunked"); r.Send(iStreamW); ZHTTP::StreamW_Chunked chunkedStream(iStreamW); ZStrimW_StreamUTF8 theStrimW(chunkedStream); ZStrimW_ML s(false, theStrimW); s.PI("xml"); s.Attr("version", "1.0"); s.Attr("encoding", "utf-8"); s.Begin("D:multistatus"); s.Attr("xmlns:D", "DAV:"); sWriteAsXML(s, results); s.End("D:multistatus"); } return true; }
bool ZWebDAV::sHandle_MOVE(const ZTrail& iPrefix, ZNode iRoot, const ZStreamR&, const ZStreamW& iStreamW, const ZTuple& iHeader, const ZTrail& iTrail, const ZTuple& iParam) { ZHTTP::Response r; r.Set("date", sAsString_WebDAV(ZTime::sNow())); r.Set("Content-Length", 0); ZNode theNode = iRoot.Trail(iTrail); if (!theNode.Exists()) { r.SetResult(404); } else { string thePath = sGetPathFromURL(ZHTTP::sGetString0(iHeader.GetValue("destination"))); ZTrail theTrail = sStripPrefix(iPrefix, ZHTTP::sDecodeTrail(thePath)); ZNode theDestNode = iRoot.Trail(theTrail); if (const ZLog::S& s = ZLog::S(ZLog::eInfo, "ZWebDAV::sHandle_MOVE")) { s << "thePath: " << thePath << "\n"; s << "theTrail: " << theTrail.AsString() << "\n"; } bool doneIt = false; if (!doneIt) doneIt = theNode.MoveTo(theDestNode); // if (!doneIt) // doneIt = theDestNode.MoveFrom(theNode); if (!doneIt) { if (ZRef<ZStreamerR> sourceStreamer = theNode.OpenR(false)) { if (const ZLog::S& s = ZLog::S(ZLog::eInfo, "ZWebDAV::sHandle_MOVE")) s << "Got a source streamer, "; const ZStreamR& source = sourceStreamer->GetStreamR(); if (ZRef<ZStreamerWPos> destStreamer = theDestNode.CreateWPos(true, false)) { if (const ZLog::S& s = ZLog::S(ZLog::eInfo, "ZWebDAV::sHandle_MOVE")) s << "and a dest streamer"; const ZStreamWPos& dest = destStreamer->GetStreamWPos(); dest.Truncate(); dest.CopyAllFrom(source); theNode.Delete(); doneIt = true; } } } if (doneIt) r.SetResult(204); else r.SetResult(400); } r.Send(iStreamW); return true; }
static void sFromStrim_BodyOfTuple(const ZStrimU& iStrimU, ZTuple& oTuple) { using namespace ZUtil_Strim; for (;;) { sSkip_WSAndCPlusPlusComments(iStrimU); string propertyName; if (!sTryRead_EscapedString(iStrimU, '"', propertyName)) { if (!sTryRead_EscapedString(iStrimU, '\'', propertyName)) { if (!ZUtil_Tuple::sRead_Identifier(iStrimU, nil, &propertyName)) break; } } sSkip_WSAndCPlusPlusComments(iStrimU); if (!sTryRead_CP(iStrimU, '=')) throw ParseException("Expected '=' after property name"); sSkip_WSAndCPlusPlusComments(iStrimU); ZTupleValue& theTupleValue = oTuple.SetMutableNull(propertyName); if (!sFromStrim_TupleValue(iStrimU, theTupleValue)) throw ParseException("Expected a property value after '='"); sSkip_WSAndCPlusPlusComments(iStrimU); if (!sTryRead_CP(iStrimU, ';') && !sTryRead_CP(iStrimU, ',')) throw ParseException("Expected a ';' or a ',' after property value"); } }
static void* sWin32_Get_Callback(void* iParam) { ZTuple* result = static_cast<ZTuple*>(iParam); IDataObject* theIDataObject; HRESULT theHRESULT = ::OleGetClipboard(&theIDataObject); if (SUCCEEDED(theHRESULT)) { *result = ZDragClip_Win_DataObject::sAsTuple(theIDataObject); theIDataObject->Release(); } else { result->Clear(); } return nil; }
void ZUITextEngine::HandleDrop(ZPoint inPoint, ZDrop& inDrop) { if (!this->AcceptsDragDrop(inDrop)) return; if (inDrop.GetDragSource() == this) { size_t dragOffset = this->PointToOffset(this->FromHost(inPoint)); size_t selectStart, selectLength; this->GetSelection(selectStart, selectLength); if (dragOffset < selectStart) { string selectedText = this->GetText(selectStart, selectLength); this->DeleteText(selectStart, selectLength); this->InsertText(dragOffset, selectedText); this->SetSelection(dragOffset, selectLength); } else if (dragOffset > selectStart+selectLength) { string selectedText = this->GetText(selectStart, selectLength); this->DeleteText(selectStart, selectLength); this->InsertText(dragOffset-selectLength, selectedText); this->SetSelection(dragOffset-selectLength, selectLength); } } else { size_t dragOffset = this->PointToOffset(inPoint); if (!this->IsRangeEditable(dragOffset, 0)) return; for (size_t currentTupleIndex = 0; currentTupleIndex < inDrop.CountTuples(); ++currentTupleIndex) { ZTuple currentTuple = inDrop.GetTuple(currentTupleIndex); if (currentTuple.Has("text/plain")) { string droppedString = currentTuple.GetString("text/plain"); this->InsertText(dragOffset, droppedString); this->SetSelection(dragOffset, droppedString.size()); // Return now, so we only drop text from the first tuple that had any return; } } } }
ZTuple ZDragClip_Win_DataObject::sAsTuple(IDataObject* iIDataObject) { ZTuple theTuple; ZDragClip_Win_DataObject* theDataObject; if (SUCCEEDED(iIDataObject->QueryInterface(ZDragClip_Win_DataObject::sIID, (void**)&theDataObject))) { theTuple = *theDataObject->GetTuple(); theDataObject->Release(); } else { vector<FORMATETC> filteredVector; ::sFilterNonHGLOBAL(iIDataObject, filteredVector); for (vector<FORMATETC>::const_iterator i = filteredVector.begin();i != filteredVector.end(); ++i) { bool isString; string thePropertyName; if (ZDragClipManager::sGet()->LookupCLIPFORMAT((*i).cfFormat, thePropertyName, isString)) { ZAssertStop(1, !thePropertyName.empty()); FORMATETC theFORMATETC = *i; STGMEDIUM theSTGMEDIUM; HRESULT theHRESULT = iIDataObject->GetData(&theFORMATETC, &theSTGMEDIUM); if (SUCCEEDED(theHRESULT)) { if (theSTGMEDIUM.tymed & TYMED_HGLOBAL) { void* globalPtr = ::GlobalLock(theSTGMEDIUM.hGlobal); // Special case text, to find and ignore the zero terminator, and to store a string. if (theFORMATETC.cfFormat == CF_TEXT) theTuple.SetString(thePropertyName, string(reinterpret_cast<char*>(globalPtr))); else theTuple.SetRaw(thePropertyName, globalPtr, ::GlobalSize(theSTGMEDIUM.hGlobal)); ::GlobalUnlock(theSTGMEDIUM.hGlobal); } ::ReleaseStgMedium(&theSTGMEDIUM); } } } } return theTuple; }
static bool sDelete(const ZTrail& iPrefix, const ZNode& iRoot, const ZNode& iNode, ZTuple& ioT) { bool allOkay = true; // Delete any descendants of iNode. for (ZNodeIter i = iNode; i; i.Advance()) { if (!sDelete(iPrefix, iRoot, i.Current(), ioT)) allOkay = false; } if (allOkay) { if (iNode.Delete()) return true; ZTuple responseT; responseT.SetString("D:href", sMakeHREF(iPrefix, iRoot, iNode)); responseT.SetString("D:status", "HTTP/1.1 404"); ioT.AppendTuple("D:response", responseT); } return false; }
static ZTuple sGetProp(const ZNode& iNode, const string& iPropName) { ZTuple propT; if (iPropName == "D:resourcetype") { if (iNode.CanHaveChildren()) propT.SetTuple(iPropName, ZTuple().SetNull("D:collection")); else propT.SetNull(iPropName); } else if (iPropName == "D:getcontenttype") { ZTupleValue theValue; if (iNode.GetProp("MIMEType", theValue)) { string theMIMEType; if (theValue.GetString(theMIMEType)) propT.SetString(iPropName, theMIMEType); } } else if (iPropName == "D:creationdate") { ZTupleValue theValue; if (iNode.GetProp("TimeCreated", theValue)) { if (ZTime theTime = theValue.GetTime()) propT.SetString(iPropName, sAsString_WebDAV(theTime)); } } else if (iPropName == "D:getlastmodified") { ZTupleValue theValue; if (iNode.GetProp("TimeModified", theValue)) { if (ZTime theTime = theValue.GetTime()) propT.SetString(iPropName, sAsString_WebDAV(theTime)); } } else if (iPropName == "D:getcontentlength") { ZTupleValue theValue; if (iNode.GetProp("ContentLength", theValue)) { int64 theLength; if (theValue.GetInt64(theLength)) propT.SetString(iPropName, ZString::sFromUInt64(theLength)); } } return propT; }
static void sCriterionUnionFromTuple( const ZTuple& iTuple, ZTBSpec::CriterionUnion& ioCriterionUnion) { const vector<ZTupleValue>& outerVector = iTuple.GetVector("Criteria"); ioCriterionUnion.resize(outerVector.size()); ZTBSpec::CriterionUnion::iterator critListIter = ioCriterionUnion.begin(); for (vector<ZTupleValue>::const_iterator outerIter = outerVector.begin(); outerIter != outerVector.end(); ++outerIter, ++critListIter) { const vector<ZTupleValue>& innerVector = (*outerIter).GetVector(); for (vector<ZTupleValue>::const_iterator inner = innerVector.begin(); inner != innerVector.end(); ++inner) { (*critListIter).push_back(ZTBSpec::Criterion((*inner).GetTuple())); } } }
ZTuple ZTBQueryNode_Combo::AsTuple() { ZTuple result; result.SetString("Kind", "Combo"); if (!fSort.empty()) { vector<ZTupleValue>& sortVector = result.SetMutableVector("Sort"); for (vector<ZTBQuery::SortSpec>::iterator i = fSort.begin(); i != fSort.end(); ++i) { ZTuple theTuple; theTuple.SetString("PropName", (*i).fPropName.AsString()); theTuple.SetBool("Ascending", (*i).fAscending); theTuple.SetInt32("Strength", (*i).fStrength); sortVector.push_back(theTuple); } } vector<ZTupleValue>& sectVector = result.SetMutableVector("Intersections"); for (vector<Intersection>::iterator i = fIntersections.begin(); i != fIntersections.end(); ++i) sectVector.push_back((*i).AsTuple()); return result; }
bool ZWebDAV::sHandle_GET(const ZTrail& iPrefix, ZNode iRoot, const ZStreamR&, const ZStreamW& iStreamW, const ZTuple& iHeader, const ZTrail& iTrail, const ZTuple& iParam) { ZNode theNode = iRoot.Trail(iTrail); ZHTTP::Response r; r.Set("date", sAsString_WebDAV(ZTime::sNow())); if (iHeader.Has("range")) { if (const ZLog::S& s = ZLog::S(ZLog::eInfo, "ZWebDAV")) s << "GET with range:\n" << iHeader; } if (theNode.Exists()) { r.SetResult(200); if (theNode.CanHaveChildren()) { r.Set("Content-Type", "text/html; charset=\"utf-8\""); r.Set("Transfer-Encoding", "chunked"); r.Send(iStreamW); ZHTTP::StreamW_Chunked chunkedStream(iStreamW); ZStrimW_StreamUTF8 theStrimW(chunkedStream); ZStrimW_ML s(false, theStrimW); s.Begin("html"); s.Begin("title"); s << theNode.Name(); s.End("title"); s.Begin("body"); for (ZNodeIter i = theNode; i; i.Advance()) { s.Begin("p"); s.Begin("a"); if (i.Current().CanHaveChildren()) { s.Attr("href", ZHTTP::sEncodeComponent(i.Current().Name()) + "/"); s << i.Current().Name() << "/"; } else { s.Attr("href", ZHTTP::sEncodeComponent(i.Current().Name())); s << i.Current().Name(); } s.End("a"); s.End("p"); } s.End("body"); s.End("html"); } else if (ZRef<ZStreamerRPos> theStreamer = theNode.OpenRPos()) { const ZStreamRPos& theStreamRPos = theStreamer->GetStreamRPos(); uint64 sentSize = theStreamRPos.GetSize(); if (ZTupleValue rangeParam = iHeader.GetValue("range")) { vector<pair<size_t, size_t> > ranges; if (!ZHTTP::sOrganizeRanges(sentSize, rangeParam, ranges)) { iStreamW.WriteString("HTTP/1.1 406 Unsatisfiable range\r\n\r\n"); return false; } r.SetResult(206, "Partial Content"); r.Set("Content-Range", ZString::sFormat("bytes %d-%d/%d", ranges.front().first, ranges.front().second - 1, sentSize)); theStreamRPos.SetPosition(ranges.front().first); sentSize = ranges.front().second - ranges.front().first; } else { r.SetResult(200); } string theMIMEType = "application/octet-stream"; ZTupleValue theMIMEValue; if (theNode.GetProp("MIMEType", theMIMEValue)) { string asString; if (theMIMEValue.GetString(asString)) theMIMEType = asString; } r.Set("Content-Type", theMIMEType); ZTupleValue theValue; if (theNode.GetProp("lastModified", theValue)) { if (ZTime theTime = theValue.GetTime()) r.Set("Last-Modified", sAsString_WebDAV(theTime)); } r.Set("Content-Transfer-Encoding", "binary"); r.Set("Content-Length", ZString::sFromUInt64(sentSize)); r.Send(iStreamW); iStreamW.CopyFrom(theStreamRPos, sentSize); } } else { r.SetResult(404); r.Send(iStreamW); r.Set("Content-Length", 0); } return true; }
ZTuple ZTBQueryNode_All::AsTuple() { ZTuple theTuple; theTuple.SetString("Kind", "All"); return theTuple; }
static void sWriteAsXML(ZStrimW_ML& s, const ZTuple& iTuple) { for (ZTuple::const_iterator i = iTuple.begin(); i != iTuple.end(); ++i) sWriteAsXML(s, iTuple.NameOf(i), iTuple.GetValue(i)); }
static ZTupleValue sReadTV(ZML::Reader& ml, const string& iName) { // We're sitting just after the begin tag. If there is any // text, suck it into a string and move on. if (ml.Current() == ZML::eToken_Text) { string allText; ZStrimW_String(allText).CopyAllFrom(ml.Text()); ml.Advance(); if (ml.Current() == ZML::eToken_TagEnd) { // We've hit an end tag, so the begin/end tags were wrapping a text value. if (iName != ml.Name()) throw runtime_error("Tags don't match. Wanted: " + iName + ", Got: " + ml.Name()); ml.Advance(); return allText; } // The text following the begin tag was spurious -- it's not representable // in the simplified tuple we're building, so we'll just ignore it. } // Accumulate all child tags into a tuple to be returned. ZTuple result; for (;;) { if (ml.Current() == ZML::eToken_TagBegin) { // We have a nested begin tag. Grab its name and recurse. string name = ml.Name(); ml.Advance(); ZTupleValue theTV = sReadTV(ml, name); result.SetValue(name, theTV); } else if (ml.Current() == ZML::eToken_TagEmpty) { // We have a nested empty tag -- we represent them as null values. string name = ml.Name(); ml.Advance(); result.SetValue(name, ZTupleValue()); } else if (ml.Current() == ZML::eToken_Text) { // We've got some text, but it's interspersed with other // tags and thus doesn't fit our model -- ignore it. ml.Advance(); } else if (ml.Current() == ZML::eToken_TagEnd) { if (iName != ml.Name()) throw runtime_error("Tags don't match. Wanted: " + iName + ", Got: " + ml.Name()); // We've hit the end tag for the tuple, so we // consume it and break out of the loop. ml.Advance(); break; } else { // We've hit the end of the reader, so we also exit the loop. break; } } return result; }