public static string GetName(ServiceAttributeId id, Type[] attributeIdDefiningClasses, LanguageBaseItem[] langBaseList, out LanguageBaseItem applicableLangBase) { if (attributeIdDefiningClasses == null) { throw new ArgumentNullException("attributeIdDefiningClasses"); } //HACK if (langBaseList == null) { if (langBaseList == null) { throw new ArgumentNullException("langBaseList"); } // Foreach: class that defines AttributeId enum. // Foreach: AttributeId enum field in that class. // Check whether its value matches the one being searched for, and return if so. // foreach (Type curDefiningType in attributeIdDefiningClasses) { //if (!(curDefiningType.IsSealed && curDefiningType.IsAbstract)) { } //---- System.Reflection.FieldInfo[] fieldArr = curDefiningType.GetFields( // With Public, no permissions required, apparently. System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); foreach (System.Reflection.FieldInfo curField in fieldArr) { if (curField.FieldType == typeof(ServiceAttributeId)) { // A multi-language attribute or a just a normal one? Object[] dotnetAtttrs = curField.GetCustomAttributes(typeof(StringWithLanguageBaseAttribute), false); if (dotnetAtttrs.Length != 0) { System.Diagnostics.Debug.Assert(dotnetAtttrs.Length == 1, "Not that it's a problem for us at all, but that Attribute should only be applied once."); string name = _GetNameIfMatchesMultiLang(id, curField, langBaseList, out applicableLangBase); if (name != null) { return(name); } } else { // No just a normal Attribute, not language base offsetting. string name = _GetNameIfMatches(id, curField); if (name != null) { applicableLangBase = null; return(name); } } //else } } //foreach } //foreach // Not found. applicableLangBase = null; return(null); }
//-------------------- // /// <summary> /// Gets the list of <see cref="T:InTheHand.Net.Bluetooth.LanguageBaseItem"/> /// items in the service record. /// </summary> /// - /// <param name="elementSequence"> /// A <see cref="T:InTheHand.Net.Bluetooth.ServiceElement"/> holding the /// data from the /// <see cref="F:InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.LanguageBaseAttributeIdList"/> /// attribute. /// </param> /// - /// <returns> /// An array of <see cref="T:InTheHand.Net.Bluetooth.LanguageBaseItem"/>. /// An array length zero is returned if the service record contains no such attribute. /// </returns> /// - /// <exception cref="T:System.ArgumentException"> /// <paramref name="elementSequence"/> is not of type /// <see cref="F:InTheHand.Net.Bluetooth.ElementType.ElementSequence"/>. /// </exception> /// <exception cref="T:System.Net.ProtocolViolationException"> /// The element sequence contains incorrectly formatted or invalid content, /// for example it contains the wrong element data types, or doesn't contain /// the elements in groups of three as required. /// </exception> public static LanguageBaseItem[] ParseListFromElementSequence(ServiceElement elementSequence) { if (elementSequence.ElementType != ElementType.ElementSequence) { throw new ArgumentException(ErrorMsgLangBaseListParseNotSequence); } IList <ServiceElement> elementList = elementSequence.GetValueAsElementList(); int numElements = elementList.Count; const int ElementsPerItem = 3; if (numElements == 0 || (numElements % ElementsPerItem) != 0) { throw new System.Net.ProtocolViolationException(ErrorMsgLangBaseListParseNotInThrees); } int numItems = numElements / ElementsPerItem; LanguageBaseItem[] items = new LanguageBaseItem[numItems]; for (int i = 0; i < numItems; ++i) { // Casts are for the non-Generic version. ServiceElement e1Lang = (ServiceElement)elementList[i * ElementsPerItem]; ServiceElement e2EncId = (ServiceElement)elementList[i * ElementsPerItem + 1]; ServiceElement e3BaseId = (ServiceElement)elementList[i * ElementsPerItem + 2]; if (e1Lang.ElementType != ElementType.UInt16 || e2EncId.ElementType != ElementType.UInt16 || e3BaseId.ElementType != ElementType.UInt16) { throw new System.Net.ProtocolViolationException(ErrorMsgLangBaseListParseNotU16); } if ((UInt16)e3BaseId.Value == 0) { throw new System.Net.ProtocolViolationException(ErrorMsgLangBaseListParseBaseInvalid); } LanguageBaseItem item = new LanguageBaseItem( (UInt16)e1Lang.Value, (UInt16)e2EncId.Value, (UInt16)e3BaseId.Value); items[i] = item; } return(items); }
_GetNameIfMatchesMultiLang(ServiceAttributeId id, System.Reflection.FieldInfo curField, LanguageBaseItem[] langBaseList, out LanguageBaseItem applicableLangBase) { foreach (LanguageBaseItem curBaseItem in langBaseList) { ServiceAttributeId baseOffset = curBaseItem.AttributeIdBase; ServiceAttributeId realId = id; unchecked { realId -= baseOffset; } // (Theorically 'unchecked' above could allow wrong results but // only 0, 1, and 2, have "[StringWithLanguageBaseAttribute]", // and it would be an odd record that could produce those // integers for wrong reasons). string fieldName = _GetNameIfMatches(realId, curField); if (fieldName != null) { applicableLangBase = curBaseItem; return(fieldName); } }//foreach applicableLangBase = null; return(null); }