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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
// $Id$
#include "RLECompressor.h"
#include "ace/OS_NS_string.h"
#if defined (__BORLANDC__) && (__BORLANDC__ >= 0x660) && (__BORLANDC__ <= 0x680)
# pragma option push -w-8072
#endif
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_RLECompressor::ACE_RLECompressor(void)
: ACE_Compressor(ACE_COMPRESSORID_RLE)
{
}
ACE_RLECompressor::~ACE_RLECompressor(void)
{
}
// Compress using Run Length Encoding (RLE)
ACE_UINT64
ACE_RLECompressor::compress( const void *in_ptr,
ACE_UINT64 in_len,
void *out_ptr,
ACE_UINT64 max_out_len )
{
const ACE_Byte *in_p = static_cast<const ACE_Byte *>(in_ptr);
ACE_Byte *out_p = static_cast<ACE_Byte *>(out_ptr);
ACE_UINT64 src_len = in_len; // Save for stats
ACE_UINT64 out_index = 0;
ACE_UINT64 out_base = 0;
size_t run_count = 0;
bool run_code = false;
if (in_p && out_p && in_len) {
while (in_len-- > 0) {
ACE_Byte cur_byte = *in_p++;
switch (out_index ? run_count : 128U) { // BootStrap to 128
case 128:
if ((out_base = out_index++) >= max_out_len) {
return ACE_UINT64(-1); // Output Exhausted
}
run_code = false;
run_count = 0; // Switch off compressing
// Fall Through
default:
// Fix problem where input exhaused but maybe compressing
if (in_len ? cur_byte == *in_p : run_code) {
if (run_code) { // In Compression?
out_p[out_base] = ACE_Byte(run_count++ | 0x80);
continue; // Stay in Compression
} else if (run_count) { // Xfering to Compression
if ((out_base = out_index++) >= max_out_len) {
return ACE_UINT64(-1); // Output Exhausted
}
run_count = 0;
}
run_code = true; // We Are Now Compressing
} else if (run_code) { // Are we in Compression?
// Finalise the Compression Run Length
out_p[out_base] = ACE_Byte(run_count | 0x80);
// Reset for Uncmpressed
if (in_len && (out_base = out_index++) >= max_out_len) {
return ACE_UINT64(-1); // Output Exhausted
}
run_code = false;
run_count = 0;
continue; // Now restart Uncompressed
}
break;
}
out_p[out_base] = ACE_Byte(run_count++ | (run_code ? 0x80 : 0));
if (out_index >= max_out_len) {
return ACE_UINT64(-1); // Output Exhausted
}
out_p[out_index++] = cur_byte;
}
this->update_stats(src_len, out_index);
}
return out_index; // return as our output length
}
// Decompress using Run Length Encoding (RLE)
ACE_UINT64
ACE_RLECompressor::decompress( const void *in_ptr,
ACE_UINT64 in_len,
void *out_ptr,
ACE_UINT64 max_out_len )
{
ACE_UINT64 out_len = 0;
const ACE_Byte *in_p = static_cast<const ACE_Byte *>(in_ptr);
ACE_Byte *out_p = static_cast<ACE_Byte *>(out_ptr);
if (in_p && out_p) while(in_len-- > 0) {
ACE_Byte cur_byte = *in_p++;
ACE_UINT32 cpy_len = ACE_UINT32((cur_byte & ACE_CHAR_MAX) + 1);
if (cpy_len > max_out_len) {
return ACE_UINT64(-1); // Output Exhausted
} else if ((cur_byte & 0x80) != 0) { // compressed
if (in_len-- > 0) {
ACE_OS::memset(out_p, *in_p++, cpy_len);
} else {
return ACE_UINT64(-1); // Output Exhausted
}
} else if (in_len >= cpy_len) {
ACE_OS::memcpy(out_p, in_p, cpy_len);
in_p += cpy_len;
in_len -= cpy_len;
} else {
return ACE_UINT64(-1); // Output Exhausted
}
out_p += cpy_len;
max_out_len -= cpy_len;
out_len += cpy_len;
}
return out_len;
}
ACE_SINGLETON_TEMPLATE_INSTANTIATE(ACE_Singleton, ACE_RLECompressor, ACE_SYNCH_MUTEX);
// Close versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__BORLANDC__) && (__BORLANDC__ >= 0x660) && (__BORLANDC__ <= 0x680)
# pragma option pop
#endif
|