/// <summary>
        /// Extracts the data from the given record and places it into the
        /// given text RTD.
        /// </summary>
        /// <param name="record">The record containing the data.</param>
        /// <param name="text">Where the data is placed.</param>
        public static void ReadTextRtd(NdefRecord record, NdefTextRtd text)
        {
            byte[] buf = record.Payload;

            if (IsBitSet(buf[0], 6))
            {
                return;
            }

            var langLen = (byte)(buf[0] & 0x3f);
            var langBuf = new byte[langLen];
            System.Buffer.BlockCopy(buf, 1, langBuf, 0, langLen);
            text.Language=System.Text.Encoding.UTF8.GetString(langBuf, 0, langBuf.Length);
            var textLen = buf.Length - 1 - langLen;

            if (textLen <= 0)
            {
                return;
            }

            var textBuf = new byte[textLen];
            System.Buffer.BlockCopy(buf, 1 + langLen, textBuf, 0, textLen);

            if (IsBitSet(buf[0], 7))
            {
                text.Encoding = "UTF-16";
                text.Text = System.Text.Encoding.Unicode.GetString(textBuf, 0, textBuf.Length);
            }
            else
            {
                text.Encoding = "UTF-8";
                text.Text = System.Text.Encoding.UTF8.GetString(textBuf, 0, textBuf.Length);
            }
        }
        /// <summary>
        /// Resolves the type name format of the given record.
        /// </summary>
        /// <param name="record">NDEF record</param>
        /// <returns>The type name format matching the given record.</returns>
        static public string GetTypeNameFormat(NdefRecord record)
        {
            var typeName = "";

            switch (record.Tnf)
            {
            case 0x00:
                typeName = "empty";
                break;

            case 0x01:
                typeName = "wkt";
                break;

            case 0x02:
                typeName = "mimetype";
                break;

            case 0x03:
                typeName = "absUri";
                break;

            case 0x04:
                typeName = "ext";
                break;

            case 0x05:
                typeName = "unknown";
                break;

            case 0x06:
                typeName = "unchanged";
                break;

            case 0x07:
                typeName = "reserved";
                break;

            default:
                typeName = "error";
                break;
            }

            return(typeName);
        }
        /// <summary>
        /// Resolves the type name format of the given record.
        /// </summary>
        /// <param name="record">NDEF record</param>
        /// <returns>The type name format matching the given record.</returns>
        public static string GetTypeNameFormat(NdefRecord record)
        {
            var typeName = "";

            switch (record.Tnf)
            {
                case 0x00:
                    typeName = "empty";
                    break;
                case 0x01:
                    typeName = "wkt";
                    break;
                case 0x02:
                    typeName = "mimetype";
                    break;
                case 0x03:
                    typeName = "absUri";
                    break;
                case 0x04:
                    typeName = "ext";
                    break;
                case 0x05:
                    typeName = "unknown";
                    break;
                case 0x06:
                    typeName = "unchanged";
                    break;
                case 0x07:
                    typeName = "reserved";
                    break;
                default:
                    typeName = "error";
                    break;
            }

            return typeName;
        }
        /// <summary>
        /// Extracts the data from the given record and places it into the
        /// given text RTD.
        /// </summary>
        /// <param name="record">The record containing the data.</param>
        /// <param name="text">Where the data is placed.</param>
        static public void ReadTextRtd(NdefRecord record, NdefTextRtd text)
        {
            byte[] buf = record.Payload;

            if (IsBitSet(buf[0], 6))
            {
                return;
            }

            var langLen = (byte)(buf[0] & 0x3f);
            var langBuf = new byte[langLen];

            System.Buffer.BlockCopy(buf, 1, langBuf, 0, langLen);
            text.Language = System.Text.Encoding.UTF8.GetString(langBuf, 0, langBuf.Length);
            var textLen = buf.Length - 1 - langLen;

            if (textLen <= 0)
            {
                return;
            }

            var textBuf = new byte[textLen];

            System.Buffer.BlockCopy(buf, 1 + langLen, textBuf, 0, textLen);

            if (IsBitSet(buf[0], 7))
            {
                text.Encoding = "UTF-16";
                text.Text     = System.Text.Encoding.Unicode.GetString(textBuf, 0, textBuf.Length);
            }
            else
            {
                text.Encoding = "UTF-8";
                text.Text     = System.Text.Encoding.UTF8.GetString(textBuf, 0, textBuf.Length);
            }
        }
        /// <summary>
        /// Creates NDEF records based on the data in the given buffer.
        /// </summary>
        /// <param name="buf">The data buffer as input.</param>
        /// <param name="list">The list of new NDEF records as output.</param>
        /// <param name="isFirstRecordSp">Defines whether the first record is smart poster or not.</param>
        private static void ReadNdefRecord(DataReader buf, List<NdefRecord> list, bool isFirstRecordSp)
        {
            var record = new NdefRecord();
            byte header = buf.ReadByte();
            record.Mb = IsBitSet(header, 7);
            record.Me = IsBitSet(header, 6);
            record.Cf = IsBitSet(header, 5);
            record.Sr = IsBitSet(header, 4);
            record.Il = IsBitSet(header, 3);
            record.Tnf = (byte)(header & 0x07);
            record.TypeLength = buf.ReadByte();
            record.IsSpRecord = isFirstRecordSp;

            if (record.Il)
            {
                record.IdLength = buf.ReadByte();
            }
            else
            {
                record.IdLength = 0;
            }

            if (record.Sr)
            {
                record.PayloadLength = buf.ReadByte();
            }
            else
            {
                var lengthBuf = new byte[4];
                buf.ReadBytes(lengthBuf);
                record.PayloadLength = BitConverter.ToUInt32(lengthBuf, 0);
            }

            if (record.TypeLength > 0)
            {
                record.Type = new byte[record.TypeLength];
                buf.ReadBytes(record.Type);
            }

            if ((record.Il) && (record.IdLength > 0))
            {
                record.Id = new byte[record.IdLength];
                buf.ReadBytes(record.Id);
            }

            if (record.PayloadLength > 0)
            {
                if ((record.Tnf == 0x01)
                    && (System.Text.Encoding.UTF8.GetString(record.Type, 0, record.TypeLength) == "Sp"))
                {
                    ReadNdefRecord(buf, list, true);
                    record.Payload = null;
                }
                else
                {
                    record.Payload = new byte[record.PayloadLength];
                    buf.ReadBytes(record.Payload);
                }
            }

            list.Add(record);

            if (!record.Me)
            {
                ReadNdefRecord(buf, list, isFirstRecordSp);
            }
        }
 /// <summary>
 /// Extracts the data from the given record and places it into the
 /// given URI RTD.
 /// </summary>
 /// <param name="record">The record containing the URI data.</param>
 /// <param name="uri">Where the data is placed.</param>
 public static void ReadUriRtd(NdefRecord record, NdefUriRtd uri)
 {
     byte[] buf = record.Payload;
     uri.Identifier = GetUriIdentifier(buf[0]);
     uri.Uri= System.Text.Encoding.UTF8.GetString(buf, 1, buf.Length-1);
 }
        /// <summary>
        /// Parses the details from the given message. The output is a string
        /// that can be appended into the log.
        /// </summary>
        /// <param name="message">The message to parse.</param>
        /// <returns>The parsed details as a string.</returns>
        private string ParseNDEF(ProximityMessage message)
        {
            var output = "";

            using (var buf = DataReader.FromBuffer(message.Data)) {
                NdefRecordUtility.ReadNdefRecord(buf, recordList);

                for (int i = 0, recordNumber = 0, spRecordNumber = 0; i < recordList.Count; i++)
                {
                    NdefRecord record = recordList.ElementAt(i);

                    if (!record.IsSpRecord)
                    {
                        if (System.Text.Encoding.UTF8.GetString(record.Type, 0, record.TypeLength) == "Sp")
                        {
                            output = output + "\n --End of Record No." + recordNumber; spRecordNumber = 0;
                            continue;
                        }
                        else
                        {
                            recordNumber++;
                            output = output + "\n --Record No." + recordNumber;
                        }
                    }
                    else
                    {
                        if (spRecordNumber == 0)
                        {
                            recordNumber++;
                            output = output + "\n --Record No." + recordNumber;
                        }

                        spRecordNumber++;
                        output = output + "\n Sp sub-record No." + spRecordNumber;
                    }

                    output = output + "\n MB:" + ((record.Mb) ? "1;" : "0;");
                    output = output + " ME:" + ((record.Me) ? "1;" : "0;");
                    output = output + " CF:" + ((record.Cf) ? "1;" : "0;");
                    output = output + " SR:" + ((record.Sr) ? "1;" : "0;");
                    output = output + " IL:" + ((record.Il) ? "1;" : "0;");

                    string typeName = NdefRecordUtility.GetTypeNameFormat(record);

                    if (record.TypeLength > 0)
                    {
                        output = output + "\n Type: " + typeName + ":"
                                 + System.Text.Encoding.UTF8.GetString(record.Type, 0, record.TypeLength);
                    }

                    if ((record.Il) && (record.IdLength > 0))
                    {
                        output = output + "\n Id:"
                                 + System.Text.Encoding.UTF8.GetString(record.Id, 0, record.IdLength);
                    }

                    if ((record.PayloadLength > 0) && (record.Payload != null))
                    {
                        if ((record.Tnf == 0x01) &&
                            (System.Text.Encoding.UTF8.GetString(record.Type, 0, record.TypeLength) == "U"))
                        {
                            NdefUriRtd uri = new NdefUriRtd();
                            NdefRecordUtility.ReadUriRtd(record, uri);
                            output = output + "\n Uri: " + uri.GetFullUri();
                        }
                        else if ((record.Tnf == 0x01) &&
                                 (System.Text.Encoding.UTF8.GetString(record.Type, 0, record.TypeLength) == "T"))
                        {
                            NdefTextRtd text = new NdefTextRtd();
                            NdefRecordUtility.ReadTextRtd(record, text);
                            output = output + "\n Language: " + text.Language;
                            output = output + "\n Encoding: " + text.Encoding;
                            output = output + "\n Text: " + text.Text;
                        }
                        else
                        {
                            if (record.Tnf == 0x01)
                            {
                                output = output + "\n Payload:"
                                         + System.Text.Encoding.UTF8.GetString(record.Payload, 0, record.Payload.Length);
                            }
                        }
                    }

                    if (!record.IsSpRecord)
                    {
                        output = output + "\n --End of Record No." + recordNumber;
                    }
                }
            }

            return(output);
        }
 /// <summary>
 /// Extracts the data from the given record and places it into the
 /// given URI RTD.
 /// </summary>
 /// <param name="record">The record containing the URI data.</param>
 /// <param name="uri">Where the data is placed.</param>
 static public void ReadUriRtd(NdefRecord record, NdefUriRtd uri)
 {
     byte[] buf = record.Payload;
     uri.Identifier = GetUriIdentifier(buf[0]);
     uri.Uri        = System.Text.Encoding.UTF8.GetString(buf, 1, buf.Length - 1);
 }
        /// <summary>
        /// Creates NDEF records based on the data in the given buffer.
        /// </summary>
        /// <param name="buf">The data buffer as input.</param>
        /// <param name="list">The list of new NDEF records as output.</param>
        /// <param name="isFirstRecordSp">Defines whether the first record is smart poster or not.</param>
        static private void ReadNdefRecord(DataReader buf, List <NdefRecord> list, bool isFirstRecordSp)
        {
            var  record = new NdefRecord();
            byte header = buf.ReadByte();

            record.Mb         = IsBitSet(header, 7);
            record.Me         = IsBitSet(header, 6);
            record.Cf         = IsBitSet(header, 5);
            record.Sr         = IsBitSet(header, 4);
            record.Il         = IsBitSet(header, 3);
            record.Tnf        = (byte)(header & 0x07);
            record.TypeLength = buf.ReadByte();
            record.IsSpRecord = isFirstRecordSp;

            if (record.Il)
            {
                record.IdLength = buf.ReadByte();
            }
            else
            {
                record.IdLength = 0;
            }

            if (record.Sr)
            {
                record.PayloadLength = buf.ReadByte();
            }
            else
            {
                var lengthBuf = new byte[4];
                buf.ReadBytes(lengthBuf);
                record.PayloadLength = BitConverter.ToUInt32(lengthBuf, 0);
            }

            if (record.TypeLength > 0)
            {
                record.Type = new byte[record.TypeLength];
                buf.ReadBytes(record.Type);
            }

            if ((record.Il) && (record.IdLength > 0))
            {
                record.Id = new byte[record.IdLength];
                buf.ReadBytes(record.Id);
            }

            if (record.PayloadLength > 0)
            {
                if ((record.Tnf == 0x01) &&
                    (System.Text.Encoding.UTF8.GetString(record.Type, 0, record.TypeLength) == "Sp"))
                {
                    ReadNdefRecord(buf, list, true);
                    record.Payload = null;
                }
                else
                {
                    record.Payload = new byte[record.PayloadLength];
                    buf.ReadBytes(record.Payload);
                }
            }

            list.Add(record);

            if (!record.Me)
            {
                ReadNdefRecord(buf, list, isFirstRecordSp);
            }
        }