1 /* Copyright (C) 2004 - 2009 Versant Inc.   http://www.db4o.com */
2 using System;
3 using System.Collections;
4 using System.Collections.Generic;
5 using System.Globalization;
6 using System.IO;
7 using Db4objects.Db4o.Config;
8 using Db4objects.Db4o.Config.Attributes;
9 using Db4objects.Db4o.Ext;
10 using Db4objects.Db4o.Foundation;
11 using Db4objects.Db4o.Internal.Activation;
12 using Db4objects.Db4o.Internal.Handlers;
13 using Db4objects.Db4o.Internal.Query;
14 using Db4objects.Db4o.Internal.Query.Processor;
15 using Db4objects.Db4o.Query;
16 using Db4objects.Db4o.Reflect;
17 using Db4objects.Db4o.Reflect.Generic;
18 using Db4objects.Db4o.Reflect.Net;
19 using Db4objects.Db4o.Typehandlers;
20 using Sharpen.IO;
21 
22 namespace Db4objects.Db4o.Internal
23 {
24     /// <exclude />
25     public class Platform4
26     {
27 		private static readonly LegacyDb4oAssemblyNameMapper _assemlbyNameMapper = new LegacyDb4oAssemblyNameMapper();
28 
29         private static List<ObjectContainerBase> _containersToBeShutdown;
30 
31 		private static readonly object _shutdownStreamsLock = new object();
32 
CollectionToArray(ObjectContainerBase stream, object obj)33 		public static object[] CollectionToArray(ObjectContainerBase stream, object obj)
34         {
35             Collection4 col = FlattenCollection(stream, obj);
36             object[] ret = new object[col.Size()];
37             col.ToArray(ret);
38             return ret;
39         }
40 
AddShutDownHook(ObjectContainerBase container)41     	internal static void AddShutDownHook(ObjectContainerBase container)
42         {
43             lock (_shutdownStreamsLock)
44             {
45                 if (_containersToBeShutdown == null)
46                 {
47 					_containersToBeShutdown = new List<ObjectContainerBase>();
48 #if !CF && !SILVERLIGHT
49                 	AppDomain.CurrentDomain.ProcessExit += OnShutDown;
50 					AppDomain.CurrentDomain.DomainUnload += OnShutDown;
51 #endif
52                 }
53                 _containersToBeShutdown.Add(container);
54             }
55         }
56 
Serialize(Object obj)57         internal static byte[] Serialize(Object obj)
58         {
59             throw new NotSupportedException();
60         }
61 
Deserialize(byte[] bytes)62         internal static Object Deserialize(byte[] bytes)
63         {
64             throw new NotSupportedException();
65         }
66 
CanSetAccessible()67         internal static bool CanSetAccessible()
68         {
69             return true;
70         }
71 
CreateReflector(Object config)72         internal static IReflector CreateReflector(Object config)
73 		{
74 #if USE_FAST_REFLECTOR && !CF && !SILVERLIGHT
75 			return new Db4objects.Db4o.Internal.Reflect.FastNetReflector();
76 #else
77 			return new NetReflector();
78 #endif
79 		}
80 
ReflectorForType(Type typeInstance)81         public static IReflector ReflectorForType(Type typeInstance)
82 		{
83 #if USE_FAST_REFLECTOR && !CF && !SILVERLIGHT
84 			return new Db4objects.Db4o.Internal.Reflect.FastNetReflector();
85 #else
86 			return new NetReflector();
87 #endif
88 		}
89 
CreateReferenceQueue()90         internal static Object CreateReferenceQueue()
91         {
92             return new WeakReferenceHandlerQueue();
93         }
94 
CreateWeakReference(Object obj)95         public static Object CreateWeakReference(Object obj)
96         {
97             return new WeakReference(obj, false);
98         }
99 
CreateActiveObjectReference(Object referenceQueue, Object yapObject, Object obj)100         internal static Object CreateActiveObjectReference(Object referenceQueue, Object yapObject, Object obj)
101         {
102             return new WeakReferenceHandler(referenceQueue, yapObject, obj);
103         }
104 
DoubleToLong(double a_double)105         internal static long DoubleToLong(double a_double)
106 		{
107 #if CF || SILVERLIGHT
108 			byte[] bytes = BitConverter.GetBytes(a_double);
109             return BitConverter.ToInt64(bytes, 0);
110 #else
111             return BitConverter.DoubleToInt64Bits(a_double);
112 #endif
113         }
114 
EvaluationCreate(Transaction a_trans, Object example)115         internal static QConEvaluation EvaluationCreate(Transaction a_trans, Object example)
116         {
117             if (example is IEvaluation || example is EvaluationDelegate)
118             {
119                 return new QConEvaluation(a_trans, example);
120             }
121             return null;
122         }
123 
EvaluationEvaluate(Object a_evaluation, ICandidate a_candidate)124         internal static void EvaluationEvaluate(Object a_evaluation, ICandidate a_candidate)
125         {
126             IEvaluation eval = a_evaluation as IEvaluation;
127             if (eval != null)
128             {
129                 eval.Evaluate(a_candidate);
130             }
131             else
132             {
133                 // use starting _ for PascalCase conversion purposes
134                 EvaluationDelegate _ed = a_evaluation as EvaluationDelegate;
135                 if (_ed != null)
136                 {
137                     _ed(a_candidate);
138                 }
139             }
140         }
141 
ExtendConfiguration(IReflectClass clazz, IConfiguration config, Config4Class classConfig)142         internal static Config4Class ExtendConfiguration(IReflectClass clazz, IConfiguration config, Config4Class classConfig)
143         {
144             Type t = GetNetType(clazz);
145             if (t == null)
146             {
147                 return classConfig;
148             }
149             ConfigurationIntrospector a = new ConfigurationIntrospector(t, classConfig, config);
150             a.Apply();
151             return a.ClassConfiguration;
152         }
153 
FlattenCollection(ObjectContainerBase stream, Object obj)154 		internal static Collection4 FlattenCollection(ObjectContainerBase stream, Object obj)
155         {
156             Collection4 collection41 = new Collection4();
157             FlattenCollection1(stream, obj, collection41);
158             return collection41;
159         }
160 
FlattenCollection1(ObjectContainerBase stream, Object obj, Collection4 collection4)161 		internal static void FlattenCollection1(ObjectContainerBase stream, Object obj, Collection4 collection4)
162         {
163             Array arr = obj as Array;
164             if (arr != null)
165             {
166                 IReflectArray reflectArray = stream.Reflector().Array();
167 
168                 Object[] flat = new Object[arr.Length];
169 
170                 reflectArray.Flatten(obj, reflectArray.Dimensions(obj), 0, flat, 0);
171                 for (int i = 0; i < flat.Length; i++)
172                 {
173                     FlattenCollection1(stream, flat[i], collection4);
174                 }
175             }
176             else
177             {
178                 // If obj implements IEnumerable, add all elements to collection4
179                 IEnumerator enumerator = GetCollectionEnumerator(obj, true);
180 
181                 // Add elements to collection if conversion was succesful
182                 if (enumerator != null)
183                 {
184                     if (enumerator is IDictionaryEnumerator)
185                     {
186                         IDictionaryEnumerator dictEnumerator = enumerator as IDictionaryEnumerator;
187                         while (enumerator.MoveNext())
188                         {
189                             FlattenCollection1(stream, dictEnumerator.Key, collection4);
190                         }
191                     }
192                     else
193                     {
194                         while (enumerator.MoveNext())
195                         {
196                             // recursive call to flatten Collections in Collections
197                             FlattenCollection1(stream, enumerator.Current, collection4);
198                         }
199                     }
200                 }
201                 else
202                 {
203                     // If obj is not a Collection, it still needs to be collected.
204                     collection4.Add(obj);
205                 }
206             }
207         }
208 
ForEachCollectionElement(Object obj, IVisitor4 visitor)209         internal static void ForEachCollectionElement(Object obj, IVisitor4 visitor)
210         {
211             IEnumerator enumerator = GetCollectionEnumerator(obj, false);
212             if (enumerator != null)
213             {
214                 // If obj is a map (IDictionary in .NET speak) call Visit() with the key
215                 // otherwise use the element itself
216                 if (enumerator is IDictionaryEnumerator)
217                 {
218                     IDictionaryEnumerator dictEnumerator = enumerator as IDictionaryEnumerator;
219                     while (enumerator.MoveNext())
220                     {
221                         visitor.Visit(dictEnumerator.Key);
222                     }
223                 }
224                 else
225                 {
226                     while (enumerator.MoveNext())
227                     {
228                         visitor.Visit(enumerator.Current);
229                     }
230                 }
231             }
232         }
233 
Format(DateTime date, bool showSeconds)234         internal static String Format(DateTime date, bool showSeconds)
235         {
236             String fmt = "yyyy-MM-dd";
237             if (showSeconds)
238             {
239                 fmt += " HH:mm:ss";
240             }
241             return date.ToString(fmt);
242         }
243 
GetCollectionEnumerator(object obj, bool allowArray)244         internal static IEnumerator GetCollectionEnumerator(object obj, bool allowArray)
245         {
246 			IEnumerable enumerable = obj as IEnumerable;
247 			if (enumerable == null) return null;
248 		    if (obj is string) return null;
249             if (!allowArray && obj is Array) return null;
250 		    return enumerable.GetEnumerator();
251 		}
252 
GetDefaultConfiguration(Config4Impl config)253         internal static void GetDefaultConfiguration(Config4Impl config)
254         {
255             if (IsCompact())
256             {
257                 config.SingleThreadedClient(true);
258             }
259 
260             Translate(config, typeof(Delegate), new TNull());
261             Translate(config, typeof(Type), new TType()); // TODO: unnecessary?
262             Translate(config, typeof(Type).GetType(), new TType());
263 
264 #if !CF && !SILVERLIGHT
265             if (IsMono())
266             {
267 
268 				Translate(config, new Exception(), new TSerializable());
269             }
270 #endif
271 
272 #if !SILVERLIGHT
273             Translate(config, new ArrayList(), new TList());
274             Translate(config, new Hashtable(), new TDictionary());
275             Translate(config, new Queue(), new TQueue());
276             Translate(config, new Stack(), new TStack());
277 #endif
278 			Translate(config, CultureInfo.InvariantCulture, new TCultureInfo());
279 
280             if (!IsCompact())
281             {
282 				Translate(config, "System.Collections.SortedList, mscorlib", new TDictionary());
283             }
284 
285             new TypeHandlerConfigurationDotNet(config).Apply();
286 
287         	config.ObjectClass(typeof (ActivatableBase)).Indexed(false);
288         }
289 
IsCompact()290         public static bool IsCompact()
291 		{
292 #if CF || SILVERLIGHT
293 			return true;
294 #else
295             return false;
296 #endif
297         }
298 
IsMono()299         internal static bool IsMono()
300         {
301             return null != Type.GetType("System.MonoType, mscorlib");
302         }
303 
GetTypeForClass(Object obj)304         public static Object GetTypeForClass(Object obj)
305         {
306             return obj;
307         }
308 
GetYapRefObject(Object obj)309         internal static Object GetYapRefObject(Object obj)
310         {
311 			WeakReferenceHandler refHandler = obj as WeakReferenceHandler;
312 			if (refHandler != null)
313             {
314 				return refHandler.Get();
315             }
316             return obj;
317         }
318 
HasCollections()319         internal static bool HasCollections()
320         {
321             return true;
322         }
323 
NeedsLockFileThread()324         public static bool NeedsLockFileThread()
325         {
326             return false;
327         }
328 
HasWeakReferences()329         public static bool HasWeakReferences()
330         {
331             return true;
332         }
333 
IgnoreAsConstraint(Object obj)334         internal static bool IgnoreAsConstraint(Object obj)
335         {
336             Type t = obj.GetType();
337             if (t.IsEnum)
338             {
339                 if (System.Convert.ToInt32(obj) == 0)
340                 {
341                     return true;
342                 }
343             }
344             return false;
345         }
346 
IsCollectionTranslator(Config4Class config4class)347         internal static bool IsCollectionTranslator(Config4Class config4class)
348         {
349             if (config4class != null)
350             {
351                 IObjectTranslator ot = config4class.GetTranslator();
352                 if (ot != null)
353                 {
354 #if SILVERLIGHT
355 					return false;
356 #else
357 					return ot is TList || ot is TDictionary || ot is TQueue || ot is TStack;
358 #endif
359 				}
360             }
361             return false;
362         }
363 
IsConnected(Sharpen.Net.Socket socket)364         public static bool IsConnected(Sharpen.Net.Socket socket)
365         {
366             if (socket == null)
367             {
368                 return false;
369             }
370             return socket.IsConnected();
371         }
372 
IsStruct(IReflectClass claxx)373         internal static bool IsStruct(IReflectClass claxx)
374         {
375             if (claxx == null)
376             {
377                 return false;
378             }
379             System.Type netClass = GetNetType(claxx);
380             if (netClass == null)
381             {
382                 return false;
383             }
384             return netClass.IsValueType;
385         }
386 
KillYapRef(Object obj)387         internal static void KillYapRef(Object obj)
388         {
389 			WeakReferenceHandler yr = obj as WeakReferenceHandler;
390             if (yr != null)
391             {
392                 yr.ObjectReference = null;
393             }
394         }
395 
LongToDouble(long l)396         internal static double LongToDouble(long l)
397 		{
398 #if CF || SILVERLIGHT
399 			byte[] bytes = BitConverter.GetBytes(l);
400             return BitConverter.ToDouble(bytes, 0);
401 #else
402             return BitConverter.Int64BitsToDouble(l);
403 #endif
404         }
405 
LockFile(string path, object file)406         internal static void LockFile(string path, object file)
407 		{
408 #if !CF && !SILVERLIGHT
409 			try
410             {
411                 FileStream stream = ((RandomAccessFile) file).Stream;
412                 stream.Lock(0, 1);
413             }
414             catch (IOException x)
415             {
416                 throw new DatabaseFileLockedException(path,x);
417             }
418 #endif
419         }
420 
UnlockFile(string path, object file)421         internal static void UnlockFile(string path, object file)
422         {
423             // do nothing. C# RAF is unlocked automatically upon closing
424         }
425 
MarkTransient(String marker)426         internal static void MarkTransient(String marker)
427         {
428             NetField.MarkTransient(marker);
429         }
430 
CallConstructor()431         internal static bool CallConstructor()
432         {
433             return false;
434         }
435 
PollReferenceQueue(Object container, Object referenceQueue)436         internal static void PollReferenceQueue(Object container, Object referenceQueue)
437         {
438             ((WeakReferenceHandlerQueue)referenceQueue).Poll((ObjectContainerBase)container);
439         }
440 
RegisterCollections(GenericReflector reflector)441         public static void RegisterCollections(GenericReflector reflector)
442         {
443 //            reflector.RegisterCollectionUpdateDepth(
444 //                typeof(IDictionary),
445 //                3);
446         }
447 
RemoveShutDownHook(ObjectContainerBase container)448         internal static void RemoveShutDownHook(ObjectContainerBase container)
449         {
450             lock (_shutdownStreamsLock)
451             {
452                 if (_containersToBeShutdown != null)
453                 {
454                     _containersToBeShutdown.Remove(container);
455                 }
456             }
457         }
458 
SetAccessible(Object obj)459         public static void SetAccessible(Object obj)
460         {
461             // do nothing
462         }
463 
OnShutDown(object sender, EventArgs args)464         private static void OnShutDown(object sender, EventArgs args)
465         {
466 			lock (_shutdownStreamsLock)
467 			{
468 				foreach (ObjectContainerBase container in _containersToBeShutdown.ToArray())
469 				{
470 					container.ShutdownHook(); // this will remove the stream for the list
471 				}
472 			}
473         }
474 
StoreStaticFieldValues(IReflector reflector, IReflectClass clazz)475         public static bool StoreStaticFieldValues(IReflector reflector, IReflectClass clazz)
476         {
477             return false;
478         }
479 
Translate(IConfiguration config, object obj, IObjectTranslator translator)480 		private static void Translate(IConfiguration config, object obj, IObjectTranslator translator)
481 		{
482 			config.ObjectClass(obj).Translate(translator);
483 		}
484 
UpdateClassName(byte[] nameBytes)485         public static byte[] UpdateClassName(byte[] nameBytes)
486         {
487             return _assemlbyNameMapper.MappedNameFor(nameBytes);
488         }
489 
WeakReferenceTarget(Object weakRef)490         public static Object WeakReferenceTarget(Object weakRef)
491         {
492             WeakReference wr = weakRef as WeakReference;
493             if (wr != null)
494             {
495                 return wr.Target;
496             }
497             return weakRef;
498         }
499 
WrapEvaluation(object evaluation)500         internal static object WrapEvaluation(object evaluation)
501 		{
502 #if CF || SILVERLIGHT
503 			// FIXME: How to better support EvaluationDelegate on the CompactFramework?
504 			return evaluation;
505 #else
506             return (evaluation is EvaluationDelegate)
507                 ? new EvaluationDelegateWrapper((EvaluationDelegate)evaluation)
508                 : evaluation;
509 #endif
510         }
511 
IsTransient(IReflectClass clazz)512         public static bool IsTransient(IReflectClass clazz)
513         {
514             Type type = GetNetType(clazz);
515             if (null == type) return false;
516         	return IsTransient(type);
517         }
518 
IsTransient(Type type)519     	public static bool IsTransient(Type type)
520     	{
521     		return type.IsPointer
522     		       || type.IsSubclassOf(typeof(Delegate))
523 #if CF || SILVERLIGHT
524 ;
525 #else
526     		       || type == typeof(System.Reflection.Pointer);
527 #endif
528     	}
529 
GetNetType(IReflectClass clazz)530     	private static Type GetNetType(IReflectClass clazz)
531         {
532             if (null == clazz)
533             {
534                 return null;
535             }
536 
537             NetClass netClass = clazz as NetClass;
538             if (null != netClass)
539             {
540                 return netClass.GetNetType();
541             }
542             IReflectClass claxx = clazz.GetDelegate();
543             if (claxx == clazz)
544             {
545                 return null;
546             }
547             return GetNetType(claxx);
548         }
549 
Types(IReflector reflector)550 		public static NetTypeHandler[] Types(IReflector reflector)
551         {
552 			return new NetTypeHandler[]
553 				{
554 					new SByteHandler(),
555 					new DecimalHandler(),
556 					new UIntHandler(),
557 					new ULongHandler(),
558 					new UShortHandler(),
559 				};
560         }
561 
IsSimple(Type a_class)562         public static bool IsSimple(Type a_class)
563         {
564             for (int i1 = 0; i1 < SIMPLE_CLASSES.Length; i1++)
565             {
566                 if (a_class == SIMPLE_CLASSES[i1])
567                 {
568                     return true;
569                 }
570             }
571             return false;
572         }
573 
574         private static Type[] SIMPLE_CLASSES = {
575 		                                        	typeof(Int32),
576 		                                        	typeof(Int64),
577 		                                        	typeof(Single),
578 		                                        	typeof(Boolean),
579 		                                        	typeof(Double),
580 		                                        	typeof(Byte),
581 		                                        	typeof(Char),
582 		                                        	typeof(Int16),
583 		                                        	typeof(String),
584 		                                        };
585 
Now()586         public static DateTime Now()
587         {
588             return DateTime.Now;
589         }
590 
IsJavaEnum(IReflector genericReflector, IReflectClass iReflectClass)591 		internal static bool IsJavaEnum(IReflector genericReflector, IReflectClass iReflectClass)
592 		{
593 			return false;
594 		}
595 
IsEnum(IReflector genericReflector, IReflectClass iReflectClass)596 		internal static bool IsEnum(IReflector genericReflector, IReflectClass iReflectClass)
597 		{
598 		    Type type = GetNetType(iReflectClass);
599             if(type == null)
600             {
601                 return false;
602             }
603 			return type.IsEnum;
604 		}
605 
UseNativeSerialization()606         public static bool UseNativeSerialization()
607         {
608             return false;
609         }
610 
RegisterPlatformHandlers(ObjectContainerBase container)611         public static void RegisterPlatformHandlers(ObjectContainerBase container)
612         {
613             EnumTypeHandler enumTypeHandler = new EnumTypeHandler();
614             container.ConfigImpl.RegisterTypeHandler(new EnumTypeHandlerPredicate(), enumTypeHandler);
615 			container.Handlers.RegisterHandlerVersion(enumTypeHandler, 4, new StandardReferenceTypeHandler());
616 			container.Handlers.RegisterHandlerVersion(enumTypeHandler, 0, new StandardReferenceTypeHandler0());
617 
618 			GuidTypeHandler guidTypeHandler = new GuidTypeHandler();
619 			container.ConfigImpl.RegisterTypeHandler(new SingleClassTypeHandlerPredicate(typeof(Guid)), guidTypeHandler);
620 			container.Handlers.RegisterHandlerVersion(guidTypeHandler, 8, new StandardReferenceTypeHandler());
621 
622             DateTimeHandler dateTimeHandler = new DateTimeHandler();
623             container.Handlers.RegisterNetTypeHandler(dateTimeHandler);
624             container.Handlers.RegisterHandlerVersion(dateTimeHandler, 6, new DateTimeHandler6());
625 
626 #if !CF
627         	DateTimeOffsetTypeHandler dateTimeOffsetHandler = new DateTimeOffsetTypeHandler();
628         	container.ConfigImpl.RegisterTypeHandler(new SingleClassTypeHandlerPredicate(typeof(DateTimeOffset)), dateTimeOffsetHandler);
629 			container.Handlers.RegisterHandlerVersion(dateTimeOffsetHandler, 9, new StandardReferenceTypeHandler());
630 #endif
631         }
632 
PrimitiveTypes()633 		public static Type[] PrimitiveTypes()
634 		{
635 			return PRIMITIVE_TYPES;
636 		}
637 
NullValue(Type type)638         public static object NullValue(Type type)
639         {
640             if(_nullValues == null)
641             {
642                 InitNullValues();
643 			}
644 
645 			return _nullValues.Get(type);
646 		}
647 
InitNullValues()648         private static void InitNullValues()
649         {
650     	    _nullValues = new Hashtable4();
651             _nullValues.Put(typeof(int), 0);
652             _nullValues.Put(typeof(uint), (uint)0);
653             _nullValues.Put(typeof(byte), (byte)0);
654     	    _nullValues.Put(typeof(short), (short)0);
655     	    _nullValues.Put(typeof(float), (float)0);
656     	    _nullValues.Put(typeof(double), (double)0);
657             _nullValues.Put(typeof(ulong), (ulong)0);
658             _nullValues.Put(typeof(long), (long)0);
659     	    _nullValues.Put(typeof(bool), false);
660             _nullValues.Put(typeof(char), (char)0);
661             _nullValues.Put(typeof(sbyte), (sbyte)0);
662             _nullValues.Put(typeof(decimal), (decimal)0);
663             _nullValues.Put(typeof(ushort), (ushort)0);
664             _nullValues.Put(typeof(DateTime), DateTime.MinValue);
665 
666         }
667 
668         private static Hashtable4 _nullValues;
669 
NullableTypeFor(Type primitiveType)670         public static Type NullableTypeFor(Type primitiveType)
671         {
672             if(_primitive2Wrapper == null)
673                 InitPrimitive2Wrapper();
674             Type wrapperClazz = (Type)_primitive2Wrapper.Get(primitiveType);
675             if(wrapperClazz==null)
676                 throw new NotImplementedException();
677             return wrapperClazz;
678         }
679 
InitPrimitive2Wrapper()680         private static void InitPrimitive2Wrapper()
681         {
682     	    _primitive2Wrapper = new Hashtable4();
683 
684         	foreach (Type type in PRIMITIVE_TYPES)
685         	{
686 				_primitive2Wrapper.Put(type, ConcreteNullableTypeFor(type));
687         	}
688         }
689 
ConcreteNullableTypeFor(Type type)690     	private static Type ConcreteNullableTypeFor(Type type)
691     	{
692     		return typeof (Nullable<>).MakeGenericType(type);
693     	}
694 
695     	private static Hashtable4 _primitive2Wrapper;
696 
697     	private static readonly Type[] PRIMITIVE_TYPES = new Type[]
698     	                                        	{
699 														typeof(int),
700 														typeof(uint),
701 														typeof(byte),
702 														typeof(short),
703 														typeof(float),
704 														typeof(double),
705 														typeof(ulong),
706 														typeof(long),
707 														typeof(bool),
708 														typeof(char),
709 														typeof(sbyte),
710 														typeof(decimal),
711 														typeof(ushort),
712 														typeof(DateTime),
713     	                                        	};
714 
ThrowUncheckedException(Exception exc)715         public static void ThrowUncheckedException(Exception exc)
716         {
717             throw exc;
718         }
719 
ToSByte(byte b)720         public static sbyte ToSByte(byte b)
721         {
722 		    return (sbyte)b;
723 	    }
724 
725     }
726 }