📄 stafdatatypes.cpp
字号:
void STAFObjectFreeSTAFStringTArray(STAFString_t *theArray, unsigned int size){ for (unsigned int i = 0; i < size; ++i) STAFStringDestruct(&theArray[i], 0); delete [] theArray;}STAFRC_t STAFObjectMarshallToString(STAFObject_t object, STAFObject_t context, STAFString_t *pString, unsigned int flags){ if (object == 0) return kSTAFInvalidObject; if (pString == 0) return kSTAFInvalidParm; // XXX: Might this want to be a new kSTAFInvalidOperation ? if ((context != 0) && (context->type != kSTAFMarshallingContextObject)) return kSTAFInvalidParm; static STAFString sMapClassKey("staf-map-class-name"); STAFString outString; if (object->type == kSTAFScalarStringObject) { outString += "@SDT/$S:"; outString += object->scalarStringValue->length(STAFString::kChar); outString += sColon; outString += *object->scalarStringValue; } else if (object->type == kSTAFNoneObject) { outString += "@SDT/$0:0:"; } else if (object->type == kSTAFListObject) { // Get the size of the list and create an array with that size. // Instead of creating an array using: // STAFString_t *stringArray = new STAFString_t[size]; // we're using a STAFRefPtr<STAFString_t> custom array type so that // the array and it's contents will get destructed (even if an // exception occurs). // For each entry in the list, add a string representation of the entry // to the array and then join the strings in the array. // Using an array and then doing a join is done for performance // reasons as it's faster than concatenating strings using +=. unsigned int size = 0; STAFObjectGetSize(object, &size); STAFRefPtr<STAFString_t> stringArray = STAFRefPtr<STAFString_t> (new STAFString_t[size], STAFRefPtr<STAFString_t>::INIT, size, STAFObjectFreeSTAFStringTArray); unsigned int i = 0; for (STAFObjectList::iterator iter = object->listValue->begin(); iter != object->listValue->end(); ++iter) { STAFString_t thisItemStringT = 0; // XXX: Check RC? STAFObjectMarshallToString(*iter, context, &thisItemStringT, flags); stringArray[i++] = thisItemStringT; } STAFString_t joinedStringT = 0; unsigned int osRC; // XXX: Check RC from STAFStringConstructJoin? STAFStringConstructJoin(&joinedStringT, stringArray, size, &osRC); STAFString dataString = STAFString(joinedStringT, STAFString::kShallow); outString += "@SDT/["; outString += object->listValue->size(); outString += sColon; outString += dataString.length(STAFString::kChar); outString += sColon; outString += dataString; } else if (object->type == kSTAFMapObject) { // If a staf-map-class-name key exists in the map, make sure that it's // map class definition is provided in the marshalling context. // If it's not, then treat the map as a plain map object. bool isMapClass = false; STAFString mapClassName; if (context && (object->mapValue->find(sMapClassKey) != object->mapValue->end())) { mapClassName = *(*object->mapValue)[sMapClassKey]-> scalarStringValue; unsigned int hasMapClassDefinition = 0; STAFRC_t rc = STAFObjectMarshallingContextHasMapClassDefinition( context, mapClassName.getImpl(), &hasMapClassDefinition); if ((rc == kSTAFOk) && (hasMapClassDefinition)) isMapClass = true; } if (isMapClass) { // Note: Not much checking is done here as all the checking is done // in STAFObjectMarshallingContextSetMapClassDefinition // XXX: This whole block could use some rework to simplify all // the dereferences STAFString dataString; dataString += sColon; dataString += mapClassName.length(STAFString::kChar); dataString += sColon; dataString += mapClassName; STAFObject_t keyList = (*(*context->contextValue-> mapClassMap->mapValue)[mapClassName]-> mapValue)["keys"]; // Get the number of keys in the map class definition and create an // array with that size. // Instead of creating an array using: // STAFString_t *stringArray = new STAFString_t[size]; // we're using a STAFRefPtr<STAFString_t> custom array type so that // the array and it's contents will get destructed (even if an // exception occurs). // For each key in the map class, add a string representation to // the array and then join the strings in the array. // Using an array and then doing a join is done for performance // reasons as it's faster than concatenating strings using +=. unsigned int size = 0; STAFObjectGetSize(keyList, &size); STAFRefPtr<STAFString_t> stringArray = STAFRefPtr<STAFString_t> (new STAFString_t[size], STAFRefPtr<STAFString_t>::INIT, size, STAFObjectFreeSTAFStringTArray); unsigned int i = 0; for (STAFObjectList::iterator iter = keyList->listValue->begin(); iter != keyList->listValue->end(); ++iter) { STAFString &keyName = *(*(*iter)->mapValue)["key"]->scalarStringValue; STAFString_t thisItemStringT = 0; STAFObject_t thisItem = (*object->mapValue)[keyName]; if (thisItem == 0) thisItem = sNoneObjT; STAFObjectMarshallToString(thisItem, context, &thisItemStringT, flags); stringArray[i++] = thisItemStringT; } STAFString_t joinedStringT = 0; unsigned int osRC; STAFStringConstructJoin(&joinedStringT, stringArray, size, &osRC); dataString += STAFString(joinedStringT, STAFString::kShallow); outString += "@SDT/%:"; outString += dataString.length(STAFString::kChar); outString += sColon; outString += dataString; } else { // Get the size of the map and create an array with that size. // Instead of creating an array using: // STAFString_t *stringArray = new STAFString_t[size]; // we're using a STAFRefPtr<STAFString_t> custom array type so that // the array and it's contents will get destructed (even if an // exception occurs). // For each key/value in the map, add a string representation to // the array and then join the strings in the array. // Using an array and then doing a join is done for performance // reasons as it's faster than concatenating strings using +=. unsigned int size = 0; STAFObjectGetSize(object, &size); STAFRefPtr<STAFString_t> stringArray = STAFRefPtr<STAFString_t> (new STAFString_t[size], STAFRefPtr<STAFString_t>::INIT, size, STAFObjectFreeSTAFStringTArray); unsigned int i = 0; for (STAFObjectMap::iterator iter = object->mapValue->begin(); iter != object->mapValue->end(); ++iter) { // First add the key STAFString entryString = sColon; entryString += iter->first.length(STAFString::kChar); entryString += sColon; entryString += iter->first; // Next add the value STAFString_t thisItemStringT = 0; // XXX: Check RC? STAFObjectMarshallToString(iter->second, context, &thisItemStringT, flags); entryString += STAFString(thisItemStringT, STAFString::kShallow); stringArray[i++] = entryString.adoptImpl(); } STAFString_t joinedStringT = 0; unsigned int osRC; STAFStringConstructJoin(&joinedStringT, stringArray, size, &osRC); STAFString dataString = STAFString(joinedStringT, STAFString::kShallow); outString += "@SDT/{:"; outString += dataString.length(STAFString::kChar); outString += sColon; outString += dataString; } } else if (object->type == kSTAFMarshallingContextObject) { STAFString dataString; unsigned int size = 0; STAFObjectGetSize(object->contextValue->mapClassMap, &size); if (size != 0) { // Get a reference to the context's map class map STAFObject_t mapClassMap = 0; STAFObjectConstructReference(&mapClassMap, object->contextValue->mapClassMap); // Now create the context map for marshalling and add the context's // map class map as the "map-class-map" object STAFObject_t contextMap = 0; STAFObjectConstructMap(&contextMap); STAFObjectMapPut(contextMap, STAFString("map-class-map").getImpl(), mapClassMap); STAFObjectDestruct(&mapClassMap); // Marshall the context map itself and then destruct it // // Note, the context map is not marshalled within any context. If it // were, we run the risk of recursive map class definitions, which // wouldn't work when unmarshalling. STAFString_t mapClassMapStringT = 0; STAFObjectMarshallToString(contextMap, 0, &mapClassMapStringT, flags); STAFObjectDestruct(&contextMap); // Generate the marshalled string, and destruct the string // containing the intermediate value STAFStringConcatenate(dataString.getImpl(), mapClassMapStringT, 0); STAFStringDestruct(&mapClassMapStringT, 0); } // Marshall the root object // // Note: We marshall the root object in the context of the context // we are marshalling (not the context that was passed in, which // might be different. STAFString_t rootObjectStringT = 0; STAFObjectMarshallToString(object->contextValue->rootObject, object, &rootObjectStringT, flags); // Finally, generate the marshalled string, and destruct the string // containing the intermediate value STAFStringConcatenate(dataString.getImpl(), rootObjectStringT, 0); STAFStringDestruct(&rootObjectStringT, 0); if (size != 0) { outString += "@SDT/*"; outString += sColon; outString += dataString.length(STAFString::kChar); outString += sColon; } outString += dataString; } else { // Do what? } *pString = outString.adoptImpl(); return kSTAFOk;}STAFRC_t STAFObjectUnmarshallFromString(STAFObject_t *newContext, STAFStringConst_t marshalledObject, STAFObject_t context, unsigned int flags){ if (newContext == 0) return kSTAFInvalidObject; if (marshalledObject == 0) return kSTAFInvalidParm; // XXX: Might this want to be a new kSTAFInvalidOperation ? if ((context != 0) && (context->type != kSTAFMarshallingContextObject)) return kSTAFInvalidParm; static STAFString marshalledDataMarker("@SDT/"); static STAFString noneMarker("@SDT/$0:0:"); static STAFString scalarMarker("@SDT/$"); static STAFString mapMarker("@SDT/{"); static STAFString mcInstanceMarker("@SDT/%"); static STAFString listMarker("@SDT/["); static STAFString contextMarker("@SDT/*"); static STAFString sMapClassKey("staf-map-class-name"); STAFObjectConstructMarshallingContext(newContext); // XXX: Probably shouldn't make a copy of the string like this, but I'm // going to make sure things work first, and then I'll optimize STAFString data(marshalledObject); if (data.startsWith(noneMarker)) { // XXX: This is all probably redundant since the marshalling context // already has a None in it. STAFObject_t noneObj = 0; STAFObjectConstructNone(&noneObj); STAFObjectMarshallingContextSetRootObject(*newContext, noneObj); STAFObjectDestruct(&noneObj); } else if (data.startsWith(scalarMarker)) { unsigned int colonIndex = data.find(sColon); colonIndex = data.find(":", colonIndex + 1); STAFObject_t stringObj = 0; STAFObjectConstructScalarString( &stringObj, data.subString(colonIndex + 1).getImpl()); // Unless told otherwise we will try to unmarshall a nested object // reference if ((flags & kSTAFIgnoreIndirectObjects) || !stringObj->scalarStringValue->startsWith(marshalledDataMarker)) { STAFObjectMarshallingContextSetRootObject(*newContext, stringObj); } else { STAFObject_t nestedContext = 0; STAFObjectUnmarshallFromString( &nestedContext, stringObj->scalarStringValue->getImpl(), context, flags); STAFObject_t primaryObject = adoptPrimaryObject(nestedContext); STAFObjectMarshallingContextSetRootObject(*newContext, primaryObject); STAFObjectDestruct(&primaryObject); } STAFObjectDestruct(&stringObj); } else if (data.startsWith(listMarker)) { unsigned int colonIndex = data.find(sColon); unsigned int numItems = data.subString(6, colonIndex - 6).asUInt(); unsigned int dataIndex = data.find(sColon, colonIndex + 1) + 1; STAFObject_t listObj = 0; STAFObjectConstructList(&listObj); for (unsigned int i = 0; i < numItems; ++i) { STAFObject_t obj = unmarshallObject(data, context, dataIndex, flags); STAFObjectListAppend(listObj, obj); STAFObjectDestruct(&obj); } STAFObjectMarshallingContextSetRootObject(*newContext, listObj); STAFObjectDestruct(&listObj); } else if (data.startsWith(mapMarker)) { unsigned int colonIndex = data.find(sColon); unsigned int numItems = data.subString(6, colonIndex - 6).asUInt(); unsigned int dataIndex = data.find(sColon, colonIndex + 1) + 1; STAFObject_t mapObj = 0; STAFObjectConstructMap(&mapObj); while (dataIndex < data.length()) { STAFString key = getCLCString(data, dataIndex); STAFObject_t obj = unmarshallObject(data, context, dataIndex, flags);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -