/// <overloads>
        /// Creates a Service Record byte array from the given
        /// <see cref="ServiceRecord"/> object.
        /// </overloads>
        /// -
        /// <summary>
        /// Creates a Service Record byte array from the given
        /// <see cref="ServiceRecord"/> object,
        /// into the specified byte array.
        /// </summary>
        /// -
        /// <remarks>
        /// See the other overload <see cref="ServiceRecordCreator.CreateServiceRecord(ServiceRecord)"/>
        /// </remarks>
        /// -
        /// <param name="record">An instance of <see cref="ServiceRecord"/>
        /// containing the record to be created.
        /// </param>
        /// <param name="buffer">An array of <see cref="byte"/> for the record
        /// to be written to.
        /// </param>
        /// -
        /// <exception cref="ArgumentOutOfRangeException">
        /// The record bytes are longer that the supplied byte array buffer.
        /// </exception>
        /// -
        /// <returns>The length of the record in the array of <see cref="T:System.Byte"/>.
        /// </returns>
        public int CreateServiceRecord(ServiceRecord record, byte[] buffer)
        {
            if (record == null)
            {
                throw new ArgumentNullException("record");
            }
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            //
            int len;
            int offset = 0;

            len     = MakeVariableLengthHeader(buffer, offset, ElementTypeDescriptor.ElementSequence, out HeaderWriteState headerState);
            offset += len;
            foreach (ServiceAttribute attr in record)
            {
                WriteAttribute(attr, buffer, ref offset);
            }//for

            CompleteHeaderWrite(headerState, buffer, offset, out _);
            System.Diagnostics.Debug.Assert(offset != 0);
            return(offset);
        }
        /// <summary>
        /// Reads the RFCOMM Channel Number value from the service record,
        /// or returns -1 if the element is not present.
        /// </summary>
        /// -
        /// <param name="record">The <see cref="ServiceRecord"/>
        /// to search for the element.
        /// </param>
        /// -
        /// <returns>The Channel Number as an unsigned byte cast to an Int32,
        /// or -1 if at the <see cref="F:InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.ProtocolDescriptorList"/>
        /// attribute is missing or contains invalid elements.
        /// </returns>
        public static int GetRfcommChannelNumber(ServiceRecord record)
        {
            ServiceElement channelElement = GetRfcommChannelElement(record);

            if (channelElement == null)
            {
                return(-1);
            }
            return(GetRfcommChannelNumber(channelElement));
        }
        /// <summary>
        /// Sets the RFCOMM Channel Number value in the service record.
        /// </summary>
        /// -
        /// <param name="record">The <see cref="T:InTheHand.Net.Bluetooth.ServiceRecord"/>
        /// in which to set the RFCOMM Channel number.
        /// </param>
        /// <param name="channelNumber">The Channel number to set in the record.
        /// </param>
        /// -
        /// <exception cref="T:System.InvalidOperationException">The
        /// <see cref="F:InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.ProtocolDescriptorList"/>
        /// attribute is missing or contains invalid elements.
        /// </exception>
        public static void SetRfcommChannelNumber(ServiceRecord record, byte channelNumber)
        {
            ServiceElement channelElement = GetRfcommChannelElement(record);

            if (channelElement == null)
            {
                throw new InvalidOperationException("ProtocolDescriptorList element does not exist or is not in the RFCOMM format.");
            }
            System.Diagnostics.Debug.Assert(channelElement.ElementType == ElementType.UInt8);
            channelElement.SetValue(channelNumber);
        }
        /// <summary>
        /// Creates a Service Record byte array from the given
        /// <see cref="T:ServiceRecord"/> object.
        /// </summary>
        /// -
        /// <remarks>
        /// <para>The only oddity (as with parsing) is with the <c>TextString</c>
        /// type.  The <see cref="T:ServiceElement"/> can
        /// either hold the string already encoded to its array of bytes or an
        /// <see cref="T:System.String"/>.  In the latter case we will always simply
        /// encode the string to an array of bytes using encoding
        /// <see cref="P:System.Text.Encoding.UTF8"/>.
        /// </para>
        /// <para>Currently any UUIDs in the record are written out in the form supplied,
        /// we should probably write a &#x2018;short-form&#x2019; equivalent if its
        /// a &#x2018;Bluetooth-based&#x2019; UUID e.g. <c>Uuid128</c> as <c>Uuid16</c>.
        /// </para>
        /// </remarks>
        /// -
        /// <param name="record">An instance of <see cref="T:ServiceRecord"/>
        /// containing the record to be created.
        /// </param>
        /// -
        /// <returns>An array of <see cref="T:System.Byte"/> containing the resultant
        /// record bytes.  The length of the array is the length of the record bytes.
        /// </returns>
        public byte[] CreateServiceRecord(ServiceRecord record)
        {
            const int MaxiOutputSize = 256;

            byte[] tmpResult = new byte[MaxiOutputSize];
            int    length    = CreateServiceRecord(record, tmpResult);

            byte[] result = new byte[length];
            Array.Copy(tmpResult, 0, result, 0, length);
            return(result);
        }
        static ServiceElement GetChannelElement(ServiceRecord record, BluetoothProtocolDescriptorType proto)
        {
            if (!record.Contains(AttributeIds.ProtocolDescriptorList))
            {
                goto NotFound;
            }
            ServiceAttribute attr = record.GetAttributeById(AttributeIds.ProtocolDescriptorList);

            return(GetChannelElement(attr, proto, out _));

NotFound:
            return(null);
        }
 /// <summary>
 /// Reads the RFCOMM Channel Number element from the service record.
 /// </summary>
 /// -
 /// <param name="record">The <see cref="ServiceRecord"/>
 /// to search for the element.
 /// </param>
 /// -
 /// <returns>The <see cref="ServiceElement"/>
 /// holding the Channel Number.
 /// or <see langword="null"/> if at the <see cref="F:InTheHand.Net.Bluetooth.AttributeIds.UniversalAttributeId.ProtocolDescriptorList"/>
 /// attribute is missing or contains invalid elements.
 /// </returns>
 public static ServiceElement GetRfcommChannelElement(ServiceRecord record)
 {
     return(GetChannelElement(record, BluetoothProtocolDescriptorType.Rfcomm));
 }
 public void Dispose()
 {
     m_record = null;
 }
 internal ServiceRecordEnumerator(ServiceRecord record)
 {
     m_record = record;
 }