/// <summary> /// Creates a NSSet with the contents of this set. /// </summary> /// <param name="value">The value to represent as a NSObject.</param> /// <returns>A NSObject representing the given value.</returns> /// <exception cref="SystemException">When one of the values contained in the map cannot be represented by a NSObject.</exception> public static NSSet Wrap(List<Object> value) { NSSet set = new NSSet(); foreach (Object o in value) set.AddObject(Wrap(o)); return set; }
/// <summary> /// Parses an object inside the currently parsed binary property list. /// For the format specification check /// <a href="http://www.opensource.apple.com/source/CF/CF-855.17/CFBinaryPList.c"> /// Apple's binary property list parser implementation</a>. /// </summary> /// <returns>The parsed object.</returns> /// <param name="obj">The object ID.</param> /// <exception cref="PropertyListFormatException">When the property list's format could not be parsed.</exception> NSObject ParseObject(int obj) { int offset = offsetTable[obj]; byte type = bytes[offset]; int objType = (type & 0xF0) >> 4; //First 4 bits int objInfo = (type & 0x0F); //Second 4 bits switch (objType) { case 0x0: { //Simple switch (objInfo) { case 0x0: { //null object (v1.0 and later) return null; } case 0x8: { //false return new NSNumber(false); } case 0x9: { //true return new NSNumber(true); } case 0xC: { //URL with no base URL (v1.0 and later) //TODO Implement binary URL parsing (not yet even implemented in Core Foundation as of revision 855.17) break; } case 0xD: { //URL with base URL (v1.0 and later) //TODO Implement binary URL parsing (not yet even implemented in Core Foundation as of revision 855.17) break; } case 0xE: { //16-byte UUID (v1.0 and later) //TODO Implement binary UUID parsing (not yet even implemented in Core Foundation as of revision 855.17) break; } case 0xF: { //filler byte return null; } } break; } case 0x1: { //integer int length = (int)Math.Pow(2, objInfo); return new NSNumber(CopyOfRange(bytes, offset + 1, offset + 1 + length), NSNumber.INTEGER); } case 0x2: { //real int length = (int)Math.Pow(2, objInfo); return new NSNumber(CopyOfRange(bytes, offset + 1, offset + 1 + length), NSNumber.REAL); } case 0x3: { //Date if (objInfo != 0x3) { throw new PropertyListFormatException("The given binary property list contains a date object of an unknown type (" + objInfo + ")"); } return new NSDate(CopyOfRange(bytes, offset + 1, offset + 9)); } case 0x4: { //Data int[] lengthAndOffset = ReadLengthAndOffset(objInfo, offset); int length = lengthAndOffset[0]; int dataoffset = lengthAndOffset[1]; return new NSData(CopyOfRange(bytes, offset + dataoffset, offset + dataoffset + length)); } case 0x5: { //ASCII String int[] lengthAndOffset = ReadLengthAndOffset(objInfo, offset); int length = lengthAndOffset[0]; //Each character is 1 byte int stroffset = lengthAndOffset[1]; return new NSString(CopyOfRange(bytes, offset + stroffset, offset + stroffset + length), "ASCII"); } case 0x6: { //UTF-16-BE String int[] lengthAndOffset = ReadLengthAndOffset(objInfo, offset); int length = lengthAndOffset[0]; int stroffset = lengthAndOffset[1]; //UTF-16 characters can have variable length, but the Core Foundation reference implementation //assumes 2 byte characters, thus only covering the Basic Multilingual Plane length *= 2; return new NSString(CopyOfRange(bytes, offset + stroffset, offset + stroffset + length), "UTF-16BE"); } case 0x7: { //UTF-8 string (v1.0 and later) int[] lengthAndOffset = ReadLengthAndOffset(objInfo, offset); int strOffset = lengthAndOffset[1]; int characters = lengthAndOffset[0]; //UTF-8 characters can have variable length, so we need to calculate the byte length dynamically //by reading the UTF-8 characters one by one int length = CalculateUtf8StringLength(bytes, offset + strOffset, characters); return new NSString(CopyOfRange(bytes, offset + strOffset, offset + strOffset + length), "UTF-8"); } case 0x8: { //UID (v1.0 and later) int length = objInfo + 1; return new UID(obj.ToString(), CopyOfRange(bytes, offset + 1, offset + 1 + length)); } case 0xA: { //Array int[] lengthAndOffset = ReadLengthAndOffset(objInfo, offset); int length = lengthAndOffset[0]; int arrayOffset = lengthAndOffset[1]; NSArray array = new NSArray(length); for (int i = 0; i < length; i++) { int objRef = (int)ParseUnsignedInt(CopyOfRange(bytes, offset + arrayOffset + i * objectRefSize, offset + arrayOffset + (i + 1) * objectRefSize)); array.Add(ParseObject(objRef)); } return array; } case 0xB: { //Ordered set (v1.0 and later) int[] lengthAndOffset = ReadLengthAndOffset(objInfo, offset); int length = lengthAndOffset[0]; int contentOffset = lengthAndOffset[1]; NSSet set = new NSSet(true); for (int i = 0; i < length; i++) { int objRef = (int)ParseUnsignedInt(CopyOfRange(bytes, offset + contentOffset + i * objectRefSize, offset + contentOffset + (i + 1) * objectRefSize)); set.AddObject(ParseObject(objRef)); } return set; } case 0xC: { //Set (v1.0 and later) int[] lengthAndOffset = ReadLengthAndOffset(objInfo, offset); int length = lengthAndOffset[0]; int contentOffset = lengthAndOffset[1]; NSSet set = new NSSet(); for (int i = 0; i < length; i++) { int objRef = (int)ParseUnsignedInt(CopyOfRange(bytes, offset + contentOffset + i * objectRefSize, offset + contentOffset + (i + 1) * objectRefSize)); set.AddObject(ParseObject(objRef)); } return set; } case 0xD: { //Dictionary int[] lengthAndOffset = ReadLengthAndOffset(objInfo, offset); int length = lengthAndOffset[0]; int contentOffset = lengthAndOffset[1]; //System.out.println("Parsing dictionary #"+obj); NSDictionary dict = new NSDictionary(); for (int i = 0; i < length; i++) { int keyRef = (int)ParseUnsignedInt(CopyOfRange(bytes, offset + contentOffset + i * objectRefSize, offset + contentOffset + (i + 1) * objectRefSize)); int valRef = (int)ParseUnsignedInt(CopyOfRange(bytes, offset + contentOffset + (length * objectRefSize) + i * objectRefSize, offset + contentOffset + (length * objectRefSize) + (i + 1) * objectRefSize)); NSObject key = ParseObject(keyRef); NSObject val = ParseObject(valRef); dict.Add(key.ToString(), val); } return dict; } default: { Console.WriteLine("WARNING: The given binary property list contains an object of unknown type (" + objType + ")"); break; } } return null; }
public static void AddBundleURLType(IIgorModule ModuleInst, string PlistPath, string NewURLScheme) { if(IgorAssert.EnsureTrue(ModuleInst, File.Exists(PlistPath), "Plist " + PlistPath + " doesn't exist!")) { FileInfo PlistFileInfo = new FileInfo(PlistPath); NSObject PlistRoot = PropertyListParser.Parse(PlistFileInfo); if(IgorAssert.EnsureTrue(ModuleInst, PlistRoot != null, "Plist " + PlistPath + " could not be parsed!")) { if(IgorAssert.EnsureTrue(ModuleInst, typeof(NSDictionary).IsAssignableFrom(PlistRoot.GetType()), "Plist " + PlistPath + " root object is not a dictionary.")) { NSDictionary RootDictionary = (NSDictionary)PlistRoot; if(IgorAssert.EnsureTrue(ModuleInst, RootDictionary != null, "Plist root is not a dictionary.")) { NSSet BundleURLTypes = null; if(RootDictionary.ContainsKey("CFBundleURLTypes")) { NSObject BundleURLTypesObj = RootDictionary.Get("CFBundleURLTypes"); if(IgorAssert.EnsureTrue(ModuleInst, BundleURLTypesObj != null, "CFBundleURLTypes wasn't found in the root dictionary even though the key exists.")) { if(IgorAssert.EnsureTrue(ModuleInst, typeof(NSArray).IsAssignableFrom(BundleURLTypesObj.GetType()), "CFBundleURLTypes isn't an NSArray.")) { BundleURLTypes = new NSSet(((NSArray)BundleURLTypesObj).GetArray()); } } } if(BundleURLTypes == null) { BundleURLTypes = new NSSet(); } bool bAlreadyExists = false; foreach(NSObject CurrentURLType in BundleURLTypes) { if(bAlreadyExists) { break; } if(IgorAssert.EnsureTrue(ModuleInst, typeof(NSDictionary).IsAssignableFrom(CurrentURLType.GetType()), "One of the CFBundleURLTypes isn't an NSDictionary.")) { NSDictionary CurrentURLTypeDict = (NSDictionary)CurrentURLType; if(IgorAssert.EnsureTrue(ModuleInst, CurrentURLTypeDict != null, "One of the CFBundleURLTypes didn't cast to NSDictionary correctly.")) { if(CurrentURLTypeDict.ContainsKey("CFBundleURLSchemes")) { NSObject CurrentURLSchemesArrayObj = CurrentURLTypeDict.Get("CFBundleURLSchemes"); if(IgorAssert.EnsureTrue(ModuleInst, typeof(NSArray).IsAssignableFrom(CurrentURLSchemesArrayObj.GetType()), "A CFBundleURLSchemes key exists for a given CFBundleURLType, but it's not an NSArray type.")) { NSArray CurrentURLSchemesArray = (NSArray)CurrentURLSchemesArrayObj; if(IgorAssert.EnsureTrue(ModuleInst, CurrentURLSchemesArray != null, "The CFBundleURLSchemes object didn't cast to NSDictionary correctly.")) { NSSet CurrentURLSchemesSet = new NSSet(CurrentURLSchemesArray.GetArray()); foreach(NSObject CurrentURLSchemeObj in CurrentURLSchemesSet) { if(IgorAssert.EnsureTrue(ModuleInst, typeof(NSString).IsAssignableFrom(CurrentURLSchemeObj.GetType()), "One of the CFBundleURLSchemes is not an NSString.")) { NSString CurrentURLScheme = (NSString)CurrentURLSchemeObj; if(IgorAssert.EnsureTrue(ModuleInst, CurrentURLScheme != null, "A CFBundleURLScheme entry didn't cast to NSString correctly.")) { if(CurrentURLScheme.GetContent() == NewURLScheme) { bAlreadyExists = true; IgorDebug.Log(ModuleInst, "URL scheme " + NewURLScheme + " is already in " + PlistPath); break; } } } } } } } } } } if(!bAlreadyExists) { NSString NewSchemeString = new NSString(NewURLScheme); NSArray NewSchemeArray = new NSArray(1); NewSchemeArray.SetValue(0, NewSchemeString); NSDictionary NewTypeDictionary = new NSDictionary(); NewTypeDictionary.Add("CFBundleURLSchemes", NewSchemeArray); BundleURLTypes.AddObject(NewTypeDictionary); NSArray BundleURLTypesArray = new NSArray(BundleURLTypes.AllObjects()); if(RootDictionary.ContainsKey("CFBundleURLTypes")) { RootDictionary["CFBundleURLTypes"] = BundleURLTypesArray; IgorDebug.Log(ModuleInst, "Updated CFBundleURLTypes to add " + NewURLScheme + "."); } else { RootDictionary.Add("CFBundleURLTypes", BundleURLTypesArray); IgorDebug.Log(ModuleInst, "Added CFBundleURLTypes to add " + NewURLScheme + "."); } IgorRuntimeUtils.DeleteFile(PlistPath); PropertyListParser.SaveAsXml(RootDictionary, PlistFileInfo); } } } } } }
public static void AddRequiredDeviceCapability(IIgorModule ModuleInst, string PlistPath, string NewRequiredDeviceCapability) { if(IgorAssert.EnsureTrue(ModuleInst, File.Exists(PlistPath), "Plist " + PlistPath + " doesn't exist!")) { FileInfo PlistFileInfo = new FileInfo(PlistPath); NSObject PlistRoot = PropertyListParser.Parse(PlistFileInfo); if(IgorAssert.EnsureTrue(ModuleInst, PlistRoot != null, "Plist " + PlistPath + " could not be parsed!")) { if(IgorAssert.EnsureTrue(ModuleInst, typeof(NSDictionary).IsAssignableFrom(PlistRoot.GetType()), "Plist " + PlistPath + " root object is not a dictionary.")) { NSDictionary RootDictionary = (NSDictionary)PlistRoot; if(IgorAssert.EnsureTrue(ModuleInst, RootDictionary != null, "Plist root is not a dictionary.")) { if(IgorAssert.EnsureTrue(ModuleInst, RootDictionary.ContainsKey("UIRequiredDeviceCapabilities"), "Can't find UIRequiredDeviceCapabilities in plist.")) { NSObject DeviceCapabilities = RootDictionary.Get("UIRequiredDeviceCapabilities"); if(IgorAssert.EnsureTrue(ModuleInst, DeviceCapabilities != null, "Plist does not contain UIRequiredDeviceCapabilities.")) { if(IgorAssert.EnsureTrue(ModuleInst, typeof(NSArray).IsAssignableFrom(DeviceCapabilities.GetType()), "Plist UIRequiredDeviceCapabilities is not an array.")) { NSArray CapabilitiesArray = (NSArray)DeviceCapabilities; if(IgorAssert.EnsureTrue(ModuleInst, CapabilitiesArray != null, "UIRequiredDeviceCapabilities is not an array.")) { if(CapabilitiesArray.ContainsObject(new NSString(NewRequiredDeviceCapability))) { IgorDebug.Log(ModuleInst, "UIRequiredDeviceCapabilities already contains " + NewRequiredDeviceCapability); } else { NSSet NewCapabilitiesSet = new NSSet(CapabilitiesArray.GetArray()); NewCapabilitiesSet.AddObject(new NSString(NewRequiredDeviceCapability)); NSArray NewCapabilitiesArray = new NSArray(NewCapabilitiesSet.AllObjects()); RootDictionary["UIRequiredDeviceCapabilities"] = NewCapabilitiesArray; IgorRuntimeUtils.DeleteFile(PlistPath); PropertyListParser.SaveAsXml(RootDictionary, PlistFileInfo); IgorDebug.Log(ModuleInst, NewRequiredDeviceCapability + " added to UIRequiredDeviceCapabilities."); } } } } } } } } } }
/// <summary> /// Finds out if this set is a subset of the given set. /// </summary> /// <returns><c>true</c> if all elements in this set are also present in the other set, <c>false</c>otherwise.</returns> /// <param name="otherSet">The other set.</param> public bool IsSubsetOfSet(NSSet otherSet) { lock (set) { foreach (NSObject o in set) { if (!otherSet.ContainsObject(o)) return false; } return true; } }
/// <summary> /// Finds out whether at least one object is present in both sets. /// </summary> /// <returns><c>true</c> if the intersection of both sets is empty, <c>false</c> otherwise.</returns> /// <param name="otherSet">The other set.</param> public bool IntersectsSet(NSSet otherSet) { lock (set) { foreach (NSObject o in set) { if (otherSet.ContainsObject(o)) return true; } return false; } }