예제 #1
0
 /// <summary>
 /// 解压数组。解压的结果保存在流中。
 /// </summary>
 /// <param name="b">字节。</param>
 /// <param name="compressor">用来解压的流。</param>
 public static void CompressBuffer(byte[] b, Stream compressor)
 {
     Thrower.ThrowArgumentNullExceptionIf(compressor, "compressor");
     using (compressor) {
         compressor.Write(b, 0, b.Length);
     }
 }
예제 #2
0
 /// <summary>
 /// 添加命名参数。
 /// </summary>
 /// <param name="d">参数键/值的集合。</param>
 /// <exception cref="ArgumentNullException"><paramref name="d" /> 为空。</exception>
 public override void AddParameters(System.Collections.IDictionary d)
 {
     Thrower.ThrowArgumentNullExceptionIf(d, "d");
     foreach (string v in d)
     {
         _command.Parameters.AddWithValue(v, d[v]);
     }
 }
예제 #3
0
 /// <summary>
 /// 解压字符串。解压的结果保存在流中。
 /// </summary>
 /// <param name="value">字符串。</param>
 /// <param name="compressor">用来解压的流。</param>
 public static void CompressString(string value, Stream compressor)
 {
     Thrower.ThrowArgumentNullExceptionIf(compressor, "compressor");
     byte[] uncompressed = System.Text.Encoding.UTF8.GetBytes(value);
     using (compressor) {
         compressor.Write(uncompressed, 0, uncompressed.Length);
     }
 }
예제 #4
0
        /// <summary>
        /// 执行一个命令,统计条数。
        /// </summary>
        /// <param name="tableName">要统计的表名。</param>
        /// <returns>个数。</returns>
        /// <exception cref="InvalidOperationException">未设置执行的命令,无法继续。</exception>
        /// <exception cref="ArgumentNullException">必须指明 Table, 以确认正在操作的表。</exception>
        public override int ExecuteCount(string tableName)
        {
            Thrower.ThrowArgumentNullExceptionIf(tableName, "tableName", "表为空");
            Sql = "SELECT COUNT(*) FROM " + tableName;
            if (SqlCondition != null)
            {
                CommandText += " WHERE " + SqlCondition;
            }
            object s = ExecuteScalar();

            return(s == null ? -1 : (int)(long)s);
        }
예제 #5
0
 /// <summary>
 /// 使用指定的流, CompressionLevel 值和 CompressionMode 值以及一个指定是否将流保留为打开状态的值,初始化 <see cref="Py.Zip.Zlib.ZipBaseStream"/> 的新实例。
 /// </summary>
 /// <param name="stream">要解压或压缩缩的流。</param>
 /// <param name="compressionMode">指示当前操作是解压或压缩。</param>
 /// <param name="leaveOpen">true 将流保留为打开状态,否则为 false。</param>
 /// <param name="level">使用的解压等级。</param>
 /// <exception cref="ArgumentNullException"><paramref name="stream"/> 为 null。</exception>
 /// <exception cref="InvalidOperationException"><paramref name="stream"/> 访问权限为 ReadOnly,mode 值为 Compress。</exception>
 public ZipBaseStream(Stream stream, CompressionMode compressionMode, CompressionLevel level, bool leaveOpen)
     : base()
 {
     Thrower.ThrowArgumentNullExceptionIf(stream, "stream");
     Thrower.ThrowInvalidOperationExceptionIf(!stream.CanWrite && compressionMode == CompressionMode.Compress, "当前流不可写");
     _flushMode = FlushType.None;
     //_workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
     _stream          = stream;
     _leaveOpen       = leaveOpen;
     _compressionMode = compressionMode;
     _level           = level;
     _isGZip          = this is GZipStream;
 }
예제 #6
0
        /// <summary>
        /// 将若干压缩缩的字节读入指定的字节数组。
        /// </summary>
        /// <param name="buffer">用于存储压缩缩的字节的数组。</param>
        /// <param name="offset">数组中开始读取的位置。</param>
        /// <param name="count">读取的压缩缩字节数。</param>
        /// <returns>压缩缩到字节数组中的字节数。</returns>
        /// <remarks>
        ///     <para>
        /// 如果需要使用 <c>DeflateStream</c> 在读取时同步解压, 可以设置解压模式到 <c>CompressionMode.Compress</c>。然后使用 Read() 方法读取并解压。
        /// 如果需要使用 <c>DeflateStream</c> 在读取时同步压缩, 可以设置解压模式到 <c>CompressionMode.DeCompress</c>。然后使用 Read() 方法读取并解压。
        /// </para>
        ///     <para>
        /// 一个 <c>DeflateStream</c> 只能用于 <c>Read()</c> 或 <c>Write()</c>, 但不能同时读写。
        /// </para>
        /// </remarks>
        /// <exception cref="ZlibException">已经执行过 Write() 。</exception>
        /// <exception cref="T:System.ArgumentException">
        ///     <paramref name="offset"/> 与 <paramref name="count"/> 的和大于缓冲区长度。</exception>
        /// <exception cref="T:System.ArgumentNullException">
        ///     <paramref name="buffer"/> 为 null。</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException">
        ///     <paramref name="offset"/> 或 <paramref name="count"/> 为负。</exception>
        /// <exception cref="T:System.IO.IOException">发生 I/O 错误。</exception>
        /// <exception cref="T:System.NotSupportedException">流不支持读取。</exception>
        /// <exception cref="T:System.ObjectDisposedException">在流关闭后调用方法。</exception>
        public override int Read(byte[] buffer, int offset, int count)
        {
            // According to MS documentation, any implementation of the IO.Stream.Read function must:
            // (a) throw an exception if offset & count reference an invalid part of the buffer,
            //     or if count < 0, or if buffer is null
            // (b) return 0 only upon EOF, or if count = 0
            // (c) if not EOF, then return at least 1 byte, up to <count> bytes

            Thrower.CheckArgumentException(buffer, offset, count);
            Thrower.ThrowObjectDisposedExceptionIf(IsDisposed, TypeName);
            if (_streamMode == StreamMode.Undefined)
            {
                Thrower.ThrowNotSupportedExceptionIf(!_stream.CanRead, "流不支持读取。");

                _streamMode = StreamMode.Reader;

                ZlibCodec.AvailableBytesIn = 0;
            }

            ValidStreamMode(StreamMode.Reader);
            if (count == 0)
            {
                return(0);
            }
            if (_noMore && WantCompress)
            {
                return(0);
            }

            Thrower.ThrowArgumentNullExceptionIf(buffer, "buffer");
            Thrower.ThrowArgumentOutOfRangeExceptionIf(count <0 || (offset + count)> buffer.GetLength(0), "count");
            Thrower.ThrowArgumentOutOfRangeExceptionIf(offset < buffer.GetLowerBound(0), "offset");

            ZlibState rc;

            // set up the output of the deflate/inflate codec:
            _z.OutputBuffer      = buffer;
            _z.NextOut           = offset;
            _z.AvailableBytesOut = count;

            // This is necessary in case _workingBuffer has been resized. (new byte[])
            // (The first reference to _workingBuffer goes through the private accessor which
            // may initialize it.)
            _z.InputBuffer = WorkingBuffer;

            do
            {
                // need data in _workingBuffer in order to deflate/inflate.  Here, we check if we have any.
                if ((_z.AvailableBytesIn == 0) && (!_noMore))
                {
                    // No data available, so try to Read data from the captive stream.
                    _z.NextIn           = 0;
                    _z.AvailableBytesIn = _stream.Read(_workingBuffer, 0, _workingBuffer.Length);
                    if (_z.AvailableBytesIn == 0)
                    {
                        _noMore = true;
                    }
                }
                // we have data in InputBuffer; now compress or decompress as appropriate
                rc = (WantCompress)
                    ? _z.Deflate(_flushMode)
                    : _z.Inflate(_flushMode);

                if (_noMore && (rc == ZlibState.BufferError))
                {
                    return(0);
                }

                if (rc != ZlibState.Success && rc != ZlibState.StreamEnd)
                {
                    throw new ZlibException(Py.Core.Str.FormatX("{0}:  结果={1} 信息={2}", (WantCompress ? "压缩" : "解压"), rc, _z.Message));
                }

                if ((_noMore || rc == ZlibState.StreamEnd) && (_z.AvailableBytesOut == count))
                {
                    break; // nothing more to read
                }
            }  while (_z.AvailableBytesOut > 0 && !_noMore && rc == ZlibState.Success);


            // workitem 8557
            // is there more room in output?
            if (_z.AvailableBytesOut > 0)
            {
                if (rc == ZlibState.Success && _z.AvailableBytesIn == 0)
                {
                    // deferred
                }

                // are we completely done reading?
                if (_noMore)
                {
                    // and in compression?
                    if (WantCompress)
                    {
                        // no more input data available; therefore we flush to
                        // try to complete the read
                        rc = _z.Deflate(FlushType.Finish);

                        if (rc != ZlibState.Success && rc != ZlibState.StreamEnd)
                        {
                            throw new ZlibException(String.Format("压缩:   状态={0}  消息={1}", rc, _z.Message));
                        }
                    }
                }
            }


            return(count - _z.AvailableBytesOut);
        }
예제 #7
0
        /// <summary>
        /// 向当前流中写入字节序列,并将此流中的当前位置提升写入的字节数。
        /// </summary>
        /// <param name="buffer">字节数组。此方法将 <paramref name="count"/> 个字节从 <paramref name="buffer"/> 复制到当前流。</param>
        /// <param name="offset"><paramref name="buffer"/> 中的从零开始的字节偏移量,从此处开始将字节复制到当前流。</param>
        /// <param name="count">要写入当前流的字节数。</param>
        /// <exception cref="T:System.ArgumentException">
        ///     <paramref name="offset"/> 与 <paramref name="count"/> 的和大于缓冲区长度。</exception>
        /// <exception cref="T:System.ArgumentNullException">
        ///     <paramref name="buffer"/> 为 null。</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException">
        ///     <paramref name="offset"/> 或 <paramref name="count"/> 为负。</exception>
        /// <exception cref="T:System.IO.IOException">发生 I/O 错误。</exception>
        /// <exception cref="T:System.NotSupportedException">流不支持写入。</exception>
        /// <exception cref="T:System.ObjectDisposedException">在流关闭后调用方法。</exception>
        public override void Write(byte[] buffer, int offset, int count)
        {
            // Fill a work buffer; when full, flip state to 'Filled'

            Thrower.ThrowArgumentNullExceptionIf(buffer, "buffer");
            Thrower.ThrowInvalidOperationExceptionIf(_isClosed, "当前流已关闭");
            Thrower.ThrowArgumentOutOfRangeExceptionIf(count < 0, "count");
            Thrower.ThrowArgumentOutOfRangeExceptionIf(offset < 0, "offset");
            // dispense any exceptions that occurred on the BG threads
            if (_pendingException != null)
            {
                throw _pendingException;
            }

            if (count == 0)
            {
                return;
            }

            if (!_firstWriteDone)
            {
                // Want to do this on first Write, first session, and not in the
                // constructor.  We want to allow the BufferSize and BuffersPerCore to
                // change after construction, but before first Write.

                #region 初始化

                _pool = new System.Collections.Generic.List <WorkItem>();
                for (int i = 0; i < BuffersPerCore * Environment.ProcessorCount; i++)
                {
                    _pool.Add(new WorkItem(_bufferSize, _compressLevel, Strategy));
                }
                _pc = _pool.Count;

                for (int i = 0; i < _pc; i++)
                {
                    _pool[i].Index = i;
                }

                // set the pointers
                _nextToFill = _nextToWrite = 0;

                #endregion

                // Only do this once (ever), the first time Write() is called:
                if (!ThreadPool.QueueUserWorkItem(new WaitCallback(PerpetualWriterMethod)))
                {
                    throw new ThreadStateException("无法保存当前线程。");
                }

                // Release the writer thread.
#if Zip_Trace
                TraceOutput(TraceBits.Synch, "Synch    _sessionReset.Set()          Write (first)");
#endif
                _sessionReset.Set();

                _firstWriteDone = true;
            }


            do
            {
                int      ix       = _nextToFill % _pc;
                WorkItem workitem = _pool[ix];
                lock (workitem) {
#if Zip_Trace
                    TraceOutput(TraceBits.Fill,
                                "Fill     lock     wi({0}) stat({1}) iba({2}) nf({3})",
                                workitem.Index,
                                workitem.CurrentStatus,
                                workitem.InputBytesAvailable,
                                _nextToFill
                                );
#endif
                    // If the status is what we want, then use the workitem.
                    if (workitem.CurrentStatus == WorkItem.Status.None ||
                        workitem.CurrentStatus == WorkItem.Status.Done ||
                        workitem.CurrentStatus == WorkItem.Status.Filling)
                    {
                        workitem.CurrentStatus = WorkItem.Status.Filling;
                        int limit = ((workitem.Buffer.Length - workitem.InputBytesAvailable) > count)
                                                        ? count
                                                        : (workitem.Buffer.Length - workitem.InputBytesAvailable);

                        // copy from the provided buffer to our workitem, starting at
                        // the tail end of whatever data we might have in there currently.
                        Array.Copy(buffer, offset, workitem.Buffer, workitem.InputBytesAvailable, limit);

                        count  -= limit;
                        offset += limit;
                        workitem.InputBytesAvailable += limit;
                        if (workitem.InputBytesAvailable == workitem.Buffer.Length)
                        {
                            workitem.CurrentStatus = WorkItem.Status.Filled;
                            // No need for interlocked.increment: the Write() method
                            // is documented as not multi-thread safe, so we can assume Write()
                            // calls come in from only one thread.
                            _nextToFill++;
#if Zip_Trace
                            TraceOutput(TraceBits.Fill,
                                        "Fill     QUWI     wi({0}) stat({1}) iba({2}) nf({3})",
                                        workitem.Index,
                                        workitem.CurrentStatus,
                                        workitem.InputBytesAvailable,
                                        _nextToFill
                                        );
#endif
                            if (!ThreadPool.QueueUserWorkItem(DeflateOne, workitem))
                            {
                                throw new ThreadStateException("无法保存当前模块。");
                            }
                        }
                    }
                    else
                    {
                        int wcycles = 0;

                        while (workitem.CurrentStatus != WorkItem.Status.None &&
                               workitem.CurrentStatus != WorkItem.Status.Done &&
                               workitem.CurrentStatus != WorkItem.Status.Filling)
                        {
#if Zip_Trace
                            TraceOutput(TraceBits.Fill,
                                        "Fill     waiting  wi({0}) stat({1}) nf({2})",
                                        workitem.Index,
                                        workitem.CurrentStatus,
                                        _nextToFill);
#endif
                            wcycles++;

                            Monitor.Pulse(workitem);
                            Monitor.Wait(workitem);
#if Zip_Trace
                            if (workitem.CurrentStatus == WorkItem.Status.None ||
                                workitem.CurrentStatus == WorkItem.Status.Done ||
                                workitem.CurrentStatus == WorkItem.Status.Filling)
                            {
                                TraceOutput(TraceBits.Fill,
                                            "Fill     A-OK     wi({0}) stat({1}) iba({2}) cyc({3})",
                                            workitem.Index,
                                            workitem.CurrentStatus,
                                            workitem.InputBytesAvailable,
                                            wcycles);
                            }
#endif
                        }
                    }
                }
            }   while (count > 0);              // until no more to write

            return;
        }
예제 #8
0
 /// <summary>
 /// 使用已有的辅助类初始化 <see cref="Py.Sql.SqlHelper"/> 的新实例,新实例和参数使用同一个连接。
 /// </summary>
 /// <param name="helper">The helper。</param>
 /// <exception cref="ArgumentNullException"><paramref name="helper" /> 为空。</exception>
 /// <exception cref="ArgumentException">传递的辅助类和当前实例的类型不相同。</exception>
 public MySqlHelper(DbHelper helper)
 {
     Thrower.ThrowArgumentNullExceptionIf(helper, "helper");
     _connection = helper.Connection as MySqlConnection;
     Thrower.ThrowArgumentExceptionIf(_connection == null, "连接空");
 }
예제 #9
0
 /// <summary>
 /// 初始化 Play.Sql.DbHelper 类的新实例。
 /// </summary>
 /// <param name="command">已创建的命令的实例。</param>
 /// <exception cref="ArgumentNullException"><paramref name="command"/> 为空。</exception>
 public MySqlHelper(MySqlCommand command)
 {
     Thrower.ThrowArgumentNullExceptionIf(command, "command");
     _connection = command.Connection;
     _command    = command;
 }
예제 #10
0
 /// <summary>
 /// 初始化 Play.Sql.DbHelper 类的新实例。
 /// </summary>
 /// <param name="connection">已创建的连接的实例。</param>
 /// <exception cref="InvalidCastException">给的连接不符合当前类的标准。</exception>
 public MySqlHelper(MySqlConnection connection)
 {
     Thrower.ThrowArgumentNullExceptionIf(connection, "connection");
     _connection = connection;
     _command    = _connection.CreateCommand();
 }