1 #include "RLECompressor.h"
2 #include "ace/OS_NS_string.h"
4 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
6 ACE_RLECompressor::ACE_RLECompressor()
7 : ACE_Compressor(ACE_COMPRESSORID_RLE
)
11 // Compress using Run Length Encoding (RLE)
13 ACE_RLECompressor::compress(const void *in_ptr
,
16 ACE_UINT64 max_out_len
)
18 const ACE_Byte
*in_p
= static_cast<const ACE_Byte
*>(in_ptr
);
19 ACE_Byte
*out_p
= static_cast<ACE_Byte
*>(out_ptr
);
21 ACE_UINT64 src_len
= in_len
; // Save for stats
22 ACE_UINT64 out_index
= 0;
23 ACE_UINT64 out_base
= 0;
25 bool run_code
= false;
27 if (in_p
&& out_p
&& in_len
) {
28 while (in_len
-- > 0) {
29 ACE_Byte cur_byte
= *in_p
++;
31 switch (out_index
? run_count
: 128U) { // BootStrap to 128
35 if ((out_base
= out_index
++) >= max_out_len
) {
36 return ACE_UINT64(-1); // Output Exhausted
39 run_count
= 0; // Switch off compressing
45 // Fix problem where input exhaused but maybe compressing
46 if (in_len
? cur_byte
== *in_p
: run_code
) {
47 if (run_code
) { // In Compression?
48 out_p
[out_base
] = ACE_Byte(run_count
++ | 0x80);
49 continue; // Stay in Compression
50 } else if (run_count
) { // Xfering to Compression
51 if ((out_base
= out_index
++) >= max_out_len
) {
52 return ACE_UINT64(-1); // Output Exhausted
56 run_code
= true; // We Are Now Compressing
58 } else if (run_code
) { // Are we in Compression?
59 // Finalise the Compression Run Length
60 out_p
[out_base
] = ACE_Byte(run_count
| 0x80);
61 // Reset for Uncmpressed
62 if (in_len
&& (out_base
= out_index
++) >= max_out_len
) {
63 return ACE_UINT64(-1); // Output Exhausted
67 continue; // Now restart Uncompressed
73 out_p
[out_base
] = ACE_Byte(run_count
++ | (run_code
? 0x80 : 0));
75 if (out_index
>= max_out_len
) {
76 return ACE_UINT64(-1); // Output Exhausted
78 out_p
[out_index
++] = cur_byte
;
80 this->update_stats(src_len
, out_index
);
83 return out_index
; // return as our output length
86 // Decompress using Run Length Encoding (RLE)
88 ACE_RLECompressor::decompress(const void *in_ptr
,
91 ACE_UINT64 max_out_len
)
93 ACE_UINT64 out_len
= 0;
95 const ACE_Byte
*in_p
= static_cast<const ACE_Byte
*>(in_ptr
);
96 ACE_Byte
*out_p
= static_cast<ACE_Byte
*>(out_ptr
);
98 if (in_p
&& out_p
) while(in_len
-- > 0) {
99 ACE_Byte cur_byte
= *in_p
++;
100 ACE_UINT32 cpy_len
= ACE_UINT32((cur_byte
& ACE_CHAR_MAX
) + 1);
102 if (cpy_len
> max_out_len
) {
103 return ACE_UINT64(-1); // Output Exhausted
104 } else if ((cur_byte
& 0x80) != 0) { // compressed
106 ACE_OS::memset(out_p
, *in_p
++, cpy_len
);
108 return ACE_UINT64(-1); // Output Exhausted
110 } else if (in_len
>= cpy_len
) {
111 ACE_OS::memcpy(out_p
, in_p
, cpy_len
);
115 return ACE_UINT64(-1); // Output Exhausted
119 max_out_len
-= cpy_len
;
126 ACE_SINGLETON_TEMPLATE_INSTANTIATE(ACE_Singleton
, ACE_RLECompressor
, ACE_SYNCH_MUTEX
);
128 // Close versioned namespace, if enabled by the user.
129 ACE_END_VERSIONED_NAMESPACE_DECL