void initBucket_nw(Bucket *bucket, unsigned long seed, int symblen, unsigned int k, unsigned int w, unsigned int s, double lt_delta, double lt_c, double eps, unsigned int N, DegDistr code, unsigned int nw, unsigned int Ns) { unsigned int i; bucket->matrix.seed = seed; bucket->symbLen = symblen; bucket->matrix.codetype = code; bucket->matrix.conf.k = k; bucket->matrix.conf.w = w; bucket->matrix.conf.s = s; bucket->matrix.conf.N = N; bucket->matrix.conf.delta = lt_delta; bucket->matrix.conf.c = lt_c; bucket->matrix.conf.epsShok = eps; if (bucket->matrix.symbols != NULL) { for (i=0; i<N; i++) { if (bucket->matrix.symbols[i].header != NULL) free(bucket->matrix.symbols[i].header); } free(bucket->matrix.symbols); } bucket->matrix.symbols = (Symbol *) chk_calloc(N, sizeof(Symbol)); if (bucket->matrix.cumulative != NULL) free(bucket->matrix.cumulative); bucket->matrix.cumulative = (double *) chk_calloc(w, sizeof(double)); switch (code) { case Luby: rubust_soliton_distribution(&bucket->matrix); break; case Shokrollahi: shokrollahi_distribution(&bucket->matrix); break; default: print_error("ERROR: currently only p2p and streaming applications can be used.\n"); exit(EXIT_FAILURE); break; } if (nw == 0) create_headers(&bucket->matrix); else create_headers_nw(&bucket->matrix, nw, Ns); return; }
int addBucketFLY(LTdecoderFLY* decoder) { int nameNewBucket = 0; Node *current = decoder->bucketFLYList; // Set the current pointer to the first bucket (if any) Node *ptr= NULL; if (decoder->bucketFLYList == NULL) { // If there are no buckets ptr = addNode(NULL); decoder->bucketFLYList = ptr; } else { // find the last bucket while (current->next != NULL) { current = current->next; } // The new bucket name will have the name of the previous one +1 nameNewBucket = ((BucketFLY *)current->data)->nameBucket +1; // Create a new node ptr = addNode(current); // Add the new node to the bucketFLYList current->next = ptr; } // Allocate a new bucket and initialize its parameters ptr->data = (void *) chk_calloc(1, sizeof(BucketFLY)); ((BucketFLY *)ptr->data)->nameBucket = nameNewBucket; ((BucketFLY *)ptr->data)->symbols = NULL; ((BucketFLY *)ptr->data)->cumulative = NULL; ((BucketFLY *)ptr->data)->genSymbs = 0; return nameNewBucket; }
unsigned int receiveEncodedSymbFLY(LTdecoderFLY *decoder, Symbol* encodedSymbols, unsigned int numberEncodedSymbols) { unsigned int i; unsigned int count = 0; Node *ptr= NULL; if (decoder == NULL) { print_error("(libLT_C:LTdecoderFLY.c:receiveEncodedSymbFLY) ERROR - Decoder pointer not correctly passed.\n"); return 0; } if ((encodedSymbols == NULL)||(numberEncodedSymbols == 0)) return 0; for (i = 0; i < numberEncodedSymbols; i++) { Symbol* currSymb = &(encodedSymbols[i]); // Create Node if (decoder->RXsymbList == NULL) { ptr = addNode(NULL); decoder->RXsymbList = ptr; } else { ptr = addNode(decoder->lastRXsymbol); decoder->lastRXsymbol->next = ptr; } decoder->lastRXsymbol = ptr; count++; // Alloc a new symbol in the decoder ptr->data = (Symbol *) chk_calloc(1, sizeof(Symbol)); Symbol *newSymbol = (Symbol *)ptr->data; // Deg newSymbol->deg = currSymb->deg; // Symb Len newSymbol->symbLen = currSymb->symbLen; // Header newSymbol->header = (unsigned int *) chk_malloc(newSymbol->deg, sizeof(unsigned int)); memcpy(newSymbol->header, currSymb->header, newSymbol->deg*sizeof(unsigned int)); // Info newSymbol->info = (char *) chk_malloc(currSymb->symbLen, sizeof(char)); memcpy(newSymbol->info, currSymb->info, currSymb->symbLen*sizeof(char)); // Update the number of received symbols decoder->NumRecSymbols++; } return count; }
void initBucketFLY(BucketFLY *bucket, unsigned long seed, int symblen, unsigned int w, unsigned int s, double lt_delta, double lt_c, double epsShok, DegDistr code) { bucket->seed = seed; bucket->symbLen = symblen; bucket->w = w; bucket->s = s; bucket->lt_delta = lt_delta; bucket->lt_c = lt_c; bucket->epsShok = epsShok; bucket->code = code; initRandom(&bucket->buckRan, seed); unsigned int i; if (bucket->symbols != NULL) { for (i=0; i<bucket->genSymbs; i++) { if (bucket->symbols[i].header != NULL) free(bucket->symbols[i].header); } free(bucket->symbols); bucket->symbols = NULL; } bucket->genSymbs = 0; if (bucket->cumulative != NULL) { free(bucket->cumulative); bucket->cumulative = NULL; } bucket->cumulative = (double *) chk_calloc(w, sizeof(double)); switch (code) { case Luby: RSDcumulative(bucket->cumulative, w, s, lt_delta, lt_c); break; case Shokrollahi: SHOKcumulative(bucket->cumulative, w, s, epsShok); break; default: print_error("ERROR: currently only LT and Raptor codes are implemented.\n"); exit(EXIT_FAILURE); break; } #ifdef DEBUGdecoderPrintBucketRandomSeed printf("Bucket[%d] - Seed: %lu\n", bucket->nameBucket, bucket->seed); #endif return; }
void deserializeSymbolList(char* tlvData, Symbol** pEncodedSymbolList, unsigned int* N) { if (tlvData == NULL) { print_error("Sorry, impossible to de-serialize the data buffer containing the symbol list because the buffer is empty!\n"); return 0; } Symbol* encodedSymbols = NULL; unsigned long long pos = 0; // ====== Read Header ====== unsigned short headerLen; char version; unsigned long long dataLen; readSerializedBasicHeader(tlvData, &headerLen, &version, N, &dataLen, &pos); if (headerLen +2 > pos) { // TODO readSerializedHeaderExtensions(tlvData, &pos); } // ====== Read symbols ====== // Allocate an array of Symbol structures encodedSymbols = (Symbol*) chk_calloc(*N, sizeof(Symbol)); // De-serialize one symbol at the time unsigned int numSymb = 0; for (numSymb = 0; numSymb < *N; numSymb++) { if (pos < (2+headerLen)+dataLen) pos = deserializeSymbol(tlvData, pos, &(encodedSymbols[numSymb])); else { print_error("tlv2symbolList: It seems that the TLV-like data buffer in not coherent. " "The current position (%lu) has exceeded the expected maximum value (%lu)." "\nNumber of de-serialized symbols: %d", pos, (2+headerLen)+dataLen, numSymb); break; } } // Make pEncodedSymbolList to point to the beginning of the generated data. *pEncodedSymbolList = NULL; *pEncodedSymbolList = encodedSymbols; return; }
int addAndInitBucketFLY(LTdecoderFLY* decoder, unsigned long seed, int symblen, unsigned int w, unsigned int s, double lt_delta, double lt_c, double epsShok, DegDistr code) { int nameNewBucket = 0; Node *current = decoder->bucketFLYList; // Set the current pointer to the first bucket (if any) Node *ptr= NULL; if (decoder->bucketFLYList == NULL) { // If there are no buckets ptr = addNode(NULL); decoder->bucketFLYList = ptr; } else { // find the last bucket while (current->next != NULL) { current = current->next; } // The new bucket name will have the name of the previous one +1 nameNewBucket = ((BucketFLY *)current->data)->nameBucket +1; // Create a new node ptr = addNode(current); // Add the new node to the bucketFLYList current->next = ptr; } // Allocate a new bucket and initialize its parameters ptr->data = (void *) chk_calloc(1, sizeof(BucketFLY)); ((BucketFLY *)ptr->data)->nameBucket = nameNewBucket; ((BucketFLY *)ptr->data)->symbols = NULL; ((BucketFLY *)ptr->data)->cumulative = NULL; ((BucketFLY *)ptr->data)->genSymbs = 0; initBucketFLY((BucketFLY *) ptr->data, seed, symblen, w, s, lt_delta, lt_c, epsShok, code); return nameNewBucket; }
void LTencodeFLY_toFile(LTencoderFLY *encoder, unsigned int N, unsigned int l, char *sourceInfo, unsigned long info_firstSymbolId, char *outfile ) { // Allocate the space to store the encoded symbols Symbol* encodedSymbols = (Symbol*) chk_calloc(N, sizeof(Symbol)); // Encode the source symbols LTencodeSymbolFLY(encoder, l, sourceInfo, info_firstSymbolId, N, encodedSymbols); // Serialize symbols char* serializedBuff = NULL; unsigned long serializedBuffLen = 0; serializedBuffLen = serializeSymbolList_explicit_append(encodedSymbols, N, &serializedBuff); // Delete the symbol list unsigned int i; for(i = 0; i < N; i++ ) { Symbol* currSymb = &(encodedSymbols[i]); if (currSymb->info != NULL) free(currSymb->info); if (currSymb->header != NULL) free(currSymb->header); } free(encodedSymbols); if (writeFile(outfile, serializedBuff, serializedBuffLen) != serializedBuffLen) { fprintf(stderr, "Encoded Information NOT written correctly.\n"); exit(EXIT_FAILURE); } // Free buffer free(serializedBuff); }
void createHeadersFly(BucketFLY *bucket, unsigned int newHeadersToGenerate, // Number of symbols to be retrieved unsigned int offset) { double sel; unsigned int genDeg; unsigned int i, j; unsigned int w = bucket->w; double *cumulative = bucket->cumulative; if (newHeadersToGenerate<1) return; if ((bucket->genSymbs == 0)&&(bucket->symbols == NULL)) bucket->symbols = (Symbol *) chk_calloc(newHeadersToGenerate, sizeof(Symbol)); else { bucket->symbols = (Symbol *) chk_realloc(bucket->symbols, bucket->genSymbs + newHeadersToGenerate, sizeof(Symbol)); for (i=0; i<newHeadersToGenerate; i++) { bucket->symbols[bucket->genSymbs+i].info = NULL; bucket->symbols[bucket->genSymbs+i].header = NULL; bucket->symbols[bucket->genSymbs+i].deg = 0; bucket->symbols[bucket->genSymbs+i].symbLen = bucket->symbLen; } } unsigned int *selectedSymbols = NULL; selectedSymbols = (unsigned int*) chk_malloc(w, sizeof(unsigned int)); for (i=0; i<newHeadersToGenerate; i++) { // Create header (the symbols are chosen between 0 and w) // therefore shifting is needed. genDeg = degree(cumulative, w, real(&bucket->buckRan)); if (genDeg > w) genDeg = w; if (genDeg == w) { chooseAllInWindowCore(w, offset, selectedSymbols, genDeg); } else { for (j=0; j<genDeg; j++) { sel = real(&bucket->buckRan); selectedSymbols[j] = rand2windowCore(w, offset, sel); if (verifySelectedSymbol(selectedSymbols, j) == False) { j--; // Doesn't repeat encoding symbols } } // sort(selectedSymbols, 0, genDeg-1); // Sort the chosen encoding symbols' list } #ifdef DEBUGdecoderPrintHeaders int deb_index; printf("BUCKET[%d] - symb[%d]\t: deg=%3d\t -> ", bucket->nameBucket, bucket->genSymbs, genDeg); for (deb_index=0; deb_index<genDeg; deb_index++) printf("%3d ", selectedSymbols[deb_index]); printf("\n"); #endif bucket->symbols[bucket->genSymbs].header = (unsigned int *) chk_malloc(genDeg, sizeof(unsigned int *)); memcpy(bucket->symbols[bucket->genSymbs].header, selectedSymbols, genDeg*sizeof(unsigned int)); bucket->symbols[bucket->genSymbs].deg = genDeg; bucket->symbols[bucket->genSymbs].symbLen = bucket->symbLen; bucket->genSymbs++; } #ifdef DEBUGdecoderPrintHeaders printf("\n"); #endif free(selectedSymbols); selectedSymbols = NULL; return; }
// Processes the received symbols Tbool processReceivedFLY(LTdecoderFLY* decoder) { Tbool one_decoded = False; unsigned int currDeg = 0; unsigned int realDeg = 0; unsigned int check = 0; Node *nextNode= NULL; int symbLen = 0; unsigned int k = decoder->k; // Start from the first received symbol (if exists) Node *current = NULL; current = decoder->RXsymbList; // All the symbols in the decode MUST have the same length!! if (current->data != NULL) symbLen = ((Symbol *)decoder->RXsymbList->data)->symbLen; else if (decoder->bucketFLYList != NULL) symbLen = ((BucketFLY *)decoder->bucketFLYList->data)->symbLen; if (symbLen==0) { print_error("ERROR: processReceivedFLY. The symbol length cannot be defined.\n"); exit(EXIT_FAILURE); } // If the decoded buffer has not been allocated yet, allocate it if (decoder->decoded == NULL) { decoder->decoded = (char *) chk_malloc(k*symbLen, sizeof(char)); } // If the decodingStatus buffer has not been allocated yet, allocate it if (decoder->decodingStatus == NULL) { decoder->decodingStatus = (char *) chk_calloc(k*symbLen, sizeof(char)); } while (current != NULL) { nextNode = current->next; if (current->data == NULL) { print_error("ERROR: process_received - current data empty.\n"); exit(EXIT_FAILURE); } Symbol *currSymb = (Symbol *) current->data; // Get the degree of the current encoded symbol currDeg = currSymb->deg; if ((currDeg<1)&&(currDeg>k)) { // It should never happen!! print_error("ERROR: process_received - out of bounds degree found.\n"); rmSymbol(&(decoder->RXsymbList), current); } #ifdef DEBUGPrintReceivedSymbolHeaders unsigned int debIndex; printf("Decoding Header: Deg = %d \t Check Symbs =", currDeg); for (debIndex = 0; debIndex < currDeg; debIndex++) printf(" %d", currSymb->header[debIndex]); printf("\n"); #endif if (currDeg == 1) { // If this symbol has degree 1 then directly decode it check = currSymb->header[0]; // Check that the encoded information exists if (currSymb->info == NULL) { print_error("ERROR: symbol info not allocated!\n"); exit(EXIT_FAILURE); } // Check that the header exists if (currSymb->header == NULL) { print_error("ERROR: symbol header not allocated!\n"); exit(EXIT_FAILURE); } // Check that the symbol in the header is within the k input symbols if (check >= k) { print_error("ERROR: decoded symbol header out of buffer.\n"); exit(EXIT_FAILURE); } // Check if the symbol in the header has not being decoded yet. if (isSymbolDecoded(decoder->decodingStatus, check*symbLen, symbLen) == False) { // Copy the information in the decoded information array memcpy(&decoder->decoded[check*symbLen], currSymb->info, symbLen*sizeof(char)); // Set the bytes in the decoding status array to 0x01 to indicate that the symbols is decoded. memset(&decoder->decodingStatus[check*symbLen], 0x01, symbLen*sizeof(char)); one_decoded = True; decoder->NumDecSymbols++; } #ifdef DEBUGprintReleasedSymbol printReleasedSymbol(check, k); #endif rmSymbol(&(decoder->RXsymbList), current); } else { // Compute the real degree of the symbol realDeg = computeRealDegree(currSymb, decoder->decodingStatus, symbLen, currDeg, k); switch (realDeg) { case 0: rmSymbol(&(decoder->RXsymbList), current); break; case 1: check = reduceDegree(&currSymb, decoder->decoded, decoder->decodingStatus, currDeg, symbLen, realDeg, decoder->xorType); if (currSymb->info == NULL) { print_error("ERROR: symbol info not allocated!\n"); exit(EXIT_FAILURE); } if (check>=k) { print_error("ERROR: decoded symbol out of buffer.\n"); exit(EXIT_FAILURE); } if (decoder->decodingStatus[check*symbLen] == 0x00) { memcpy(&decoder->decoded[check*symbLen], currSymb->info, symbLen*sizeof(char)); memset(&decoder->decodingStatus[check*symbLen], 0x01, symbLen*sizeof(char)); one_decoded = True; decoder->NumDecSymbols++; } rmSymbol(&(decoder->RXsymbList), current); #ifdef DEBUGprintReleasedSymbol printReleasedSymbol(check, k); #endif break; default: break; } } current = nextNode; } // Update lastRXsymbol (necessary for adding new received symbols) current = decoder->RXsymbList; while (current != NULL) { if (current->next == NULL) { decoder->lastRXsymbol = current; break; } current = current->next; } return one_decoded; }
/** Function to read a multi-sequence file */ int read_multiseq(char *filename, Tmultiseq *mseqdata) { FILE *fp = NULL; int r; char *ptr, cdeb, c; size_t file_sz, i, k, m; /* Obtain the size of the file*/ file_sz = get_filesize(filename); /* Read open the file */ if ((fp = fopen(filename ,"r")) == NULL) { fprintf(stderr, "Error: could not open FASTA file %s", filename); exit(EXIT_FAILURE); } /* Allocate memory */ mseqdata->data = (char *)chk_calloc(file_sz + 1, sizeof(char)); /* Read the whole file */ ptr = mseqdata->data; mseqdata->nb = 0; mseqdata->len = 0; cdeb = c = '\0'; while (file_sz > 0) { r = fgetc(fp); /* stop reading if end-of-file */ if (r == EOF) { *ptr = '\0'; break; } if (c == '\n' || c == '\0') { cdeb = (char)r; } c = (char)r; /* raise char-flag when start-of-sequence-name and increment the sequence number counter */ if (c == '>') { ++ mseqdata->nb; if (ptr != mseqdata->data) { *ptr = '\0'; ++ mseqdata->len; ++ ptr; -- file_sz; } } /* replace 'end of line' by 'end of string' for the sequence name */ if (c == '\n' && cdeb == '>') { c = '\0'; } /* store the char if not 'end of line' */ if (c != '\n') { *ptr = c; ++ mseqdata->len; ++ ptr; -- file_sz; } } /* close the file */ fclose(fp); /* allocate memory for the multiseq table */ mseqdata->tab = (struct _tmb_ *)chk_calloc(mseqdata->nb, sizeof(struct _tmb_)); /* assign to the table element pointer their values */ k = i = 0; while (i < mseqdata->len) { switch (mseqdata->data[i]) { case '>': mseqdata->tab[k].name = &(mseqdata->data[i + 1]); break; case '\0': mseqdata->tab[k].seq = &(mseqdata->data[i + 1]); m = i + 1; while (mseqdata->data[m] != '\0') { ++ m;}; mseqdata->tab[k].size = m - (i + 1); i = m; ++ k; break; default: break; } ++ i; } return EXIT_SUCCESS; }
unsigned int LTencodeSymbolFLY_buffer(LTencoderFLY *encoder, int symbLen, char* info, unsigned long info_firstSymbolId, Symbol* encodedSymbols, unsigned int N, unsigned long window_firstSymbolId) { unsigned int genDeg = 0; unsigned int *selectedSymbols = NULL; unsigned int ii, jj, j, kk; double sel; unsigned int w = encoder->currConfig->config->w; double *cumulative = encoder->currConfig->cumulative; unsigned int IDfirstSymbol = encoder->currConfig->genSymbols; // The output must be already allocated if ((symbLen < 1)||(info == NULL)||(encodedSymbols == NULL)) { print_error("ERROR - encoding process - no encoded information generated.\n"); if (symbLen < 1) print_error(" symbLen = %d\n.", symbLen); if (info == NULL) print_error(" info vector not allocated.\n"); if (encodedSymbols == NULL) print_error(" encoded symbol list not allocated.\n"); exit(EXIT_FAILURE); } // Allocate the vector for the selected symbols selectedSymbols = (unsigned int*) chk_calloc(w, sizeof(unsigned int)); for (ii=0; ii<N; ii++) { Symbol* currSymb = &(encodedSymbols[ii]); genDeg = degree(cumulative, w, real(&(encoder->currConfig)->randomGenerator)); if (genDeg > w) genDeg = w; if (genDeg == w) { chooseAllInWindowCore(w, window_firstSymbolId, selectedSymbols, genDeg); } else { for (jj=0; jj<genDeg; jj++) { sel = real(&(encoder->currConfig)->randomGenerator); selectedSymbols[jj] = rand2windowCore(w, window_firstSymbolId, sel); if (verifySelectedSymbol(selectedSymbols, jj) == False) { jj--; // Doesn't repeat encoding symbols } } // This encoder can sort the selected symbols if the following line is uncommented. //sort(selectedSymbols, 0, genDeg-1); // Sort the chosen encoding symbols' list } // Allocate memory for the header currSymb->header = (unsigned int*) chk_malloc(genDeg, sizeof(unsigned int)); // Allocate memory for the encoded information currSymb->info = (char*) chk_malloc(symbLen, sizeof(char)); // Saves the degree in the symbol's header currSymb->deg = genDeg; // Saves the symbol length in the symbol's header currSymb->symbLen = symbLen; // Assign the id to the new symbol currSymb->id = encoder->currConfig->genSymbols+1; // Copy the Info of the first input symbol indicated in the header memcpy(currSymb->header, selectedSymbols, genDeg*sizeof(unsigned int)); #ifdef DEBUGencoderPrintHeaders int deb_index; printf("ENCODER - symb[%d]\t: deg=%3d\t -> ", (int) encoder->currConfig->genSymbols, genDeg); for (deb_index=0; deb_index<genDeg; deb_index++) printf("%3d ", selectedSymbols[deb_index]); printf("\n"); #endif // Saves the selected source symbols' ID in the current Symbol memcpy(currSymb->info, &info[(selectedSymbols[0]-info_firstSymbolId)*symbLen], symbLen*sizeof(char)); // EX-OR the other symbols of the header if (encoder->xorType != NO) { for (j=1; j<genDeg; j++) { // EX-OR COMPUTATION calcXOR(&info[(selectedSymbols[j]-info_firstSymbolId)*symbLen], currSymb->info, symbLen, encoder->xorType); } } else { for (j=1; j<genDeg; j++) { // EX-OR COMPUTATION for (kk=0; kk<symbLen; kk++) { currSymb->info[kk] ^= info[(selectedSymbols[j]-info_firstSymbolId)*symbLen + kk]; } } } // Increase the number of generated symbols encoder->currConfig->genSymbols++; encoder->totGenSymbols++; } #ifdef DEBUGencoderPrintHeaders printf("\n"); #endif // free and initialize the tmp symbol free(selectedSymbols); selectedSymbols = NULL; return IDfirstSymbol; }
int main(int argc, char *argv[]) { if (argc != 3) { fprintf(stderr, "ERROR passing arguments!\n " "The first argument is the input file, the second is the decoded file.\n"); return EXIT_FAILURE; } char* infile = argv[1]; char* outfile = argv[2]; printf("---Encoding file %s\n", infile); printf("---Recovered Info in file %s\n", outfile); // Create the input source ulong infilelen = 0; sourceInfo = readFile(infile, &infilelen); if (sourceInfo == NULL) { fprintf(stderr, "ERROR source file not correctly read.\n"); return EXIT_FAILURE; } /* Simple initialization */ l = 1; k = infilelen/l; w = k/128; s = w/2; c = 0.4; delta = 0.5; seed = 663; N = (1.0+RED_EPS)*k; Ns = (k - w)/s + 1; nw = (1.0+RED_EPS)*s; printf("number of input symbols = %d\n", k); printf("number of encoding windows = %d\n", Ns); printf("number of encoded symbols per window = %d\n", nw); /* * * ALLOCATIONS * */ // Allocate the encoder data structure encoder = mallocEncoderFLY(seed); // Init the encoder data structure setEncoderFLY_LT(encoder, w, s, delta, c); // Allocate the decoder data structure decoder = mallocDecoderFLY(N); uint i; Symbol* encodedSymbols; for (i = 0; i < Ns; i++) { // === ENCODING === // Allocate the space to store the encoded symbols encodedSymbols = (Symbol*) chk_calloc(nw, sizeof(Symbol)); // Consider the source symbols of the current window to generate nw encoded symbols LTencodeSymbolFLY(encoder, l, sourceInfo, s*i, nw, encodedSymbols); printf("Encoding window %d completed (Number encoded symbols: %u).\n", i, getNumEncodedSymbols(encoder)); // === DECODING === // Receive the encoded symbols receiveEncodedSymbFLY(decoder, encodedSymbols, nw); printf("Decoding the received information (up to the %d-th window).\tDecoded: %d\n", i, getNumDecoded(decoder)); // Decode the symbols decodingProcessFLY(decoder); // Free the allocated encodedSymbols freeSymbList(encodedSymbols, nw); } /* * * RESULTS * */ // See new decoded symbols printf("\n"); // Count all decoded symbols printf("TOT received symbols: %d\n", getNumReceived(decoder)); printf("TOT decoded symbols: %d\n", getNumDecoded(decoder)); char *decodedInfo = getDecodedInformation(decoder); // Write the decoded information on a file if (writeFile(outfile, decodedInfo, k*l) == k*l) printf("Output written correctly.\n"); else fprintf(stderr, "Output NOT written correctly.\n"); /* * * FREES * */ // Finally, free the memory free(sourceInfo); freeEncoderFLY(encoder); freeDecoderFLY(decoder); return EXIT_SUCCESS; }
unsigned int serializeSymbol(Symbol* encodedSymbol, char version, char** pTlvData) { unsigned int totLen = 0; unsigned int valueLen = 0; unsigned int i = 0; char* tlvData = NULL; Tbool explicit = (Tbool)(version & 0x01); if (encodedSymbol->info == NULL) { print_error("serializeSymbol: The symbol does not contain encoded information!"); return 0; } if (encodedSymbol->deg == 0) { print_error("serializeSymbol: The symbol does not contain degree information!"); return 0; } if (encodedSymbol->header == NULL) { print_error("serializeSymbol: The symbol does not contain information about the IDs of the generator symbols!"); return 0; } // The length does not count the first two bytes, i.e. TLV_SYMBOL and the value of the total length of the serialized symbol. valueLen = 1 + // TLV_DATA__INFO 4 + // TLV_DATA__INFO length encodedSymbol->symbLen; // number of bytes of information if (explicit == True) { valueLen += 1 + // TLV_DATA__ENCODING_SYMBS 4 + // TLV_DATA__ENCODING_SYMBS length encodedSymbol->deg*sizeof(unsigned int); // number of bytes representing all the generators } totLen = 1 + // TLV_DATA__SYMBOL 4 + // TLV_DATA__SYMBOL length valueLen; // Allocate the char array tlvData = (char*) chk_calloc(totLen, sizeof(char)); // Write the data tlvData[i] = TLV_DATA__SYMBOL; i += sizeof(char); memcpy((char*)(tlvData+i), (unsigned int*) &(valueLen), sizeof(unsigned int)); i += sizeof(unsigned int); tlvData[i] = TLV_DATA__INFO; i += sizeof(char); memcpy((char*)(tlvData+i), (unsigned int*) &(encodedSymbol->symbLen), sizeof(unsigned int)); i += sizeof(unsigned int); memcpy((char*)(tlvData+i), encodedSymbol->info, encodedSymbol->symbLen*sizeof(char)); i += encodedSymbol->symbLen*sizeof(char); if (explicit == True) { tlvData[i] = TLV_DATA__ENCODING_SYMBS; i += sizeof(char); memcpy((char*)(tlvData+i), (unsigned int*) &(encodedSymbol->deg), sizeof(unsigned int)); i += sizeof(unsigned int); memcpy((char*)(tlvData+i), encodedSymbol->header, encodedSymbol->deg*sizeof(unsigned int)); i += encodedSymbol->deg*sizeof(unsigned int); } // Make pTlvData point to the beginning of the generated data. *pTlvData = NULL; *pTlvData = tlvData; return totLen; }
unsigned long long serializeSymbolList_explicit(Symbol* encodedSymbols, unsigned int N, char** pTlvData) { char* tlvData = NULL; char version = 0x01; // explicit short int valueHeaderLen = 0; unsigned int totHeaderLen = 0; unsigned int i = 0; if (encodedSymbols == NULL) { print_error("symbolList2TLV_explicit: The symbol list is empty!"); return 0; } if (N == 0) { print_error("symbolList2TLV_explicit: The number of symbols to be converted to TLV format has to specified!"); return 0; } // Compute header length valueHeaderLen = sizeof(char) + // TLV_HEADER__VERSION sizeof(char) + // TLV_HEADER__VERSION value sizeof(char) + // TLV_HEADER__NUM_SYMBS sizeof(unsigned int) + // TLV_HEADER__NUM_SYMBS value sizeof(char) + // TLV_HEADER__DATA_LENGTH sizeof(unsigned long long); // TLV_HEADER__DATA_LENGTH value totHeaderLen = sizeof(char) + // TLV_HEADER__LENGTH sizeof(char) + // TLV_HEADER__LENGTH value valueHeaderLen; // Allocate buffer for header char* header_buff = (char*) chk_calloc(totHeaderLen, sizeof(char)); // Create header header_buff[i] = TLV_HEADER__LENGTH; i += sizeof(char); header_buff[i] = (char) valueHeaderLen; i += sizeof(char); header_buff[i] = TLV_HEADER__VERSION; i += sizeof(char); header_buff[i] = version; // explicit i += sizeof(char); header_buff[i] = TLV_HEADER__NUM_SYMBS; i += sizeof(char); memcpy((char*)(header_buff+i), (unsigned int*) &N, sizeof(unsigned int)); i += sizeof(unsigned int); header_buff[i] = TLV_HEADER__DATA_LENGTH; i += sizeof(char); // We still have to add the total length of the data! // Create the data_buff char* data_buff = NULL; unsigned long long data_buff_len = 0; unsigned int i_symb = 0; for (i_symb = 0; i_symb < N; i_symb++) { char *symb_buff = NULL; unsigned int tlvSymbLen = 0; // Serialize the current symbol tlvSymbLen = serializeSymbol(&encodedSymbols[i_symb], version, &symb_buff); // Reallocate the data_buff data_buff = (char*) chk_realloc(data_buff, data_buff_len+tlvSymbLen, sizeof(char)); // Copy symb_buff at the end of the data_buff memcpy((char*)(data_buff + data_buff_len), symb_buff, tlvSymbLen*sizeof(char)); // Update the length variable of the data_buff data_buff_len += tlvSymbLen; // free the symb_buff variable free(symb_buff); } // Now we have the value of the data_buff_len and we can update the field in the header memcpy((char*)(header_buff+i), &data_buff_len, sizeof(unsigned long long)); i += sizeof(unsigned long long); // Create the tlv stream tlvData = (char*) chk_calloc(totHeaderLen+data_buff_len, sizeof(char)); // Copy the header memcpy(tlvData, header_buff, totHeaderLen*sizeof(char)); // Copy the serialized data memcpy((char*)(tlvData+totHeaderLen), data_buff, data_buff_len*sizeof(char)); // Free temporary buffers free(header_buff); free(data_buff); // Make pTlvData point to the beginning of the generated data. *pTlvData = tlvData; return (unsigned long long) totHeaderLen+data_buff_len; }
unsigned int receiveSymbFLY(LTdecoderFLY *decoder, BucketFLY *bucket, char *encodedInfo, // encodedInfo is the vector of encoded bits unsigned int encodedInfoLength, // length of the encodedInfo vector (thus number of encoded bits) unsigned int IDfirstSymb, // ID of the first encoded symbol unsigned long offset) { // ID of the first source symbol considered in the encoding window unsigned int i; unsigned int count = 0; Node *ptr= NULL; unsigned int packetSymbols = (unsigned int)(encodedInfoLength/(bucket->symbLen)); if (IDfirstSymb+packetSymbols > bucket->genSymbs) { createHeadersFly(bucket, (IDfirstSymb+packetSymbols)-(bucket->genSymbs), offset); } for (i=0; i<packetSymbols; i++) { // Create Node if (decoder->RXsymbList == NULL) { ptr = addNode(NULL); decoder->RXsymbList = ptr; } else { ptr = addNode(decoder->lastRXsymbol); decoder->lastRXsymbol->next = ptr; } decoder->lastRXsymbol = ptr; count++; // Alloc a new symbol in the decoder ptr->data = (Symbol *) chk_calloc(1, sizeof(Symbol)); Symbol *newSymbol = (Symbol *)ptr->data; // Create pointer to the current symbol in the bucket Symbol* currSymbol = &(bucket->symbols[IDfirstSymb+i]); // Deg newSymbol->deg = currSymbol->deg; // Symb Len newSymbol->symbLen = currSymbol->symbLen; // Header newSymbol->header = (unsigned int *)chk_malloc(newSymbol->deg, sizeof(unsigned int)); memcpy(newSymbol->header, currSymbol->header, newSymbol->deg*sizeof(unsigned int)); // Info newSymbol->info = (char *)chk_malloc(bucket->symbLen, sizeof(char)); memcpy(newSymbol->info, &encodedInfo[i*bucket->symbLen], bucket->symbLen*sizeof(char)); #ifdef DEBUGdecoderPrintHeaders int deb_index; printf("DECODER[%d] - symb[%d]\t: deg=%3d\t -> ", bucket->nameBucket, IDfirstSymb+i, newSymbol->deg); for (deb_index=0; deb_index<newSymbol->deg; deb_index++) printf("%3d ", currSymbol->header[deb_index]); printf("\n"); #endif } // Update the number of received symbols decoder->NumRecSymbols += count; return count; }
int main (int argc, char *argv[]) { FILE *fp = NULL; char *lline = NULL, *lname = NULL; Tmultiseq msdat; size_t nl, nsel, maxl, lc; size_t *tab_start = NULL, *tab_stop = NULL; struct _tmb_ memb, **tab_nss = NULL, *ppos = NULL; size_t i, j; if (argc != 3) { fputs("Usage:\n", stderr); fprintf(stderr, " %s <multi-sequence file name> <ranges selection file name>\n", argv[0]); exit(EXIT_FAILURE); } /* Read the sequences file */ read_multiseq(argv[1], &msdat); /* Sort the table of name/seq/size along the sequence name */ qsort(msdat.tab, msdat.nb, sizeof(struct _tmb_), cmpname); /* Get the number of line in the selection file */ nl = fline_count(argv[2], &maxl); /* Allocate memory for the selection table */ tab_start = (size_t *)chk_calloc(nl, sizeof(size_t)); tab_stop = (size_t *)chk_calloc(nl, sizeof(size_t)); tab_nss = (struct _tmb_ **)chk_calloc(nl, sizeof(struct _tmb_ *)); /* Allocate temporary memory */ maxl += 3; /* 3 -> '\0' & '\n' */ lname = (char *)chk_calloc(maxl, sizeof(char)); lline = (char *)chk_calloc(maxl, sizeof(char)); /* Read each line of the selection file */ nsel = lc = 0; fp = fopen(argv[2], "r"); while (fgets(lline, maxl, fp) != NULL) { ++ lc; sscanf(lline,"%s %zd %zd\n", lname, &i, &j); if (i <= j) { /* binary search of the sequence in the table from its name */ memb.name = lname; ppos = bsearch(&memb, msdat.tab, msdat.nb, sizeof(struct _tmb_), cmpname); if (ppos == NULL) { fprintf(stderr, "Warning: Unknown sequence name [line %zd]: %s\n", lc, lname); } else { tab_start[nsel] = i; tab_stop[nsel] = j; tab_nss[nsel] = ppos; ++nsel; } } else { fprintf(stderr, "Warning: inconsistent start=%zd > stop=%zd [line %zd]\n", i, j, lc); } } /* free temporary memory ... */ free(lname); free(lline); /* ... and close file */ fclose(fp); /* Print the selected sequences (in selection order) */ { size_t sssz; /* size of the sub-sequence */ char *ssp; /* pointer to the beginning of the sub-sequence */ for (i=0; i<nsel; ++i) { /* print the sequence name */ printf(">%s\n", tab_nss[i]->name); /* print the sequence from start to stop */ sssz = tab_stop[i] - tab_start[i] + 1; /* IMPORTANT: if in the selection file, the sequence index is 1-2-3...-n and not 0-1-2...-n therefore replace the following line by ssp = tab_nss[i].seq + tab_start[i] - 1; */ ssp = tab_nss[i]->seq + tab_start[i]; /* For safety test out-of-range indices, IMPORTANT holds here also */ if (tab_start[i] > tab_nss[i]->size || tab_stop[i] > tab_nss[i]->size) { fprintf(stderr, "Warning: start=%zd or stop=%zd is out of range\n", tab_start[i], tab_stop[i]); } else { for (j=0; j<sssz; ++j) { putchar(ssp[j]); } putchar('\n'); } } } /* free all allocated memory */ free_multiseq(&msdat); free(tab_start); free(tab_stop); free(tab_nss); return EXIT_SUCCESS; }
unsigned int LTencodeInfoFLY(LTencoderFLY *encoder, int symbLen, char *info, unsigned long window_firstSymbolId, // window_firstSymbolId indicates the the first symbol of the window unsigned int N, char *output) { unsigned int genDeg = 0; unsigned int *selectedSymbols = NULL; unsigned int ii, jj, j, kk; double sel; unsigned int w = encoder->currConfig->config->w; double *cumulative = encoder->currConfig->cumulative; unsigned int IDfirstSymbol = encoder->currConfig->genSymbols; // The output must be already allocated if ((symbLen < 1)||(NULL == info)||(NULL == output)) { print_error("ERROR - encoding process - no encoded information generated.\n"); if (symbLen < 1) print_error(" symbLen = %d\n", symbLen); if (NULL == info) print_error(" info vector not allocated\n"); if (NULL == output) print_error(" output vector not allocated\n"); exit(EXIT_FAILURE); } // Allocate the vector for the selected symbols selectedSymbols = (unsigned int*) chk_calloc(w, sizeof(unsigned int)); for (ii=0; ii<N; ii++) { genDeg = degree(cumulative, w, real(&(encoder->currConfig)->randomGenerator)); if (genDeg > w) genDeg = w; if (genDeg == w) { chooseAllInWindowCore(w, window_firstSymbolId, selectedSymbols, genDeg); } else { for (jj=0; jj<genDeg; jj++) { sel = real(&(encoder->currConfig)->randomGenerator); selectedSymbols[jj] = rand2windowCore(w, window_firstSymbolId, sel); if (verifySelectedSymbol(selectedSymbols, jj) == False) { jj--; // Doesn't repeat encoding symbols } } // This encoder does not sort because does not save the headers // sort(selectedSymbols, 0, genDeg-1); // Sort the chosen encoding symbols' list } #ifdef DEBUGencoderPrintHeaders int deb_index; printf("ENCODER - symb[%d]\t: deg=%3d\t -> ", (int) encoder->currConfig->genSymbols, genDeg); for (deb_index=0; deb_index<genDeg; deb_index++) printf("%3d ", selectedSymbols[deb_index]); printf("\n"); #endif // Copy the Info of the first input symbol indicated in the header memcpy(&output[ii*symbLen], &info[selectedSymbols[0]*symbLen], symbLen*sizeof(char)); // EX-OR the other symbols of the header if (encoder->xorType != NO) { for (j=1; j<genDeg; j++) { // EX-OR COMPUTATION calcXOR(&info[selectedSymbols[j]*symbLen], &output[ii*symbLen], symbLen, encoder->xorType); } } else { for (j=1; j<genDeg; j++) { // EX-OR COMPUTATION for (kk=0; kk<symbLen; kk++) { output[ii*symbLen + kk] ^= info[selectedSymbols[j]*symbLen + kk]; } } } // Increase the number of generated symbols encoder->currConfig->genSymbols++; encoder->totGenSymbols++; } #ifdef DEBUGencoderPrintHeaders printf("\n"); #endif // free and initialize the tmp symbol free(selectedSymbols); selectedSymbols = NULL; return IDfirstSymbol; }