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 }