/// <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); } }
/// <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]); } }
/// <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); } }
/// <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); }
/// <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; }
/// <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); }
/// <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; }
/// <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, "连接空"); }
/// <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; }
/// <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(); }