private static ServiceElement CreateEnglishUtf8PrimaryLanguageServiceElement() { ServiceElement englishUtf8PrimaryLanguage = LanguageBaseItem.CreateElementSequenceFromList( new LanguageBaseItem[] { LanguageBaseItem.CreateEnglishUtf8PrimaryLanguageItem() }); return(englishUtf8PrimaryLanguage); }
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); }
public String GetPrimaryMultiLanguageStringAttributeById(ServiceAttributeId id) { LanguageBaseItem lang = this.GetPrimaryLanguageBaseItem(); if (lang == null) { lang = LanguageBaseItem.CreateEnglishUtf8PrimaryLanguageItem(); } return(GetMultiLanguageStringAttributeById(id, lang)); }
/// <summary> /// Returns the attribute with the given ID and natural language. /// </summary> /// - /// <param name="id">The id of the service attribute to locate, as a /// <see cref="T:InTheHand.Net.Bluetooth.ServiceAttributeId"/>.</param> /// <param name="language"> /// Which multi-language version of the string attribute to locate. /// </param> /// - /// <returns>A <see cref="T:InTheHand.Net.Bluetooth.ServiceAttribute"/> holding /// the attribute with the specified ID and language. /// Is never <see langword="null"/>. /// </returns> /// - /// <exception cref="T:System.Collections.Generic.KeyNotFoundException"> /// There is no attribute with the given Id with the given language base in the record. /// </exception> public ServiceAttribute GetAttributeById(ServiceAttributeId id, LanguageBaseItem language) { if (language == null) { throw new ArgumentNullException("language"); } ServiceAttributeId actualId = CreateLanguageBasedAttributeId(id, language.AttributeIdBase); ServiceAttribute attr = GetAttributeById(actualId); System.Diagnostics.Debug.Assert(attr != null); return(attr); }
//-------------------------------------------------------------- /// <summary> /// Determines whether a TextString service attribute with the specified ID /// and natural language /// is in the List. /// </summary> /// - /// <param name="id">The id of the service attribute to locate, as a /// <see cref="T:InTheHand.Net.Bluetooth.ServiceAttributeId"/>.</param> /// <param name="language"> /// Which multi-language version of the string attribute to locate. /// </param> /// - /// <returns>true if item is found in the record; otherwise, false. </returns> public bool Contains(ServiceAttributeId id, LanguageBaseItem language) { if (language == null) { throw new ArgumentNullException("language"); } ServiceAttributeId actualId = CreateLanguageBasedAttributeId(id, language.AttributeIdBase); ServiceAttribute tmp; bool found = TryGetAttributeById(actualId, out tmp); return(found && (tmp.Value.ElementType == ElementType.TextString)); }
public String GetMultiLanguageStringAttributeById(ServiceAttributeId id, LanguageBaseItem language) { if (language == null) { throw new ArgumentNullException("language"); } ServiceAttributeId actualId = CreateLanguageBasedAttributeId(id, language.AttributeIdBase); ServiceAttribute attr = GetAttributeById(actualId); ServiceElement element = attr.Value; // (No need to check that element is of type TextString, that's handled inside the following). String str = element.GetValueAsString(language); return(str); }
/// <summary> /// Get the value of the <see cref="F:InTheHand.Net.Bluetooth.ElementTypeDescriptor.TextString"/>, /// when it is encoded as specified by the given IETF Charset identifer. /// </summary> /// - /// <remarks> /// Note that a strict decoding of the string is carried out /// (except on the NETCF where it is not supported). /// Thus if the value is not in the specified encoding, or has been /// encoded incorrectly, then an error will occur. /// </remarks> /// - /// <returns> /// A <see cref="T:System.String"/> holding the value of the /// <see cref="F:InTheHand.Net.Bluetooth.ElementTypeDescriptor.TextString"/> /// from the service element. /// </returns> /// - /// <exception cref="T:System.InvalidOperationException"> /// The service element is not of type /// <see cref="F:InTheHand.Net.Bluetooth.ElementTypeDescriptor.TextString"/>. /// </exception> /// <exception cref="T:System.Text.DecoderFallbackException"> /// If the value in the service element is not a valid string in the given encoding. /// </exception> public String GetValueAsString(LanguageBaseItem languageBase) { if (languageBase == null) { throw new ArgumentNullException("languageBase"); } Encoding enc = languageBase.GetEncoding(); #if !PocketPC if (_strictStringDecoding) { enc = (Encoding)enc.Clone(); //not in NETCFv1 enc.DecoderFallback = new DecoderExceptionFallback(); // not in NETCF. // Not intended for encoding, but set it anyway. enc.EncoderFallback = new EncoderExceptionFallback(); // not in NETCF. } #endif return(GetValueAsString(enc)); }
//-------------------------------------------------------------- /// <summary> /// Gets the list of LanguageBaseAttributeId items in the service record. /// </summary> /// - /// <remarks> /// See also <see cref="M:InTheHand.Net.Bluetooth.ServiceRecord.GetPrimaryLanguageBaseItem"/>. /// </remarks> /// - /// <returns> /// An array of <see cref="T:InTheHand.Net.Bluetooth.LanguageBaseItem"/>. /// An array of length zero is returned if the service record contains no such attribute. /// </returns> /// - /// <seealso cref="M:InTheHand.Net.Bluetooth.ServiceRecord.GetPrimaryLanguageBaseItem"/> public LanguageBaseItem[] GetLanguageBaseList() { if (!Contains(InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.LanguageBaseAttributeIdList)) { return(new LanguageBaseItem[0]); } ServiceAttribute attr = GetAttributeById(InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.LanguageBaseAttributeIdList); if (attr.Value.ElementType != ElementType.ElementSequence) { return(new LanguageBaseItem[0]); } LanguageBaseItem[] langList; try { langList = LanguageBaseItem.ParseListFromElementSequence(attr.Value); } catch (System.Net.ProtocolViolationException) { return(new LanguageBaseItem[0]); } return(langList); }
_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); }
//-------------------- // /// <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); } #if V1 IList elementList = elementSequence.GetValueAsElementList(); #else IList <ServiceElement> elementList = elementSequence.GetValueAsElementList(); #endif 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); }
//-------------------- /// <summary> /// Create a data element for the /// <see cref="F:InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.LanguageBaseAttributeIdList"/> /// attribute /// from the list of <see cref="T:InTheHand.Net.Bluetooth.LanguageBaseItem"/> /// </summary> /// - /// <param name="list"> /// An array of <see cref="T:InTheHand.Net.Bluetooth.LanguageBaseItem"/>. /// </param> /// - /// <returns> /// A <see cref="T:InTheHand.Net.Bluetooth.ServiceElement"/> holding the /// <see cref="F:InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.LanguageBaseAttributeIdList"/> /// element, to be added to a generally the /// <see cref="T:InTheHand.Net.Bluetooth.ServiceRecord"/>. /// </returns> public static ServiceElement CreateElementSequenceFromList(LanguageBaseItem[] list) { #if ! V1 IList<ServiceElement> children = new List<ServiceElement>(); #else IList children = new ArrayList(); #endif foreach (LanguageBaseItem item in list) { //String lang = item.NaturalLanguage; //UInt16 langNumerical = GetLanguageIdStringAsBytes(lang); UInt16 langNumerical = item.NaturalLanguageAsUInt16; children.Add(new ServiceElement(ElementType.UInt16, (UInt16)langNumerical)); children.Add(new ServiceElement(ElementType.UInt16, (UInt16)item.EncodingId)); children.Add(new ServiceElement(ElementType.UInt16, (UInt16)item.AttributeIdBase)); } return new ServiceElement(ElementType.ElementSequence, children); }
//-------------------- // /// <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); } #if V1 IList elementList = elementSequence.GetValueAsElementList(); #else IList<ServiceElement> elementList = elementSequence.GetValueAsElementList(); #endif 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; }
private static void DumpString(System.IO.TextWriter writer, int depth, ServiceElement element, LanguageBaseItem langBase) { if (langBase != null) { try { String value = element.GetValueAsString(langBase); writer.WriteLine("{0}: [{1}] '{2}'", element.ElementType, langBase.NaturalLanguage, value); } catch (NotSupportedException ex) { System.Diagnostics.Debug.Assert(ex.Message != null); System.Diagnostics.Debug.Assert(ex.Message.StartsWith("Unrecognized character encoding")); writer.WriteLine("{0}: Failure: {1}", element.ElementType, ex.Message); } } else { try { String hack = element.GetValueAsStringUtf8(); if (hack.IndexOf((char)0) != -1) { throw new #if !WinCE System.Text.DecoderFallbackException #else // NETCF doesn't support DecoderFallbackException this what the docs say. ArgumentException #endif ("EEEEE contains nulls! UTF-16?!"); } writer.WriteLine("{0} (guessing UTF-8): '{1}'", element.ElementType, hack); } catch ( // TODO ! What exception thrown by UTF8Encoding on NETCF? #if !WinCE System.Text.DecoderFallbackException #else // NETCF doesn't support DecoderFallbackException this what the docs say. ArgumentException #endif ) { writer.WriteLine("{0} (Unknown/bad encoding):", element.ElementType); var arr = (byte[])element.Value; var str = BitConverter.ToString(arr); WritePrefix(writer, depth); // On another line. writer.WriteLine("Length: {0}, >>{1}<<", arr.Length, str); }//try } }
public String GetMultiLanguageStringAttributeById(ServiceAttributeId id, LanguageBaseItem language) { if (language == null) { throw new ArgumentNullException("language"); } ServiceAttributeId actualId = CreateLanguageBasedAttributeId(id, language.AttributeIdBase); ServiceAttribute attr = GetAttributeById(actualId); ServiceElement element = attr.Value; // (No need to check that element is of type TextString, that's handled inside the following). String str = element.GetValueAsString(language); return str; }
_GetNameIfMatchesMultiLang(ServiceAttributeId id, System.Reflection.FieldInfo curField, LanguageBaseItem[] langBaseList, out LanguageBaseItem applicableLangBase) { foreach (LanguageBaseItem curBaseItem in langBaseList) { ServiceAttributeId baseOffset = curBaseItem.AttributeIdBase; ServiceAttributeId realId = id; realId -= baseOffset; string fieldName = _GetNameIfMatches(realId, curField); if (fieldName != null) { applicableLangBase = curBaseItem; return fieldName; } }//foreach applicableLangBase = null; return null; }
/// <summary> /// Get the value of the <see cref="F:InTheHand.Net.Bluetooth.ElementTypeDescriptor.TextString"/>, /// when it is encoded as specified by the given IETF Charset identifer. /// </summary> /// - /// <remarks> /// Note that a strict decoding of the string is carried out /// (except on the NETCF where it is not supported). /// Thus if the value is not in the specified encoding, or has been /// encoded incorrectly, then an error will occur. /// </remarks> /// - /// <returns> /// A <see cref="T:System.String"/> holding the value of the /// <see cref="F:InTheHand.Net.Bluetooth.ElementTypeDescriptor.TextString"/> /// from the service element. /// </returns> /// - /// <exception cref="T:System.InvalidOperationException"> /// The service element is not of type /// <see cref="F:InTheHand.Net.Bluetooth.ElementTypeDescriptor.TextString"/>. /// </exception> /// <exception cref="T:System.Text.DecoderFallbackException"> /// If the value in the service element is not a valid string in the given encoding. /// </exception> public String GetValueAsString(LanguageBaseItem languageBase) { if (languageBase == null) { throw new ArgumentNullException("languageBase"); } Encoding enc = languageBase.GetEncoding(); #if ! PocketPC if (m_strictStringDecoding) { enc = (Encoding)enc.Clone(); //not in NETCFv1 enc.DecoderFallback = new DecoderExceptionFallback(); // not in NETCF. // Not intended for encoding, but set it anyway. enc.EncoderFallback = new EncoderExceptionFallback(); // not in NETCF. } #endif return GetValueAsString(enc); }
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> /// Determines whether a TextString service attribute with the specified ID /// and natural language /// is in the List. /// </summary> /// - /// <param name="id">The id of the service attribute to locate, as a /// <see cref="T:InTheHand.Net.Bluetooth.ServiceAttributeId"/>.</param> /// <param name="language"> /// Which multi-language version of the string attribute to locate. /// </param> /// - /// <returns>true if item is found in the record; otherwise, false. </returns> public bool Contains(ServiceAttributeId id, LanguageBaseItem language) { if (language == null) { throw new ArgumentNullException("language"); } ServiceAttributeId actualId = CreateLanguageBasedAttributeId(id, language.AttributeIdBase); ServiceAttribute tmp; bool found = TryGetAttributeById(actualId, out tmp); return found && (tmp.Value.ElementType == ElementType.TextString); }
private static void DumpString(System.IO.TextWriter writer, int depth, ServiceElement element, LanguageBaseItem langBase) { if (langBase != null) { try { String value = element.GetValueAsString(langBase); writer.WriteLine("{0}: [{1}] '{2}'", element.ElementType, langBase.NaturalLanguage, value); } catch (NotSupportedException ex) { System.Diagnostics.Debug.Assert(ex.Message != null); System.Diagnostics.Debug.Assert(ex.Message.StartsWith("Unrecognized character encoding")); writer.WriteLine("{0}: Failure: {1}", element.ElementType, ex.Message); } } else { try { String hack = element.GetValueAsStringUtf8(); writer.WriteLine("{0} (guessing UTF-8): '{1}'", element.ElementType, hack); } catch ( // TODO ! What exception thrown by UTF8Encoding on NETCF? #if ! WinCE System.Text.DecoderFallbackException #else // NETCF doesn't support DecoderFallbackException this what the docs say. ArgumentException #endif ) { writer.WriteLine("{0} (Unknown/bad encoding):", element.ElementType); }//try } }
/// <summary> /// Returns the attribute with the given ID and natural language. /// </summary> /// - /// <param name="id">The id of the service attribute to locate, as a /// <see cref="T:InTheHand.Net.Bluetooth.ServiceAttributeId"/>.</param> /// <param name="language"> /// Which multi-language version of the string attribute to locate. /// </param> /// - /// <returns>A <see cref="T:InTheHand.Net.Bluetooth.ServiceAttribute"/> holding /// the attribute with the specified ID and language. /// Is never <see langword="null"/>. /// </returns> /// - /// <exception cref="T:System.Collections.Generic.KeyNotFoundException"> /// There is no attribute with the given Id with the given language base in the record. /// </exception> public ServiceAttribute GetAttributeById(ServiceAttributeId id, LanguageBaseItem language) { if (language == null) { throw new ArgumentNullException("language"); } ServiceAttributeId actualId = CreateLanguageBasedAttributeId(id, language.AttributeIdBase); ServiceAttribute attr = GetAttributeById(actualId); System.Diagnostics.Debug.Assert(attr != null); return attr; }