2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
6 // Any parts of this program derived from the xMule, lMule or eMule project,
7 // or contributed by third-party developers are copyrighted by their
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "ArchSpecific.h"
30 * RLE encoder implementation. This is RLE implementation for very specific
31 * purpose: encode DIFFERENCE between subsequent states of status bar.
33 * This difference is calculated by xor-ing with previous data
35 * We can't use implementation with "control char" since this encoder
36 * will process binary data - not ascii (or unicode) strings
38 void RLE_Data::setup(int len
, bool use_diff
, unsigned char * content
)
41 m_use_diff
= use_diff
;
44 m_buff
= new unsigned char[m_len
];
46 memcpy(m_buff
, content
, m_len
);
48 memset(m_buff
, 0, m_len
);
51 // in worst case 2-byte sequence encoded as 3. So, data can grow at 1/3
52 m_enc_buff
= new unsigned char[m_len
*4/3 + 1];
54 m_buff
= m_enc_buff
= 0;
58 RLE_Data
&RLE_Data::operator=(const RLE_Data
&obj
)
65 setup(obj
.m_len
, obj
.m_use_diff
, obj
.m_buff
);
76 void RLE_Data::Realloc(int size
)
78 if ( size
== m_len
) {
82 unsigned char *buff
= new unsigned char[size
];
84 memset(buff
+ m_len
, 0, size
- m_len
);
85 memcpy(buff
, m_buff
, m_len
);
87 memcpy(buff
, m_buff
, size
);
92 buff
= new unsigned char[size
*4/3 + 1];
94 memset(buff
+ m_len
*4/3 + 1, 0, (size
- m_len
)*4/3);
95 memcpy(buff
, m_enc_buff
, m_len
*4/3 + 1);
97 memcpy(buff
, m_enc_buff
, size
*4/3 + 1);
105 const unsigned char *RLE_Data::Decode(const unsigned char *buff
, int len
)
112 while ( j
!= m_len
) {
114 if ( i
< (len
-1) ) {
115 if (buff
[i
+1] == buff
[i
]) {
117 memset(m_enc_buff
+ j
, buff
[i
], buff
[i
+ 2]);
121 // this is single byte
122 m_enc_buff
[j
++] = buff
[i
++];
125 // only 1 byte left in encoded data - it can't be sequence
126 m_enc_buff
[j
++] = buff
[i
++];
127 // if there's no more data, but buffer end is not reached,
128 // it must be error in some point
130 printf("RLE_Data: decoding error. %d bytes decoded to %d instead of %d\n", len
, j
, m_len
);
136 // Recreate data from diff
139 for (int k
= 0; k
< m_len
; k
++) {
140 m_buff
[k
] ^= m_enc_buff
[k
];
147 void PartFileEncoderData::Decode(unsigned char *gapdata
, int gaplen
, unsigned char *partdata
, int partlen
)
149 m_part_status
.Decode(partdata
, partlen
);
151 // in a first dword - real size
152 uint32 gapsize
= ENDIAN_NTOHL( RawPeekUInt32( gapdata
) );
153 gapdata
+= sizeof(uint32
);
154 m_gap_status
.Realloc(gapsize
*2*sizeof(uint64
));
156 m_gap_status
.Decode(gapdata
, gaplen
- sizeof(uint32
));
159 unsigned char RLE_Data_BV::m_buff
[256];
161 RLE_Data_BV::RLE_Data_BV(int len
) : m_last_buff(len
)
165 int RLE_Data_BV::Encode(std::vector
<bool> &data
)
167 unsigned char *curr
= m_buff
;
168 std::vector
<bool>::const_iterator i
= data
.begin();
169 std::vector
<bool>::const_iterator j
= m_last_buff
.begin();
170 while( i
!= data
.end() ) {
171 unsigned char count
= 0;
172 while ( (i
!= data
.end()) && ( (*i
^ *j
) == false) ) {
183 // File_checked_for_headers