@@ -119,54 +119,52 @@ - (id)serializedValueForScalarValue: (NSValue *)value
119119
120120- (id )serializedReferenceForObject : (COObject *)value
121121{
122- /* Some root object relationships are special in the sense the value can be
123- a core object but its persistency isn't enabled. We interpret these
124- one-to-one relationships as transient.
125- Usually a root object belongs to some other objects at run-time, in some
126- cases the root object want to hold a backward pointer (inverse
127- relationship) to those non-persistent object(s).
128- For example, a root object can be a layout item whose parent item is the
129- window group... In such a case, we don't want to persist the window
130- group, but ignore it. At deseserialiation time, the app is responsible
131- to add the item back to the window group (the parent item would be
132- restored then). */
133- if ([value isPersistent ] || [value objectGraphContext ] == [self objectGraphContext ])
122+ /* Some root object relationships are special in the sense the value can be
123+ a core object but its persistency isn't enabled. We interpret these
124+ one-to-one relationships as transient.
125+ Usually a root object belongs to some other objects at run-time, in some
126+ cases the root object want to hold a backward pointer (inverse
127+ relationship) to those non-persistent object(s).
128+ For example, a root object can be a layout item whose parent item is the
129+ window group... In such a case, we don't want to persist the window
130+ group, but ignore it. At deseserialiation time, the app is responsible
131+ to add the item back to the window group (the parent item would be
132+ restored then). */
133+ if (![value isPersistent ] && [value objectGraphContext ] != [self objectGraphContext ])
134+ {
135+ ETAssert ([value isRoot ]);
136+ return [NSNull null ];
137+ }
138+
139+ if ([value persistentRoot ] == [self persistentRoot ])
140+ {
141+ return [value UUID ];
142+ }
143+ else
144+ {
145+ // Serialize this cross-persistent root reference as a COPath
146+
147+ NSAssert ([value isRoot ], @" A property must point to a root object "
148+ " for references accross persistent roots" );
149+
150+ COPersistentRoot *referencedPersistentRoot = [value persistentRoot ];
151+ COObjectGraphContext *referencedPersistentRootCurrentBranchGraph =
152+ [referencedPersistentRoot objectGraphContext ];
153+ COObjectGraphContext *referencedObjectGraph = [value objectGraphContext ];
154+ COBranch *referencedBranch = [value branch ];
155+
156+ if (referencedObjectGraph == referencedPersistentRootCurrentBranchGraph)
134157 {
135- if ([value persistentRoot ] == [self persistentRoot ])
136- {
137- return [value UUID ];
138- }
139- else
140- {
141- // Serialize this cross-persistent root reference as a COPath
142-
143- NSAssert ([value isRoot ], @" A property must point to a root object "
144- " for references accross persistent roots" );
145-
146- COPersistentRoot *referencedPersistentRoot = [value persistentRoot ];
147- COObjectGraphContext *referencedPersistentRootCurrentBranchGraph =
148- [referencedPersistentRoot objectGraphContext ];
149- COObjectGraphContext *referencedObjectGraph = [value objectGraphContext ];
150- COBranch *referencedBranch = [value branch ];
151-
152- if (referencedObjectGraph == referencedPersistentRootCurrentBranchGraph)
153- {
154- // Serialize as a reference to the current branch
155- return [COPath pathWithPersistentRoot: [referencedPersistentRoot UUID ]];
156- }
157- else
158- {
159- // Serialize as a reference to a specific branch
160- return [COPath pathWithPersistentRoot: [referencedPersistentRoot UUID ]
161- branch: [referencedBranch UUID ]];
162- }
163- }
158+ // Serialize as a reference to the current branch
159+ return [COPath pathWithPersistentRoot: [referencedPersistentRoot UUID ]];
164160 }
165161 else
166162 {
167- ETAssert ([value isRoot ]);
168- return [NSNull null ];
163+ // Serialize as a reference to a specific branch
164+ return [COPath pathWithPersistentRoot: [referencedPersistentRoot UUID ]
165+ branch: [referencedBranch UUID ]];
169166 }
167+ }
170168}
171169
172170- (id ) serializedValueForValue : (id )value
@@ -250,20 +248,14 @@ - (id)serializedValueForValue: (id)aValue
250248 {
251249 return [NSNull null ];
252250 }
253- else if ([value isKindOfClass: [ETUUID class ]]
254- || [value isKindOfClass: [COPath class ]])
251+ else if ([value isKindOfClass: [COObject class ]])
255252 {
256- return value;
253+ return [ self serializedReferenceForObject: value] ;
257254 }
258255 else if ([value isKindOfClass: [COAttachmentID class ]])
259256 {
260257 return value;
261258 }
262- else if ([value isKindOfClass: [COObject class ]])
263- {
264- return [self serializedReferenceForObject: value];
265- }
266-
267259 else if ([self isSerializablePrimitiveValue: value])
268260 {
269261 return value;
@@ -325,6 +317,59 @@ - (BOOL) isSerializableScalarTypeName: (NSString *)aTypeName
325317 || [aTypeName isEqualToString: @" NSRange" ]);
326318}
327319
320+ - (COType)serializedTypeForNumber : (NSNumber *)value
321+ {
322+ NSParameterAssert (value == nil || [value isKindOfClass: [NSNumber class ]]);
323+
324+ // TODO: A bit ugly, would be better to add new entity descriptions
325+ // such as NSBOOLNumber, NSCGFloatNumber etc.
326+ if (value == nil )
327+ return kCOTypeString ;
328+
329+ if (strcmp ([value objCType ], @encode (BOOL )) == 0
330+ || strcmp ([value objCType ], @encode (NSInteger )) == 0
331+ || strcmp ([value objCType ], @encode (NSUInteger )) == 0 )
332+ {
333+ return kCOTypeInt64 ;
334+ }
335+ else if (strcmp ([value objCType ], @encode (CGFloat)) == 0
336+ || strcmp ([value objCType ], @encode (double )) == 0
337+ || strcmp ([value objCType ], @encode (float )) == 0 )
338+ {
339+ return kCOTypeDouble ;
340+ }
341+
342+ // FIXME: Finish the above... we should handle all values that NSNumber can encode,
343+ // except unsigned integers larger than the maximum value of int64_t.
344+ ETAssertUnreachable ();
345+ return 0 ;
346+ }
347+
348+ - (NSString *)primitiveTypeNameFromValue : (id )value
349+ {
350+ if ([value isKindOfClass: [COObject class ]])
351+ {
352+ return @" COObject" ;
353+ }
354+ else if ([value isKindOfClass: [NSString class ]])
355+ {
356+ return @" NSString" ;
357+ }
358+ else if ([value isKindOfClass: [NSNumber class ]])
359+ {
360+ return @" NSNumber" ;
361+ }
362+ else if ([value isKindOfClass: [NSData class ]])
363+ {
364+ return @" NSData" ;
365+ }
366+ else if ([value isKindOfClass: [COAttachmentID class ]])
367+ {
368+ return @" COAttachmentID" ;
369+ }
370+ return nil ;
371+ }
372+
328373- (COType)serializedTypeForUnivaluedPropertyDescription : (ETPropertyDescription *)aPropertyDesc
329374 ofValue : (id )value
330375{
@@ -335,9 +380,22 @@ - (COType)serializedTypeForUnivaluedPropertyDescription: (ETPropertyDescription
335380 if (aPropertyDesc.valueTransformerName != nil )
336381 {
337382 ETAssert (![type isEqual: aPropertyDesc.type]);
338- return [self .serializablePersistentTypes[type.name ] intValue ];
383+ return [self .serializablePersistentTypes[typeName ] intValue ];
339384 }
340-
385+
386+ if ([typeName isEqualToString: @" NSObject" ])
387+ {
388+ if (value != nil )
389+ {
390+ typeName = [self primitiveTypeNameFromValue: value];
391+ }
392+ else
393+ {
394+ // NOTE: We use an arbitrary type
395+ return kCOTypeBlob ;
396+ }
397+ }
398+
341399 if ([self isCoreObjectEntityType: type])
342400 {
343401 return ([aPropertyDesc isComposite ] ? kCOTypeCompositeReference : kCOTypeReference );
@@ -349,7 +407,7 @@ - (COType)serializedTypeForUnivaluedPropertyDescription: (ETPropertyDescription
349407 return kCOTypeInt64 ;
350408 }
351409 else if ([typeName isEqualToString: @" CGFloat" ]
352- || [typeName isEqualToString: @" Double" ])
410+ || [typeName isEqualToString: @" Double" ])
353411 {
354412 return kCOTypeDouble ;
355413 }
@@ -359,29 +417,7 @@ - (COType)serializedTypeForUnivaluedPropertyDescription: (ETPropertyDescription
359417 }
360418 else if ([typeName isEqualToString: @" NSNumber" ])
361419 {
362- NSParameterAssert (value == nil || [value isKindOfClass: [NSNumber class ]]);
363-
364- // TODO: A bit ugly, would be better to add new entity descriptions
365- // such as NSBOOLNumber, NSCGFloatNumber etc.
366- if (value == nil )
367- return kCOTypeString ;
368-
369- if (strcmp ([value objCType ], @encode (BOOL )) == 0
370- || strcmp ([value objCType ], @encode (NSInteger )) == 0
371- || strcmp ([value objCType ], @encode (NSUInteger )) == 0 )
372- {
373- return kCOTypeInt64 ;
374- }
375- else if (strcmp ([value objCType ], @encode (CGFloat)) == 0
376- || strcmp ([value objCType ], @encode (double )) == 0
377- || strcmp ([value objCType ], @encode (float )) == 0 )
378- {
379- return kCOTypeDouble ;
380- }
381-
382- // FIXME: Finish the above... we should handle all values that NSNumber can encode,
383- // except unsigned integers larger than the maximum value of int64_t.
384- ETAssertUnreachable ();
420+ [self serializedTypeForNumber: value];
385421 }
386422 else if ([typeName isEqualToString: @" NSData" ])
387423 {
@@ -395,56 +431,6 @@ - (COType)serializedTypeForUnivaluedPropertyDescription: (ETPropertyDescription
395431 {
396432 return kCOTypeAttachment ;
397433 }
398- else if ([self serializationGetterForProperty: [aPropertyDesc name ]] != NULL )
399- {
400- // For a case like ETShape.pathResizeSelector, the COObject subclass
401- // implements -serializedPathResizeSelector to return an NSString.
402- // However, the typeName is "SEL".
403-
404- /* Serialialization accessors can override the types declared in the
405- property description using either NSString or NSData, but no other
406- types.
407- For a multivalued property, the same applies, since the property
408- description type is the element type. For example, a serialization
409- getter can return an array of ETUTI objects as an array of NSString
410- objects. */
411- if ([value isKindOfClass: [NSString class ]])
412- {
413- return kCOTypeString ;
414- }
415- else if ([value isKindOfClass: [NSData class ]])
416- {
417- return kCOTypeBlob ;
418- }
419- else if ([value isKindOfClass: [COObject class ]])
420- {
421- ETAssert ([typeName isEqualToString: @" NSObject" ]);
422-
423- /* For persistent relationship such as -[ETLayoutItem representedObject],
424- where the value must be a COObject entity type (or some derived kind)
425- to be persisted. For other NSObject derived instances, the
426- relationship is treated as transient.
427-
428- For such property, a serialization getter must be implemented to
429- return nil when the value is not a persistent COObject instance
430- (otherwise -serializedValueForValue:propertyDescription: raises
431- an exception). */
432- return kCOTypeReference ;
433- }
434- else if (value == nil )
435- {
436- // NOTE: We use an arbitrary type
437- return kCOTypeBlob ;
438- }
439- else
440- {
441- NSString *getterString =
442- NSStringFromSelector ([self serializationGetterForProperty: [aPropertyDesc name ]]);
443-
444- NSAssert3 (NO , @" Unsupported serialization type %@ for %@ returned by "
445- " serialization getter %@ " , type, value, getterString);
446- }
447- }
448434 else if ([typeName isEqualToString: @" NSDate" ])
449435 {
450436 /* * For convenience, serialize NSDate as a int64_t using Java semantics. */
0 commit comments