ZFCompareResult ZFVersionCompare(ZF_IN const zfchar *version0, ZF_IN const zfchar *version1, ZF_IN_OPT ZFComparer<const zfchar *>::Comparer subVersionComparer /* = ZFComparerForVersion */) { ZFCoreArrayPOD<zfindexRange> pos0; ZFCoreArrayPOD<zfindexRange> pos1; if(zfCoreDataPairSplitString(pos0, zfindexMax, version0, zfindexMax, '\0', '\0', zfText(".")) != zfnull || zfCoreDataPairSplitString(pos1, zfindexMax, version1, zfindexMax, '\0', '\0', zfText(".")) != zfnull) { return ZFCompareUncomparable; } zfindex count = zfmMin(pos0.count(), pos1.count()); for(zfindex i = 0; i < count; ++i) { ZFCompareResult cmp = subVersionComparer( zfstring(version0 + pos0[i].start, pos0[i].count).cString() , zfstring(version1 + pos1[i].start, pos1[i].count).cString() ); switch(cmp) { case ZFCompareUncomparable: case ZFCompareSmaller: case ZFCompareGreater: return cmp; case ZFCompareTheSame: continue; default: zfCoreCriticalShouldNotGoHere(); return ZFCompareUncomparable; } } if(pos0.count() > pos1.count()) { return ZFCompareGreater; } else if(pos0.count() < pos1.count()) { return ZFCompareSmaller; } else { return ZFCompareTheSame; } }
ZF_NAMESPACE_GLOBAL_BEGIN #if 1 ZF_GLOBAL_INITIALIZER_INIT(ZFCore_ZFSerializable_debug_ErrorLog) { ZFCALLBACK_LOCAL_BEGIN_2(zfindex, tmp, const void *, param0, zfindex, param1) { zfLogTrimT() << zfstring((const zfchar *)param0, param1); return zfindexMax; }
/* * // '_' if null for encoded data * * { * ClassNameEncoded * ( * refTypeEncoded : refDataEncoded * ) * ( * AttributeNameEncoded = AttributeValueEncoded; * AttributeNameEncoded = AttributeValueEncoded; * ) * [ * {ReferenceData}, * {ChildElement0}, * {ChildElement1} * ] * } */ zfbool _ZFP_ZFSerializableDataFromString(ZF_OUT ZFSerializableData &serializableData, ZF_IN_OUT const zfchar *&encodedData, ZF_IN zfindex encodedDataLen, ZF_OUT zfstring *outErrorHintToAppend, ZF_IN_OPT zfbool validateTail = zffalse) { if(encodedData == zfnull) { ZFSerializableUtil::errorOccurred(outErrorHintToAppend, zfText("invalid param")); return zffalse; } const zfchar *srcEnd = (encodedData + ((encodedDataLen == zfindexMax) ? zfslen(encodedData) : encodedDataLen)); zfbool ret = zffalse; do { const zfchar *pLeft = zfnull; const zfchar *pRight = zfnull; zfstring decodedTmp; zfcharSkipSpaceAndEndl(encodedData, srcEnd); if(encodedData >= srcEnd || *encodedData != '{') {break;} ++encodedData; // class name zfcharSkipSpaceAndEndl(encodedData, srcEnd); pLeft = pRight = encodedData; while(*encodedData != '(' && encodedData < srcEnd) { if(!zfcharIsSpace(*encodedData)) { zfcharMoveNext(encodedData); pRight = encodedData; } else { zfcharMoveNext(encodedData); } } if(encodedData >= srcEnd || *encodedData != '(') {break;} ++encodedData; if(pRight == pLeft + 1 && *pLeft == '_') { serializableData.itemClassSet(zfnull); } else { ZFCoreDataDecode(decodedTmp, zfstring(pLeft, pRight - pLeft).cString()); serializableData.itemClassSet(decodedTmp.cString()); decodedTmp.removeAll(); } // refType zfcharSkipSpaceAndEndl(encodedData, srcEnd); pLeft = pRight = encodedData; while(*encodedData != ':' && encodedData < srcEnd) { if(!zfcharIsSpace(*encodedData)) { zfcharMoveNext(encodedData); pRight = encodedData; } else { zfcharMoveNext(encodedData); } } if(encodedData >= srcEnd || *encodedData != ':') {break;} ++encodedData; if(pRight == pLeft + 1 && *pLeft == '_') { serializableData.referenceRefTypeSet(zfnull); } else { ZFCoreDataDecode(decodedTmp, zfstring(pLeft, pRight - pLeft).cString()); serializableData.referenceRefTypeSet(decodedTmp.cString()); decodedTmp.removeAll(); } // refData zfcharSkipSpaceAndEndl(encodedData, srcEnd); pLeft = pRight = encodedData; while(*encodedData != ')' && encodedData < srcEnd) { if(!zfcharIsSpace(*encodedData)) { zfcharMoveNext(encodedData); pRight = encodedData; } else { zfcharMoveNext(encodedData); } } if(encodedData >= srcEnd || *encodedData != ')') {break;} ++encodedData; if(pRight == pLeft + 1 && *pLeft == '_') { serializableData.referenceRefDataSet(zfnull); } else { ZFCoreDataDecode(decodedTmp, zfstring(pLeft, pRight - pLeft).cString()); serializableData.referenceRefDataSet(decodedTmp.cString()); decodedTmp.removeAll(); } zfcharSkipSpaceAndEndl(encodedData, srcEnd); while(*encodedData != '(' && encodedData < srcEnd) {zfcharMoveNext(encodedData);} if(encodedData >= srcEnd || *encodedData != '(') {break;} ++encodedData; // attributes zfcharSkipSpaceAndEndl(encodedData, srcEnd); while(encodedData < srcEnd) { if(*encodedData == ')') { ++encodedData; ret = zftrue; break; } // name pLeft = pRight = encodedData; while(*encodedData != '=' && encodedData < srcEnd) { if(!zfcharIsSpace(*encodedData)) { zfcharMoveNext(encodedData); pRight = encodedData; } else { zfcharMoveNext(encodedData); } } if(encodedData >= srcEnd || *encodedData != '=') {break;} ++encodedData; zfstring attributeName; ZFCoreDataDecode(attributeName, zfstring(pLeft, pRight - pLeft).cString()); // value zfcharSkipSpaceAndEndl(encodedData, srcEnd); pLeft = pRight = encodedData; while(*encodedData != ';' && encodedData < srcEnd) { if(!zfcharIsSpace(*encodedData)) { zfcharMoveNext(encodedData); pRight = encodedData; } else { zfcharMoveNext(encodedData); } } if(encodedData >= srcEnd || *encodedData != ';') {break;} ++encodedData; ZFCoreDataDecode(decodedTmp, zfstring(pLeft, pRight - pLeft).cString()); // save if(!attributeName.isEmpty() && !decodedTmp.isEmpty()) { serializableData.attributeSet(attributeName.cString(), decodedTmp.cString()); } decodedTmp.removeAll(); zfcharSkipSpaceAndEndl(encodedData, srcEnd); } if(!ret) {break;} ret = zffalse; zfcharSkipSpaceAndEndl(encodedData, srcEnd); if(encodedData >= srcEnd || *encodedData != '[') {break;} ++encodedData; // elements zfcharSkipSpaceAndEndl(encodedData, srcEnd); while(encodedData < srcEnd) { if(*encodedData == ']') { ++encodedData; ret = zftrue; break; } { ZFSerializableData element; if(!_ZFP_ZFSerializableDataFromString(element, encodedData, srcEnd - encodedData, outErrorHintToAppend)) { return zffalse; } serializableData.elementAdd(element); } zfcharSkipSpaceAndEndl(encodedData, srcEnd); if(encodedData >= srcEnd || (*encodedData != ',' && *encodedData != ']')) {break;} if(*encodedData == ',') { ++encodedData; zfcharSkipSpaceAndEndl(encodedData, srcEnd); if(encodedData >= srcEnd || *encodedData == ']') {break;} } } if(!ret) {break;} ret = zffalse; // tail zfcharSkipSpaceAndEndl(encodedData, srcEnd); if(encodedData >= srcEnd || *encodedData != '}') {break;} ++encodedData; if(validateTail) { zfcharSkipSpaceAndEndl(encodedData, srcEnd); if(encodedData < srcEnd) {break;} } ret = zftrue; } while(zffalse); if(!ret) { ZFSerializableUtil::errorOccurred(outErrorHintToAppend, zfText("wrong serializable string format at position: \"%s\""), zfstring(encodedData, srcEnd - encodedData).cString()); } return ret; }
zfbool ZFJsonToSerializableData(ZF_OUT ZFSerializableData &serializableData, ZF_IN const ZFJsonItem *jsonObject, ZF_OUT_OPT zfstring *outErrorHintToAppend /* = zfnull */, ZF_OUT_OPT const ZFJsonItem **outErrorPos /* = zfnull */) { if(jsonObject == zfnull) { ZFSerializableUtil::errorOccurred(outErrorHintToAppend, zfText("null json object")); if(outErrorPos != zfnull) { *outErrorPos = jsonObject; } return zffalse; } const ZFJsonItem *elementJsonArray = zfnull; for(zfiterator jsonItemIt = jsonObject->jsonItemIterator(); jsonObject->jsonItemIteratorIsValid(jsonItemIt); jsonObject->jsonItemIteratorNext(jsonItemIt)) { const zfchar *key = jsonObject->jsonItemIteratorGetKey(jsonItemIt); const ZFJsonItem *jsonItem = jsonObject->jsonItemIteratorGet(jsonItemIt); zfassert(jsonItem != zfnull); if(*key == _ZFP_ZFJsonSerializeKey_classPrefix) { serializableData.itemClassSet(key + 1); if(jsonItem->jsonType() != ZFJsonType::e_JsonArray) { ZFSerializableUtil::errorOccurred(outErrorHintToAppend, zfText("json item %s not type of %s"), jsonItem->objectInfo().cString(), ZFJsonType::EnumNameForValue(ZFJsonType::e_JsonArray)); if(outErrorPos != zfnull) { *outErrorPos = jsonItem; } return zffalse; } elementJsonArray = jsonItem; } else { if(jsonItem->jsonType() != ZFJsonType::e_JsonValue) { ZFSerializableUtil::errorOccurred(outErrorHintToAppend, zfText("json item %s not type of %s"), jsonItem->objectInfo().cString(), ZFJsonType::EnumNameForValue(ZFJsonType::e_JsonValue)); if(outErrorPos != zfnull) { *outErrorPos = jsonItem; } return zffalse; } const zfchar *value = jsonItem->jsonValue(); if(zfscmpTheSame(key, ZFSerializableKeyword_refType)) { serializableData.referenceRefTypeSet(value); } else if(zfscmpTheSame(key, ZFSerializableKeyword_refData)) { serializableData.referenceRefDataSet(value); } else { serializableData.attributeSet(zfstring(key).cString(), value); } } } if(serializableData.itemClass() == zfnull) { ZFSerializableUtil::errorOccurred(outErrorHintToAppend, zfText("missing class node (which looks like \"@ClassName\")")); if(outErrorPos != zfnull) { *outErrorPos = jsonObject; } return zffalse; } if(elementJsonArray != zfnull) { for(zfindex i = 0; i < elementJsonArray->jsonObjectCount(); ++i) { ZFSerializableData childData; if(!ZFJsonToSerializableData(childData, elementJsonArray->jsonObjectAtIndex(i), outErrorHintToAppend, outErrorPos)) { return zffalse; } serializableData.elementAdd(childData); } } if(outErrorPos != zfnull) { *outErrorPos = zfnull; } return serializableData.referenceCheckLoad(outErrorHintToAppend, zfnull); }