public static void SendString(DataOutputStream stream, string message)
 {
     Task.Run(() =>
     {
         stream.WriteChars(message);
         stream.WriteChar(END);
     });
 }
Пример #2
0
 /// <summary>
 /// Writes an ICU data header.
 /// Does not write a copyright string.
 /// </summary>
 /// <param name="dataFormat"></param>
 /// <param name="formatVersion"></param>
 /// <param name="dataVersion"></param>
 /// <param name="dos"></param>
 /// <returns>The length of the header (number of bytes written).</returns>
 /// <exception cref="IOException">From the <see cref="DataOutputStream"/>.</exception>
 public static int WriteHeader(int dataFormat, int formatVersion, int dataVersion,
                               DataOutputStream dos)
 {
     // ucmndata.h MappedData
     dos.WriteChar(32);  // headerSize
     dos.WriteByte(MAGIC1);
     dos.WriteByte(MAGIC2);
     // unicode/udata.h UDataInfo
     dos.WriteChar(20);         // sizeof(UDataInfo)
     dos.WriteChar(0);          // reservedWord
     dos.WriteByte(1);          // isBigEndian
     dos.WriteByte(CHAR_SET_);  // charsetFamily
     dos.WriteByte(CHAR_SIZE_); // sizeofUChar
     dos.WriteByte(0);          // reservedByte
     dos.WriteInt32(dataFormat);
     dos.WriteInt32(formatVersion);
     dos.WriteInt32(dataVersion);
     // 8 bytes padding for 32 bytes headerSize (multiple of 16).
     dos.WriteInt64(0);
     Debug.Assert(dos.Length == 32);
     return(32);
 }
Пример #3
0
        /// <summary>
        /// Serialize a <see cref="Trie2_16"/> onto an <see cref="Stream"/>.
        /// </summary>
        /// <remarks>
        /// A <see cref="Trie2"/> can be serialized multiple times.
        /// The serialized data is compatible with ICU4C UTrie2 serialization.
        /// <see cref="Trie2"/> serialization is unrelated to .NET object serialization.
        /// </remarks>
        /// <param name="os">The stream to which the serialized Trie2 data will be written.</param>
        /// <returns>The number of bytes written.</returns>
        /// <exception cref="IOException">On an error writing to the <see cref="Stream"/>.</exception>
        public int Serialize(Stream os)
        {
            DataOutputStream dos = new DataOutputStream(os);
            int bytesWritten     = 0;

            bytesWritten += SerializeHeader(dos);
            for (int i = 0; i < dataLength; i++)
            {
                dos.WriteChar(index[data16 + i]);
            }
            bytesWritten += dataLength * 2;
            return(bytesWritten);
        }
Пример #4
0
        /// <summary>
        /// Serializes the build table to an output stream.
        /// <para/>
        /// Compacts the build-time trie after all values are set, and then
        /// writes the serialized form onto an output stream.
        /// <para/>
        /// After this, this build-time Trie can only be serialized again and/or closed;
        /// no further values can be added.
        /// <para/>
        /// This function is the rough equivalent of utrie_seriaize() in ICU4C.
        /// </summary>
        /// <param name="os">The output stream to which the seriaized trie will be written.
        /// If nul, the function still returns the size of the serialized Trie.</param>
        /// <param name="reduceTo16Bits">If true, reduce the data size to 16 bits.  The resulting
        /// serialized form can then be used to create a <see cref="CharTrie"/>.</param>
        /// <param name="datamanipulate">Builder raw fold method implementation.</param>
        /// <returns>The number of bytes written to the output stream.</returns>
        public virtual int Serialize(Stream os, bool reduceTo16Bits,
                                     ITrieBuilderDataManipulate datamanipulate)
        {
            if (datamanipulate == null)
            {
                throw new ArgumentException("Parameters can not be null");
            }

            // fold and compact if necessary, also checks that indexLength is
            // within limits
            if (!m_isCompacted_)
            {
                // compact once without overlap to improve folding
                Compact(false);
                // fold the supplementary part of the index array
                Fold(datamanipulate);
                // compact again with overlap for minimum data array length
                Compact(true);
                m_isCompacted_ = true;
            }

            // is dataLength within limits?
            int length;

            if (reduceTo16Bits)
            {
                length = m_dataLength_ + m_indexLength_;
            }
            else
            {
                length = m_dataLength_;
            }
            if (length >= MaxDataLength)
            {
                throw new IndexOutOfRangeException("Data length too small");
            }

            //  struct UTrieHeader {
            //      int32_t   signature;
            //      int32_t   options  (a bit field)
            //      int32_t   indexLength
            //      int32_t   dataLength
            length = Trie.HeaderLength + 2 * m_indexLength_;
            if (reduceTo16Bits)
            {
                length += 2 * m_dataLength_;
            }
            else
            {
                length += 4 * m_dataLength_;
            }

            if (os == null)
            {
                // No output stream.  Just return the length of the serialized Trie, in bytes.
                return(length);
            }

            DataOutputStream dos = new DataOutputStream(os);

            dos.WriteInt32(Trie.HeaderSignature);

            int options = Trie.IndexStage1Shift | (Trie.IndexStage2Shift << Trie.HeaderOptionsIndexShift);

            if (!reduceTo16Bits)
            {
                options |= Trie.HeaderOptionsDataIs32Bit;
            }
            if (m_isLatin1Linear_)
            {
                options |= Trie.HeaderOptionsLatin1IsLinearMask;
            }
            dos.WriteInt32(options);

            dos.WriteInt32(m_indexLength_);
            dos.WriteInt32(m_dataLength_);

            /* write the index (stage 1) array and the 16/32-bit data (stage 2) array */
            if (reduceTo16Bits)
            {
                /* write 16-bit index values shifted right by UTRIE_INDEX_SHIFT, after adding indexLength */
                for (int i = 0; i < m_indexLength_; i++)
                {
                    int v = (m_index_[i] + m_indexLength_).TripleShift(Trie.IndexStage2Shift);
                    dos.WriteChar(v);
                }

                /* write 16-bit data values */
                for (int i = 0; i < m_dataLength_; i++)
                {
                    int v = m_data_[i] & 0x0000ffff;
                    dos.WriteChar(v);
                }
            }
            else
            {
                /* write 16-bit index values shifted right by UTRIE_INDEX_SHIFT */
                for (int i = 0; i < m_indexLength_; i++)
                {
                    int v = (m_index_[i]).TripleShift(Trie.IndexStage2Shift);
                    dos.WriteChar(v);
                }

                /* write 32-bit data values */
                for (int i = 0; i < m_dataLength_; i++)
                {
                    dos.WriteInt32(m_data_[i]);
                }
            }

            return(length);
        }
Пример #5
0
        /// <summary>
        /// Serializes the build table to an output stream.
        /// Compacts the build-time trie after all values are set, and then writes
        /// the serialized form onto an output stream.
        /// After this, this build-time Trie can only be serialized again and/or
        /// closed; no further values can be added.
        /// This function is the rough equivalent of utrie_seriaize() in ICU4C.
        /// </summary>
        ///
        /// <param name="os">the output stream to which the seriaized trie will be written.If nul, the function still returns the size of the serializedTrie.</param>
        /// <param name="reduceTo16Bits">If true, reduce the data size to 16 bits. The resultingserialized form can then be used to create a CharTrie.</param>
        /// <param name="datamanipulate">builder raw fold method implementation</param>
        /// <returns>the number of bytes written to the output stream.</returns>
        public int Serialize(Stream os, bool reduceTo16Bits,
                             TrieBuilder.DataManipulate datamanipulate)
        {
            if (datamanipulate == null)
            {
                throw new ArgumentException("Parameters can not be null");
            }

            // fold and compact if necessary, also checks that indexLength is
            // within limits
            if (!m_isCompacted_)
            {
                // compact once without overlap to improve folding
                Compact(false);
                // fold the supplementary part of the index array
                Fold(datamanipulate);
                // compact again with overlap for minimum data array length
                Compact(true);
                m_isCompacted_ = true;
            }

            // is dataLength within limits?
            int length;

            if (reduceTo16Bits)
            {
                length = m_dataLength_ + m_indexLength_;
            }
            else
            {
                length = m_dataLength_;
            }
            if (length >= IBM.ICU.Impl.TrieBuilder.MAX_DATA_LENGTH_)
            {
                throw new IndexOutOfRangeException("Data length too small".ToString());
            }

            // struct UTrieHeader {
            // int32_t signature;
            // int32_t options (a bit field)
            // int32_t indexLength
            // int32_t dataLength
            length = IBM.ICU.Impl.Trie.HEADER_LENGTH_ + 2 * m_indexLength_;
            if (reduceTo16Bits)
            {
                length += 2 * m_dataLength_;
            }
            else
            {
                length += 4 * m_dataLength_;
            }

            if (os == null)
            {
                // No output stream. Just return the length of the serialized Trie,
                // in bytes.
                return(length);
            }

            DataOutputStream dos = new DataOutputStream(os);

            dos.WriteInt(IBM.ICU.Impl.Trie.HEADER_SIGNATURE_);

            int options = IBM.ICU.Impl.Trie.INDEX_STAGE_1_SHIFT_
                          | (IBM.ICU.Impl.Trie.INDEX_STAGE_2_SHIFT_ << IBM.ICU.Impl.Trie.HEADER_OPTIONS_INDEX_SHIFT_);

            if (!reduceTo16Bits)
            {
                options |= IBM.ICU.Impl.Trie.HEADER_OPTIONS_DATA_IS_32_BIT_;
            }
            if (m_isLatin1Linear_)
            {
                options |= IBM.ICU.Impl.Trie.HEADER_OPTIONS_LATIN1_IS_LINEAR_MASK_;
            }
            dos.WriteInt(options);

            dos.WriteInt(m_indexLength_);
            dos.WriteInt(m_dataLength_);

            /*
             * write the index (stage 1) array and the 16/32-bit data (stage 2)
             * array
             */
            if (reduceTo16Bits)
            {
                /*
                 * write 16-bit index values shifted right by UTRIE_INDEX_SHIFT,
                 * after adding indexLength
                 */
                for (int i = 0; i < m_indexLength_; i++)
                {
                    int v = (int)(((uint)(m_index_[i] + m_indexLength_)) >> IBM.ICU.Impl.Trie.INDEX_STAGE_2_SHIFT_);
                    dos.WriteChar((char)v);
                }

                /* write 16-bit data values */
                for (int i_0 = 0; i_0 < m_dataLength_; i_0++)
                {
                    int v_1 = m_data_[i_0] & 0x0000ffff;
                    dos.WriteChar((char)v_1);
                }
            }
            else
            {
                /* write 16-bit index values shifted right by UTRIE_INDEX_SHIFT */
                for (int i_2 = 0; i_2 < m_indexLength_; i_2++)
                {
                    int v_3 = (int)(((uint)(m_index_[i_2])) >> IBM.ICU.Impl.Trie.INDEX_STAGE_2_SHIFT_);
                    dos.WriteChar((char)v_3);
                }

                /* write 32-bit data values */
                for (int i_4 = 0; i_4 < m_dataLength_; i_4++)
                {
                    dos.WriteInt(m_data_[i_4]);
                }
            }

            return(length);
        }
            public void Run()
            {
                // Create a DataInputStream for communication; the client is using a DataOutputStream to write to us.
                var dInStream = new DataInputStream(socket.InputStream);
                // We'll also want a DataOutputStream, very briefly, to send our ACK character.
                var  dOutStream = new DataOutputStream(socket.OutputStream);
                bool Handled;

                while (!StopToken.IsCancellationRequested)
                {
                    Handled = false;

                    // Get the next message
                    try
                    {
                        var data = ReadString(dInStream).Split(onNEXT, 3);
                        if (data.Length != 3)
                        {
                            Log.Debug(_tag, $"Data has <3 entries; [0] is {data.ElementAtOrDefault(0)}, [1] is {data.ElementAtOrDefault(1)}, [2] is {data.ElementAtOrDefault(2)}");
                        }
                        var address = data.ElementAtOrDefault(0);
                        var sender  = data.ElementAtOrDefault(1);
                        var message = data.ElementAtOrDefault(2);

                        // If it's not for me, ignore it.  Shouldn't happen in current code anyway.
                        if (!address.IsOneOf(WiFiMessageReceiver.MyIPaddress, ALL))
                        {
                            Log.Debug(_tag, $"Received \"{message}\" addressed to {address} (I'm {WiFiMessageReceiver.MyIPaddress}); ignoring it, but you should look into how it happened.");
                            continue;
                        }

                        dOutStream.WriteChar(ACKchar);

                        //if (server.DoACK && !message.StartsWith(ACK))
                        //    server.ForwardTo(sender, "Server", $"{ACK}: relaying [{message}] from {sender}.");

                        // Now handle the message contents
                        if (message.StartsWith($"{INTRODUCING}{NEXT}"))
                        {
                            var newTeammate = TeamMember.FromIntroductionString(message);
                            Log.Debug(_tag, $"Received introduction from {newTeammate.IPaddress}, giving their name ({newTeammate.Name}) and roles {newTeammate.Roles.Join()}.  Adding to address book.");
                            AddressBook.Add(newTeammate);
                        }
                        // If it doesn't fall into one of our special cases, handle it as a normal message.
                        else
                        {
                            server.OnMessageReceived.Raise(new Message()
                            {
                                From    = sender,
                                To      = address,
                                Content = message
                            });
                            //if (DoACK) SendMessage(sender, $"{ACK}: received [{message}] from {sender}.");
                        }
                    }
                    catch (Java.IO.EOFException e)
                    {
                        Log.Debug(_tag, $"EOFException: {e.Message} ({e}).  Logging & rethrowing.");
                        throw e;
                        //Log.Debug(_tag, $"EOFException: {e.Message} ({e}).  Trying to reopen stream.");
                        //dInStream.Dispose();
                        //dInStream = new DataInputStream(socket.InputStream);
                        //Handled = true;
                        //continue;
                    }
                    catch (Exception e)
                    {
                        if (e.InnerException != null && e.InnerException is Java.IO.EOFException)
                        {
                            Log.Debug(_tag, $"Wrapped EOFException: {e}.  Logging & rethrowing.  Status of socket is: IsInputShutdown? {socket.IsInputShutdown}. KeepAlive? {socket.KeepAlive}. Linger? {socket.SoLinger}.  Timeout? {socket.SoTimeout}. ReuseAddress? {socket.ReuseAddress}. Channel? {socket.Channel}.");
                            throw e.InnerException;
                            //Log.Debug(_tag, $"Wrapped EOFException: {e}.  Trying to reopen stream.  Status of socket is: IsInputShutdown? {socket.IsInputShutdown}. KeepAlive? {socket.KeepAlive}. Linger? {socket.SoLinger}.  Timeout? {socket.SoTimeout}. ReuseAddress? {socket.ReuseAddress}. Channel? {socket.Channel}.");
                            //dInStream.Dispose();
                            //dInStream = new DataInputStream(socket.InputStream);
                            ////Handled = true;
                            //continue;
                        }
                        else
                        {
                            //Handled = false;
                            throw e;
                        }
                    }
                    finally
                    {
                        if (!Handled)
                        {
                            Log.Debug(_tag, $"ServerThread to {socket.InetAddress.CanonicalHostName} self-disrupted.");
                            Stop();
                        }
                    }
                }
            }