Skip to content

Instantly share code, notes, and snippets.

@kumagi
Created February 9, 2010 14:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kumagi/299262 to your computer and use it in GitHub Desktop.
Save kumagi/299262 to your computer and use it in GitHub Desktop.
Deviding tag
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <time.h>
class deviding_tag {
private:
unsigned int length;
unsigned char* data;
enum defaultsize{
BUFFSIZE = 8,
};
public:
deviding_tag(void):length(0),data(NULL){
}
~deviding_tag(){
if(data){
free(data);
}
}
bool isComplete(void) const{
for(int i=length-1;i>0;i--){
if(data[i] != 0)
return 0;
}
return data[0] == 1;
}
void dump(void) const {
unsigned int flag = 0;
for(int i=length-1;i>=0;i--){
if(flag == 1 || (data[i] != 0)){
fprintf(stderr,"%02x",data[i]);
flag = 1;
}
}
}
void setZero(void){
length = 0;
data = NULL;
}
void init(void){
length = BUFFSIZE;
data = (unsigned char*)malloc(length);
for(unsigned int i=length-1;i>0;--i){
data[i] = 0;
}
data[0] = 1;
}
void receive(const int socket){
read(socket,&length,sizeof(unsigned int));
if(data != NULL){
free(data);
}
data = (unsigned char*)malloc(length);
if(length > 0){
read(socket,data,length);
}
}
int Serialize(void* buff) const {
unsigned int* intptr = (unsigned int*)buff;
*intptr++ = length;
if(length > 0){
memcpy(&intptr,data,length);
}
return 4+length;
}
deviding_tag& operator=(deviding_tag& rhs){
assert(data == NULL && length == 0);
if(length < rhs.length){
if(data){
free(data);
}
data = (unsigned char*)malloc(rhs.length);
}else if(rhs.length < length ){
for(int i = length; i<rhs.length; i++){
data[i] = 0;
}
}
length = rhs.length;
for(int i=0;i < rhs.length;i++){
data[i] = rhs.data[i];
}
return *this;
}
deviding_tag& operator/=(deviding_tag& rhs){
assert(data == NULL && length == 0);
if(rhs.data[rhs.length-1]&(1<<7)){
rhs.length *= 2;
rhs.data = (unsigned char*)realloc(rhs.data,rhs.length);
for(int i = rhs.length/2;i<rhs.length;i++){
rhs.data[i] = 0;
}
}
unsigned int carry = 0,_carry;
for(int i = 0;i<rhs.length;++i){
if(carry == 0 && rhs.data[i] == 0) continue;
_carry = carry;
carry = rhs.data[i]>>7;
rhs.data[i] = (rhs.data[i]<<1) | _carry;
if(carry == 0) break;
}
return *this = rhs;
}
deviding_tag& operator+=(deviding_tag& rhs){
unsigned char carry = 0;
int shorter_length = length < rhs.length ? length : rhs.length;
for(int i = shorter_length-1; i>=0 ;i--){
if(rhs.data[i] == 0 && carry==0) continue;
unsigned char hit = data[i] & rhs.data[i];
if(hit == 0){
data[i] |= rhs.data[i];
unsigned char carryhit = data[i] & (carry<<7);
if(carryhit == 0){
data[i] |= carry<<7;
break;
}else{
while(1){
if(data[i] & carryhit){
data[i] ^= carryhit;
carryhit >>= 1;
continue;
}
if(carryhit == 0){
carry = 1;
break;
}
data[i] |= carryhit;
carry = 0;
break;
}
}
}else {
while(1){
if(data[i] & hit){// || rhs.data[i] & hit){
data[i] ^= hit;
hit >>= 1;
continue;
}
if(hit == 0){
carry = 1;
break;
}
data[i] |= hit;
carry = 0;
break;
}
}
}
return *this;
}
unsigned int size(void) const{
return sizeof(int) + length;
}
};
// -------------- test code ---------------
void swap(int* a,int* b){
int c = *a;
*a = *b;
*b = c;
}
#define MAX 40
int main(void){
deviding_tag tag[MAX];
tag[0].init();
assert(tag[0].isComplete());
for(int i=1;i<MAX;i++){
fprintf(stderr,"%d:",i);
tag[i] /= tag[0];
tag[i].dump();
fprintf(stderr,"\n");
}
printf("\n");
srand(time(NULL));
int *shuffled;
shuffled=(int*)malloc(MAX*4);
for(int i=0;i<MAX;++i)
shuffled[i] = i;
for(int i=1;i<MAX;++i)
swap(&shuffled[i],&shuffled[(rand()%(MAX-1))+1]);
for(int i=1;i<MAX;i++){
tag[0].dump();
fprintf(stderr," + ");
tag[i].dump();
fprintf(stderr," = ");
tag[0] += tag[i];
tag[0].dump();
fprintf(stderr,"\n");
}
assert(tag[0].isComplete());
fprintf(stderr,"assertion ok\n");
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment