/// <summary>
        /// Stores data to cache.
        ///
        /// If data does not already exist for this key on the server, or if the key is being
        /// deleted, the specified value will not be stored.
        /// The server will automatically delete the value when the expiration time has been reached.
        ///
        /// If compression is enabled, and the data is longer than the compression threshold
        /// the data will be stored in compressed form.
        ///
        /// As of the current release, all objects stored will use .NET serialization.
        /// </summary>
        /// <param name="cmdname">action to take (set, add, replace)</param>
        /// <param name="key">key to store cache under</param>
        /// <param name="obj">object to cache</param>
        /// <param name="expiry">expiration</param>
        /// <param name="hashCode">if not null, then the int hashcode to use</param>
        /// <param name="asString">store this object as a string?</param>
        /// <returns>true/false indicating success</returns>
        private bool Set(string cmdname, string key, object obj, DateTime expiry, object hashCode, bool asString)
        {
            if (expiry < DateTime.Now)
            {
                return(true);
            }

            if (cmdname == null || cmdname.Trim().Length == 0 || string.IsNullOrEmpty(key))
            {
                return(false);
            }
            key = Prefix + key;

            // get SockIO obj
            SockIO sock = SockIOPool.GetInstance(_poolName).GetSock(key, hashCode);

            if (sock == null)
            {
                return(false);
            }

            if (expiry == DateTime.MaxValue)
            {
                expiry = new DateTime(0);
            }

            // store flags
            int flags = 0;

            // byte array to hold data
            byte[] val;
            int    length = 0;

            // useful for sharing data between .NET and non-.NET
            // and also for storing ints for the increment method
            if (NativeHandler.IsHandled(obj))
            {
                if (asString)
                {
                    if (obj != null)
                    {
                        try
                        {
                            val    = Encoding.UTF8.GetBytes(obj.ToString());
                            length = val.Length;
                        }
                        catch
                        {
                            sock.Close();
                            sock = null;
                            return(false);
                        }
                    }
                    else
                    {
                        val    = new byte[0];
                        length = 0;
                    }
                }
                else
                {
                    try
                    {
                        val    = NativeHandler.Encode(obj);
                        length = val.Length;
                    }
                    catch
                    {
                        sock.Close();
                        sock = null;
                        return(false);
                    }
                }
            }
            else
            {
                if (obj != null)
                {
                    // always serialize for non-primitive types
                    try
                    {
                        var memStream = new MemoryStream();
                        new BinaryFormatter().Serialize(memStream, obj);
                        val    = memStream.GetBuffer();
                        length = (int)memStream.Length;
                        flags |= F_SERIALIZED;
                    }
                    catch
                    {
                        // return socket to pool and bail
                        sock.Close();
                        sock = null;
                        return(false);
                    }
                }
                else
                {
                    val    = new byte[0];
                    length = 0;
                }
            }

            // now try to compress if we want to
            // and if the length is over the threshold
            if (_compressEnable && length > _compressThreshold)
            {
                MemoryStream memoryStream = null;
                GZipStream   gos          = null;
                try
                {
                    memoryStream = new MemoryStream();
                    gos          = new GZipStream(memoryStream, CompressionMode.Compress);
                    gos.Write(val, 0, length);
                    gos.Flush();

                    // store it and set compression flag
                    val    = memoryStream.GetBuffer();
                    length = (int)memoryStream.Length;
                    flags |= F_COMPRESSED;
                }
                finally
                {
                    if (memoryStream != null)
                    {
                        memoryStream.Close();
                        memoryStream.Dispose();
                    }
                    if (gos != null)
                    {
                        gos.Close();
                        gos.Dispose();
                    }
                }
            }

            // now write the data to the cache server
            try
            {
                string cmd = cmdname + " " + key + " " + flags + " "
                             + GetExpirationTime(expiry) + " " + length + "\r\n";
                sock.Write(Encoding.UTF8.GetBytes(cmd));
                sock.Write(val, 0, length);
                sock.Write(Encoding.UTF8.GetBytes("\r\n"));
                sock.Flush();

                // get result code
                string line = sock.ReadLine();

                if (STORED == line)
                {
                    sock.Close();
                    sock = null;
                    return(true);
                }
            }
            catch
            {
                try
                {
                    if (sock != null)
                    {
                        sock.TrueClose();
                    }
                }
                finally
                {
                    sock = null;
                }
            }

            if (sock != null)
            {
                sock.Close();
            }

            return(false);
        }
        /// <summary>
        /// This method loads the data from cache into a Hashtable.
        ///
        /// Pass a SockIO object which is ready to receive data and a Hashtable
        /// to store the results.
        /// </summary>
        /// <param name="sock">socket waiting to pass back data</param>
        /// <param name="hm">hashmap to store data into</param>
        /// <param name="asString">if true, and if we are using NativehHandler, return string val</param>
        private void LoadItems(SockIO sock, Hashtable hm, bool asString)
        {
            while (true)
            {
                string line = sock.ReadLine();

                if (line.StartsWith(VALUE))
                {
                    string[] info   = line.Split(' ');
                    string   key    = info[1];
                    int      flag   = int.Parse(info[2], new NumberFormatInfo());
                    int      length = int.Parse(info[3], new NumberFormatInfo());

                    // read obj into buffer
                    byte[] buf = new byte[length];
                    sock.Read(buf);
                    sock.ClearEndOfLine();

                    // ready object
                    object o = null;

                    // check for compression
                    if ((flag & F_COMPRESSED) != 0)
                    {
                        MemoryStream mem = null;
                        GZipStream   gzi = null;
                        try
                        {
                            // read the input stream, and write to a byte array output stream since
                            // we have to read into a byte array, but we don't know how large it
                            // will need to be, and we don't want to resize it a bunch
                            mem = new MemoryStream(buf.Length);
                            gzi = new GZipStream(new MemoryStream(buf), CompressionMode.Compress);

                            int count;
                            var tmp = new byte[2048];
                            while ((count = gzi.Read(tmp, 0, tmp.Length)) > 0)
                            {
                                mem.Write(tmp, 0, count);
                            }

                            // store uncompressed back to buffer
                            buf = mem.ToArray();
                        }
                        finally
                        {
                            if (mem != null)
                            {
                                mem.Close();
                                mem.Dispose();
                            }
                            if (gzi != null)
                            {
                                gzi.Close();
                                gzi.Dispose();
                            }
                        }
                    }

                    // we can only take out serialized objects
                    if ((flag & F_SERIALIZED) == 0)
                    {
                        if (_primitiveAsString || asString)
                        {
                            o = Encoding.GetEncoding(_defaultEncoding).GetString(buf);
                        }
                        else
                        {
                            // decoding object
                            try
                            {
                                o = NativeHandler.Decode(buf);
                            }
                            catch (Exception e)
                            {
                                return;
                            }
                        }
                    }
                    else
                    {
                        // deserialize if the data is serialized
                        MemoryStream memStream = null;
                        try
                        {
                            memStream = new MemoryStream(buf);
                            o         = new BinaryFormatter().Deserialize(memStream);
                        }
                        catch (SerializationException e)
                        {
                        }
                        finally
                        {
                            if (memStream != null)
                            {
                                memStream.Close();
                                memStream.Dispose();
                            }
                        }
                    }

                    // store the object into the cache
                    hm[key] = o;
                }
                else if (END == line)
                {
                    break;
                }
            }
        }