| 1 | #include "Util/utils.h" |
| 2 | #include <math.h> |
| 3 | #include <cds/Vector.h> |
| 4 | |
| 5 | void free_work(Work_t* work) |
| 6 | { |
| 7 | free(work->inputFileName); |
| 8 | free(work->ranks); |
| 9 | free(work); |
| 10 | } |
| 11 | |
| 12 | void free_result(Result_t* result) |
| 13 | { |
| 14 | free(result->medoids_ID); |
| 15 | free(result->medoids_ranks); |
| 16 | free(result); |
| 17 | } |
| 18 | |
| 19 | char readInt(FILE* stream, int64_t* integer) |
| 20 | { |
| 21 | *integer = 0; |
| 22 | char curChar = fgetc(stream); |
| 23 | int sign = (curChar == '-' ? -1 : 1); |
| 24 | while (curChar < '0' || curChar > '9') |
| 25 | curChar = fgetc(stream); |
| 26 | ungetc(curChar, stream); |
| 27 | while ((curChar = fgetc(stream)) >= '0' && curChar <= '9') |
| 28 | *integer = 10 * (*integer) + (int64_t) (curChar - '0'); |
| 29 | (*integer) *= sign; |
| 30 | return curChar; |
| 31 | } |
| 32 | |
| 33 | char readReal(FILE* stream, Real* real) |
| 34 | { |
| 35 | int64_t integerPart; |
| 36 | char nextChar = readInt(stream, &integerPart); |
| 37 | int64_t fractionalPart = 0; |
| 38 | int countZeros = 0; |
| 39 | if (nextChar == '.') |
| 40 | { |
| 41 | //need to count zeros |
| 42 | while ((nextChar = fgetc(stream)) == '0') |
| 43 | countZeros++; |
| 44 | if (nextChar >= '0' && nextChar <= '9') |
| 45 | { |
| 46 | ungetc(nextChar, stream); |
| 47 | nextChar = readInt(stream, &fractionalPart); |
| 48 | } |
| 49 | } |
| 50 | int64_t exponent = 0; |
| 51 | if (nextChar == 'e' || nextChar == 'E') |
| 52 | nextChar = readInt(stream, &exponent); |
| 53 | int64_t divisorForFractional = pow(10, floor(log10(fractionalPart > 0 ? fractionalPart : 1))+1); |
| 54 | *real = ( (Real)integerPart |
| 55 | + (integerPart < 0 ? -1 : 1) * (Real)fractionalPart/(divisorForFractional*pow(10,countZeros)) ) |
| 56 | * pow(10,exponent); |
| 57 | return nextChar; |
| 58 | } |
| 59 | |
| 60 | // convert n-bytes binary integers to uint32_t |
| 61 | uint32_t bInt_to_uint(Byte* pInteger, size_t bytesCount) |
| 62 | { |
| 63 | uint32_t integer = 0; |
| 64 | for (size_t i = 0; i < bytesCount; i++) |
| 65 | integer += ((uint32_t) (pInteger[i])) << (i << 3); |
| 66 | return integer; |
| 67 | } |
| 68 | |
| 69 | // serialize integers with a portable bytes order |
| 70 | void write_int(uint32_t integer, size_t bytesCount, Byte* buffer) |
| 71 | { |
| 72 | Byte chunk; |
| 73 | // write from left to right, from least to most significative bit |
| 74 | for (size_t i = 0; i < bytesCount; i++) |
| 75 | { |
| 76 | chunk = (integer >> (i << 3)) & 0xFF; |
| 77 | buffer[i] = chunk; |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | // Expected size of a Work message in bytes: |
| 82 | uint32_t get_packedWork_length(uint32_t nbSeriesInChunk) |
| 83 | { |
| 84 | return NCHAR_FNAME + 4 + 4*nbSeriesInChunk + 4 + 4 + 4; |
| 85 | } |
| 86 | |
| 87 | // Expected size of a Result message in bytes: (uint32_t is on 4 bytes) |
| 88 | uint32_t get_packedResult_length(uint32_t nbClusters) |
| 89 | { |
| 90 | return 4 + 4 * nbClusters + 4 * nbClusters; |
| 91 | } |
| 92 | |
| 93 | // get metadata: nbSeries |
| 94 | uint32_t get_nbSeries(const char* ifileName) |
| 95 | { |
| 96 | FILE* ifile = fopen(ifileName, "rb"); |
| 97 | fseek(ifile, 0, SEEK_SET); |
| 98 | Byte binaryInt[4]; |
| 99 | size_t lengthRead = fread(binaryInt, 4, 1, ifile); |
| 100 | if (lengthRead != 1) |
| 101 | fprintf(stderr,"Warning: getting nbSeries from truncated binary file.\n"); |
| 102 | fclose(ifile); |
| 103 | return bInt_to_uint(binaryInt, 4); |
| 104 | } |
| 105 | |
| 106 | // get metadata: tsLength |
| 107 | uint32_t get_tsLength(const char* ifileName) |
| 108 | { |
| 109 | FILE* ifile = fopen(ifileName, "rb"); |
| 110 | fseek(ifile, 4, SEEK_SET); |
| 111 | Byte binaryInt[4]; |
| 112 | size_t lengthRead = fread(binaryInt, 4, 1, ifile); |
| 113 | if (lengthRead != 1) |
| 114 | fprintf(stderr,"Warning: getting tsLength from truncated binary file.\n"); |
| 115 | fclose(ifile); |
| 116 | return bInt_to_uint(binaryInt, 4); |
| 117 | } |