Bug Summary

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')

Annotated Source Code

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
28using namespace sysync;
29
30
31/*
32 * Implementation of TSyncItemType
33 */
34
35/* TSyncItemType members */
36
37void 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
66TSyncItemType::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
79TSyncItemType::~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
98GZones *TSyncItemType::getSessionZones(void)
99{
100 return getSession() ? getSession()->getSessionZones() : NULL__null;
101} // TSyncItemType::getSessionZones
102
103
104#ifdef SYDEBUG2
105
106TDebugLogger *TSyncItemType::getDbgLogger(void)
107{
108 // commands log to session's logger
109 return fSessionP ? getSession()->getDbgLogger() : NULL__null;
110} // TSyncItemType::getDbgLogger
111
112uInt32 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
124TSyncItemType *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)
140bool 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
152bool 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
170const 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.
201bool 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
211bool 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
220TSyncItemType *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
258TSyncItemType *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
280TSyncItemType *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
303TSyncItemType *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)
377bool 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
481SmlDevInfXmitPtr_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
494SmlDevInfXmitListPtr_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
519TSyncItem *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
553TSyncItem *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()) {
1
Assuming the condition is false
2
Taking false branch
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) {
3
Assuming 'syncitemP' is non-null
4
Taking true branch
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) {
5
Assuming 'aSyncOp' is not equal to sop_delete
6
Assuming 'aSyncOp' is not equal to sop_archive_delete
7
Assuming 'aSyncOp' is not equal to sop_soft_delete
8
Assuming 'aSyncOp' is not equal to sop_copy
9
Assuming 'aSyncOp' is not equal to sop_move
10
Taking true branch
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) {
11
Assuming the condition is true
12
Assuming the condition is true
13
Assuming the condition is true
14
Taking true branch
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) {
15
Assuming pointer value is null
16
Taking false branch
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) {
17
Taking false branch
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) {
18
Assuming 'aFormat' is equal to fmt_b64
19
Taking true branch
669 MemSize_t origSize = aItemP->data->length;
20
Access to field 'length' results in a dereference of a null pointer (loaded from field 'data')
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
722SmlItemPtr_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