#ifndef BIT_WRITE_H_ #define BIT_WRITE_H_ #include <stdio.h> #include<iostream> #include <fstream> #include <stdlib.h> #include <string> #include <string.h> #include <cmath> #include <time.h> #include<algorithm> #include<queue> #include<vector> #include<cmath> #include <getopt.h> #include "print128.h" //given a bit number l(how does it save),should return a vector of numbers uint8_t *write_delta_s(int *in, uint8_t *out, uint8_t l, int numbers, int size) { uint64_t code = 0; int occupy = 0; int endbit = (l * numbers); int end = 0; int *tmpin = in; if (endbit % 8 == 0) { end = endbit / 8; } else { end = (int)endbit / 8 + 1; } uint8_t *last = out + end; uint64_t left_val = 0; while (out <= last) { while (occupy < 8) { if (tmpin >= in + size) { occupy = 8; break; } bool sign = 1; int tmpnum = tmpin[0]; if (tmpnum <= 0) { sign = 0; tmpnum = -tmpnum; } uint64_t value1 = ((tmpnum & ((1L << (l - 1)) - 1)) + (sign << (l - 1))); code += (value1 << occupy); occupy += l; tmpin++; } //end while while (occupy >= 8) { left_val = code >> 8; //std::cout<<code<<std::endl; code = code & ((1L << 8) - 1); occupy -= 8; out[0] = unsigned((uint8_t)code); code = left_val; //std::cout<<occupy<<" "<<left_val<<" "<<unsigned(out[0])<<std::endl; out++; } } return out; } uint8_t* write_delta(int *in,uint8_t* out, uint8_t l, int numbers){ uint64_t code =0; int occupy = 0; int endbit = (l*numbers); int end=0; int* tmpin =in; if(endbit%8==0){ end=endbit/8; } else{ end = (int)endbit/8+1; } uint8_t* last=out+end; uint64_t left_val = 0; while(out<=last){ while(occupy<8){ bool sign = 1; int tmpnum = tmpin[0]; if (tmpnum <= 0){ sign = 0; tmpnum=-tmpnum; } uint64_t value1= ((tmpnum & ((1L<<(l-1))-1)) + (sign<<(l-1))); code += (value1<<occupy); occupy += l; tmpin++; }//end while while(occupy>=8){ left_val = code >> 8; //std::cout<<code<<std::endl; code = code & ((1L<<8) - 1); occupy-=8; out[0]= unsigned((uint8_t)code); code = left_val; //std::cout<<occupy<<" "<<left_val<<" "<<unsigned(out[0])<<std::endl; out++; } } return out; } uint32_t* write_delta32(int *in,uint32_t* out, uint8_t l, int numbers){ uint64_t code =0; int occupy = 0; int endbit = (l*numbers); int end=0; int* tmpin =in; if(endbit%32==0){ end=endbit/32; } else{ end = (int)endbit/32+1; } uint32_t* last=out+end; uint64_t left_val = 0; while(out<=last){ while(occupy<32){ bool sign = 1; int tmpnum = tmpin[0]; if (tmpnum <= 0){ sign = 0; tmpnum=-tmpnum; } uint64_t value1= ((tmpnum & ((1L<<(l-1))-1)) + (sign<<(l-1))); code += (value1<<occupy); occupy += l; tmpin++; }//end while while(occupy>=32){ left_val = code >> 32; //std::cout<<code<<std::endl; code = code & ((1L<<32) - 1); occupy-=32; out[0]= (uint32_t)code; code = left_val; //std::cout<<occupy<<" "<<left_val<<" "<<unsigned(out[0])<<std::endl; out++; } } return out; } uint8_t * write_delta_T(int *in, uint8_t *out, uint8_t l, int numbers) { uint64_t code = 0; int occupy = 0; uint64_t endbit = (l * (uint64_t)numbers); uint32_t end = 0; int writeind = 0; int *tmpin = in; int readind = 0; if (endbit % 8 == 0) { end = endbit / 8; } else { end = endbit / 8 + 1; } uint8_t *last = out + end; uint64_t left_val = 0; while (out <= last) { while (occupy < 8) { if (tmpin >= in + numbers) { occupy = 8; break; } bool sign = 1; int tmpnum = tmpin[0]; if (tmpnum <= 0){ sign = 0; tmpnum=-tmpnum; } uint64_t value1 = (tmpnum & (((1UL) << (uint8_t)(l - 1)) - 1)) + (((uint64_t)sign) << (uint8_t)(l - 1)); code += (value1 << (uint8_t)occupy); occupy += l; tmpin++; readind++; } //end while while (occupy >= 8) { left_val = code >> (uint8_t)8; //std::cout<<code<<std::endl; code = code & ((1 << 8) - 1); uint8_t tmp_char = code; occupy -= 8; out[0] = tmp_char; code = left_val; //std::cout<< writeind<<std::endl; //std::cout<<occupy<<" "<<left_val<<" "<<unsigned(out[0])<<std::endl; out++; } } int pad = ceil((sizeof(uint32_t)*8 - l)/8); for (int i = 0; i < pad; i++) { out[0] = 0; out++; } return out; } template <typename T> uint8_t * write_delta_int_T(std::vector<T>& in,std::vector<bool>& signvec, uint8_t *out, uint8_t l, int numbers) { uint128_t code = 0; int occupy = 0; uint64_t endbit = (l * (uint64_t)numbers); uint64_t end = 0; int writeind = 0; int readind = 0; if (endbit % 8 == 0) { end = endbit / 8; } else { end = endbit / 8 + 1; } uint8_t *last = out + end; uint64_t left_val = 0; while (out <= last) { while (occupy < 8) { if (readind >= numbers) { occupy = 8; break; } T tmpnum = in[readind]; bool sign = signvec[readind]; T value1 = (tmpnum & (((T)1 << (uint8_t)(l - 1)) - 1)) + (((T)sign) << (uint8_t)(l - 1)); code += ((uint128_t)value1 << (uint8_t)occupy); occupy += l; readind++; } //end while while (occupy >= 8) { left_val = code >> (uint8_t)8; //std::cout<<code<<std::endl; code = code & ((1 << 8) - 1); uint8_t tmp_char = code; occupy -= 8; out[0] = tmp_char; code = left_val; //std::cout<< writeind<<std::endl; //std::cout<<occupy<<" "<<left_val<<" "<<unsigned(out[0])<<std::endl; out++; } } int pad = 8 - end % 8; for (int i = 0; i < pad; i++) { out[0] = 0; out++; } return out; } template <typename T> uint8_t * write_FOR_int_T(T *in, uint8_t *out, uint8_t l, int numbers) { uint128_t code = 0; int occupy = 0; uint64_t endbit = (l * (uint64_t)numbers); uint64_t end = 0; int writeind = 0; T *tmpin = in; int readind = 0; if (endbit % 8 == 0) { end = endbit / 8; } else { end = endbit / 8 + 1; } uint8_t *last = out + end; uint64_t left_val = 0; while (out <= last) { while (occupy < 8) { if (tmpin >= in + numbers) { occupy = 8; break; } T tmpnum = tmpin[0]; T value1 = (tmpnum & (((T)1 << l) - 1)); code += ((uint128_t)value1 << (uint8_t)occupy); occupy += l; tmpin++; readind++; } //end while while (occupy >= 8) { left_val = code >> (uint8_t)8; //std::cout<<code<<std::endl; code = code & ((1 << 8) - 1); uint8_t tmp_char = code; occupy -= 8; out[0] = tmp_char; code = left_val; //std::cout<< writeind<<std::endl; //std::cout<<occupy<<" "<<left_val<<" "<<unsigned(out[0])<<std::endl; out++; } } int pad = ceil((sizeof(uint32_t)*8 - l)/8); for (int i = 0; i < pad; i++) { out[0] = 0; out++; } return out; } uint8_t* write_delta_default(uint32_t *in,uint8_t* out, uint8_t l, int numbers){ for(int i=0;i<numbers;i++){ uint32_t code =in[i]; out[0]=code & ((1L<<8)-1); out++; out[0]=(code>>8) &((1L<<8)-1); out++; out[0]=(code>>16) &((1L<<8)-1); out++; out[0]=(code>>24) &((1L<<8)-1); out++; } return out; } uint8_t *write_string_delta_string(long_int *in, uint8_t *out, uint32_t l, int numbers) { long_int code = 0; int occupy = 0; uint64_t endbit = (l * numbers); int end = 0; long_int *tmpin = in; if (endbit % 8 == 0) { end = endbit / 8; } else { end = (int)endbit / 8 + 1; } uint8_t *last = out + end; long_int left_val = 0; while (out <= last) { while (occupy < 8) { if (tmpin >= in + numbers) { occupy = 8; break; } bool sign = 1; long_int tmpnum = tmpin[0]; if (tmpnum <= 0) { sign = 0; tmpnum = -tmpnum; } long_int value1 = ((tmpnum & (((long_int)1 << (l - 1)) - 1)) + ((long_int)sign << (l - 1))); //std::cout<<value1<<std::endl; code += (value1 << occupy); occupy += l; tmpin++; } //end while while (occupy >= 8) { left_val = code >> 8; //std::cout<<code<<std::endl; code = code & (((long_int)1 << 8) - 1); uint8_t tmp_char = code.convert_to<uint8_t>(); occupy -= 8; out[0] = tmp_char; code = left_val; //std::cout<<occupy<<" "<<left_val<<" "<<unsigned(out[0])<<std::endl; out++; } } return out; } uint8_t *write_string_delta_string_mpz(std::vector<mpz_t *> in, uint8_t *out, uint32_t l, int numbers) { mpz_t code; mpz_init(code); int occupy = 0; uint64_t endbit = (l * numbers); int end = 0; int idx = 0; if (endbit % 8 == 0) { end = endbit / 8; } else { end = (int)endbit / 8 + 1; } uint8_t *last = out + end; while (out <= last) { while (occupy < 8) { if (idx >= numbers) { occupy = 8; break; } bool sign = 1; // tmpnum = tmpin[0]; if (mpz_sgn(*in[idx]) <= 0) { sign = 0; mpz_neg(*in[idx], *in[idx]); } mpz_t value1; mpz_init(value1); // long_int value1 = ((tmpnum & ((1 << (l - 1)) - 1)) + (sign << (l - 1))); mpz_t tmp1; mpz_init(tmp1); mpz_t tmp2; mpz_init(tmp2); mpz_set_ui(tmp2, 1); mpz_mul_2exp(tmp2, tmp2, l - 1); mpz_sub_ui(tmp2, tmp2, 1); mpz_and(tmp1, *in[idx], tmp2); if (sign) { mpz_add(value1, tmp1, tmp2); mpz_add_ui(value1, value1, 1); } else { mpz_set(value1, tmp1); } mpz_mul_2exp(value1, value1, occupy); mpz_add(code, code, value1); occupy += l; idx++; } //end while while (occupy >= 8) { // left_val = code >> 8; mpz_t imm_256; mpz_init(imm_256); mpz_set_ui(imm_256, 256); mpz_t tmp_char; mpz_init(tmp_char); mpz_mod(tmp_char, code, imm_256); uint8_t tmp_char_uint8 = mpz_get_ui(tmp_char); out[0] = tmp_char_uint8; mpz_t tmp_char_left; mpz_init(tmp_char_left); mpz_div(tmp_char_left, code, imm_256); mpz_set(code, tmp_char_left); occupy -= 8; out++; mpz_clear(tmp_char); mpz_clear(tmp_char_left); } } return out; } uint8_t *write_string_delta_string_128(int128_t *in, uint8_t *out, uint32_t l, int numbers) { uint128_t code = 0; int occupy = 0; uint64_t endbit = (l * numbers); int end = 0; int writeind = 0; int128_t *tmpin = in; if (endbit % 8 == 0) { end = endbit / 8; } else { end = (int)endbit / 8 + 1; } uint8_t *last = out + end; uint128_t left_val = 0; while (out <= last) { while (occupy < 8) { if (tmpin >= in + numbers) { occupy = 8; break; } bool sign = 1; int128_t tmpnum = tmpin[0]; if (tmpnum <= 0) { sign = 0; tmpnum = -tmpnum; } uint128_t value1 = ((tmpnum & (( ((uint128_t)1) << (l - 1)) - 1)) + ( ((uint128_t)sign) << (l - 1))); code += (value1 << occupy); occupy += l; tmpin++; } //end while while (occupy >= 8) { left_val = code >> 8; //std::cout<<code<<std::endl; code = code & ((1 << 8) - 1); uint8_t tmp_char = code; occupy -= 8; out[0] = tmp_char; code = left_val; writeind ++; //std::cout<< writeind<<std::endl; //std::cout<<occupy<<" "<<left_val<<" "<<unsigned(out[0])<<std::endl; out++; } } return out; } template <typename T> uint8_t * write_delta_string(T *in, std::vector<bool>& signvec, uint8_t * string_len, uint8_t *out, uint32_t l, size_t numbers) { T code = 0; int occupy = 0; uint64_t endbit = ((l+8) * numbers); int end = 0; int writeind = 0; T *tmpin = in; int readind = 0; if (endbit % 8 == 0) { end = endbit / 8; } else { end = (int)endbit / 8 + 1; } uint8_t *last = out + end; T left_val = 0; while (out <= last) { while (occupy < 8) { if (tmpin >= in + numbers) { occupy = 8; break; } bool sign = signvec[readind]; T tmpnum = tmpin[0]; T value1 = (tmpnum & ((((T)1) << (uint8_t)(l - 1)) - 1)) + (((T)sign) << (uint8_t)(l - 1)); value1 += ((T)string_len[readind])<<(uint8_t)l; code += (value1 << (uint8_t)occupy); occupy += (l+8); tmpin++; readind++; } //end while while (occupy >= 8) { left_val = code >> (uint8_t)8; //std::cout<<code<<std::endl; code = code & ((1 << 8) - 1); uint8_t tmp_char = code; occupy -= 8; out[0] = tmp_char; code = left_val; //std::cout<< writeind<<std::endl; //std::cout<<occupy<<" "<<left_val<<" "<<unsigned(out[0])<<std::endl; out++; } } int pad = ceil((sizeof(T)*8 - l)/8); for (int i = 0; i < pad; i++) { out[0] = 0; out++; } return out; } #endif