| 1048 | // *** Check cases of rdf:resource plus explicit attr qualifiers (like xml:lang). |
| 1049 | |
| 1050 | static void |
| 1051 | SerializeAsRDF ( const XMPMeta & xmpObj, |
| 1052 | XMP_VarString & headStr, // Everything up to the padding. |
| 1053 | XMP_VarString & tailStr, // Everything after the padding. |
| 1054 | XMP_OptionBits options, |
| 1055 | XMP_StringPtr newline, |
| 1056 | XMP_StringPtr indentStr, |
| 1057 | XMP_Index baseIndent ) |
| 1058 | { |
| 1059 | const size_t treeNameLen = xmpObj.tree.name.size(); |
| 1060 | const size_t indentLen = strlen ( indentStr ); |
| 1061 | |
| 1062 | // First estimate the worst case space and reserve room in the output string. This optimization |
| 1063 | // avoids reallocating and copying the output as it grows. The initial count does not look at |
| 1064 | // the values of properties, so it does not account for character entities, e.g. 
 for newline. |
| 1065 | // Since there can be a lot of these in things like the base 64 encoding of a large thumbnail, |
| 1066 | // inflate the count by 1/4 (easy to do) to accommodate. |
| 1067 | |
| 1068 | // *** Need to include estimate for alias comments. |
| 1069 | |
| 1070 | size_t outputLen = 2 * (strlen(kPacketHeader) + strlen(kRDF_XMPMetaStart) + strlen(kRDF_RDFStart) + 3*baseIndent*indentLen); |
| 1071 | |
| 1072 | for ( size_t schemaNum = 0, schemaLim = xmpObj.tree.children.size(); schemaNum < schemaLim; ++schemaNum ) { |
| 1073 | const XMP_Node * currSchema = xmpObj.tree.children[schemaNum]; |
| 1074 | outputLen += 2*(baseIndent+2)*indentLen + strlen(kRDF_SchemaStart) + treeNameLen + strlen(kRDF_SchemaEnd) + 2; |
| 1075 | outputLen += EstimateRDFSize ( currSchema, baseIndent+2, indentLen ); |
| 1076 | } |
| 1077 | |
| 1078 | outputLen += (outputLen >> 2); // Inflate by 1/4, an empirical fudge factor. |
| 1079 | |
| 1080 | // Now generate the RDF into the head string as UTF-8. |
| 1081 | |
| 1082 | XMP_Index level; |
| 1083 | |
| 1084 | headStr.erase(); |
| 1085 | headStr.reserve ( outputLen ); |
| 1086 | |
| 1087 | // Write the packet header PI. |
| 1088 | if ( ! (options & kXMP_OmitPacketWrapper) ) { |
| 1089 | for ( level = baseIndent; level > 0; --level ) headStr += indentStr; |
| 1090 | headStr += kPacketHeader; |
| 1091 | headStr += newline; |
| 1092 | } |
| 1093 | |
| 1094 | // Write the xmpmeta element's start tag. |
| 1095 | if ( ! (options & kXMP_OmitXMPMetaElement) ) { |
| 1096 | for ( level = baseIndent; level > 0; --level ) headStr += indentStr; |
| 1097 | headStr += kRDF_XMPMetaStart; |
| 1098 | headStr += kXMPCore_VersionMessage "\">"; |
| 1099 | headStr += newline; |
| 1100 | } |
| 1101 | |
| 1102 | // Write the rdf:RDF start tag. |
| 1103 | for ( level = baseIndent+1; level > 0; --level ) headStr += indentStr; |
| 1104 | headStr += kRDF_RDFStart; |
| 1105 | headStr += newline; |
| 1106 | |
| 1107 | // Write all of the properties. |
no test coverage detected