forked from IronLanguages/ironpython3
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBZ2Compressor.cs
More file actions
93 lines (74 loc) · 3.13 KB
/
BZ2Compressor.cs
File metadata and controls
93 lines (74 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// Copyright 2012 Jeff Hardy
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using Ionic.BZip2;
using IronPython.Runtime;
using Microsoft.Scripting.Runtime;
using Microsoft.Scripting.Utils;
namespace IronPython.Modules.Bz2 {
public static partial class Bz2Module {
[PythonType]
public class BZ2Compressor {
public const string __doc__ =
@"BZ2Compressor([compresslevel=9]) -> compressor object
Create a new compressor object. This object may be used to compress
data sequentially. If you want to compress data in one shot, use the
compress() function instead. The compresslevel parameter, if given,
must be a number between 1 and 9.
";
private readonly int compresslevel;
private readonly MemoryStream output;
private readonly BZip2OutputStream bz2Output;
private long lastPosition = 0;
public BZ2Compressor(int compresslevel = DEFAULT_COMPRESSLEVEL) {
this.compresslevel = compresslevel;
this.output = new MemoryStream();
this.bz2Output = new BZip2OutputStream(this.output, compresslevel, true);
}
[Documentation(@"compress(data) -> bytes
Provide more data to the compressor object. It will return chunks of
compressed data whenever possible, or b'' otherwise.
When you've finished providing data
to compress, call the flush() method to finish the compression process,
and return what is left in the internal buffers.
")]
public Bytes compress([NotNone] IBufferProtocol data) {
using var buffer = data.GetBuffer();
byte[] bytes = buffer.AsUnsafeArray() ?? buffer.ToArray();
this.bz2Output.Write(bytes, 0, bytes.Length);
return Bytes.Make(this.GetLatestData());
}
[Documentation(@"flush() -> bytes
Finish the compression process and return what is left in internal buffers.
You must not use the compressor object after calling this method.
")]
public Bytes flush() {
this.bz2Output.Close();
return Bytes.Make(this.GetLatestData());
}
/// <summary>
/// Copy the latest data from the memory buffer.
///
/// This won't always contain data, because comrpessed data is only written after a block is filled.
/// </summary>
/// <returns></returns>
private byte[] GetLatestData() {
long newDataCount = this.output.Position - this.lastPosition;
byte[] result = new byte[newDataCount];
if (newDataCount > 0) {
Array.Copy(this.output.GetBuffer(), this.lastPosition, result, 0, newDataCount);
this.lastPosition = this.output.Position;
}
return result;
}
}
}
}