/** * * 将xml的parameters参数写入到jceOutputStream中 * * @param inXml * @param _os */ void XmlProxyCallback::_writeParameters(taf::JceOutputStream<taf::BufferWriter> &os) { _xmlReq.IntoElem(); int iTag = 0; while (_xmlReq.FindElem()) { iTag ++; //忽略out参数 if (TC_Common::lower(_xmlReq.GetAttrib("in")) == "true") { _writeField(iTag, _xmlReq.GetTagName(), _xmlReq.GetData(), os); } } _xmlReq.OutOfElem(); }
void XmlProxyCallback::_writeField(const int &iTag, const MCD_STR &sTagName, const MCD_STR &sData, taf::JceOutputStream<taf::BufferWriter> & os) { if (TC_Common::lower(sTagName) == "bool") { taf::Bool bValue = TC_Common::upper(sData) == "TRUE"; os.write(bValue, iTag); } else if (TC_Common::lower(sTagName) == "byte") { taf::Char cValue; if (sData.size() > 1) { cValue = TC_Common::x2c(sData); } os.write(cValue,iTag); } else if (TC_Common::lower(sTagName) == "short") { os.write(TC_Common::strto<taf::Short>(sData), iTag); } else if (TC_Common::lower(sTagName) == "int") { os.write(TC_Common::strto<taf::Int32>(sData), iTag); } else if (TC_Common::lower(sTagName) == "long") { os.write(TC_Common::strto<taf::Int64>(sData), iTag); } else if (TC_Common::lower(sTagName) == "float") { os.write(TC_Common::strto<taf::Float>(sData), iTag); } else if (TC_Common::lower(sTagName) == "double") { os.write(TC_Common::strto<taf::Double>(sData), iTag); } else if (TC_Common::lower(sTagName) == "string") { os.write(sData, iTag); } else if (TC_Common::lower(sTagName) == "enum") { os.write(TC_Common::strto<taf::Int32>(sData), iTag); } else if (TC_Common::lower(sTagName) == "struct") { DataHead h(DataHead::eStructBegin, iTag); h.writeTo(os); _xmlReq.IntoElem(); while (_xmlReq.FindElem()) { int iSubTag = TC_Common::strto<int>(_xmlReq.GetAttrib("tag")); _writeField(iSubTag, _xmlReq.GetTagName(), _xmlReq.GetData(), os); } _xmlReq.OutOfElem(); h.setType(DataHead::eStructEnd); h.setTag(0); h.writeTo(os); } else if (TC_Common::lower(sTagName) == "vector") { DataHead h(DataHead::eList, iTag); h.writeTo(os); _xmlReq.IntoElem(); int n = 0; taf::JceOutputStream<taf::BufferWriter> vectorCt; while (_xmlReq.FindElem()) { ++ n; int iSubTag = 0; _writeField(iSubTag, _xmlReq.GetTagName(), _xmlReq.GetData(), vectorCt); } _xmlReq.OutOfElem(); os.write(n, 0); os.writeBuf(vectorCt.getBuffer(), vectorCt.getLength()); } else if (TC_Common::lower(sTagName) == "vector_char") { DataHead h(DataHead::eSimpleList, iTag); h.writeTo(os); DataHead hh(DataHead::eChar, 0); hh.writeTo(os); string sBin = TC_Common::str2bin(_xmlReq.GetData()); os.write(sBin.length(), 0); os.writeBuf(sBin.c_str(), sBin.length()); } else if (TC_Common::lower(sTagName) == "map") { DataHead h(DataHead::eMap, iTag); h.writeTo(os); _xmlReq.IntoElem();//into map int n = 0 ; taf::JceOutputStream<taf::BufferWriter> mapCt; while (_xmlReq.FindElem())//find entry { ++ n; _xmlReq.IntoElem();//into entry for (int i = 0 ; i < 2; i++) { if (_xmlReq.FindElem())//find key or value { _writeField(i, _xmlReq.GetTagName(), _xmlReq.GetData(), mapCt); } } _xmlReq.OutOfElem();//out entry } _xmlReq.OutOfElem();//out map os.write(n,0); os.writeBuf(mapCt.getBuffer(), mapCt.getLength()); } }
BSONObj ObjectWrapper::toBSON() { if (getScope(_context)->getProto<BSONInfo>().instanceOf(_object)) { BSONObj* originalBSON = nullptr; bool altered; std::tie(originalBSON, altered) = BSONInfo::originalBSON(_context, _object); if (originalBSON && !altered) return *originalBSON; } JS::RootedId id(_context); // INCREDIBLY SUBTLE BEHAVIOR: // // (jcarey): Be very careful about how the Rooting API is used in // relationship to WriteFieldRecursionFrames. Mozilla'a API more or less // demands that the rooting types are on the stack and only manipulated as // regular objects, which we aren't doing here. The reason they do this is // because the rooting types must be global created and destroyed in an // entirely linear order. This is impossible to screw up in regular use, // but our unwinding of the recursion frames makes it easy to do here. // // The roots above need to be before the first frame is emplaced (so // they'll be destroyed after it) and none of the roots in the below code // (or in ValueWriter::writeThis) can live longer than until the call to // emplace() inside ValueWriter. The runtime asserts enabled by MozJS's // debug mode will catch runtime errors, but be aware of how difficult this // is to get right and what to look for if one of them bites you. BSONObjBuilder b; { // NOTE: Keep the frames in a scope so that it is clear that // we always destroy them before we destroy 'b'. It is // important to do so: if 'b' is destroyed before the frames, // and we don't pop all of the frames (say, due to an // exeption), then the frame dtors would write to freed // memory. WriteFieldRecursionFrames frames; frames.emplace(_context, _object, nullptr, StringData{}); // We special case the _id field in top-level objects and move it to the front. // This matches other drivers behavior and makes finding the _id field quicker in BSON. if (hasOwnField(InternedString::_id)) { _writeField(&b, InternedString::_id, &frames, frames.top().originalBSON); } while (frames.size()) { auto& frame = frames.top(); // If the index is the same as length, we've seen all the keys at this // level and should go up a level if (frame.idx == frame.ids.length()) { frames.pop(); continue; } if (frame.idx == 0 && frame.originalBSON && !frame.altered) { // If this is our first look at the object and it has an unaltered // bson behind it, move idx to the end so we'll roll up on the next // pass through the loop. frame.subbob_or(&b)->appendElements(*frame.originalBSON); frame.idx = frame.ids.length(); continue; } id.set(frame.ids[frame.idx++]); if (frames.size() == 1) { IdWrapper idw(_context, id); // TODO: check if it's cheaper to just compare with an interned // string of "_id" rather than with ascii if (idw.isString() && idw.equalsAscii("_id")) { continue; } } // writeField invokes ValueWriter with the frame stack, which will push // onto frames for subobjects, which will effectively recurse the loop. _writeField(frame.subbob_or(&b), JS::HandleId(id), &frames, frame.originalBSON); } } const int sizeWithEOO = b.len() + 1 /*EOO*/ - 4 /*BSONObj::Holder ref count*/; uassert(17260, str::stream() << "Converting from JavaScript to BSON failed: " << "Object size " << sizeWithEOO << " exceeds limit of " << BSONObjMaxInternalSize << " bytes.", sizeWithEOO <= BSONObjMaxInternalSize); return b.obj(); }