File: | libsynthesis/src/sysync/syncitemtype.cpp |
Warning: | line 669, column 32 Access to field 'length' results in a dereference of a null pointer (loaded from field 'data') |
1 | /* | |||
2 | * File: SyncItemType.cpp | |||
3 | * | |||
4 | * Author: Lukas Zeller (luz@plan44.ch) | |||
5 | * | |||
6 | * TSyncItemType | |||
7 | * Type description and converter (template) for TSyncItem. | |||
8 | * | |||
9 | * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch | |||
10 | * | |||
11 | * 2001-05-16 : luz : created | |||
12 | * | |||
13 | */ | |||
14 | ||||
15 | // includes | |||
16 | #include "prefix_file.h" | |||
17 | ||||
18 | #include "sysync.h" | |||
19 | #include "syncitemtype.h" | |||
20 | #include "syncitem.h" | |||
21 | #include "synccommand.h" | |||
22 | #include "syncsession.h" | |||
23 | ||||
24 | #ifdef ZIPPED_BINDATA_SUPPORT1 | |||
25 | #include "zlib.h" | |||
26 | #endif | |||
27 | ||||
28 | using namespace sysync; | |||
29 | ||||
30 | ||||
31 | /* | |||
32 | * Implementation of TSyncItemType | |||
33 | */ | |||
34 | ||||
35 | /* TSyncItemType members */ | |||
36 | ||||
37 | void TSyncItemType::init( | |||
38 | TSyncSession *aSessionP, | |||
39 | TDataTypeConfig *aTypeConfigP, | |||
40 | const char *aCTType, | |||
41 | const char *aVerCT, | |||
42 | TSyncDataStore *aRelatedDatastoreP | |||
43 | ) | |||
44 | { | |||
45 | // link to config | |||
46 | fTypeConfigP=aTypeConfigP; | |||
47 | // link to session | |||
48 | fSessionP=aSessionP; | |||
49 | // set type name and vers (if any) | |||
50 | fTypeName=aCTType; | |||
51 | if (aVerCT) fTypeVers=aVerCT; | |||
52 | // set relation to a specific datastore (if any) | |||
53 | fRelatedDatastoreP=aRelatedDatastoreP; | |||
54 | // assume local | |||
55 | fIsRemoteType = false; | |||
56 | ||||
57 | #if defined(ZIPPED_BINDATA_SUPPORT1) && defined(SYDEBUG2) | |||
58 | // data compression accounting | |||
59 | fRawDataBytes=0; | |||
60 | fZippedDataBytes=0; | |||
61 | #endif | |||
62 | ||||
63 | } // TSyncItemType::init | |||
64 | ||||
65 | ||||
66 | TSyncItemType::TSyncItemType( | |||
67 | TSyncSession *aSessionP, | |||
68 | TDataTypeConfig *aTypeConfigP, | |||
69 | const char *aCTType, | |||
70 | const char *aVerCT, | |||
71 | TSyncDataStore *aRelatedDatastoreP | |||
72 | ) | |||
73 | { | |||
74 | // only basic init | |||
75 | init(aSessionP,aTypeConfigP,aCTType,aVerCT,aRelatedDatastoreP); | |||
76 | } // TSyncItemType::TSyncItemType | |||
77 | ||||
78 | ||||
79 | TSyncItemType::~TSyncItemType() | |||
80 | { | |||
81 | #if defined(ZIPPED_BINDATA_SUPPORT1) && defined(SYDEBUG2) | |||
82 | // show compression statistics, if any | |||
83 | if (fSessionP && fRawDataBytes && fZippedDataBytes) { | |||
84 | POBJDEBUGPRINTFX(fSessionP,DBG_HOT,({ if ((fSessionP) && (((0x00000001) & (fSessionP) ->getDbgMask()) == (0x00000001))) (fSessionP)->getDbgLogger ()->setNextMask(0x00000001).DebugPrintfLastMask ( "##### Type '%s', zippedbindata send statistics: raw=%ld, compressed=%ld, compressed down to %ld%%" , getTypeName(), (long)fRawDataBytes, (long)fZippedDataBytes, (long)(fZippedDataBytes*100/fRawDataBytes) ); } | |||
85 | "##### Type '%s', zippedbindata send statistics: raw=%ld, compressed=%ld, compressed down to %ld%%",{ if ((fSessionP) && (((0x00000001) & (fSessionP) ->getDbgMask()) == (0x00000001))) (fSessionP)->getDbgLogger ()->setNextMask(0x00000001).DebugPrintfLastMask ( "##### Type '%s', zippedbindata send statistics: raw=%ld, compressed=%ld, compressed down to %ld%%" , getTypeName(), (long)fRawDataBytes, (long)fZippedDataBytes, (long)(fZippedDataBytes*100/fRawDataBytes) ); } | |||
86 | getTypeName(),{ if ((fSessionP) && (((0x00000001) & (fSessionP) ->getDbgMask()) == (0x00000001))) (fSessionP)->getDbgLogger ()->setNextMask(0x00000001).DebugPrintfLastMask ( "##### Type '%s', zippedbindata send statistics: raw=%ld, compressed=%ld, compressed down to %ld%%" , getTypeName(), (long)fRawDataBytes, (long)fZippedDataBytes, (long)(fZippedDataBytes*100/fRawDataBytes) ); } | |||
87 | (long)fRawDataBytes,{ if ((fSessionP) && (((0x00000001) & (fSessionP) ->getDbgMask()) == (0x00000001))) (fSessionP)->getDbgLogger ()->setNextMask(0x00000001).DebugPrintfLastMask ( "##### Type '%s', zippedbindata send statistics: raw=%ld, compressed=%ld, compressed down to %ld%%" , getTypeName(), (long)fRawDataBytes, (long)fZippedDataBytes, (long)(fZippedDataBytes*100/fRawDataBytes) ); } | |||
88 | (long)fZippedDataBytes,{ if ((fSessionP) && (((0x00000001) & (fSessionP) ->getDbgMask()) == (0x00000001))) (fSessionP)->getDbgLogger ()->setNextMask(0x00000001).DebugPrintfLastMask ( "##### Type '%s', zippedbindata send statistics: raw=%ld, compressed=%ld, compressed down to %ld%%" , getTypeName(), (long)fRawDataBytes, (long)fZippedDataBytes, (long)(fZippedDataBytes*100/fRawDataBytes) ); } | |||
89 | (long)(fZippedDataBytes*100/fRawDataBytes){ if ((fSessionP) && (((0x00000001) & (fSessionP) ->getDbgMask()) == (0x00000001))) (fSessionP)->getDbgLogger ()->setNextMask(0x00000001).DebugPrintfLastMask ( "##### Type '%s', zippedbindata send statistics: raw=%ld, compressed=%ld, compressed down to %ld%%" , getTypeName(), (long)fRawDataBytes, (long)fZippedDataBytes, (long)(fZippedDataBytes*100/fRawDataBytes) ); } | |||
90 | )){ if ((fSessionP) && (((0x00000001) & (fSessionP) ->getDbgMask()) == (0x00000001))) (fSessionP)->getDbgLogger ()->setNextMask(0x00000001).DebugPrintfLastMask ( "##### Type '%s', zippedbindata send statistics: raw=%ld, compressed=%ld, compressed down to %ld%%" , getTypeName(), (long)fRawDataBytes, (long)fZippedDataBytes, (long)(fZippedDataBytes*100/fRawDataBytes) ); }; | |||
91 | } | |||
92 | #endif | |||
93 | } // TSyncItemType::~TSyncItemType | |||
94 | ||||
95 | ||||
96 | ||||
97 | // get session zones pointer | |||
98 | GZones *TSyncItemType::getSessionZones(void) | |||
99 | { | |||
100 | return getSession() ? getSession()->getSessionZones() : NULL__null; | |||
101 | } // TSyncItemType::getSessionZones | |||
102 | ||||
103 | ||||
104 | #ifdef SYDEBUG2 | |||
105 | ||||
106 | TDebugLogger *TSyncItemType::getDbgLogger(void) | |||
107 | { | |||
108 | // commands log to session's logger | |||
109 | return fSessionP ? getSession()->getDbgLogger() : NULL__null; | |||
110 | } // TSyncItemType::getDbgLogger | |||
111 | ||||
112 | uInt32 TSyncItemType::getDbgMask(void) | |||
113 | { | |||
114 | if (!fSessionP) return 0; // no session, no debug | |||
115 | return fSessionP->getDbgMask(); | |||
116 | } // TSyncItemType::getDbgMask | |||
117 | ||||
118 | #endif | |||
119 | ||||
120 | ||||
121 | ||||
122 | ||||
123 | // helper to create same-typed instance via base class | |||
124 | TSyncItemType *TSyncItemType::newCopyForSameType( | |||
125 | TSyncSession *aSessionP, // the session | |||
126 | TSyncDataStore *aDatastoreP // the datastore | |||
127 | ) | |||
128 | { | |||
129 | // create new itemtype of appropriate derived class type that can handle | |||
130 | // this type | |||
131 | MP_RETURN_NEW(TSyncItemType,DBG_OBJINST,"TSyncItemType",TSyncItemType(aSessionP,fTypeConfigP,getTypeName(),getTypeVers(),aDatastoreP))return new TSyncItemType(aSessionP,fTypeConfigP,getTypeName() ,getTypeVers(),aDatastoreP); | |||
132 | } // TSyncItemType::newCopyForSameType | |||
133 | ||||
134 | ||||
135 | ||||
136 | // check if type is supported | |||
137 | // - if version specified is NULL, first name-matching flavour is returned | |||
138 | // - if type has no version, it matches any versions given | |||
139 | // - if aVersMustMatch is set, version must match (both w/o version is a match, too) | |||
140 | bool TSyncItemType::supportsType(const char *aName, const char *aVers, bool aVersMustMatch) | |||
141 | { | |||
142 | if (!aName) return false; // no support for unnamed | |||
143 | if (!aVers) aVers=""; // empty version | |||
144 | return ( | |||
145 | strucmp(fTypeName.c_str(),aName)==0 && | |||
146 | ( ((*aVers==0 || fTypeVers.empty()) && !aVersMustMatch) || strucmp(fTypeVers.c_str(),aVers)==0 ) | |||
147 | ); | |||
148 | } // TSyncItemType::supportsType | |||
149 | ||||
150 | ||||
151 | ||||
152 | bool TSyncItemType::supportsType(SmlDevInfXmitPtr_t aXmitType, bool aVersMustMatch) | |||
153 | { | |||
154 | if (!aXmitType) return false; // null type not found | |||
155 | return ( | |||
156 | supportsType( | |||
157 | smlPCDataToCharP(aXmitType->cttype), | |||
158 | smlPCDataToCharP(aXmitType->verct), | |||
159 | aVersMustMatch | |||
160 | ) | |||
161 | ); | |||
162 | } // TSyncItemType::supportsType | |||
163 | ||||
164 | ||||
165 | ||||
166 | /// @brief get CTCap entry | |||
167 | /// @param aOnlyForDS[in] | |||
168 | /// - if NULL, CTCap is generated suitable for all datastores | |||
169 | /// - if not NULL, CTCap is generated specifically for the datastore passed | |||
170 | const SmlDevInfCTCapPtr_t TSyncItemType::getCTCapDevInf(TLocalEngineDS *aOnlyForDS, TTypeVariantDescriptor aVariantDescriptor, bool aWithoutCTCapProps) | |||
171 | { | |||
172 | SmlDevInfCTCapPtr_t ctcap=NULL__null; | |||
173 | // get item type and property description (part of <CTCap>), if any | |||
174 | // - first see if we have (and are allowed to show) property descriptions at all | |||
175 | SmlDevInfCTDataPropListPtr_t proplistP = NULL__null; | |||
176 | if (fSessionP->fShowCTCapProps && !aWithoutCTCapProps) | |||
177 | proplistP = newCTDataPropList(aVariantDescriptor); | |||
178 | // - and if we should report field level replace capability to remote | |||
179 | bool acceptsFieldLevel = getSession()->getSyncMLVersion()>=syncml_vers_1_2 && canAcceptFieldLevelUpdates(); | |||
180 | if (proplistP || acceptsFieldLevel) { | |||
181 | // there are properties available for this item, create DevInfCTCap | |||
182 | ctcap = SML_NEW(SmlDevInfCTCap_t)((SmlDevInfCTCap_t*) _smlMalloc(sizeof(SmlDevInfCTCap_t))); | |||
183 | // - add type name | |||
184 | ctcap->cttype=newPCDataString(getTypeName()); | |||
185 | // - for DS 1.2, add the VerCT | |||
186 | if (getSession()->getSyncMLVersion()>=syncml_vers_1_2) | |||
187 | ctcap->verct=newPCDataString(getTypeVers()); | |||
188 | else | |||
189 | ctcap->verct=NULL__null; | |||
190 | // - init the flags | |||
191 | ctcap->flags= acceptsFieldLevel ? SmlDevInfFieldLevel_f0x0010 : 0; | |||
192 | // - add property list | |||
193 | ctcap->prop=proplistP; | |||
194 | } | |||
195 | return ctcap; | |||
196 | } // TSyncItemType::getCTCapDevInf | |||
197 | ||||
198 | ||||
199 | // intended for creating SyncItemTypes for remote databases from | |||
200 | // transmitted DevInf. | |||
201 | bool TSyncItemType::analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP) | |||
202 | { | |||
203 | // Note: derived classes will possibly get some type-related info out of the CTCaps | |||
204 | return true; | |||
205 | } // TSyncItemType::analyzeCTCap | |||
206 | ||||
207 | ||||
208 | /// @brief copy CTCap derived info from another SyncItemType | |||
209 | /// @return false if item not compatible | |||
210 | /// @note required to create remote type variants from ruleMatch type alternatives | |||
211 | bool TSyncItemType::copyCTCapInfoFrom(TSyncItemType &aSourceItem) | |||
212 | { | |||
213 | // no generic CTCap info to copy | |||
214 | return true; | |||
215 | } // TSyncItemType::copyCTCapInfoFrom | |||
216 | ||||
217 | ||||
218 | ||||
219 | // - static function to search type in a TSyncItemTypePContainer | |||
220 | TSyncItemType *TSyncItemType::findTypeInList( | |||
221 | TSyncItemTypePContainer &aList, | |||
222 | const char *aName, const char *aVers, | |||
223 | bool aVersMustMatch, | |||
224 | bool aMustBeImplemented, | |||
225 | TSyncDataStore *aRelatedDatastoreP // if not NULL, type must be specific to this datastore (or unspecific) | |||
226 | ) | |||
227 | { | |||
228 | TSyncItemTypePContainer::iterator pos; | |||
229 | // first priority: return type which is specific to aRelatedDatastoreP | |||
230 | for (pos=aList.begin(); pos!=aList.end(); ++pos) { | |||
231 | if ((*pos)->supportsType(aName,aVers,aVersMustMatch)) { | |||
232 | // found, return if implementation is ok and related to the correct datastore (or no relation requested) | |||
233 | if ( | |||
234 | ( !aMustBeImplemented || (*pos)->isImplemented() ) && | |||
235 | ( (aRelatedDatastoreP==NULL__null) || ((*pos)->getRelatedDatastore()==aRelatedDatastoreP) ) | |||
236 | ) | |||
237 | return (*pos); // return it | |||
238 | } | |||
239 | } | |||
240 | if (aRelatedDatastoreP) { | |||
241 | // second priority: return type which is expressedly not specific to a datastore | |||
242 | for (pos=aList.begin(); pos!=aList.end(); ++pos) { | |||
243 | if ((*pos)->supportsType(aName,aVers,aVersMustMatch)) { | |||
244 | // found, return if implementation is ok and related to the correct datastore | |||
245 | if ( | |||
246 | (!aMustBeImplemented || (*pos)->isImplemented()) && | |||
247 | ((*pos)->getRelatedDatastore()==NULL__null) | |||
248 | ) | |||
249 | return (*pos); // return it | |||
250 | } | |||
251 | } | |||
252 | } | |||
253 | return NULL__null; // not found | |||
254 | } // static TSyncItemType::findTypeInList | |||
255 | ||||
256 | ||||
257 | // - static function to search type in a TSyncItemTypePContainer | |||
258 | TSyncItemType *TSyncItemType::findTypeInList( | |||
259 | TSyncItemTypePContainer &aList, | |||
260 | SmlDevInfXmitPtr_t aXmitType, // name and version of type | |||
261 | bool aVersMustMatch, | |||
262 | bool aMustBeImplemented, | |||
263 | TSyncDataStore *aRelatedDatastoreP // if not NULL, type must be specific to THIS datastore (or unspecific) | |||
264 | ) | |||
265 | { | |||
266 | return ( | |||
267 | findTypeInList( | |||
268 | aList, | |||
269 | smlPCDataToCharP(aXmitType->cttype), | |||
270 | smlPCDataToCharP(aXmitType->verct), | |||
271 | aVersMustMatch, | |||
272 | aMustBeImplemented, | |||
273 | aRelatedDatastoreP | |||
274 | ) | |||
275 | ); | |||
276 | } // static TSyncItemType::findTypeInList | |||
277 | ||||
278 | ||||
279 | // - static function to add new or copied ItemType to passed list | |||
280 | TSyncItemType *TSyncItemType::registerRemoteType( | |||
281 | TSyncSession *aSessionP, | |||
282 | SmlDevInfXmitPtr_t aXmitTypeP, // name and version of type | |||
283 | TSyncItemTypePContainer &aLocalItemTypes, // list to look up local types (for reference) | |||
284 | TSyncItemTypePContainer &aNewItemTypes, // list to add analyzed types if not already there | |||
285 | TSyncDataStore *aRelatedDatastoreP | |||
286 | ) | |||
287 | { | |||
288 | return ( | |||
289 | registerRemoteType( | |||
290 | aSessionP, | |||
291 | smlPCDataToCharP(aXmitTypeP->cttype), | |||
292 | smlPCDataToCharP(aXmitTypeP->verct), | |||
293 | aLocalItemTypes, | |||
294 | aNewItemTypes, | |||
295 | aRelatedDatastoreP | |||
296 | ) | |||
297 | ); | |||
298 | } // static TSyncItemType::registerRemoteType | |||
299 | ||||
300 | ||||
301 | // - static function to add new or copied ItemType to passed list | |||
302 | // If type is already in aNewItemTypes, nothing will be added | |||
303 | TSyncItemType *TSyncItemType::registerRemoteType( | |||
304 | TSyncSession *aSessionP, | |||
305 | const char *aName, const char *aVers, // name and version of type | |||
306 | TSyncItemTypePContainer &aLocalItemTypes, // list to look up local types (for reference) - aRelatedDatastoreP does NOT relate to the types here, as these are local ones | |||
307 | TSyncItemTypePContainer &aNewItemTypes, // list to add analyzed types if not already there | |||
308 | TSyncDataStore *aRelatedDatastoreP // if NULL, type is not related to a specific (remote!) datastore | |||
309 | ) | |||
310 | { | |||
311 | if (!aName) SYSYNC_THROW(TSyncException("cannot register type w/o name"))throw TSyncException("cannot register type w/o name"); | |||
312 | #ifdef SYDEBUG2 | |||
313 | if (aSessionP) { | |||
314 | // Show warning if no version | |||
315 | if (!aVers || *aVers==0) { | |||
316 | POBJDEBUGPRINTFX(aSessionP,DBG_REMOTEINFO,("WARNING: Registering type with no version specification!")){ if ((aSessionP) && (((0x00000100) & (aSessionP) ->getDbgMask()) == (0x00000100))) (aSessionP)->getDbgLogger ()->setNextMask(0x00000100).DebugPrintfLastMask ("WARNING: Registering type with no version specification!" ); }; | |||
317 | } | |||
318 | } | |||
319 | #endif | |||
320 | // - check if type is already in the list (version must match, but implementation not required | |||
321 | TSyncItemType *newitemtypeP = findTypeInList(aNewItemTypes,aName,aVers,true,false,aRelatedDatastoreP); | |||
322 | if (newitemtypeP) { | |||
323 | POBJDEBUGPRINTFX(aSessionP,DBG_REMOTEINFO+DBG_EXOTIC,({ if ((aSessionP) && (((0x00000100 +0x80000000) & (aSessionP)->getDbgMask()) == (0x00000100 +0x80000000))) ( aSessionP)->getDbgLogger()->setNextMask(0x00000100 +0x80000000 ).DebugPrintfLastMask ( "Type already registered as '%s' Version='%s'" , newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers () ? newitemtypeP->getTypeVers() : "[none]" ); } | |||
324 | "Type already registered as '%s' Version='%s'",{ if ((aSessionP) && (((0x00000100 +0x80000000) & (aSessionP)->getDbgMask()) == (0x00000100 +0x80000000))) ( aSessionP)->getDbgLogger()->setNextMask(0x00000100 +0x80000000 ).DebugPrintfLastMask ( "Type already registered as '%s' Version='%s'" , newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers () ? newitemtypeP->getTypeVers() : "[none]" ); } | |||
325 | newitemtypeP->getTypeName(),{ if ((aSessionP) && (((0x00000100 +0x80000000) & (aSessionP)->getDbgMask()) == (0x00000100 +0x80000000))) ( aSessionP)->getDbgLogger()->setNextMask(0x00000100 +0x80000000 ).DebugPrintfLastMask ( "Type already registered as '%s' Version='%s'" , newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers () ? newitemtypeP->getTypeVers() : "[none]" ); } | |||
326 | newitemtypeP->hasTypeVers() ? newitemtypeP->getTypeVers() : "[none]"{ if ((aSessionP) && (((0x00000100 +0x80000000) & (aSessionP)->getDbgMask()) == (0x00000100 +0x80000000))) ( aSessionP)->getDbgLogger()->setNextMask(0x00000100 +0x80000000 ).DebugPrintfLastMask ( "Type already registered as '%s' Version='%s'" , newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers () ? newitemtypeP->getTypeVers() : "[none]" ); } | |||
327 | )){ if ((aSessionP) && (((0x00000100 +0x80000000) & (aSessionP)->getDbgMask()) == (0x00000100 +0x80000000))) ( aSessionP)->getDbgLogger()->setNextMask(0x00000100 +0x80000000 ).DebugPrintfLastMask ( "Type already registered as '%s' Version='%s'" , newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers () ? newitemtypeP->getTypeVers() : "[none]" ); }; | |||
328 | } | |||
329 | else { | |||
330 | // - check if one of the local item types supports this type | |||
331 | // Note: SySync engine only has one global list of supported types. It might contain multiple entries for | |||
332 | // the same type, when related to different datastores. The following search will find the first with | |||
333 | // matching name - this is no problem as long as all types with same name have the same CLASS type | |||
334 | // (as the only reason to look up in local types is to create the correct class' instance). When | |||
335 | // actually USED later by datastores, each datastore finds it's own INSTANCES via it's tx/rx(pref). | |||
336 | // No need for version match, but for implementation | |||
337 | TSyncItemType *localitemtypeP = findTypeInList(aLocalItemTypes,aName,aVers,false,true,NULL__null); // local types are not specific to a datastore | |||
338 | if (localitemtypeP) { | |||
339 | // %%% test for conforming version if type being registered has no version spec | |||
340 | // local itemtype exists that can support this type/vers | |||
341 | // - create new item type of same class (type-specialized derivate of TSyncItemType) | |||
342 | // - but relate it to the remote datastore (for DS1.2, or none for DS1.1 and earlier) | |||
343 | newitemtypeP = localitemtypeP->newCopyForSameType(aSessionP,aRelatedDatastoreP); | |||
344 | } | |||
345 | else { | |||
346 | // no local support of this type | |||
347 | // - create base class item just describing the type found | |||
348 | // (but without handling abilities) | |||
349 | newitemtypeP = new TSyncItemType(aSessionP,NULL__null,aName,aVers,aRelatedDatastoreP); | |||
350 | } | |||
351 | // this is a remote type! | |||
352 | newitemtypeP->defineAsRemoteType(); | |||
353 | // add item to list | |||
354 | aNewItemTypes.push_back(newitemtypeP); | |||
355 | POBJDEBUGPRINTFX(aSessionP,DBG_REMOTEINFO+DBG_HOT,({ if ((aSessionP) && (((0x00000100 +0x00000001) & (aSessionP)->getDbgMask()) == (0x00000100 +0x00000001))) ( aSessionP)->getDbgLogger()->setNextMask(0x00000100 +0x00000001 ).DebugPrintfLastMask ( "Registered Type '%s' Version='%s', %s%s, related to remote datastore '%s'" , newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers () ? newitemtypeP->getTypeVers() : "[none]", newitemtypeP-> isImplemented() ? "implemented by local type " : "NOT implemented" , newitemtypeP->isImplemented() ? newitemtypeP->getTypeConfig ()->getName() : "", aRelatedDatastoreP ? aRelatedDatastoreP ->getName() : "<none>" ); } | |||
356 | "Registered Type '%s' Version='%s', %s%s, related to remote datastore '%s'",{ if ((aSessionP) && (((0x00000100 +0x00000001) & (aSessionP)->getDbgMask()) == (0x00000100 +0x00000001))) ( aSessionP)->getDbgLogger()->setNextMask(0x00000100 +0x00000001 ).DebugPrintfLastMask ( "Registered Type '%s' Version='%s', %s%s, related to remote datastore '%s'" , newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers () ? newitemtypeP->getTypeVers() : "[none]", newitemtypeP-> isImplemented() ? "implemented by local type " : "NOT implemented" , newitemtypeP->isImplemented() ? newitemtypeP->getTypeConfig ()->getName() : "", aRelatedDatastoreP ? aRelatedDatastoreP ->getName() : "<none>" ); } | |||
357 | newitemtypeP->getTypeName(),{ if ((aSessionP) && (((0x00000100 +0x00000001) & (aSessionP)->getDbgMask()) == (0x00000100 +0x00000001))) ( aSessionP)->getDbgLogger()->setNextMask(0x00000100 +0x00000001 ).DebugPrintfLastMask ( "Registered Type '%s' Version='%s', %s%s, related to remote datastore '%s'" , newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers () ? newitemtypeP->getTypeVers() : "[none]", newitemtypeP-> isImplemented() ? "implemented by local type " : "NOT implemented" , newitemtypeP->isImplemented() ? newitemtypeP->getTypeConfig ()->getName() : "", aRelatedDatastoreP ? aRelatedDatastoreP ->getName() : "<none>" ); } | |||
358 | newitemtypeP->hasTypeVers() ? newitemtypeP->getTypeVers() : "[none]",{ if ((aSessionP) && (((0x00000100 +0x00000001) & (aSessionP)->getDbgMask()) == (0x00000100 +0x00000001))) ( aSessionP)->getDbgLogger()->setNextMask(0x00000100 +0x00000001 ).DebugPrintfLastMask ( "Registered Type '%s' Version='%s', %s%s, related to remote datastore '%s'" , newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers () ? newitemtypeP->getTypeVers() : "[none]", newitemtypeP-> isImplemented() ? "implemented by local type " : "NOT implemented" , newitemtypeP->isImplemented() ? newitemtypeP->getTypeConfig ()->getName() : "", aRelatedDatastoreP ? aRelatedDatastoreP ->getName() : "<none>" ); } | |||
359 | newitemtypeP->isImplemented() ? "implemented by local type " : "NOT implemented",{ if ((aSessionP) && (((0x00000100 +0x00000001) & (aSessionP)->getDbgMask()) == (0x00000100 +0x00000001))) ( aSessionP)->getDbgLogger()->setNextMask(0x00000100 +0x00000001 ).DebugPrintfLastMask ( "Registered Type '%s' Version='%s', %s%s, related to remote datastore '%s'" , newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers () ? newitemtypeP->getTypeVers() : "[none]", newitemtypeP-> isImplemented() ? "implemented by local type " : "NOT implemented" , newitemtypeP->isImplemented() ? newitemtypeP->getTypeConfig ()->getName() : "", aRelatedDatastoreP ? aRelatedDatastoreP ->getName() : "<none>" ); } | |||
360 | newitemtypeP->isImplemented() ? newitemtypeP->getTypeConfig()->getName() : "",{ if ((aSessionP) && (((0x00000100 +0x00000001) & (aSessionP)->getDbgMask()) == (0x00000100 +0x00000001))) ( aSessionP)->getDbgLogger()->setNextMask(0x00000100 +0x00000001 ).DebugPrintfLastMask ( "Registered Type '%s' Version='%s', %s%s, related to remote datastore '%s'" , newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers () ? newitemtypeP->getTypeVers() : "[none]", newitemtypeP-> isImplemented() ? "implemented by local type " : "NOT implemented" , newitemtypeP->isImplemented() ? newitemtypeP->getTypeConfig ()->getName() : "", aRelatedDatastoreP ? aRelatedDatastoreP ->getName() : "<none>" ); } | |||
361 | aRelatedDatastoreP ? aRelatedDatastoreP->getName() : "<none>"{ if ((aSessionP) && (((0x00000100 +0x00000001) & (aSessionP)->getDbgMask()) == (0x00000100 +0x00000001))) ( aSessionP)->getDbgLogger()->setNextMask(0x00000100 +0x00000001 ).DebugPrintfLastMask ( "Registered Type '%s' Version='%s', %s%s, related to remote datastore '%s'" , newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers () ? newitemtypeP->getTypeVers() : "[none]", newitemtypeP-> isImplemented() ? "implemented by local type " : "NOT implemented" , newitemtypeP->isImplemented() ? newitemtypeP->getTypeConfig ()->getName() : "", aRelatedDatastoreP ? aRelatedDatastoreP ->getName() : "<none>" ); } | |||
362 | )){ if ((aSessionP) && (((0x00000100 +0x00000001) & (aSessionP)->getDbgMask()) == (0x00000100 +0x00000001))) ( aSessionP)->getDbgLogger()->setNextMask(0x00000100 +0x00000001 ).DebugPrintfLastMask ( "Registered Type '%s' Version='%s', %s%s, related to remote datastore '%s'" , newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers () ? newitemtypeP->getTypeVers() : "[none]", newitemtypeP-> isImplemented() ? "implemented by local type " : "NOT implemented" , newitemtypeP->isImplemented() ? newitemtypeP->getTypeConfig ()->getName() : "", aRelatedDatastoreP ? aRelatedDatastoreP ->getName() : "<none>" ); }; | |||
363 | // Only show this if we REALLY have a local type-to-DS relation (NEVER so far - that is in 3.1.2.1) | |||
364 | if (newitemtypeP->isImplemented() && localitemtypeP && localitemtypeP->getRelatedDatastore()) { | |||
365 | POBJDEBUGPRINTFX(aSessionP,DBG_REMOTEINFO,({ if ((aSessionP) && (((0x00000100) & (aSessionP) ->getDbgMask()) == (0x00000100))) (aSessionP)->getDbgLogger ()->setNextMask(0x00000100).DebugPrintfLastMask ( "- Implementation is exclusively related to local datastore '%s'" , localitemtypeP->getRelatedDatastore()->getName() ); } | |||
366 | "- Implementation is exclusively related to local datastore '%s'",{ if ((aSessionP) && (((0x00000100) & (aSessionP) ->getDbgMask()) == (0x00000100))) (aSessionP)->getDbgLogger ()->setNextMask(0x00000100).DebugPrintfLastMask ( "- Implementation is exclusively related to local datastore '%s'" , localitemtypeP->getRelatedDatastore()->getName() ); } | |||
367 | localitemtypeP->getRelatedDatastore()->getName(){ if ((aSessionP) && (((0x00000100) & (aSessionP) ->getDbgMask()) == (0x00000100))) (aSessionP)->getDbgLogger ()->setNextMask(0x00000100).DebugPrintfLastMask ( "- Implementation is exclusively related to local datastore '%s'" , localitemtypeP->getRelatedDatastore()->getName() ); } | |||
368 | )){ if ((aSessionP) && (((0x00000100) & (aSessionP) ->getDbgMask()) == (0x00000100))) (aSessionP)->getDbgLogger ()->setNextMask(0x00000100).DebugPrintfLastMask ( "- Implementation is exclusively related to local datastore '%s'" , localitemtypeP->getRelatedDatastore()->getName() ); }; | |||
369 | } | |||
370 | } // if not already in list | |||
371 | return newitemtypeP; | |||
372 | } // static TSyncItemType::registerRemoteType | |||
373 | ||||
374 | ||||
375 | /// @brief static function to analyze CTCap and add entries to passed list | |||
376 | /// @todo %%% to be moved to TMimeDirItemType (as basic TSyncItemType does not really know the VERSION property) | |||
377 | bool TSyncItemType::analyzeCTCapAndCreateItemTypes( | |||
378 | TSyncSession *aSessionP, | |||
379 | TRemoteDataStore *aRemoteDataStoreP, ///< if not NULL, this is the datastore to which this type is local (DS 1.2 case) | |||
380 | SmlDevInfCTCapPtr_t aCTCapP, | |||
381 | TSyncItemTypePContainer &aLocalItemTypes, ///< list to look up local types (for reference) | |||
382 | TSyncItemTypePContainer &aNewItemTypes ///< list to add analyzed types if not already there | |||
383 | ) | |||
384 | { | |||
385 | bool versfound = false; | |||
386 | ||||
387 | // create one TSyncItemType for each type contained in this CTCap | |||
388 | if (aCTCapP) { | |||
389 | // type name | |||
390 | const char *name = smlPCDataToCharP(aCTCapP->cttype); | |||
391 | // - from DS 1.2 on, we should have the verct without digging into properties | |||
392 | const char *vers = smlPCDataToCharP(aCTCapP->verct); | |||
393 | if (vers && *vers) { | |||
394 | // we have a non-empty version from verct (new DS 1.2 devinf) | |||
395 | #ifdef SYDEBUG2 | |||
396 | if (aSessionP) { PLOGDEBUGBLOCKFMTCOLL(aSessionP->getDbgLogger(),("RemoteCTCap", "Registering remote Type/Version from >=DS 1.2 style CTCap", "type=%s|version=%s", name, vers)){ if (aSessionP->getDbgLogger()) (aSessionP->getDbgLogger ())->DebugOpenBlockCollapsed ("RemoteCTCap", "Registering remote Type/Version from >=DS 1.2 style CTCap" , "type=%s|version=%s", name, vers); }; } | |||
397 | #endif | |||
398 | // valenum shows version supported | |||
399 | TSyncItemType *newitemtypeP = | |||
400 | registerRemoteType( | |||
401 | aSessionP, | |||
402 | name,vers, // name and version of type | |||
403 | aLocalItemTypes, // list to look up local types (for reference) | |||
404 | aNewItemTypes, // list to add it to | |||
405 | aRemoteDataStoreP | |||
406 | ); | |||
407 | // now let new item process the CTCap | |||
408 | if (newitemtypeP) newitemtypeP->analyzeCTCap(aCTCapP); | |||
409 | #ifdef SYDEBUG2 | |||
410 | if (aSessionP) { PLOGDEBUGENDBLOCK(aSessionP->getDbgLogger(),"RemoteCTCap"){ if (aSessionP->getDbgLogger()) (aSessionP->getDbgLogger ())->DebugCloseBlock( "RemoteCTCap"); }; } | |||
411 | #endif | |||
412 | versfound=true; | |||
413 | } | |||
414 | else { | |||
415 | // - pre-DS 1.2 hack: try to find VERSION property | |||
416 | SmlDevInfCTDataPropListPtr_t prlP = aCTCapP->prop; | |||
417 | while (prlP) { | |||
418 | // get property name | |||
419 | const char *n = smlPCDataToCharP(prlP->data->prop->name); | |||
420 | if (n && strcmp(n,"VERSION")==0) { | |||
421 | // version property found. Now create flavour for each ValEnum | |||
422 | SmlPcdataListPtr_t velP = prlP->data->prop->valenum; | |||
423 | while (velP) { | |||
424 | vers = smlPCDataToCharP(velP->data); | |||
425 | if (vers) { | |||
426 | versfound=true; // found at least one | |||
427 | #ifdef SYDEBUG2 | |||
428 | if (aSessionP) { PLOGDEBUGBLOCKFMTCOLL(aSessionP->getDbgLogger(),("RemoteCTCap", "Registering remote Type/Version from old style CTCap w/o verct", "type=%s|version=%s", name, vers)){ if (aSessionP->getDbgLogger()) (aSessionP->getDbgLogger ())->DebugOpenBlockCollapsed ("RemoteCTCap", "Registering remote Type/Version from old style CTCap w/o verct" , "type=%s|version=%s", name, vers); }; } | |||
429 | #endif | |||
430 | // valenum shows version supported | |||
431 | TSyncItemType *newitemtypeP = | |||
432 | registerRemoteType( | |||
433 | aSessionP, | |||
434 | name,vers, // name and version of type | |||
435 | aLocalItemTypes, // list to look up local types (for reference) | |||
436 | aNewItemTypes, // list to add it to | |||
437 | aRemoteDataStoreP | |||
438 | ); | |||
439 | // now let new item process the CTCap | |||
440 | if (newitemtypeP) newitemtypeP->analyzeCTCap(aCTCapP); | |||
441 | #ifdef SYDEBUG2 | |||
442 | if (aSessionP) { PLOGDEBUGENDBLOCK(aSessionP->getDbgLogger(),"RemoteCTCap"){ if (aSessionP->getDbgLogger()) (aSessionP->getDbgLogger ())->DebugCloseBlock( "RemoteCTCap"); }; } | |||
443 | #endif | |||
444 | } // if version is not null | |||
445 | // next | |||
446 | velP=velP->next; | |||
447 | } // while valenums | |||
448 | break; // VERSION found, done with properties for now | |||
449 | } // while properties | |||
450 | prlP=prlP->next; | |||
451 | } // while | |||
452 | } | |||
453 | if (!versfound) { | |||
454 | // version is NULL, for a start, create type w/o version | |||
455 | #ifdef SYDEBUG2 | |||
456 | if (aSessionP) { PLOGDEBUGBLOCKFMT(aSessionP->getDbgLogger(),("RemoteCTCap", "Registering remote Type w/o version from CTCap", "type=%s|version=[none]", name)){ if (aSessionP->getDbgLogger()) (aSessionP->getDbgLogger ())->DebugOpenBlockExpanded ("RemoteCTCap", "Registering remote Type w/o version from CTCap" , "type=%s|version=[none]", name); }; } | |||
457 | #endif | |||
458 | TSyncItemType *newitemtypeP = | |||
459 | registerRemoteType( | |||
460 | aSessionP, | |||
461 | name,NULL__null, // name, but no version | |||
462 | aLocalItemTypes, // list to look up local types (for reference) | |||
463 | aNewItemTypes, // list to add it to | |||
464 | aRemoteDataStoreP | |||
465 | ); | |||
466 | // now let new item process the CTCap | |||
467 | if (newitemtypeP) newitemtypeP->analyzeCTCap(aCTCapP); | |||
468 | #ifdef SYDEBUG2 | |||
469 | if (aSessionP) { PLOGDEBUGENDBLOCK(aSessionP->getDbgLogger(),"RemoteCTCap"){ if (aSessionP->getDbgLogger()) (aSessionP->getDbgLogger ())->DebugCloseBlock( "RemoteCTCap"); }; } | |||
470 | #endif | |||
471 | // this is ok, too | |||
472 | return true; | |||
473 | } // without version | |||
474 | } | |||
475 | return versfound; | |||
476 | } // static TSyncItemType::analyzeCTCapAndCreateItemTypes | |||
477 | ||||
478 | ||||
479 | ||||
480 | // get type as transmit format | |||
481 | SmlDevInfXmitPtr_t TSyncItemType::newXMitDevInf(void) | |||
482 | { | |||
483 | SmlDevInfXmitPtr_t xmitP; | |||
484 | ||||
485 | xmitP = SML_NEW(SmlDevInfXmit_t)((SmlDevInfXmit_t*) _smlMalloc(sizeof(SmlDevInfXmit_t))); | |||
486 | xmitP->cttype=newPCDataString(getTypeName()); | |||
487 | xmitP->verct=newPCDataString(getTypeVers()); | |||
488 | ||||
489 | return xmitP; | |||
490 | } // TSyncItemType::newXMitDevInf | |||
491 | ||||
492 | ||||
493 | // static helper: get type list as transmit format | |||
494 | SmlDevInfXmitListPtr_t TSyncItemType::newXMitListDevInf( | |||
495 | TSyncItemTypePContainer &aTypeList, | |||
496 | TSyncItemType *aDontIncludeP | |||
497 | ) | |||
498 | { | |||
499 | SmlDevInfXmitListPtr_t resultP = NULL__null; | |||
500 | SmlDevInfXmitListPtr_t *listPP = &resultP; | |||
501 | ||||
502 | TSyncItemTypePContainer::iterator pos; | |||
503 | for (pos=aTypeList.begin(); pos!=aTypeList.end(); ++pos) { | |||
504 | if (aDontIncludeP!=(*pos)) { // only if item in list does not match "except" item | |||
505 | // new list item | |||
506 | (*listPP) = SML_NEW(SmlDevInfXmitList_t)((SmlDevInfXmitList_t*) _smlMalloc(sizeof(SmlDevInfXmitList_t ))); | |||
507 | (*listPP)->next=NULL__null; | |||
508 | // add type | |||
509 | (*listPP)->data=(*pos)->newXMitDevInf(); | |||
510 | // next | |||
511 | listPP=&((*listPP)->next); | |||
512 | } | |||
513 | } | |||
514 | return resultP; | |||
515 | } // TSyncItemType::newXMitListDevInf | |||
516 | ||||
517 | ||||
518 | // create new empty sync item | |||
519 | TSyncItem *TSyncItemType::newSyncItem( | |||
520 | TSyncItemType *aTargetItemTypeP, // the targeted type (for optimizing field lists etc.) | |||
521 | TLocalEngineDS *aLocalDataStoreP // the datastore | |||
522 | ) | |||
523 | { | |||
524 | if (!aLocalDataStoreP) { | |||
525 | PDEBUGPRINTFX(DBG_ERROR,("Trying to call newSyncItem w/o datastore")){ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ("Trying to call newSyncItem w/o datastore" ); }; | |||
526 | return NULL__null; | |||
527 | } | |||
528 | // test if implemented at all | |||
529 | if (!isImplemented()) { | |||
530 | PDEBUGPRINTFX(DBG_ERROR,({ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ( "Tried to create SyncItem for unimplemented SyncItemType '%s' (%s)" , fTypeName.c_str(), fTypeVers.c_str() ); } | |||
531 | "Tried to create SyncItem for unimplemented SyncItemType '%s' (%s)",{ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ( "Tried to create SyncItem for unimplemented SyncItemType '%s' (%s)" , fTypeName.c_str(), fTypeVers.c_str() ); } | |||
532 | fTypeName.c_str(),{ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ( "Tried to create SyncItem for unimplemented SyncItemType '%s' (%s)" , fTypeName.c_str(), fTypeVers.c_str() ); } | |||
533 | fTypeVers.c_str(){ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ( "Tried to create SyncItem for unimplemented SyncItemType '%s' (%s)" , fTypeName.c_str(), fTypeVers.c_str() ); } | |||
534 | )){ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ( "Tried to create SyncItem for unimplemented SyncItemType '%s' (%s)" , fTypeName.c_str(), fTypeVers.c_str() ); }; | |||
535 | return NULL__null; | |||
536 | } | |||
537 | // check for compatibility with targeted type | |||
538 | if (!isCompatibleWith(aTargetItemTypeP)) { | |||
539 | PDEBUGPRINTFX(DBG_ERROR,({ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ( "Local type (%s) is not assignment compatible with remote target type (%s) - probably multiple types with same name/version but different fieldlists in config" , getTypeConfig()->getName(),aTargetItemTypeP-> getTypeConfig ()->getName() ); } | |||
540 | "Local type (%s) is not assignment compatible with remote target type (%s) - probably multiple types with same name/version but different fieldlists in config",{ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ( "Local type (%s) is not assignment compatible with remote target type (%s) - probably multiple types with same name/version but different fieldlists in config" , getTypeConfig()->getName(),aTargetItemTypeP-> getTypeConfig ()->getName() ); } | |||
541 | getTypeConfig()->getName(),aTargetItemTypeP-> getTypeConfig()->getName(){ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ( "Local type (%s) is not assignment compatible with remote target type (%s) - probably multiple types with same name/version but different fieldlists in config" , getTypeConfig()->getName(),aTargetItemTypeP-> getTypeConfig ()->getName() ); } | |||
542 | )){ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ( "Local type (%s) is not assignment compatible with remote target type (%s) - probably multiple types with same name/version but different fieldlists in config" , getTypeConfig()->getName(),aTargetItemTypeP-> getTypeConfig ()->getName() ); }; | |||
543 | return NULL__null; | |||
544 | } | |||
545 | // get appropriate item | |||
546 | TSyncItem *syncitemP = internalNewSyncItem(aTargetItemTypeP,aLocalDataStoreP); | |||
547 | // return new item (if any) | |||
548 | return syncitemP; | |||
549 | } // TSyncItemType::newSyncItem | |||
550 | ||||
551 | ||||
552 | // create new sync item from SyncML data | |||
553 | TSyncItem *TSyncItemType::newSyncItem( | |||
554 | SmlItemPtr_t aItemP, // SyncML toolkit item Data to be converted into SyncItem | |||
555 | TSyncOperation aSyncOp, // the operation to be performed with this item | |||
556 | TFmtTypes aFormat, // the format (normally fmt_chr) | |||
557 | TSyncItemType *aTargetItemTypeP, // the targeted type (for optimizing field lists etc.) | |||
558 | TLocalEngineDS *aLocalDataStoreP, // local datastore | |||
559 | TStatusCommand &aStatusCmd // status command that might be modified in case of error | |||
560 | ) | |||
561 | { | |||
562 | TSyncItem *syncitemP = NULL__null; | |||
563 | // test if implemented at all | |||
564 | if (!isImplemented()) { | |||
| ||||
565 | DEBUGPRINTFX(DBG_ERROR,({ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ( "Tried to create SyncItem for unimplemented SyncItemType '%s' (%s)" , fTypeName.c_str(), fTypeVers.c_str() ); } | |||
566 | "Tried to create SyncItem for unimplemented SyncItemType '%s' (%s)",{ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ( "Tried to create SyncItem for unimplemented SyncItemType '%s' (%s)" , fTypeName.c_str(), fTypeVers.c_str() ); } | |||
567 | fTypeName.c_str(),{ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ( "Tried to create SyncItem for unimplemented SyncItemType '%s' (%s)" , fTypeName.c_str(), fTypeVers.c_str() ); } | |||
568 | fTypeVers.c_str(){ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ( "Tried to create SyncItem for unimplemented SyncItemType '%s' (%s)" , fTypeName.c_str(), fTypeVers.c_str() ); } | |||
569 | )){ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ( "Tried to create SyncItem for unimplemented SyncItemType '%s' (%s)" , fTypeName.c_str(), fTypeVers.c_str() ); }; | |||
570 | aStatusCmd.setStatusCode(415); | |||
571 | ADDDEBUGITEM(aStatusCmd,"Known, but unimplemented Item Type"){ if ((((0x00000001) & getDbgMask()) == (0x00000001))) aStatusCmd .addItemString("Known, but unimplemented Item Type"); }; | |||
572 | return NULL__null; | |||
573 | } | |||
574 | PDEBUGBLOCKFMT(("Item_Parse","parsing SyncML item",getDbgLogger()->DebugOpenBlockExpanded ("Item_Parse","parsing SyncML item" , "SyncOp=%s|format=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncOp ], encodingFmtNames[aFormat], smlSrcTargLocURIToCharP(aItemP-> target), smlSrcTargLocURIToCharP(aItemP->source) ) | |||
575 | "SyncOp=%s|format=%s|LocalID=%s|RemoteID=%s",getDbgLogger()->DebugOpenBlockExpanded ("Item_Parse","parsing SyncML item" , "SyncOp=%s|format=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncOp ], encodingFmtNames[aFormat], smlSrcTargLocURIToCharP(aItemP-> target), smlSrcTargLocURIToCharP(aItemP->source) ) | |||
576 | SyncOpNames[aSyncOp],getDbgLogger()->DebugOpenBlockExpanded ("Item_Parse","parsing SyncML item" , "SyncOp=%s|format=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncOp ], encodingFmtNames[aFormat], smlSrcTargLocURIToCharP(aItemP-> target), smlSrcTargLocURIToCharP(aItemP->source) ) | |||
577 | encodingFmtNames[aFormat],getDbgLogger()->DebugOpenBlockExpanded ("Item_Parse","parsing SyncML item" , "SyncOp=%s|format=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncOp ], encodingFmtNames[aFormat], smlSrcTargLocURIToCharP(aItemP-> target), smlSrcTargLocURIToCharP(aItemP->source) ) | |||
578 | smlSrcTargLocURIToCharP(aItemP->target),getDbgLogger()->DebugOpenBlockExpanded ("Item_Parse","parsing SyncML item" , "SyncOp=%s|format=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncOp ], encodingFmtNames[aFormat], smlSrcTargLocURIToCharP(aItemP-> target), smlSrcTargLocURIToCharP(aItemP->source) ) | |||
579 | smlSrcTargLocURIToCharP(aItemP->source)getDbgLogger()->DebugOpenBlockExpanded ("Item_Parse","parsing SyncML item" , "SyncOp=%s|format=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncOp ], encodingFmtNames[aFormat], smlSrcTargLocURIToCharP(aItemP-> target), smlSrcTargLocURIToCharP(aItemP->source) ) | |||
580 | ))getDbgLogger()->DebugOpenBlockExpanded ("Item_Parse","parsing SyncML item" , "SyncOp=%s|format=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncOp ], encodingFmtNames[aFormat], smlSrcTargLocURIToCharP(aItemP-> target), smlSrcTargLocURIToCharP(aItemP->source) ); | |||
581 | SYSYNC_TRYtry { | |||
582 | // get appropriate item type | |||
583 | syncitemP = internalNewSyncItem(aTargetItemTypeP,aLocalDataStoreP); | |||
584 | // get local and remote IDs | |||
585 | if (syncitemP) { | |||
586 | // set operation type | |||
587 | syncitemP->setSyncOp(aSyncOp); | |||
588 | // an appropriate syncitem was created, set target and source now | |||
589 | // - we have received this item from remote, so target=myself, source=remote party | |||
590 | syncitemP->setLocalID(relativeURI(smlSrcTargLocURIToCharP(aItemP->target))); | |||
591 | #ifdef DONT_STRIP_PATHPREFIX_FROM_REMOTEIDS1 | |||
592 | syncitemP->setRemoteID(smlSrcTargLocURIToCharP(aItemP->source)); | |||
593 | #else | |||
594 | syncitemP->setRemoteID(relativeURI(smlSrcTargLocURIToCharP(aItemP->source))); | |||
595 | #endif | |||
596 | PDEBUGPRINTFX(DBG_DATA+DBG_DETAILS,({ if (((0x00000080 +0x40000000) & getDbgMask()) == (0x00000080 +0x40000000)) getDbgLogger()->setNextMask(0x00000080 +0x40000000 ).DebugPrintfLastMask ( "Created new item of datatype '%s', localID='%s' remoteID='%s'" , getTypeConfig()->getName(), syncitemP->getLocalID(), syncitemP ->getRemoteID() ); } | |||
597 | "Created new item of datatype '%s', localID='%s' remoteID='%s'",{ if (((0x00000080 +0x40000000) & getDbgMask()) == (0x00000080 +0x40000000)) getDbgLogger()->setNextMask(0x00000080 +0x40000000 ).DebugPrintfLastMask ( "Created new item of datatype '%s', localID='%s' remoteID='%s'" , getTypeConfig()->getName(), syncitemP->getLocalID(), syncitemP ->getRemoteID() ); } | |||
598 | getTypeConfig()->getName(),{ if (((0x00000080 +0x40000000) & getDbgMask()) == (0x00000080 +0x40000000)) getDbgLogger()->setNextMask(0x00000080 +0x40000000 ).DebugPrintfLastMask ( "Created new item of datatype '%s', localID='%s' remoteID='%s'" , getTypeConfig()->getName(), syncitemP->getLocalID(), syncitemP ->getRemoteID() ); } | |||
599 | syncitemP->getLocalID(),{ if (((0x00000080 +0x40000000) & getDbgMask()) == (0x00000080 +0x40000000)) getDbgLogger()->setNextMask(0x00000080 +0x40000000 ).DebugPrintfLastMask ( "Created new item of datatype '%s', localID='%s' remoteID='%s'" , getTypeConfig()->getName(), syncitemP->getLocalID(), syncitemP ->getRemoteID() ); } | |||
600 | syncitemP->getRemoteID(){ if (((0x00000080 +0x40000000) & getDbgMask()) == (0x00000080 +0x40000000)) getDbgLogger()->setNextMask(0x00000080 +0x40000000 ).DebugPrintfLastMask ( "Created new item of datatype '%s', localID='%s' remoteID='%s'" , getTypeConfig()->getName(), syncitemP->getLocalID(), syncitemP ->getRemoteID() ); } | |||
601 | )){ if (((0x00000080 +0x40000000) & getDbgMask()) == (0x00000080 +0x40000000)) getDbgLogger()->setNextMask(0x00000080 +0x40000000 ).DebugPrintfLastMask ( "Created new item of datatype '%s', localID='%s' remoteID='%s'" , getTypeConfig()->getName(), syncitemP->getLocalID(), syncitemP ->getRemoteID() ); }; | |||
602 | if (aSyncOp!=sop_delete && aSyncOp!=sop_archive_delete && aSyncOp!=sop_soft_delete && aSyncOp!=sop_copy && aSyncOp!=sop_move) { | |||
603 | // Item has data, parse it | |||
604 | // - uncompress data first if zippedbindata selected in type | |||
605 | #ifdef ZIPPED_BINDATA_SUPPORT1 | |||
606 | if (fTypeConfigP->fZippedBindata && fSessionP->getEncoding()==SML_WBXML && fSessionP->getSyncMLVersion()>=syncml_vers_1_1) { | |||
607 | // this type uses zipped bindata and we have WBXML (we cannot use zipped bindata in XML) | |||
608 | // - get input data | |||
609 | MemPtr_t zipBinPayload = NULL__null; | |||
610 | MemSize_t zipBinSize = 0; | |||
611 | MemPtr_t expandedPayload = NULL__null; | |||
612 | sInt32 expandedSize = 0; | |||
613 | if (aItemP->data) { | |||
614 | if ((zipBinSize=aItemP->data->length)>0) { | |||
615 | zipBinPayload = (MemPtr_t) aItemP->data->content; | |||
616 | } | |||
617 | } | |||
618 | // uncompress it, if we have data at all | |||
619 | if (zipBinPayload) { | |||
620 | // - <item><meta><maxobjsize> contains expanded size of payload for pre-allocating the buffer | |||
621 | SmlMetInfMetInfPtr_t metaP = smlPCDataToMetInfP(aItemP->meta); | |||
622 | if (metaP && metaP->maxobjsize) { | |||
623 | smlPCDataToLong(metaP->maxobjsize, expandedSize); | |||
624 | } | |||
625 | if (expandedSize>0) { | |||
626 | // we have data to expand AND we know how big the output will be (if we did not get MaxObjSize, this | |||
627 | // means that the data is not compressed | |||
628 | expandedPayload = (MemPtr_t) smlLibMalloc(expandedSize+1); // we need one more for the terminator | |||
629 | // uncompress the <data> payload with gzip | |||
630 | z_stream zipstream; | |||
631 | // - no special alloc | |||
632 | zipstream.zalloc=NULL__null; | |||
633 | zipstream.zfree=NULL__null; | |||
634 | zipstream.opaque=NULL__null; | |||
635 | // - no input yet | |||
636 | zipstream.next_in=NULL__null; | |||
637 | zipstream.avail_in=0; | |||
638 | // - init deflate | |||
639 | inflateInit2(&zipstream,15+32)inflateInit2_((&zipstream), (15+32), "1.2.8", (int)sizeof (z_stream)); // 15=default window size, +16=sets gzip detect flag (+32: sets gzip+zlib detect flag) | |||
640 | // - actually inflate item's <data>... | |||
641 | zipstream.next_in=zipBinPayload; | |||
642 | zipstream.avail_in=zipBinSize; | |||
643 | // - ...into new buffer | |||
644 | zipstream.next_out=expandedPayload; | |||
645 | zipstream.avail_out=expandedSize; | |||
646 | int err = inflate(&zipstream,Z_SYNC_FLUSH2); | |||
647 | // - replace compressed by expanded data if everything's fine | |||
648 | if (err==Z_OK0 && zipstream.avail_in==0) { | |||
649 | // make sure data is null terminated | |||
650 | expandedPayload[expandedSize]=0; | |||
651 | // set expanded data in place of compressed | |||
652 | aItemP->data->length=expandedSize; | |||
653 | aItemP->data->content=expandedPayload; | |||
654 | // forget compressed data | |||
655 | smlLibFree(zipBinPayload); | |||
656 | } | |||
657 | else { | |||
658 | // if failed, get rid of unneeded buffer | |||
659 | smlLibFree(expandedPayload); | |||
660 | } | |||
661 | // clean up zip decompressor | |||
662 | inflateEnd(&zipstream); | |||
663 | } // if expected data size is known (from maxobjsize), i.e. was sent compressed | |||
664 | } // if input data available at all | |||
665 | } // if zippedBinData enabled | |||
666 | #endif | |||
667 | // convert payload (as a whole) from known format encodings | |||
668 | if (aFormat==fmt_b64) { | |||
669 | MemSize_t origSize = aItemP->data->length; | |||
| ||||
670 | cAppCharP origData = (cAppCharP)aItemP->data->content; | |||
671 | if (origSize) { | |||
672 | // something to decode, do it and replace original content | |||
673 | aItemP->data->content = b64::decode(origData, origSize, (uInt32 *)&(aItemP->data->length)); | |||
674 | // we don't need the original data any more | |||
675 | b64::free((void *)origData); | |||
676 | } | |||
677 | } | |||
678 | // convert payload (as a whole) from UTF16 (Unicode) to UTF-8 | |||
679 | if (fTypeConfigP->fUseUTF16) { | |||
680 | // get original size | |||
681 | MemSize_t origSize = aItemP->data->length; | |||
682 | cAppCharP origData = (cAppCharP)aItemP->data->content; | |||
683 | if (origSize) { | |||
684 | // we usually don't need more memory than the original | |||
685 | string utf8Payload; | |||
686 | // now convert | |||
687 | appendUTF16AsUTF8( | |||
688 | (const uInt16 *)origData, | |||
689 | origSize/2, | |||
690 | fTypeConfigP->fMSBFirst, | |||
691 | utf8Payload, | |||
692 | false, false | |||
693 | ); | |||
694 | // replace contents | |||
695 | if (MemSize_t(utf8Payload.size())<origSize) origSize=utf8Payload.size(); | |||
696 | // copy into existing contents, as UTF-8 is usually smaller | |||
697 | memcpy((void *)aItemP->data->content,utf8Payload.c_str(),origSize+1); // include terminator byte in copy | |||
698 | aItemP->data->length=origSize; | |||
699 | } | |||
700 | } | |||
701 | // fill in data, if any (virtual method implemented in descendant) | |||
702 | if (!internalFillInData(syncitemP,aItemP,aLocalDataStoreP,aStatusCmd)) { | |||
703 | // delete item, as it could not be filled properly | |||
704 | delete syncitemP; | |||
705 | PDEBUGPRINTFX(DBG_ERROR,("Could not fill item -> immediately deleted, none returned")){ if (((0x00000002) & getDbgMask()) == (0x00000002)) getDbgLogger ()->setNextMask(0x00000002).DebugPrintfLastMask ("Could not fill item -> immediately deleted, none returned" ); }; | |||
706 | syncitemP=NULL__null; // none any more | |||
707 | } | |||
708 | } | |||
709 | } | |||
710 | PDEBUGENDBLOCK("Item_Parse")getDbgLogger()->DebugCloseBlock( "Item_Parse"); | |||
711 | } | |||
712 | SYSYNC_CATCH (...)catch(...) { | |||
713 | PDEBUGENDBLOCK("Item_Parse")getDbgLogger()->DebugCloseBlock( "Item_Parse"); | |||
714 | SYSYNC_RETHROWthrow; | |||
715 | SYSYNC_ENDCATCH} | |||
716 | // return new item (if any) | |||
717 | return syncitemP; | |||
718 | } // TSyncItemType::newSyncItem | |||
719 | ||||
720 | ||||
721 | // - create new SyncML toolkit item from SyncItem | |||
722 | SmlItemPtr_t TSyncItemType::newSmlItem( | |||
723 | TSyncItem *aSyncItemP, // the syncitem to be represented as SyncML | |||
724 | TLocalEngineDS *aLocalDatastoreP // local datastore | |||
725 | ) | |||
726 | { | |||
727 | SmlItemPtr_t smlitemP = NULL__null; | |||
728 | PDEBUGBLOCKFMT(("Item_Generate","generating SyncML item",getDbgLogger()->DebugOpenBlockExpanded ("Item_Generate","generating SyncML item" , "SyncOp=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncItemP-> getSyncOp()], aSyncItemP->getLocalID(), aSyncItemP->getRemoteID () ) | |||
729 | "SyncOp=%s|LocalID=%s|RemoteID=%s",getDbgLogger()->DebugOpenBlockExpanded ("Item_Generate","generating SyncML item" , "SyncOp=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncItemP-> getSyncOp()], aSyncItemP->getLocalID(), aSyncItemP->getRemoteID () ) | |||
730 | SyncOpNames[aSyncItemP->getSyncOp()],getDbgLogger()->DebugOpenBlockExpanded ("Item_Generate","generating SyncML item" , "SyncOp=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncItemP-> getSyncOp()], aSyncItemP->getLocalID(), aSyncItemP->getRemoteID () ) | |||
731 | aSyncItemP->getLocalID(),getDbgLogger()->DebugOpenBlockExpanded ("Item_Generate","generating SyncML item" , "SyncOp=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncItemP-> getSyncOp()], aSyncItemP->getLocalID(), aSyncItemP->getRemoteID () ) | |||
732 | aSyncItemP->getRemoteID()getDbgLogger()->DebugOpenBlockExpanded ("Item_Generate","generating SyncML item" , "SyncOp=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncItemP-> getSyncOp()], aSyncItemP->getLocalID(), aSyncItemP->getRemoteID () ) | |||
733 | ))getDbgLogger()->DebugOpenBlockExpanded ("Item_Generate","generating SyncML item" , "SyncOp=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncItemP-> getSyncOp()], aSyncItemP->getLocalID(), aSyncItemP->getRemoteID () ); | |||
734 | SYSYNC_TRYtry { | |||
735 | // allocate an empty smlItem | |||
736 | smlitemP = newItem(); | |||
737 | // data only if not delete, copy or map | |||
738 | TSyncOperation syncop = aSyncItemP->getSyncOp(); | |||
739 | if (syncop!=sop_delete && syncop!=sop_archive_delete && syncop!=sop_soft_delete && syncop!=sop_copy) { | |||
740 | // let virtual method implemented in descendant fill in data and, possibly, meta. | |||
741 | if (!internalSetItemData(aSyncItemP,smlitemP,aLocalDatastoreP)) { | |||
742 | SYSYNC_THROW(TSyncException("newSmlItem: internalSetItemData() failed"))throw TSyncException("newSmlItem: internalSetItemData() failed" ); | |||
743 | } | |||
744 | // convert payload (as a whole) to UTF16 (Unicode) | |||
745 | if (fTypeConfigP->fUseUTF16) { | |||
746 | string utf16bytestream; | |||
747 | appendUTF8ToUTF16ByteString( | |||
748 | (cAppCharP)smlitemP->data->content, | |||
749 | utf16bytestream, | |||
750 | fTypeConfigP->fMSBFirst, | |||
751 | lem_none, | |||
752 | 0 | |||
753 | ); | |||
754 | // dispose old data | |||
755 | smlLibFree((appPointer)smlitemP->data->content); | |||
756 | // create new data block | |||
757 | smlitemP->data->content= (void*)( (const char *)smlLibMalloc(utf16bytestream.size()+2) ); | |||
758 | smlitemP->data->length = utf16bytestream.size(); | |||
759 | // copy contents | |||
760 | memcpy((appPointer)smlitemP->data->content,utf16bytestream.c_str(),utf16bytestream.size()); | |||
761 | } | |||
762 | // compress data if zippedbindata selected in type | |||
763 | #ifdef ZIPPED_BINDATA_SUPPORT1 | |||
764 | if (fTypeConfigP->fZippedBindata && fSessionP->getEncoding()==SML_WBXML && fSessionP->getSyncMLVersion()>=syncml_vers_1_1) { | |||
765 | // this type uses zipped bindata and we have WBXML (we cannot use zipped bindata in XML) | |||
766 | // compress the <data> payload with gzip if there IS any data | |||
767 | MemSize_t expandedSize = 0; | |||
768 | MemPtr_t expandedPayload = NULL__null; | |||
769 | MemPtr_t zipBinPayload = NULL__null; | |||
770 | // - get expanded data | |||
771 | if (smlitemP->data) { | |||
772 | if ((expandedSize=smlitemP->data->length)>0) { | |||
773 | expandedPayload = (MemPtr_t) smlitemP->data->content; | |||
774 | } | |||
775 | } | |||
776 | if (expandedPayload) { | |||
777 | // there is data to send - zip it and send it as binary | |||
778 | // - assume output will not be bigger than input | |||
779 | zipBinPayload = (MemPtr_t) smlLibMalloc(expandedSize); | |||
780 | if (zipBinPayload) { | |||
781 | // compress the <data> payload with gzip | |||
782 | z_stream zipstream; | |||
783 | // - no special alloc | |||
784 | zipstream.zalloc=NULL__null; | |||
785 | zipstream.zfree=NULL__null; | |||
786 | zipstream.opaque=NULL__null; | |||
787 | // - no input yet | |||
788 | zipstream.next_in=NULL__null; | |||
789 | zipstream.avail_in=0; | |||
790 | // - init deflate | |||
791 | int comprLevel = fTypeConfigP->fZipCompressionLevel; | |||
792 | if (comprLevel>9 || comprLevel<0) | |||
793 | comprLevel=Z_DEFAULT_COMPRESSION(-1); | |||
794 | deflateInit(&zipstream,comprLevel)deflateInit_((&zipstream), (comprLevel), "1.2.8", (int)sizeof (z_stream)); | |||
795 | // - actually deflate item's <data>... | |||
796 | zipstream.next_in=expandedPayload; | |||
797 | zipstream.avail_in=expandedSize; // not more than uncompressed version would take | |||
798 | // - ...into new buffer | |||
799 | zipstream.next_out=zipBinPayload; | |||
800 | zipstream.avail_out=expandedSize; | |||
801 | int err = deflate(&zipstream,Z_SYNC_FLUSH2); | |||
802 | // - replace compressed by expanded data if everything's fine | |||
803 | if (err==Z_OK0 && zipstream.avail_in==0) { | |||
804 | // compression ok, set compressed data in place of original | |||
805 | smlitemP->data->length=zipstream.total_out; | |||
806 | smlitemP->data->content=zipBinPayload; | |||
807 | // forget original data | |||
808 | smlLibFree(expandedPayload); | |||
809 | // only if we have succeeded, we will set the maxobjsize and format Otherwise, we'll send uncompressed data | |||
810 | SmlMetInfMetInfPtr_t metaP = smlPCDataToMetInfP(smlitemP->meta); | |||
811 | if (!metaP) { | |||
812 | // we have no meta yet at all, create it first | |||
813 | smlitemP->meta = newMeta(); | |||
814 | metaP = (SmlMetInfMetInfPtr_t)(smlitemP->meta->content); | |||
815 | } | |||
816 | // - store expanded size in meta maxobjsize | |||
817 | if (metaP->maxobjsize) | |||
818 | smlFreePcdata(metaP->maxobjsize); // delete if there is already something here | |||
819 | metaP->maxobjsize=newPCDataLong(expandedSize); | |||
820 | // - set format to "bin" as a flag that contents are compressed | |||
821 | if (metaP->format) | |||
822 | smlFreePcdata(metaP->format); // delete if there is already something here | |||
823 | metaP->format=newPCDataString("bin"); | |||
824 | } | |||
825 | else { | |||
826 | // if failed, get rid of unneeded buffer | |||
827 | smlLibFree(zipBinPayload); | |||
828 | } | |||
829 | // update statistics | |||
830 | #ifdef SYDEBUG2 | |||
831 | POBJDEBUGPRINTFX(fSessionP,DBG_DATA,({ if ((fSessionP) && (((0x00000080) & (fSessionP) ->getDbgMask()) == (0x00000080))) (fSessionP)->getDbgLogger ()->setNextMask(0x00000080).DebugPrintfLastMask ( "zippedbindata item statistics: raw=%ld, compressed=%ld, compressed down to %ld%%" , (long)expandedSize, (long)smlitemP->data->length, (long )smlitemP->data->length*100/expandedSize ); } | |||
832 | "zippedbindata item statistics: raw=%ld, compressed=%ld, compressed down to %ld%%",{ if ((fSessionP) && (((0x00000080) & (fSessionP) ->getDbgMask()) == (0x00000080))) (fSessionP)->getDbgLogger ()->setNextMask(0x00000080).DebugPrintfLastMask ( "zippedbindata item statistics: raw=%ld, compressed=%ld, compressed down to %ld%%" , (long)expandedSize, (long)smlitemP->data->length, (long )smlitemP->data->length*100/expandedSize ); } | |||
833 | (long)expandedSize,{ if ((fSessionP) && (((0x00000080) & (fSessionP) ->getDbgMask()) == (0x00000080))) (fSessionP)->getDbgLogger ()->setNextMask(0x00000080).DebugPrintfLastMask ( "zippedbindata item statistics: raw=%ld, compressed=%ld, compressed down to %ld%%" , (long)expandedSize, (long)smlitemP->data->length, (long )smlitemP->data->length*100/expandedSize ); } | |||
834 | (long)smlitemP->data->length,{ if ((fSessionP) && (((0x00000080) & (fSessionP) ->getDbgMask()) == (0x00000080))) (fSessionP)->getDbgLogger ()->setNextMask(0x00000080).DebugPrintfLastMask ( "zippedbindata item statistics: raw=%ld, compressed=%ld, compressed down to %ld%%" , (long)expandedSize, (long)smlitemP->data->length, (long )smlitemP->data->length*100/expandedSize ); } | |||
835 | (long)smlitemP->data->length*100/expandedSize{ if ((fSessionP) && (((0x00000080) & (fSessionP) ->getDbgMask()) == (0x00000080))) (fSessionP)->getDbgLogger ()->setNextMask(0x00000080).DebugPrintfLastMask ( "zippedbindata item statistics: raw=%ld, compressed=%ld, compressed down to %ld%%" , (long)expandedSize, (long)smlitemP->data->length, (long )smlitemP->data->length*100/expandedSize ); } | |||
836 | )){ if ((fSessionP) && (((0x00000080) & (fSessionP) ->getDbgMask()) == (0x00000080))) (fSessionP)->getDbgLogger ()->setNextMask(0x00000080).DebugPrintfLastMask ( "zippedbindata item statistics: raw=%ld, compressed=%ld, compressed down to %ld%%" , (long)expandedSize, (long)smlitemP->data->length, (long )smlitemP->data->length*100/expandedSize ); }; | |||
837 | fRawDataBytes+=expandedSize; | |||
838 | fZippedDataBytes+=smlitemP->data->length; | |||
839 | #endif | |||
840 | // clean up zip compressor | |||
841 | deflateEnd(&zipstream); | |||
842 | } // can allocate | |||
843 | } // if any payload at all | |||
844 | } | |||
845 | #endif | |||
846 | } | |||
847 | // set source and target (AFTER setting data, as item data might influence item ID | |||
848 | // in some special cases (as for Nokia 9500-style email) | |||
849 | // - we will send this item to remote, so target=remote party, source=myself | |||
850 | smlitemP->target=newOptLocation(aSyncItemP->getRemoteID()); | |||
851 | smlitemP->source=newOptLocation(aSyncItemP->getLocalID()); | |||
852 | PDEBUGENDBLOCK("Item_Generate")getDbgLogger()->DebugCloseBlock( "Item_Generate"); | |||
853 | } | |||
854 | SYSYNC_CATCH (...)catch(...) { | |||
855 | PDEBUGENDBLOCK("Item_Generate")getDbgLogger()->DebugCloseBlock( "Item_Generate"); | |||
856 | SYSYNC_RETHROWthrow; | |||
857 | SYSYNC_ENDCATCH} | |||
858 | // return smlItem | |||
859 | return smlitemP; | |||
860 | } // TSyncItemType::newSmlItem | |||
861 | ||||
862 | ||||
863 | ||||
864 | /* end of TSyncItemType implementation */ | |||
865 | ||||
866 | // eof |