<commit_before>#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <ctime>
#include <string>
#include <climits>
#include <queue>

#include "myers.h"

using namespace std;

int readFastaSequences(const char* path, vector< vector<unsigned char> >* seqs,
                       unsigned char* letterIdx, char* idxToLetter, bool* inAlphabet, int &alphabetLength);

void printAlignment(const unsigned char* query, const int queryLength,
                    const unsigned char* target, const int targetLength,
                    const unsigned char* alignment, const int alignmentLength,
                    const int modeCode, const char* idxToLetter);

// For debugging
void printSeq(const vector<unsigned char> &seq) {
    for (int i = 0; i < seq.size(); i++)
        printf("%d ", seq[i]);
    printf("\n");
}

int main(int argc, char * const argv[]) {

    //----------------------------- PARSE COMMAND LINE ------------------------//
    // If true, there will be no output.
    bool silent = false;
    // Alignment mode.
    char mode[16] = "NW";
    // How many best sequences (those with smallest score) do we want.
    // If 0, then we want them all.
    int numBestSeqs = 0;
    bool findAlignment = false;
    int option;
    while ((option = getopt(argc, argv, "a:n:sc")) >= 0) { // : is not a delimiter but indicator of parameter
        switch (option) {
        case 'a': strcpy(mode, optarg); break;
        case 'n': numBestSeqs = atoi(optarg); break;
        case 's': silent = true; break;
        case 'c': findAlignment = true; break;
        }
    }
    if (optind + 2 != argc) {
        fprintf(stderr, "\n");
        fprintf(stderr, "Usage: aligner [options...] <queries.fasta> <target.fasta>\n");
        fprintf(stderr, "Options:\n");
        fprintf(stderr, "\t-s  If specified, there will be no score output (silent mode).\n");
        fprintf(stderr, "\t-a HW|NW|SHW  Alignment mode that will be used. [default: NW]\n");
        fprintf(stderr, "\t-n N  Score will be calculated only for N best sequences (best = with smallest score)."
                        "If N = 0 then all sequences will be calculated. "
                        "Specifying small N can make total calculation much faster. [default: 0]\n");
        fprintf(stderr, "\t-c If specified, alignment will be found and printed.\n");
        return 1;
    }
    //-------------------------------------------------------------------------//

    int modeCode;
    if (!strcmp(mode, "SHW"))
        modeCode = MYERS_MODE_SHW;
    else if (!strcmp(mode, "HW"))
        modeCode = MYERS_MODE_HW;
    else if (!strcmp(mode, "NW"))
        modeCode = MYERS_MODE_NW;
    else {
        printf("Invalid mode!\n");
        return 1;
    }
    printf("Using mode %s\n", mode);

    // Alphabet information, will be constructed on fly while reading sequences
    unsigned char letterIdx[128]; //!< letterIdx[c] is index of letter c in alphabet
    char idxToLetter[128]; //!< numToLetter[i] is letter that has index i in alphabet
    bool inAlphabet[128]; // inAlphabet[c] is true if c is in alphabet
    for (int i = 0; i < 128; i++) {
        inAlphabet[i] = false;
    }
    int alphabetLength = 0;

    int readResult;
    // Read queries
    char* queriesFilepath = argv[optind];
    vector< vector<unsigned char> >* querySequences = new vector< vector<unsigned char> >();
    printf("Reading queries fasta file...\n");
    readResult = readFastaSequences(queriesFilepath, querySequences, letterIdx, idxToLetter,
                                    inAlphabet, alphabetLength);
    if (readResult) {
        printf("Error: There is no file with name %s\n", queriesFilepath);
        delete querySequences;
        return 1;
    }
    int numQueries = querySequences->size();

    // Read target
    char* targetFilepath = argv[optind+1];
    vector< vector<unsigned char> >* targetSequences = new vector< vector<unsigned char> >();
    printf("Reading target fasta file...\n");
    readResult = readFastaSequences(targetFilepath, targetSequences, letterIdx, idxToLetter,
                                    inAlphabet, alphabetLength);
    if (readResult) {
        printf("Error: There is no file with name %s\n", targetFilepath);
        delete querySequences;
        delete targetSequences;
        return 1;
    }
    unsigned char* target = (*targetSequences)[0].data();
    int targetLength = (*targetSequences)[0].size();

    printf("Alphabet: ");
    for (int c = 0; c < 128; c++)
        if (inAlphabet[c])
            printf("%c ", c);
    printf("\n");
    printf("Alphabet length: %d\n", alphabetLength);

    // ----------------------------- MAIN CALCULATION ----------------------------- //
    printf("\nSearching...\n");
    int* scores = new int[numQueries];
    int* pos    = new int[numQueries];
    priority_queue<int> bestScores; // Contains numBestSeqs best scores
    int k = -1;
    unsigned char* alignment = NULL; int alignmentLength;
    clock_t start = clock();

    if (!findAlignment) {
        printf("0/%d", numQueries);
        fflush(stdout);
    }
    for (int i = 0; i < numQueries; i++) {
        unsigned char* query = (*querySequences)[i].data();
        int queryLength = (*querySequences)[i].size();
        // Calculate score
        myersCalcEditDistance(query, queryLength, target, targetLength,
                              alphabetLength, k, modeCode, scores + i, pos + i,
                              findAlignment, &alignment, &alignmentLength);

        // If we want only numBestSeqs best sequences, update best scores and adjust k to largest score.
        if (numBestSeqs > 0) {
            if (scores[i] >= 0) {
                bestScores.push(scores[i]);
                if (bestScores.size() > numBestSeqs) {
                    bestScores.pop();
                }
                if (bestScores.size() == numBestSeqs) {
                    k = bestScores.top() - 1;
                }
            }
        }

        if (!findAlignment) {
            printf("\r%d/%d", i+1, numQueries);
            fflush(stdout);
        } else {
            // Print alignment if it was found
            if (alignment) {
                printf("\n");
                printAlignment(query, queryLength, target, targetLength,
                               alignment, alignmentLength, modeCode, idxToLetter);
            }
        }

        if (alignment)
            free(alignment);
    }
    printf("\n");

    if (!silent) {
        int scoreLimit = -1; // Only scores <= then scoreLimit will be printed (we consider -1 as infinity)
        printf("\n");

        if (bestScores.size() > 0) {
            printf("%d best scores:\n", (int)bestScores.size());
            scoreLimit = bestScores.top();
        }

        printf("Scores (score, position) \n");
        for (int i = 0; i < numQueries; i++)
            if (scores[i] > -1 && (scoreLimit == -1 || scores[i] <= scoreLimit))
                printf("%d: (%d, %d)\n", i, scores[i], pos[i]);

    }

    clock_t finish = clock();
    double cpuTime = ((double)(finish-start))/CLOCKS_PER_SEC;
    printf("\nCpu time of searching: %lf\n", cpuTime);
    // ---------------------------------------------------------------------------- //

    // Free allocated space
    delete querySequences;
    delete targetSequences;
    delete[] scores;
    delete[] pos;

    return 0;
}

/** Reads sequences from fasta file.
 * Function is passed current alphabet information and will update it if needed.
 * @param [in] path Path to fasta file containing sequences.
 * @param [out] seqs Sequences will be stored here, each sequence as vector of indexes from alphabet.
 * @param [inout] letterIdx  Array of length 128. letterIdx[c] is index of letter c in alphabet.
 * @param [inout] inAlphabet  Array of length 128. inAlphabet[c] is true if c is in alphabet.
 * @param [inout] alphabetLength
 * @return 0 if all ok, positive number otherwise.
 */
int readFastaSequences(const char* path, vector< vector<unsigned char> >* seqs,
                       unsigned char* letterIdx, char* idxToLetter, bool* inAlphabet, int &alphabetLength) {
    seqs->clear();

    FILE* file = fopen(path, "r");
    if (file == 0)
        return 1;

    bool inHeader = false;
    bool inSequence = false;
    int buffSize = 4096;
    char buffer[buffSize];
    while (!feof(file)) {
        int read = fread(buffer, sizeof(char), buffSize, file);
        for (int i = 0; i < read; ++i) {
            char c = buffer[i];
            if (inHeader) { // I do nothing if in header
                if (c == '\n')
                    inHeader = false;
            } else {
                if (c == '>') {
                    inHeader = true;
                    inSequence = false;
                } else {
                    if (c == '\r' || c == '\n')
                        continue;
                    // If starting new sequence, initialize it.
                    if (inSequence == false) {
                        inSequence = true;
                        seqs->push_back(vector<unsigned char>());
                    }

                    if (!inAlphabet[c]) { // I construct alphabet on fly
                        inAlphabet[c] = true;
                        letterIdx[c] = alphabetLength;
                        idxToLetter[alphabetLength] = c;
                        alphabetLength++;
                    }
                    seqs->back().push_back(letterIdx[c]);
                }
            }
        }
    }

    fclose(file);
    return 0;
}

void printAlignment(const unsigned char* query, const int queryLength,
                    const unsigned char* target, const int targetLength,
                    const unsigned char* alignment, const int alignmentLength,
                    const int modeCode, const char* idxToLetter) {
    printf("query length = %d, target length = %d\n", queryLength, targetLength);
    int tIdx = 0;
    int qIdx = 0;
    int targetLettersToSkip = 0;
    if (modeCode == MYERS_MODE_HW) {
        for (int j = 0; j < alignmentLength && alignment[j] == 2; j++) {
            targetLettersToSkip++;
            tIdx++;
        }
    }
    for (int start = targetLettersToSkip; start < alignmentLength; start += 50) {
        // target
        printf("T: ");
        int startTIdx = tIdx;
        for (int j = start; j < start + 50 && j < alignmentLength; j++) {
            if (alignment[j] == 1)
                printf("_");
            else
                printf("%c", idxToLetter[target[tIdx++]]);
        }
        printf(" (%d - %d)\n", startTIdx, tIdx - 1);
        // query
        printf("Q: ");
        int startQIdx = qIdx;
        for (int j = start; j < start + 50 && j < alignmentLength; j++) {
            if (alignment[j] == 2)
                printf("_");
            else
                printf("%c", idxToLetter[query[qIdx++]]);
        }
        printf(" (%d - %d)\n", startQIdx, qIdx - 1);
        printf("\n");
    }
}
<commit_msg>Fixed bug with alignment output<commit_after>#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <ctime>
#include <string>
#include <climits>
#include <queue>

#include "myers.h"

using namespace std;

int readFastaSequences(const char* path, vector< vector<unsigned char> >* seqs,
                       unsigned char* letterIdx, char* idxToLetter, bool* inAlphabet, int &alphabetLength);

void printAlignment(const unsigned char* query, const int queryLength,
                    const unsigned char* target, const int targetLength,
                    const unsigned char* alignment, const int alignmentLength,
                    const int position, const int modeCode, const char* idxToLetter);

// For debugging
void printSeq(const vector<unsigned char> &seq) {
    for (int i = 0; i < seq.size(); i++)
        printf("%d ", seq[i]);
    printf("\n");
}

int main(int argc, char * const argv[]) {

    //----------------------------- PARSE COMMAND LINE ------------------------//
    // If true, there will be no output.
    bool silent = false;
    // Alignment mode.
    char mode[16] = "NW";
    // How many best sequences (those with smallest score) do we want.
    // If 0, then we want them all.
    int numBestSeqs = 0;
    bool findAlignment = false;
    int option;
    int kArg = -1;
    while ((option = getopt(argc, argv, "a:n:k:sc")) >= 0) { // : is not a delimiter but indicator of parameter
        switch (option) {
        case 'a': strcpy(mode, optarg); break;
        case 'n': numBestSeqs = atoi(optarg); break;
        case 'k': kArg = atoi(optarg); break;
        case 's': silent = true; break;
        case 'c': findAlignment = true; break;
        }
    }
    if (optind + 2 != argc) {
        fprintf(stderr, "\n");
        fprintf(stderr, "Usage: aligner [options...] <queries.fasta> <target.fasta>\n");
        fprintf(stderr, "Options:\n");
        fprintf(stderr, "\t-s  If specified, there will be no score output (silent mode).\n");
        fprintf(stderr, "\t-a HW|NW|SHW  Alignment mode that will be used. [default: NW]\n");
        fprintf(stderr, "\t-n N  Score will be calculated only for N best sequences (best = with smallest score)."
                " If N = 0 then all sequences will be calculated."
                " Specifying small N can make total calculation much faster. [default: 0]\n");
        fprintf(stderr, "\t-c If specified, alignment will be found and printed.\n");
        fprintf(stderr, "\t-k K  Sequences with score > K will be discarded."
                " Smaller k, faster calculation.");
        return 1;
    }
    //-------------------------------------------------------------------------//

    int modeCode;
    if (!strcmp(mode, "SHW"))
        modeCode = MYERS_MODE_SHW;
    else if (!strcmp(mode, "HW"))
        modeCode = MYERS_MODE_HW;
    else if (!strcmp(mode, "NW"))
        modeCode = MYERS_MODE_NW;
    else {
        printf("Invalid mode!\n");
        return 1;
    }
    printf("Using mode %s\n", mode);

    // Alphabet information, will be constructed on fly while reading sequences
    unsigned char letterIdx[128]; //!< letterIdx[c] is index of letter c in alphabet
    char idxToLetter[128]; //!< numToLetter[i] is letter that has index i in alphabet
    bool inAlphabet[128]; // inAlphabet[c] is true if c is in alphabet
    for (int i = 0; i < 128; i++) {
        inAlphabet[i] = false;
    }
    int alphabetLength = 0;

    int readResult;
    // Read queries
    char* queriesFilepath = argv[optind];
    vector< vector<unsigned char> >* querySequences = new vector< vector<unsigned char> >();
    printf("Reading queries fasta file...\n");
    readResult = readFastaSequences(queriesFilepath, querySequences, letterIdx, idxToLetter,
                                    inAlphabet, alphabetLength);
    if (readResult) {
        printf("Error: There is no file with name %s\n", queriesFilepath);
        delete querySequences;
        return 1;
    }
    int numQueries = querySequences->size();

    // Read target
    char* targetFilepath = argv[optind+1];
    vector< vector<unsigned char> >* targetSequences = new vector< vector<unsigned char> >();
    printf("Reading target fasta file...\n");
    readResult = readFastaSequences(targetFilepath, targetSequences, letterIdx, idxToLetter,
                                    inAlphabet, alphabetLength);
    if (readResult) {
        printf("Error: There is no file with name %s\n", targetFilepath);
        delete querySequences;
        delete targetSequences;
        return 1;
    }
    unsigned char* target = (*targetSequences)[0].data();
    int targetLength = (*targetSequences)[0].size();

    printf("Alphabet: ");
    for (int c = 0; c < 128; c++)
        if (inAlphabet[c])
            printf("%c ", c);
    printf("\n");
    printf("Alphabet length: %d\n", alphabetLength);

    // ----------------------------- MAIN CALCULATION ----------------------------- //
    printf("\nSearching...\n");
    int* scores = new int[numQueries];
    int* pos    = new int[numQueries];
    priority_queue<int> bestScores; // Contains numBestSeqs best scores
    int k = kArg;
    unsigned char* alignment = NULL; int alignmentLength;
    clock_t start = clock();

    if (!findAlignment) {
        printf("0/%d", numQueries);
        fflush(stdout);
    }
    for (int i = 0; i < numQueries; i++) {
        unsigned char* query = (*querySequences)[i].data();
        int queryLength = (*querySequences)[i].size();
        // Calculate score
        myersCalcEditDistance(query, queryLength, target, targetLength,
                              alphabetLength, k, modeCode, scores + i, pos + i,
                              findAlignment, &alignment, &alignmentLength);

        // If we want only numBestSeqs best sequences, update best scores and adjust k to largest score.
        if (numBestSeqs > 0) {
            if (scores[i] >= 0) {
                bestScores.push(scores[i]);
                if (bestScores.size() > numBestSeqs) {
                    bestScores.pop();
                }
                if (bestScores.size() == numBestSeqs) {
                    k = bestScores.top() - 1;
                    if (kArg >= 0 && kArg < k)
                        k = kArg;
                }
            }
        }

        if (!findAlignment) {
            printf("\r%d/%d", i+1, numQueries);
            fflush(stdout);
        } else {
            // Print alignment if it was found
            if (alignment) {
                printf("\n");
                printAlignment(query, queryLength, target, targetLength,
                               alignment, alignmentLength,
                               pos[i], modeCode, idxToLetter);
            }
        }

        if (alignment)
            free(alignment);
    }
    printf("\n");

    if (!silent) {
        int scoreLimit = -1; // Only scores <= then scoreLimit will be printed (we consider -1 as infinity)
        printf("\n");

        if (bestScores.size() > 0) {
            printf("%d best scores:\n", (int)bestScores.size());
            scoreLimit = bestScores.top();
        }

        printf("Scores (score, position) \n");
        for (int i = 0; i < numQueries; i++)
            if (scores[i] > -1 && (scoreLimit == -1 || scores[i] <= scoreLimit))
                printf("%d: (%d, %d)\n", i, scores[i], pos[i]);

    }

    clock_t finish = clock();
    double cpuTime = ((double)(finish-start))/CLOCKS_PER_SEC;
    printf("\nCpu time of searching: %lf\n", cpuTime);
    // ---------------------------------------------------------------------------- //

    // Free allocated space
    delete querySequences;
    delete targetSequences;
    delete[] scores;
    delete[] pos;

    return 0;
}

/** Reads sequences from fasta file.
 * Function is passed current alphabet information and will update it if needed.
 * @param [in] path Path to fasta file containing sequences.
 * @param [out] seqs Sequences will be stored here, each sequence as vector of indexes from alphabet.
 * @param [inout] letterIdx  Array of length 128. letterIdx[c] is index of letter c in alphabet.
 * @param [inout] inAlphabet  Array of length 128. inAlphabet[c] is true if c is in alphabet.
 * @param [inout] alphabetLength
 * @return 0 if all ok, positive number otherwise.
 */
int readFastaSequences(const char* path, vector< vector<unsigned char> >* seqs,
                       unsigned char* letterIdx, char* idxToLetter, bool* inAlphabet, int &alphabetLength) {
    seqs->clear();

    FILE* file = fopen(path, "r");
    if (file == 0)
        return 1;

    bool inHeader = false;
    bool inSequence = false;
    int buffSize = 4096;
    char buffer[buffSize];
    while (!feof(file)) {
        int read = fread(buffer, sizeof(char), buffSize, file);
        for (int i = 0; i < read; ++i) {
            char c = buffer[i];
            if (inHeader) { // I do nothing if in header
                if (c == '\n')
                    inHeader = false;
            } else {
                if (c == '>') {
                    inHeader = true;
                    inSequence = false;
                } else {
                    if (c == '\r' || c == '\n')
                        continue;
                    // If starting new sequence, initialize it.
                    if (inSequence == false) {
                        inSequence = true;
                        seqs->push_back(vector<unsigned char>());
                    }

                    if (!inAlphabet[c]) { // I construct alphabet on fly
                        inAlphabet[c] = true;
                        letterIdx[c] = alphabetLength;
                        idxToLetter[alphabetLength] = c;
                        alphabetLength++;
                    }
                    seqs->back().push_back(letterIdx[c]);
                }
            }
        }
    }

    fclose(file);
    return 0;
}

void printAlignment(const unsigned char* query, const int queryLength,
                    const unsigned char* target, const int targetLength,
                    const unsigned char* alignment, const int alignmentLength,
                    const int position, const int modeCode, const char* idxToLetter) {
    printf("query length = %d, target length = %d\n", queryLength, targetLength);
    int tIdx = -1;
    int qIdx = -1;
    if (modeCode == MYERS_MODE_HW) {
        tIdx = position;
        for (int i = 0; i < alignmentLength; i++) {
            if (alignment[i] != 1)
                tIdx--;
        }
    }
    printf("%d\n", alignment[0]);
    for (int start = 0; start < alignmentLength; start += 50) {
        // target
        printf("T: ");
        int startTIdx;
        for (int j = start; j < start + 50 && j < alignmentLength; j++) {
            if (alignment[j] == 1)
                printf("_");
            else
                printf("%c", idxToLetter[target[++tIdx]]);
            if (j == start)
                startTIdx = tIdx;
        }
        printf(" (%d - %d)\n", max(startTIdx, 0), tIdx);
        // query
        printf("Q: ");
        int startQIdx = qIdx;
        for (int j = start; j < start + 50 && j < alignmentLength; j++) {
            if (alignment[j] == 2)
                printf("_");
            else
                printf("%c", idxToLetter[query[++qIdx]]);
            if (j == start)
                startQIdx = qIdx;
        }
        printf(" (%d - %d)\n", max(startQIdx, 0), qIdx);
        printf("\n");
    }
}
<|endoftext|>


<commit_before>/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <ndb_global.h>
#include <SimpleProperties.hpp>
#include <NdbOut.hpp>
#include <NdbTCP.h>
#include <UtilBuffer.hpp>

bool
SimpleProperties::Writer::first(){
  return reset();
}

bool
SimpleProperties::Writer::add(Uint16 key, Uint32 value){
  Uint32 head = Uint32Value;
  head <<= 16;
  head += key;
  if(!putWord(htonl(head)))
    return false;

  return putWord(htonl(value));
}

bool
SimpleProperties::Writer::add(const char * value, int len){
  const Uint32 valLen = (len + 3) / 4;

  if ((len % 4) == 0)
    return putWords((Uint32*)value, valLen);

  const Uint32 putLen= valLen - 1;
  if (!putWords((Uint32*)value, putLen))
    return false;

  // Special handling of last bytes
  union {
    Uint32 lastWord;
    char lastBytes[4];
  };
  memcpy(lastBytes,
         value + putLen*4,
         len - putLen*4);
  return putWord(lastWord);
}

bool
SimpleProperties::Writer::add(Uint16 key, const char * value){
  Uint32 head = StringValue;
  head <<= 16;
  head += key;
  if(!putWord(htonl(head)))
    return false;
  Uint32 strLen = strlen(value) + 1; // Including NULL-byte
  if(!putWord(htonl(strLen)))
    return false;

  return add(value, (int)strLen);

}

bool
SimpleProperties::Writer::add(Uint16 key, const void* value, int len){
  Uint32 head = BinaryValue;
  head <<= 16;
  head += key;
  if(!putWord(htonl(head)))
    return false;
  if(!putWord(htonl(len)))
    return false;

  return add((const char*)value, len);
}

SimpleProperties::Reader::Reader(){
  m_itemLen = 0;
}

bool
SimpleProperties::Reader::first(){
  reset();
  m_itemLen = 0;
  return readValue();
}

bool
SimpleProperties::Reader::next(){
  return readValue();
}

bool
SimpleProperties::Reader::valid() const {
  return m_type != InvalidValue;
}

Uint16
SimpleProperties::Reader::getKey() const{
  return m_key;
}

Uint16
SimpleProperties::Reader::getValueLen() const {
  switch(m_type){
  case Uint32Value:
    return 4;
  case StringValue:
  case BinaryValue:
    return m_strLen;
  case InvalidValue:
    return 0;
  }
  return 0;
}

SimpleProperties::ValueType
SimpleProperties::Reader::getValueType() const {
  return m_type;
}

Uint32
SimpleProperties::Reader::getUint32() const {
  return m_ui32_value;
}

char *
SimpleProperties::Reader::getString(char * dst) const {
  if(peekWords((Uint32*)dst, m_itemLen))
    return dst;
  return 0;
}

bool
SimpleProperties::Reader::readValue(){
  if(!step(m_itemLen)){
    m_type = InvalidValue;
    return false;
  }

  Uint32 tmp;
  if(!getWord(&tmp)){
    m_type = InvalidValue;
    return false;
  }

  tmp = ntohl(tmp);
  m_key = tmp & 0xFFFF;
  m_type = (SimpleProperties::ValueType)(tmp >> 16);
  switch(m_type){
  case Uint32Value:
    m_itemLen = 1;
    if(!peekWord(&m_ui32_value))
      return false;
    m_ui32_value = ntohl(m_ui32_value);
    return true;
  case StringValue:
  case BinaryValue:
    if(!getWord(&tmp))
      return false;
    m_strLen = ntohl(tmp);
    m_itemLen = (m_strLen + 3)/4;
    return true;
  default:
    m_itemLen = 0;
    m_type = InvalidValue;
    return false;
  }
}

SimpleProperties::UnpackStatus
SimpleProperties::unpack(Reader & it, void * dst,
			 const SP2StructMapping _map[], Uint32 mapSz,
			 bool ignoreMinMax,
			 bool ignoreUnknownKeys){
  do {
    if(!it.valid())
      break;

    bool found = false;
    Uint16 key = it.getKey();
    for(Uint32 i = 0; i<mapSz; i++){
      if(key == _map[i].Key){
	found = true;
	if(_map[i].Type == InvalidValue)
	  return Break;
	if(_map[i].Type != it.getValueType())
	  return TypeMismatch;

	char * _dst = (char *)dst;
	_dst += _map[i].Offset;

	switch(it.getValueType()){
	case Uint32Value:{
	  const Uint32 val = it.getUint32();
	  if(!ignoreMinMax){
	    if(val < _map[i].minValue)
	      return ValueTooLow;
	    if(val > _map[i].maxValue)
	      return ValueTooHigh;
	  }
	  * ((Uint32 *)_dst) = val;
	  break;
        }
	case BinaryValue:
        case StringValue:{
	  unsigned len = it.getValueLen();
	  if(len < _map[i].minValue)
	    return ValueTooLow;
	  if(len > _map[i].maxValue)
	    return ValueTooHigh;
          it.getString(_dst);
          break;
	}
	default:
	  abort();
	}
	break;
      }
    }
    if(!found && !ignoreUnknownKeys)
      return UnknownKey;
  } while(it.next());

  return Eof;
}

SimpleProperties::UnpackStatus
SimpleProperties::pack(Writer & it, const void * __src,
		       const SP2StructMapping _map[], Uint32 mapSz,
		       bool ignoreMinMax){

  const char * _src = (const char *)__src;

  for(Uint32 i = 0; i<mapSz; i++){
    bool ok = false;
    const char * src = _src + _map[i].Offset;
    switch(_map[i].Type){
    case SimpleProperties::InvalidValue:
      ok = true;
      break;
    case SimpleProperties::Uint32Value:{
      Uint32 val = * ((Uint32*)src);
      if(!ignoreMinMax){
	if(val < _map[i].minValue)
	  return ValueTooLow;
	if(val > _map[i].maxValue)
	  return ValueTooHigh;
      }
      ok = it.add(_map[i].Key, val);
    }
      break;
    case SimpleProperties::BinaryValue:{
      const char * src_len = _src + _map[i].Length_Offset;
      Uint32 len = *((Uint32*)src_len);
      if(!ignoreMinMax){
	if(len == _map[i].maxValue)
	  return ValueTooHigh;
      }
      ok = it.add(_map[i].Key, src, len);
      break;
    }
    case SimpleProperties::StringValue:
      if(!ignoreMinMax){
	size_t len = strlen(src);
	if(len == _map[i].maxValue)
	  return ValueTooHigh;
      }
      ok = it.add(_map[i].Key, src);
      break;
    }
    if(!ok)
      return OutOfMemory;
  }

  return Eof;
}

void
SimpleProperties::Reader::printAll(NdbOut& ndbout){
  char tmp[1024];
  for(first(); valid(); next()){
    switch(getValueType()){
    case SimpleProperties::Uint32Value:
      ndbout << "Key: " << getKey()
             << " value(" << getValueLen() << ") : "
             << getUint32() << endl;
      break;
    case SimpleProperties::BinaryValue:
    case SimpleProperties::StringValue:
      if(getValueLen() < 1024){
	getString(tmp);
	ndbout << "Key: " << getKey()
	       << " value(" << getValueLen() << ") : "
	       << "\"" << tmp << "\"" << endl;
      } else {
	ndbout << "Key: " << getKey()
	       << " value(" << getValueLen() << ") : "
	       << "\"" << "<TOO LONG>" << "\"" << endl;

      }
      break;
    default:
      ndbout << "Unknown type for key: " << getKey()
             << " type: " << (Uint32)getValueType() << endl;
    }
  }
}

SimplePropertiesLinearReader::SimplePropertiesLinearReader
(const Uint32 * src, Uint32 len){
  m_src = src;
  m_len = len;
  m_pos = 0;
  first();
}

void
SimplePropertiesLinearReader::reset() {
  m_pos = 0;
}

bool
SimplePropertiesLinearReader::step(Uint32 len){
  m_pos += len;
  return m_pos < m_len;
}

bool
SimplePropertiesLinearReader::getWord(Uint32 * dst) {
  if(m_pos<m_len){
    * dst = m_src[m_pos++];
    return true;
  }
  return false;
}

bool
SimplePropertiesLinearReader::peekWord(Uint32 * dst) const {
  if(m_pos<m_len){
    * dst = m_src[m_pos];
    return true;
  }
  return false;
}

bool
SimplePropertiesLinearReader::peekWords(Uint32 * dst, Uint32 len) const {
  if(m_pos + len <= m_len){
    memcpy(dst, &m_src[m_pos], 4 * len);
    return true;
  }
  return false;
}

LinearWriter::LinearWriter(Uint32 * src, Uint32 len){
  m_src = src;
  m_len = len;
  reset();
}

bool LinearWriter::reset() { m_pos = 0; return m_len > 0;}

bool
LinearWriter::putWord(Uint32 val){
  if(m_pos < m_len){
    m_src[m_pos++] = val;
    return true;
  }
  return false;
}

bool
LinearWriter::putWords(const Uint32 * src, Uint32 len){
  if(m_pos + len <= m_len){
    memcpy(&m_src[m_pos], src, 4 * len);
    m_pos += len;
    return true;
  }
  return false;
}

Uint32
LinearWriter::getWordsUsed() const { return m_pos;}

UtilBufferWriter::UtilBufferWriter(UtilBuffer & b)
  : m_buf(b)
{
  reset();
}

bool UtilBufferWriter::reset() { m_buf.clear(); return true;}

bool
UtilBufferWriter::putWord(Uint32 val){
  return (m_buf.append(&val, 4) == 0);
}

bool
UtilBufferWriter::putWords(const Uint32 * src, Uint32 len){
  return (m_buf.append(src, 4 * len) == 0);
}

Uint32
UtilBufferWriter::getWordsUsed() const { return m_buf.length() / 4;}

#if 0
LinearPagesReader::LinearPagesReader(const Uint32 * base,
				     Uint32 pageSize,
				     Uint32 headerSize,
				     Uint32 noOfPages,
				     Uint32 len){
  m_base = base;
  m_pageSz = pageSize;
  m_noOfPages = noOfPages;
  m_pageHeaderSz = headerSize;
  m_len = len;
  reset();
}

void
LinearPagesReader::reset() { m_pos = 0;}

bool
LinearPagesReader::step(Uint32 len){
  m_pos += len;
  return m_pos < m_len;
}

bool
LinearPagesReader::getWord(Uint32 * dst) {
  if(m_pos<m_len){
    * dst = m_base[getPos(m_pos++)];
    return true;
  }
  return false;
}

bool
LinearPagesReader::peekWord(Uint32 * dst) const {
  if(m_pos<m_len){
    * dst = m_base[getPos(m_pos)];
    return true;
  }
  return false;
}

bool
LinearPagesReader::peekWords(Uint32 * dst, Uint32 len) const {
  if(m_pos + len <= m_len){
    for(Uint32 i = 0; i<len; i++)
      * (dst + i) = m_base[getPos(m_pos + i)];
    return true;
  }
  return false;
}

Uint32
LinearPagesReader::getPos(Uint32 pos) const {
  const Uint32 sz = (m_pageSz - m_pageHeaderSz);
  Uint32 no = pos / sz;
  Uint32 in = pos % sz;
  return no * m_pageSz + m_pageHeaderSz + in;
}

LinearPagesWriter::LinearPagesWriter(Uint32 * base,
				     Uint32 pageSize,
				     Uint32 noOfPages,
				     Uint32 headerSize){
  m_base = base;
  m_pageSz = pageSize;
  m_noOfPages = noOfPages;
  m_pageHeaderSz = headerSize;
  m_len = noOfPages * (pageSize - headerSize);
  reset();
}

bool
LinearPagesWriter::putWord(Uint32 val){
  if(m_pos < m_len){
    m_base[getPos(m_pos++)] = val;
    return true;
  }
  return false;
}

bool
LinearPagesWriter::putWords(const Uint32 * src, Uint32 len){
  if(m_pos + len <= m_len){
    for(Uint32 i = 0; i<len; i++)
      m_base[getPos(m_pos++)] = src[i];
    return true;
  }
  return false;
}

#if 0
Uint32
LinearPagesWriter::getWordsUsed() const {
  return getPos(m_pos);
}
#endif

Uint32
LinearPagesWriter::getPagesUsed() const {
  return m_pos / (m_pageSz - m_pageHeaderSz);
}

Uint32
LinearPagesWriter::getPos(Uint32 pos) const {
  const Uint32 sz = (m_pageSz - m_pageHeaderSz);
  Uint32 no = pos / sz;
  Uint32 in = pos % sz;
  return no * m_pageSz + m_pageHeaderSz + in;
}
#endif
<commit_msg>ndb -   Fix compile error with gcc296<commit_after>/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <ndb_global.h>
#include <SimpleProperties.hpp>
#include <NdbOut.hpp>
#include <NdbTCP.h>
#include <UtilBuffer.hpp>

bool
SimpleProperties::Writer::first(){
  return reset();
}

bool
SimpleProperties::Writer::add(Uint16 key, Uint32 value){
  Uint32 head = Uint32Value;
  head <<= 16;
  head += key;
  if(!putWord(htonl(head)))
    return false;

  return putWord(htonl(value));
}

bool
SimpleProperties::Writer::add(const char * value, int len){
  const Uint32 valLen = (len + 3) / 4;

  if ((len % 4) == 0)
    return putWords((Uint32*)value, valLen);

  const Uint32 putLen= valLen - 1;
  if (!putWords((Uint32*)value, putLen))
    return false;

  // Special handling of last bytes
  union {
    Uint32 lastWord;
    char lastBytes[4];
  } tmp;
  tmp.lastWord =0 ;
  memcpy(tmp.lastBytes,
         value + putLen*4,
         len - putLen*4);
  return putWord(tmp.lastWord);
}

bool
SimpleProperties::Writer::add(Uint16 key, const char * value){
  Uint32 head = StringValue;
  head <<= 16;
  head += key;
  if(!putWord(htonl(head)))
    return false;
  Uint32 strLen = strlen(value) + 1; // Including NULL-byte
  if(!putWord(htonl(strLen)))
    return false;

  return add(value, (int)strLen);

}

bool
SimpleProperties::Writer::add(Uint16 key, const void* value, int len){
  Uint32 head = BinaryValue;
  head <<= 16;
  head += key;
  if(!putWord(htonl(head)))
    return false;
  if(!putWord(htonl(len)))
    return false;

  return add((const char*)value, len);
}

SimpleProperties::Reader::Reader(){
  m_itemLen = 0;
}

bool
SimpleProperties::Reader::first(){
  reset();
  m_itemLen = 0;
  return readValue();
}

bool
SimpleProperties::Reader::next(){
  return readValue();
}

bool
SimpleProperties::Reader::valid() const {
  return m_type != InvalidValue;
}

Uint16
SimpleProperties::Reader::getKey() const{
  return m_key;
}

Uint16
SimpleProperties::Reader::getValueLen() const {
  switch(m_type){
  case Uint32Value:
    return 4;
  case StringValue:
  case BinaryValue:
    return m_strLen;
  case InvalidValue:
    return 0;
  }
  return 0;
}

SimpleProperties::ValueType
SimpleProperties::Reader::getValueType() const {
  return m_type;
}

Uint32
SimpleProperties::Reader::getUint32() const {
  return m_ui32_value;
}

char *
SimpleProperties::Reader::getString(char * dst) const {
  if(peekWords((Uint32*)dst, m_itemLen))
    return dst;
  return 0;
}

bool
SimpleProperties::Reader::readValue(){
  if(!step(m_itemLen)){
    m_type = InvalidValue;
    return false;
  }

  Uint32 tmp;
  if(!getWord(&tmp)){
    m_type = InvalidValue;
    return false;
  }

  tmp = ntohl(tmp);
  m_key = tmp & 0xFFFF;
  m_type = (SimpleProperties::ValueType)(tmp >> 16);
  switch(m_type){
  case Uint32Value:
    m_itemLen = 1;
    if(!peekWord(&m_ui32_value))
      return false;
    m_ui32_value = ntohl(m_ui32_value);
    return true;
  case StringValue:
  case BinaryValue:
    if(!getWord(&tmp))
      return false;
    m_strLen = ntohl(tmp);
    m_itemLen = (m_strLen + 3)/4;
    return true;
  default:
    m_itemLen = 0;
    m_type = InvalidValue;
    return false;
  }
}

SimpleProperties::UnpackStatus
SimpleProperties::unpack(Reader & it, void * dst,
			 const SP2StructMapping _map[], Uint32 mapSz,
			 bool ignoreMinMax,
			 bool ignoreUnknownKeys){
  do {
    if(!it.valid())
      break;

    bool found = false;
    Uint16 key = it.getKey();
    for(Uint32 i = 0; i<mapSz; i++){
      if(key == _map[i].Key){
	found = true;
	if(_map[i].Type == InvalidValue)
	  return Break;
	if(_map[i].Type != it.getValueType())
	  return TypeMismatch;

	char * _dst = (char *)dst;
	_dst += _map[i].Offset;

	switch(it.getValueType()){
	case Uint32Value:{
	  const Uint32 val = it.getUint32();
	  if(!ignoreMinMax){
	    if(val < _map[i].minValue)
	      return ValueTooLow;
	    if(val > _map[i].maxValue)
	      return ValueTooHigh;
	  }
	  * ((Uint32 *)_dst) = val;
	  break;
        }
	case BinaryValue:
        case StringValue:{
	  unsigned len = it.getValueLen();
	  if(len < _map[i].minValue)
	    return ValueTooLow;
	  if(len > _map[i].maxValue)
	    return ValueTooHigh;
          it.getString(_dst);
          break;
	}
	default:
	  abort();
	}
	break;
      }
    }
    if(!found && !ignoreUnknownKeys)
      return UnknownKey;
  } while(it.next());

  return Eof;
}

SimpleProperties::UnpackStatus
SimpleProperties::pack(Writer & it, const void * __src,
		       const SP2StructMapping _map[], Uint32 mapSz,
		       bool ignoreMinMax){

  const char * _src = (const char *)__src;

  for(Uint32 i = 0; i<mapSz; i++){
    bool ok = false;
    const char * src = _src + _map[i].Offset;
    switch(_map[i].Type){
    case SimpleProperties::InvalidValue:
      ok = true;
      break;
    case SimpleProperties::Uint32Value:{
      Uint32 val = * ((Uint32*)src);
      if(!ignoreMinMax){
	if(val < _map[i].minValue)
	  return ValueTooLow;
	if(val > _map[i].maxValue)
	  return ValueTooHigh;
      }
      ok = it.add(_map[i].Key, val);
    }
      break;
    case SimpleProperties::BinaryValue:{
      const char * src_len = _src + _map[i].Length_Offset;
      Uint32 len = *((Uint32*)src_len);
      if(!ignoreMinMax){
	if(len == _map[i].maxValue)
	  return ValueTooHigh;
      }
      ok = it.add(_map[i].Key, src, len);
      break;
    }
    case SimpleProperties::StringValue:
      if(!ignoreMinMax){
	size_t len = strlen(src);
	if(len == _map[i].maxValue)
	  return ValueTooHigh;
      }
      ok = it.add(_map[i].Key, src);
      break;
    }
    if(!ok)
      return OutOfMemory;
  }

  return Eof;
}

void
SimpleProperties::Reader::printAll(NdbOut& ndbout){
  char tmp[1024];
  for(first(); valid(); next()){
    switch(getValueType()){
    case SimpleProperties::Uint32Value:
      ndbout << "Key: " << getKey()
             << " value(" << getValueLen() << ") : "
             << getUint32() << endl;
      break;
    case SimpleProperties::BinaryValue:
    case SimpleProperties::StringValue:
      if(getValueLen() < 1024){
	getString(tmp);
	ndbout << "Key: " << getKey()
	       << " value(" << getValueLen() << ") : "
	       << "\"" << tmp << "\"" << endl;
      } else {
	ndbout << "Key: " << getKey()
	       << " value(" << getValueLen() << ") : "
	       << "\"" << "<TOO LONG>" << "\"" << endl;

      }
      break;
    default:
      ndbout << "Unknown type for key: " << getKey()
             << " type: " << (Uint32)getValueType() << endl;
    }
  }
}

SimplePropertiesLinearReader::SimplePropertiesLinearReader
(const Uint32 * src, Uint32 len){
  m_src = src;
  m_len = len;
  m_pos = 0;
  first();
}

void
SimplePropertiesLinearReader::reset() {
  m_pos = 0;
}

bool
SimplePropertiesLinearReader::step(Uint32 len){
  m_pos += len;
  return m_pos < m_len;
}

bool
SimplePropertiesLinearReader::getWord(Uint32 * dst) {
  if(m_pos<m_len){
    * dst = m_src[m_pos++];
    return true;
  }
  return false;
}

bool
SimplePropertiesLinearReader::peekWord(Uint32 * dst) const {
  if(m_pos<m_len){
    * dst = m_src[m_pos];
    return true;
  }
  return false;
}

bool
SimplePropertiesLinearReader::peekWords(Uint32 * dst, Uint32 len) const {
  if(m_pos + len <= m_len){
    memcpy(dst, &m_src[m_pos], 4 * len);
    return true;
  }
  return false;
}

LinearWriter::LinearWriter(Uint32 * src, Uint32 len){
  m_src = src;
  m_len = len;
  reset();
}

bool LinearWriter::reset() { m_pos = 0; return m_len > 0;}

bool
LinearWriter::putWord(Uint32 val){
  if(m_pos < m_len){
    m_src[m_pos++] = val;
    return true;
  }
  return false;
}

bool
LinearWriter::putWords(const Uint32 * src, Uint32 len){
  if(m_pos + len <= m_len){
    memcpy(&m_src[m_pos], src, 4 * len);
    m_pos += len;
    return true;
  }
  return false;
}

Uint32
LinearWriter::getWordsUsed() const { return m_pos;}

UtilBufferWriter::UtilBufferWriter(UtilBuffer & b)
  : m_buf(b)
{
  reset();
}

bool UtilBufferWriter::reset() { m_buf.clear(); return true;}

bool
UtilBufferWriter::putWord(Uint32 val){
  return (m_buf.append(&val, 4) == 0);
}

bool
UtilBufferWriter::putWords(const Uint32 * src, Uint32 len){
  return (m_buf.append(src, 4 * len) == 0);
}

Uint32
UtilBufferWriter::getWordsUsed() const { return m_buf.length() / 4;}

#if 0
LinearPagesReader::LinearPagesReader(const Uint32 * base,
				     Uint32 pageSize,
				     Uint32 headerSize,
				     Uint32 noOfPages,
				     Uint32 len){
  m_base = base;
  m_pageSz = pageSize;
  m_noOfPages = noOfPages;
  m_pageHeaderSz = headerSize;
  m_len = len;
  reset();
}

void
LinearPagesReader::reset() { m_pos = 0;}

bool
LinearPagesReader::step(Uint32 len){
  m_pos += len;
  return m_pos < m_len;
}

bool
LinearPagesReader::getWord(Uint32 * dst) {
  if(m_pos<m_len){
    * dst = m_base[getPos(m_pos++)];
    return true;
  }
  return false;
}

bool
LinearPagesReader::peekWord(Uint32 * dst) const {
  if(m_pos<m_len){
    * dst = m_base[getPos(m_pos)];
    return true;
  }
  return false;
}

bool
LinearPagesReader::peekWords(Uint32 * dst, Uint32 len) const {
  if(m_pos + len <= m_len){
    for(Uint32 i = 0; i<len; i++)
      * (dst + i) = m_base[getPos(m_pos + i)];
    return true;
  }
  return false;
}

Uint32
LinearPagesReader::getPos(Uint32 pos) const {
  const Uint32 sz = (m_pageSz - m_pageHeaderSz);
  Uint32 no = pos / sz;
  Uint32 in = pos % sz;
  return no * m_pageSz + m_pageHeaderSz + in;
}

LinearPagesWriter::LinearPagesWriter(Uint32 * base,
				     Uint32 pageSize,
				     Uint32 noOfPages,
				     Uint32 headerSize){
  m_base = base;
  m_pageSz = pageSize;
  m_noOfPages = noOfPages;
  m_pageHeaderSz = headerSize;
  m_len = noOfPages * (pageSize - headerSize);
  reset();
}

bool
LinearPagesWriter::putWord(Uint32 val){
  if(m_pos < m_len){
    m_base[getPos(m_pos++)] = val;
    return true;
  }
  return false;
}

bool
LinearPagesWriter::putWords(const Uint32 * src, Uint32 len){
  if(m_pos + len <= m_len){
    for(Uint32 i = 0; i<len; i++)
      m_base[getPos(m_pos++)] = src[i];
    return true;
  }
  return false;
}

#if 0
Uint32
LinearPagesWriter::getWordsUsed() const {
  return getPos(m_pos);
}
#endif

Uint32
LinearPagesWriter::getPagesUsed() const {
  return m_pos / (m_pageSz - m_pageHeaderSz);
}

Uint32
LinearPagesWriter::getPos(Uint32 pos) const {
  const Uint32 sz = (m_pageSz - m_pageHeaderSz);
  Uint32 no = pos / sz;
  Uint32 in = pos % sz;
  return no * m_pageSz + m_pageHeaderSz + in;
}
#endif
<|endoftext|>


<commit_before>#include <string>
#include <iostream>

#include "config.h"

int main()
{
  std::cout << "\nAbout to parse...\n";

  Config* config = new Config;

  if (config->load("default.cfg"))
  {
    std::cout << "\nParsing finished.\n";

    std::cout << "\nDump of config:\n";
    config->dump();

    std::cout << "\nPort value:\n";
    std::cout << config->iData("core.net.port") << "\n";

    std::cout << "\nKeys in 'core.net':\n";
    std::list<std::string>* tmp = config->mData("core.net")->keys();
    std::list<std::string>::iterator tmp_iter = tmp->begin();
    for (;tmp_iter!=tmp->end();++tmp_iter)
    {
      std::cout << *tmp_iter << "\n";
    }

    std::cout << "\n";
  }
  else
  {
    std::cout << "\nParsing failed!\n\n";
  }
}
<commit_msg>forgot the <list> include in app.cpp<commit_after>#include <string>
#include <list>
#include <iostream>

#include "config.h"

int main()
{
  std::cout << "\nAbout to parse...\n";

  Config* config = new Config;

  if (config->load("default.cfg"))
  {
    std::cout << "\nParsing finished.\n";

    std::cout << "\nDump of config:\n";
    config->dump();

    std::cout << "\nPort value:\n";
    std::cout << config->iData("core.net.port") << "\n";

    std::cout << "\nKeys in 'core.net':\n";
    std::list<std::string>* tmp = config->mData("core.net")->keys();
    std::list<std::string>::iterator tmp_iter = tmp->begin();
    for (;tmp_iter!=tmp->end();++tmp_iter)
    {
      std::cout << *tmp_iter << "\n";
    }

    std::cout << "\n";
  }
  else
  {
    std::cout << "\nParsing failed!\n\n";
  }
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "CppUnitTest.h"
#include "..\ProjectEuler\Problem1.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace ProjectEulerTests
{
	TEST_CLASS(Problem1Tests)
	{
	public:

		TEST_METHOD(SumMultiplesOf3And5Below_Input0_Returns0)
		{
            auto result = Problem1::SumMultiplesOf3And5Below(0);
            Assert::AreEqual(0, result);
		}
	};
}<commit_msg>green-commit - SumMultiplesOf3And5Below_Input1_Returns0, SumMultiplesOf3And5Below_Input2_Returns0, SumMultiplesOf3And5Below_Input3_Returns0<commit_after>#include "stdafx.h"
#include "CppUnitTest.h"
#include "..\ProjectEuler\Problem1.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace ProjectEulerTests
{
	TEST_CLASS(Problem1Tests)
	{
	public:

		TEST_METHOD(SumMultiplesOf3And5Below_Input0_Returns0)
		{
            auto result = Problem1::SumMultiplesOf3And5Below(0);
            Assert::AreEqual(0, result);
		}

        TEST_METHOD(SumMultiplesOf3And5Below_Input1_Returns0)
        {
            auto result = Problem1::SumMultiplesOf3And5Below(1);
            Assert::AreEqual(0, result);
        }

        TEST_METHOD(SumMultiplesOf3And5Below_Input2_Returns0)
        {
            auto result = Problem1::SumMultiplesOf3And5Below(2);
            Assert::AreEqual(0, result);
        }

        TEST_METHOD(SumMultiplesOf3And5Below_Input3_Returns0)
        {
            auto result = Problem1::SumMultiplesOf3And5Below(3);
            Assert::AreEqual(0, result);
        }
	};
}<|endoftext|>


<commit_before>/* This file is part of Strigi Desktop Search
 *
 * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#include "jstreamsconfig.h"
#include "filelister.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include "stgdirent.h" //dirent replacement (includes native if available)

#ifdef HAVE_DIRECT_H
#include <direct.h>
#endif
#include <errno.h>
#ifndef PATH_MAX
 #define PATH_MAX _MAX_PATH
#endif

using namespace std;

FileLister::FileLister() {
    m_callback = 0;
    m_dirCallback = 0;
    path = 0;
    length = 0;
}
FileLister::~FileLister() {
    if (length) {
        free(path);
    }
}
#include <stdio.h>
void
FileLister::listFiles(const char *dir, time_t oldestdate) {
    if (m_callback == 0) return;
    m_oldestdate = oldestdate;
    int len = strlen(dir);
    resize(len+2);
    strcpy(path, dir);
    // check that the dirname ends in '/'
    if (path[len-1] != '/') {
        strcpy(path+len, "/");
        len++;
    }
    walk_directory(len);
}
char*
FileLister::resize(uint len) {
    if (len > length) {
        length = len + 100;
        path = (char*) realloc(path, length);
    }
    return path;
}
/**
 * Walk through a directory. The directory name must end in a '/'.
 **/
bool
FileLister::walk_directory(uint len) {
    bool expandedPath = false;
    DIR *dir;
    struct dirent *subdir;
    struct stat dirstat;

#ifndef _WIN32
    // call dir function callback, actually there's only inotify dir callback
    if (m_dirCallback != 0)
        m_dirCallback (path);
#endif

#ifdef _WIN32
    // remove the trailing '/' on windows machines before the call to opendir(),
    // but do not strip off the trailing slash from windows c:/
    if ( len > 3) {
        path[len-1] = '\0';
    }
#endif

    // open the directory
    dir = opendir(path);
    if (dir == 0) {
        return true;
    }
#ifdef _WIN32
    path[len-1] = '/';
#endif

    subdir = readdir(dir);
    while (subdir) {

        // skip the directories '.' and '..'
        char c1 = subdir->d_name[0];
        if (c1 == '.') {
            char c2 = subdir->d_name[1];
            if (c2 == '.' || c2 == '\0') {
                subdir = readdir(dir);
                continue;
            }
        }

        uint l = len+strlen(subdir->d_name);
        path = resize(l+1);
        strcpy(path+len, subdir->d_name);
        if (lstat(path, &dirstat) == 0) {
            bool c = true;
            if ( dirstat.st_mode & S_IFREG
                    && dirstat.st_mtime >= m_oldestdate) {
                c = m_callback(path, len, l, dirstat.st_mtime);
            } else if ( dirstat.st_mode & S_IFDIR) {
                strcpy(path+l, "/");
                c = walk_directory(l+1);
            }
            if (!c) break;
/*        } else {
            fprintf(stderr, "Could not stat '%s': %s\n", cwd,
                strerror(errno));*/
        }

        subdir = readdir(dir);
    }

    // clean up
    closedir(dir);
    // go back to where we came from
    //chdir("..");
    return true;
}
<commit_msg>Better detection of symbolic links.<commit_after>/* This file is part of Strigi Desktop Search
 *
 * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#include "jstreamsconfig.h"
#include "filelister.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include "stgdirent.h" //dirent replacement (includes native if available)

#ifdef HAVE_DIRECT_H
#include <direct.h>
#endif
#include <errno.h>
#ifndef PATH_MAX
 #define PATH_MAX _MAX_PATH
#endif

using namespace std;

FileLister::FileLister() {
    m_callback = 0;
    m_dirCallback = 0;
    path = 0;
    length = 0;
}
FileLister::~FileLister() {
    if (length) {
        free(path);
    }
}
#include <stdio.h>
void
FileLister::listFiles(const char *dir, time_t oldestdate) {
    if (m_callback == 0) return;
    m_oldestdate = oldestdate;
    int len = strlen(dir);
    resize(len+2);
    strcpy(path, dir);
    // check that the dirname ends in '/'
    if (path[len-1] != '/') {
        strcpy(path+len, "/");
        len++;
    }
    walk_directory(len);
}
char*
FileLister::resize(uint len) {
    if (len > length) {
        length = len + 100;
        path = (char*) realloc(path, length);
    }
    return path;
}
/**
 * Walk through a directory. The directory name must end in a '/'.
 **/
bool
FileLister::walk_directory(uint len) {
    bool expandedPath = false;
    DIR *dir;
    struct dirent *subdir;
    struct stat dirstat;

#ifndef _WIN32
    // call dir function callback, actually there's only inotify dir callback
    if (m_dirCallback != 0)
        m_dirCallback (path);
#endif

#ifdef _WIN32
    // remove the trailing '/' on windows machines before the call to opendir(),
    // but do not strip off the trailing slash from windows c:/
    if ( len > 3) {
        path[len-1] = '\0';
    }
#endif

    // open the directory
    dir = opendir(path);
    if (dir == 0) {
        return true;
    }
#ifdef _WIN32
    path[len-1] = '/';
#endif

    subdir = readdir(dir);
    while (subdir) {

        // skip the directories '.' and '..'
        char c1 = subdir->d_name[0];
        if (c1 == '.') {
            char c2 = subdir->d_name[1];
            if (c2 == '.' || c2 == '\0') {
                subdir = readdir(dir);
                continue;
            }
        }

        uint l = len+strlen(subdir->d_name);
        path = resize(l+1);
        strcpy(path+len, subdir->d_name);
        if (lstat(path, &dirstat) == 0) {
            bool c = true;
            if ( S_ISREG(dirstat.st_mode)
                    && dirstat.st_mtime >= m_oldestdate) {
                c = m_callback(path, len, l, dirstat.st_mtime);
            } else if ( dirstat.st_mode & S_IFDIR) {
                strcpy(path+l, "/");
                c = walk_directory(l+1);
            }
            if (!c) break;
/*        } else {
            fprintf(stderr, "Could not stat '%s': %s\n", cwd,
                strerror(errno));*/
        }

        subdir = readdir(dir);
    }

    // clean up
    closedir(dir);
    // go back to where we came from
    //chdir("..");
    return true;
}
<|endoftext|>


<commit_before>#include "subcommand.hpp"
#include "../vg.hpp"
#include "../utility.hpp"
#include "../mapper.hpp"
#include "../stream.hpp"
#include "../alignment.hpp"

#include <unistd.h>
#include <getopt.h>

using namespace vg;
using namespace vg::subcommand;

void help_annotate(char** argv) {
    cerr << "usage: " << argv[0] << " annotate [options] >output.{gam,vg}" << endl
         << "    -x, --xg-name FILE     an xg index describing a graph" << endl
         << "    -b, --bed-name FILE    a bed file describing a subpath" << endl
         << "    -d, --db-name DIR      a rocksdb index of a GAM" << endl
         << "    -v, --vg FILE          annotate this graph" << endl
         << "    -g, --gcsa FILE        a GCSA2 index file base name" << endl
         << "    -a, --gam FILE         alignments to annotate" << endl
         << "    -p, --positions        annotate alignments with reference positions" << endl
         << "    -n, --novelty          table for each read: name, bp not in xg, nodes not in xg" << endl;
}

int main_annotate(int argc, char** argv) {

    if (argc == 2) {
        help_annotate(argv);
        return 1;
    }

    string xg_name;
    string rocksdb_name;
    string gcsa_name;
    string vg_name;
    string bed_name;
    string gam_name;
    bool add_positions = false;
    bool novelty = false;

    int c;
    optind = 2; // force optind past command positional argument
    while (true) {
        static struct option long_options[] =
        {
            {"gam", required_argument, 0, 'a'},
            {"gcsa", required_argument, 0, 'g'},
            {"positions", no_argument, 0, 'p'},
            {"vg", required_argument, 0, 'v'},
            {"xg-name", required_argument, 0, 'x'},
            {"bed-name", required_argument, 0, 'b'},
            {"db-name", required_argument, 0, 'd'},
            {"novelty", no_argument, 0, 'n'},
            {0, 0, 0, 0}
        };

        int option_index = 0;
        c = getopt_long (argc, argv, "hx:d:v:g:a:pb:n",
                long_options, &option_index);

        // Detect the end of the options.
        if (c == -1)
            break;

        switch (c)
        {
        case 'd':
            rocksdb_name = optarg;
            break;

        case 'x':
            xg_name = optarg;
            break;

        case 'v':
            vg_name = optarg;
            break;

        case 'g':
            gcsa_name = optarg;
            break;

        case 'a':
            gam_name = optarg;
            break;

        case 'b':
            bed_name = optarg;
            break;

        case 'p':
            add_positions = true;
            break;

        case 'n':
            novelty = true;
            break;

        case 'h':
        case '?':
            help_annotate(argv);
            exit(1);
            break;

        default:
            abort ();
        }
    }
    xg::XG* xg_index = nullptr;
    if (!xg_name.empty()) {
        ifstream in(xg_name);
        xg_index = new xg::XG(in);
    } else {
        cerr << "error [vg annotate]: no xg index provided" << endl;
        return 1;
    }

    Mapper mapper(xg_index, nullptr, nullptr);

    if (!gam_name.empty()) {
        vector<Alignment> buffer;
        if (add_positions) {
            //map<string, double> Mapper::alignment_mean_path_positions(const Alignment& aln, bool first_hit_only);
            function<void(Alignment&)> lambda = [&](Alignment& aln) {
                mapper.annotate_with_initial_path_positions(aln);
                buffer.push_back(aln);
                stream::write_buffered(cout, buffer, 100);
            };
            get_input_file(gam_name, [&](istream& in) {
                    stream::for_each(in, lambda);
                });
            stream::write_buffered(cout, buffer, 0); // flush
        } else if (novelty) {
            cout << "name\tlength.bp\tunaligned.bp\tknown.nodes\tknown.bp\tnovel.nodes\tnovel.bp" << endl;
            function<void(Alignment&)> lambda = [&](Alignment& aln) {
                // count the number of positions in the alignment that aren't in the graph
                int total_bp = aln.sequence().size();
                int unaligned_bp = 0;
                int known_nodes = 0;
                int known_bp = 0;
                int novel_nodes = 0;
                int novel_bp = 0;
                for (auto& mapping : aln.path().mapping()) {
                    if (mapping.has_position()) {
                        auto& pos = mapping.position();
                        if (xg_index->has_node(pos.node_id())) {
                            ++known_nodes;
                            known_bp += mapping_to_length(mapping);
                        } else {
                            ++novel_nodes;
                            novel_bp += mapping_to_length(mapping);
                        }
                    } else {
                        unaligned_bp += mapping_to_length(mapping);
                    }
                }
                cout << aln.name() << "\t"
                << total_bp << "\t"
                << unaligned_bp << "\t"
                << known_nodes << "\t"
                << known_bp << "\t"
                << novel_nodes << "\t"
                << novel_bp << endl;
            };
            get_input_file(gam_name, [&](istream& in) {
                    stream::for_each(in, lambda);
                });
        }
    } else if (!bed_name.empty()) {
        vector<Alignment> buffer;
        if (add_positions) {
            ifstream bed_stream(bed_name.c_str());

            parse_bed_regions(bed_stream, xg_index, &buffer);
            stream::write_buffered(cout, buffer, 0); // flush
        }
    } else {
        cerr << "only GAM or BED annotation is implemented" << endl;
        return 1;
    }

    if (xg_index) {
        delete xg_index;
    }

    return 0;
}

static Subcommand vg_annotate("annotate", "annotate alignments with graphs and graphs with alignments",
                              main_annotate);
<commit_msg>Add interface as a subcommand<commit_after>#include "subcommand.hpp"
#include "../vg.hpp"
#include "../utility.hpp"
#include "../mapper.hpp"
#include "../stream.hpp"
#include "../alignment.hpp"

#include <unistd.h>
#include <getopt.h>

using namespace vg;
using namespace vg::subcommand;

void help_annotate(char** argv) {
    cerr << "usage: " << argv[0] << " annotate [options] >output.{gam,vg}" << endl
         << "    -x, --xg-name FILE     an xg index describing a graph" << endl
         << "    -b, --bed-name FILE    a bed file describing a subpath" << endl
         << "    -f, --gff3-name FILE   a gff3 file describing a subpath" << endl
         << "    -t, --gtf-name FILE    a gtf file describing a subpath" << endl
         << "    -d, --db-name DIR      a rocksdb index of a GAM" << endl
         << "    -v, --vg FILE          annotate this graph" << endl
         << "    -g, --gcsa FILE        a GCSA2 index file base name" << endl
         << "    -a, --gam FILE         alignments to annotate" << endl
         << "    -p, --positions        annotate alignments with reference positions" << endl
         << "    -n, --novelty          table for each read: name, bp not in xg, nodes not in xg" << endl;
}

int main_annotate(int argc, char** argv) {

    if (argc == 2) {
        help_annotate(argv);
        return 1;
    }

    string xg_name;
    string rocksdb_name;
    string gcsa_name;
    string vg_name;
    string bed_name;
    string gff3_name;
    string gtf_name;
    string gam_name;
    bool add_positions = false;
    bool novelty = false;

    int c;
    optind = 2; // force optind past command positional argument
    while (true) {
        static struct option long_options[] =
        {
            {"gam", required_argument, 0, 'a'},
            {"gcsa", required_argument, 0, 'g'},
            {"positions", no_argument, 0, 'p'},
            {"vg", required_argument, 0, 'v'},
            {"xg-name", required_argument, 0, 'x'},
            {"bed-name", required_argument, 0, 'b'},
            {"gff3-name", required_argument, 0, 'f'},
            {"gtf-name", required_argument, 0, 't'},
            {"db-name", required_argument, 0, 'd'},
            {"novelty", no_argument, 0, 'n'},
            {0, 0, 0, 0}
        };

        int option_index = 0;
        c = getopt_long (argc, argv, "hx:d:v:g:a:pb:f:t:n",
                long_options, &option_index);

        // Detect the end of the options.
        if (c == -1)
            break;

        switch (c)
        {
        case 'd':
            rocksdb_name = optarg;
            break;

        case 'x':
            xg_name = optarg;
            break;

        case 'v':
            vg_name = optarg;
            break;

        case 'g':
            gcsa_name = optarg;
            break;

        case 'a':
            gam_name = optarg;
            break;

        case 'b':
            bed_name = optarg;
            break;

        case 'f':
            gff3_name = optarg;
            break;

        case 't':
            gtf_name = optarg;
            break;

        case 'p':
            add_positions = true;
            break;

        case 'n':
            novelty = true;
            break;

        case 'h':
        case '?':
            help_annotate(argv);
            exit(1);
            break;

        default:
            abort ();
        }
    }
    xg::XG* xg_index = nullptr;
    if (!xg_name.empty()) {
        ifstream in(xg_name);
        xg_index = new xg::XG(in);
    } else {
        cerr << "error [vg annotate]: no xg index provided" << endl;
        return 1;
    }

    Mapper mapper(xg_index, nullptr, nullptr);

    if (!gam_name.empty()) {
        vector<Alignment> buffer;
        if (add_positions) {
            //map<string, double> Mapper::alignment_mean_path_positions(const Alignment& aln, bool first_hit_only);
            function<void(Alignment&)> lambda = [&](Alignment& aln) {
                mapper.annotate_with_initial_path_positions(aln);
                buffer.push_back(aln);
                stream::write_buffered(cout, buffer, 100);
            };
            get_input_file(gam_name, [&](istream& in) {
                    stream::for_each(in, lambda);
                });
            stream::write_buffered(cout, buffer, 0); // flush
        } else if (novelty) {
            cout << "name\tlength.bp\tunaligned.bp\tknown.nodes\tknown.bp\tnovel.nodes\tnovel.bp" << endl;
            function<void(Alignment&)> lambda = [&](Alignment& aln) {
                // count the number of positions in the alignment that aren't in the graph
                int total_bp = aln.sequence().size();
                int unaligned_bp = 0;
                int known_nodes = 0;
                int known_bp = 0;
                int novel_nodes = 0;
                int novel_bp = 0;
                for (auto& mapping : aln.path().mapping()) {
                    if (mapping.has_position()) {
                        auto& pos = mapping.position();
                        if (xg_index->has_node(pos.node_id())) {
                            ++known_nodes;
                            known_bp += mapping_to_length(mapping);
                        } else {
                            ++novel_nodes;
                            novel_bp += mapping_to_length(mapping);
                        }
                    } else {
                        unaligned_bp += mapping_to_length(mapping);
                    }
                }
                cout << aln.name() << "\t"
                << total_bp << "\t"
                << unaligned_bp << "\t"
                << known_nodes << "\t"
                << known_bp << "\t"
                << novel_nodes << "\t"
                << novel_bp << endl;
            };
            get_input_file(gam_name, [&](istream& in) {
                    stream::for_each(in, lambda);
                });
        }
    } else if (!bed_name.empty()) {
        vector<Alignment> buffer;
        if (add_positions) {
            ifstream bed_stream(bed_name.c_str());

            parse_bed_regions(bed_stream, xg_index, &buffer);
            stream::write_buffered(cout, buffer, 0); // flush
        }
    } else if (!gff3_name.empty()) {
        vector<Alignment> buffer;
        if (add_positions) {
            ifstream gff3_stream(gff3_name.c_str());

            parse_gff3_regions(gff3_stream, xg_index, &buffer);
            stream::write_buffered(cout, buffer, 0); // flush
        }
    } else if (!gtf_name.empty()) {
        vector<Alignment> buffer;
        if (add_positions) {
            ifstream gtf_stream(gtf_name.c_str());

            parse_gtf_regions(gtf_stream, xg_index, &buffer);
            stream::write_buffered(cout, buffer, 0); // flush
        }
    } else {
        cerr << "only GAM or BED annotation is implemented" << endl;
        return 1;
    }

    if (xg_index) {
        delete xg_index;
    }

    return 0;
}

static Subcommand vg_annotate("annotate", "annotate alignments with graphs and graphs with alignments",
                              main_annotate);
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include "tac/ArithmeticIdentities.hpp"
#include "tac/OptimizerUtils.hpp"

using namespace eddic;

void tac::ArithmeticIdentities::operator()(std::shared_ptr<tac::Quadruple>& quadruple){
        switch(quadruple->op){
            case tac::Operator::ADD:
                if(*quadruple->arg1 == 0){
                    replaceRight(*this, quadruple, *quadruple->arg2);
                } else if(*quadruple->arg2 == 0){
                    replaceRight(*this, quadruple, *quadruple->arg1);
                }

                break;
            case tac::Operator::SUB:
                if(*quadruple->arg2 == 0){
                    replaceRight(*this, quadruple, *quadruple->arg1);
                }

                //a = b - b => a = 0
                else if(*quadruple->arg1 == *quadruple->arg2){
                    replaceRight(*this, quadruple, 0);
                }

                //a = 0 - b => a = -b
                else if(*quadruple->arg1 == 0){
                    replaceRight(*this, quadruple, *quadruple->arg2, tac::Operator::MINUS);
                }

                break;
            case tac::Operator::MUL:
                if(*quadruple->arg1 == 1){
                    replaceRight(*this, quadruple, *quadruple->arg2);
                } else if(*quadruple->arg2 == 1){
                    replaceRight(*this, quadruple, *quadruple->arg1);
                }

                else if(*quadruple->arg1 == 0){
                    replaceRight(*this, quadruple, 0);
                } else if(*quadruple->arg2 == 0){
                    replaceRight(*this, quadruple, 0);
                }

                else if(*quadruple->arg1 == -1){
                    replaceRight(*this, quadruple, *quadruple->arg2, tac::Operator::MINUS);
                } else if(*quadruple->arg2 == -1){
                    replaceRight(*this, quadruple, *quadruple->arg1, tac::Operator::MINUS);
                }

                break;
            case tac::Operator::DIV:
                if(*quadruple->arg2 == 1){
                    replaceRight(*this, quadruple, *quadruple->arg1);
                }

                else if(*quadruple->arg1 == 0){
                    replaceRight(*this, quadruple, 0);
                }

                //a = b / b => a = 1
                else if(*quadruple->arg1 == *quadruple->arg2){
                    replaceRight(*this, quadruple, 1);
                }

                else if(*quadruple->arg2 == 1){
                    replaceRight(*this, quadruple, *quadruple->arg1, tac::Operator::MINUS);
                }

                break;
            default:
                break;
        }
}
<commit_msg>Apply arithmetic identities to float<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include "tac/ArithmeticIdentities.hpp"
#include "tac/OptimizerUtils.hpp"

using namespace eddic;

void tac::ArithmeticIdentities::operator()(std::shared_ptr<tac::Quadruple>& quadruple){
        switch(quadruple->op){
            case tac::Operator::ADD:
                if(*quadruple->arg1 == 0){
                    replaceRight(*this, quadruple, *quadruple->arg2);
                } else if(*quadruple->arg2 == 0){
                    replaceRight(*this, quadruple, *quadruple->arg1);
                }

                break;
            case tac::Operator::SUB:
                if(*quadruple->arg2 == 0){
                    replaceRight(*this, quadruple, *quadruple->arg1);
                }

                //a = b - b => a = 0
                else if(*quadruple->arg1 == *quadruple->arg2){
                    replaceRight(*this, quadruple, 0);
                }

                //a = 0 - b => a = -b
                else if(*quadruple->arg1 == 0){
                    replaceRight(*this, quadruple, *quadruple->arg2, tac::Operator::MINUS);
                }

                break;
            case tac::Operator::MUL:
                if(*quadruple->arg1 == 1){
                    replaceRight(*this, quadruple, *quadruple->arg2);
                } else if(*quadruple->arg2 == 1){
                    replaceRight(*this, quadruple, *quadruple->arg1);
                }

                else if(*quadruple->arg1 == 0){
                    replaceRight(*this, quadruple, 0);
                } else if(*quadruple->arg2 == 0){
                    replaceRight(*this, quadruple, 0);
                }

                else if(*quadruple->arg1 == -1){
                    replaceRight(*this, quadruple, *quadruple->arg2, tac::Operator::MINUS);
                } else if(*quadruple->arg2 == -1){
                    replaceRight(*this, quadruple, *quadruple->arg1, tac::Operator::MINUS);
                }

                break;
            case tac::Operator::DIV:
                if(*quadruple->arg2 == 1){
                    replaceRight(*this, quadruple, *quadruple->arg1);
                }

                else if(*quadruple->arg1 == 0){
                    replaceRight(*this, quadruple, 0);
                }

                //a = b / b => a = 1
                else if(*quadruple->arg1 == *quadruple->arg2){
                    replaceRight(*this, quadruple, 1);
                }

                else if(*quadruple->arg2 == 1){
                    replaceRight(*this, quadruple, *quadruple->arg1, tac::Operator::MINUS);
                }

                break;
            case tac::Operator::FADD:
                if(*quadruple->arg1 == 0.0){
                    replaceRight(*this, quadruple, *quadruple->arg2, tac::Operator::FASSIGN);
                } else if(*quadruple->arg2 == 0.0){
                    replaceRight(*this, quadruple, *quadruple->arg1, tac::Operator::FASSIGN);
                }

                break;
            case tac::Operator::FSUB:
                if(*quadruple->arg2 == 0.0){
                    replaceRight(*this, quadruple, *quadruple->arg1, tac::Operator::FASSIGN);
                }

                //a = b - b => a = 0
                else if(*quadruple->arg1 == *quadruple->arg2){
                    replaceRight(*this, quadruple, 0.0, tac::Operator::FASSIGN);
                }

                //a = 0 - b => a = -b
                else if(*quadruple->arg1 == 0.0){
                    replaceRight(*this, quadruple, *quadruple->arg2, tac::Operator::FMINUS);
                }

                break;
            case tac::Operator::FMUL:
                if(*quadruple->arg1 == 1.0){
                    replaceRight(*this, quadruple, *quadruple->arg2, tac::Operator::FASSIGN);
                } else if(*quadruple->arg2 == 1.0){
                    replaceRight(*this, quadruple, *quadruple->arg1, tac::Operator::FASSIGN);
                }

                else if(*quadruple->arg1 == 0.0){
                    replaceRight(*this, quadruple, 0.0, tac::Operator::FASSIGN);
                } else if(*quadruple->arg2 == 0){
                    replaceRight(*this, quadruple, 0.0, tac::Operator::FASSIGN);
                }

                else if(*quadruple->arg1 == -1.0){
                    replaceRight(*this, quadruple, *quadruple->arg2, tac::Operator::FMINUS);
                } else if(*quadruple->arg2 == -1.0){
                    replaceRight(*this, quadruple, *quadruple->arg1, tac::Operator::FMINUS);
                }

                break;
            case tac::Operator::FDIV:
                if(*quadruple->arg2 == 1.0){
                    replaceRight(*this, quadruple, *quadruple->arg1, tac::Operator::FASSIGN);
                }

                else if(*quadruple->arg1 == 0.0){
                    replaceRight(*this, quadruple, 0.0, tac::Operator::FASSIGN);
                }

                //a = b / b => a = 1
                else if(*quadruple->arg1 == *quadruple->arg2){
                    replaceRight(*this, quadruple, 1.0, tac::Operator::FASSIGN);
                }

                else if(*quadruple->arg2 == 1.0){
                    replaceRight(*this, quadruple, *quadruple->arg1, tac::Operator::MINUS);
                }

                break;
            default:
                break;
        }
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libetonyek project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <algorithm>
#include <string>

#include <boost/make_shared.hpp>

#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>

#include "IWASnappyStream.h"
#include "IWORKMemoryStream.h"

using namespace libetonyek;

using std::string;

namespace test
{

namespace
{

void assertCompressed(const string &message, const unsigned char *const expected, const size_t expectedSize, const unsigned char *const compressed, const size_t compressedSize)
{
  const RVNGInputStreamPtr_t stream(new IWORKMemoryStream(compressed, compressedSize));
  const RVNGInputStreamPtr_t uncompressedStream(IWASnappyStream::uncompressBlock(stream));
  unsigned long uncompressedSize = 0;
  const unsigned char *const uncompressed = uncompressedStream->read(expectedSize, uncompressedSize);
  CPPUNIT_ASSERT_EQUAL_MESSAGE(message + ": size", expectedSize, uncompressedSize);
  CPPUNIT_ASSERT_MESSAGE(message + ": input exhausted", uncompressedStream->isEnd());
  CPPUNIT_ASSERT_MESSAGE(message + ": content", std::equal(expected, expected + expectedSize, uncompressed));
}

void assertAnyException(const string &message, const unsigned char *const compressed, const size_t compressedSize)
{
  const RVNGInputStreamPtr_t stream(new IWORKMemoryStream(compressed, compressedSize));
  bool exception = false;
  try
  {
    IWASnappyStream uncompressedStream(stream);
  }
  catch (...)
  {
    exception = true;
  }
  CPPUNIT_ASSERT_MESSAGE(message, exception);
}

}

class IWASnappyStreamTest : public CPPUNIT_NS::TestFixture
{
public:
  virtual void setUp();
  virtual void tearDown();

private:
  CPPUNIT_TEST_SUITE(IWASnappyStreamTest);
  CPPUNIT_TEST(testSimple);
  CPPUNIT_TEST(testInvalid);
  CPPUNIT_TEST_SUITE_END();

private:
  void testSimple();
  void testInvalid();
};

void IWASnappyStreamTest::setUp()
{
}

void IWASnappyStreamTest::tearDown()
{
}

#define BYTES(b) (reinterpret_cast<const unsigned char *>(b)), (sizeof(b) - 1)

void IWASnappyStreamTest::testSimple()
{
  // assertCompressed("empty", BYTES(""), BYTES("\x1\x0"));
  assertCompressed("literal run", BYTES("a"), BYTES("\x1\x0\x61"));
  assertCompressed("literal run", BYTES("ab"), BYTES("\x2\x4\x61\x62"));
  assertCompressed("long literal run", BYTES("ab"), BYTES("\x2\xf0\x1\x61\x62"));
  assertCompressed("very long literal run", BYTES("ab"), BYTES("\x2\xf4\x1\x0\x61\x62"));
  assertCompressed("extra long literal run", BYTES("ab"), BYTES("\x2\xf8\x1\x0\x0\x61\x62"));
  assertCompressed("near reference",
                   BYTES("abcdabcd"), BYTES("\x8\xc\x61\x62\x63\x64\x1\x4"));
  assertCompressed("near reference of length 5",
                   BYTES("abcdeabcde"), BYTES("\xa\x10\x61\x62\x63\x64\x65\x5\x5"));
  assertCompressed("near reference to the middle of a run",
                   BYTES("abcdefbcde"), BYTES("\xa\x14\x61\x62\x63\x64\x65\x66\x1\x5"));
  assertCompressed("repeated near reference",
                   BYTES("abcbcbcb"), BYTES("\x8\x8\x61\x62\x63\x5\x2"));
  assertCompressed("far reference", BYTES("aa"), BYTES("\x2\x0\x61\x2\x1\x0"));
  assertCompressed("far reference of length 2",
                   BYTES("abab"), BYTES("\x4\x4\x61\x62\x6\x2\x0"));
}

void IWASnappyStreamTest::testInvalid()
{
  assertAnyException("Too short literal run", BYTES("\x4\x10\x61"));
  assertAnyException("Near reference without any data", BYTES("\x1\x5\x0"));
  assertAnyException("Far reference without any data", BYTES("\x1\x2\x1\x0"));
}

#undef BYTES

CPPUNIT_TEST_SUITE_REGISTRATION(IWASnappyStreamTest);

}

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<commit_msg>add test for decompression of a complete input<commit_after>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libetonyek project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <algorithm>
#include <string>

#include <boost/make_shared.hpp>

#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>

#include "IWASnappyStream.h"
#include "IWORKMemoryStream.h"

using namespace libetonyek;

using std::string;

namespace test
{

namespace
{

void assertCompressed(const string &message, const unsigned char *const expected, const size_t expectedSize, const unsigned char *const compressed, const size_t compressedSize)
{
  const RVNGInputStreamPtr_t stream(new IWORKMemoryStream(compressed, compressedSize));
  const RVNGInputStreamPtr_t uncompressedStream(IWASnappyStream::uncompressBlock(stream));
  unsigned long uncompressedSize = 0;
  const unsigned char *const uncompressed = uncompressedStream->read(expectedSize, uncompressedSize);
  CPPUNIT_ASSERT_EQUAL_MESSAGE(message + ": size", expectedSize, uncompressedSize);
  CPPUNIT_ASSERT_MESSAGE(message + ": input exhausted", uncompressedStream->isEnd());
  CPPUNIT_ASSERT_MESSAGE(message + ": content", std::equal(expected, expected + expectedSize, uncompressed));
}

void assertCompressedFull(const string &message, const unsigned char *const expected, const size_t expectedSize, const unsigned char *const compressed, const size_t compressedSize)
{
  const RVNGInputStreamPtr_t stream(new IWORKMemoryStream(compressed, compressedSize));
  IWASnappyStream uncompressedStream(stream);
  unsigned long uncompressedSize = 0;
  const unsigned char *const uncompressed = uncompressedStream.read(expectedSize, uncompressedSize);
  CPPUNIT_ASSERT_EQUAL_MESSAGE(message + ": size", expectedSize, uncompressedSize);
  CPPUNIT_ASSERT_MESSAGE(message + ": input exhausted", uncompressedStream.isEnd());
  CPPUNIT_ASSERT_MESSAGE(message + ": content", std::equal(expected, expected + expectedSize, uncompressed));
}

void assertAnyException(const string &message, const unsigned char *const compressed, const size_t compressedSize)
{
  const RVNGInputStreamPtr_t stream(new IWORKMemoryStream(compressed, compressedSize));
  bool exception = false;
  try
  {
    IWASnappyStream uncompressedStream(stream);
  }
  catch (...)
  {
    exception = true;
  }
  CPPUNIT_ASSERT_MESSAGE(message, exception);
}

}

class IWASnappyStreamTest : public CPPUNIT_NS::TestFixture
{
public:
  virtual void setUp();
  virtual void tearDown();

private:
  CPPUNIT_TEST_SUITE(IWASnappyStreamTest);
  CPPUNIT_TEST(testBlock);
  CPPUNIT_TEST(testInvalid);
  CPPUNIT_TEST(testFull);
  CPPUNIT_TEST_SUITE_END();

private:
  void testBlock();
  void testInvalid();
  void testFull();
};

void IWASnappyStreamTest::setUp()
{
}

void IWASnappyStreamTest::tearDown()
{
}

#define BYTES(b) (reinterpret_cast<const unsigned char *>(b)), (sizeof(b) - 1)

void IWASnappyStreamTest::testBlock()
{
  // assertCompressed("empty", BYTES(""), BYTES("\x1\x0"));
  assertCompressed("literal run", BYTES("a"), BYTES("\x1\x0\x61"));
  assertCompressed("literal run", BYTES("ab"), BYTES("\x2\x4\x61\x62"));
  assertCompressed("long literal run", BYTES("ab"), BYTES("\x2\xf0\x1\x61\x62"));
  assertCompressed("very long literal run", BYTES("ab"), BYTES("\x2\xf4\x1\x0\x61\x62"));
  assertCompressed("extra long literal run", BYTES("ab"), BYTES("\x2\xf8\x1\x0\x0\x61\x62"));
  assertCompressed("near reference",
                   BYTES("abcdabcd"), BYTES("\x8\xc\x61\x62\x63\x64\x1\x4"));
  assertCompressed("near reference of length 5",
                   BYTES("abcdeabcde"), BYTES("\xa\x10\x61\x62\x63\x64\x65\x5\x5"));
  assertCompressed("near reference to the middle of a run",
                   BYTES("abcdefbcde"), BYTES("\xa\x14\x61\x62\x63\x64\x65\x66\x1\x5"));
  assertCompressed("repeated near reference",
                   BYTES("abcbcbcb"), BYTES("\x8\x8\x61\x62\x63\x5\x2"));
  assertCompressed("far reference", BYTES("aa"), BYTES("\x2\x0\x61\x2\x1\x0"));
  assertCompressed("far reference of length 2",
                   BYTES("abab"), BYTES("\x4\x4\x61\x62\x6\x2\x0"));
}

void IWASnappyStreamTest::testInvalid()
{
  assertAnyException("Too short literal run", BYTES("\x4\x10\x61"));
  assertAnyException("Near reference without any data", BYTES("\x1\x5\x0"));
  assertAnyException("Far reference without any data", BYTES("\x1\x2\x1\x0"));
}

void IWASnappyStreamTest::testFull()
{
  assertCompressedFull("literal run", BYTES("a"), BYTES("\x0\x3\x0\x0\x1\x0\x61"));
}

#undef BYTES

CPPUNIT_TEST_SUITE_REGISTRATION(IWASnappyStreamTest);

}

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<|endoftext|>


<commit_before>/*
 * pHashTest.cpp
 *
 *  Created on: 25 Jul 2013
 *      Author: nicholas
 */

#include <gtest/gtest.h>
#include <iostream>
#include "../../include/hash/ImagePHash.hpp"
#include <GraphicsMagick/Magick++.h>

using namespace Magick;

TEST(ImagePHashTest, hashImage) {
	ImagePHash iph;
	long pHash = iph.getLongHash("src/test/hash/testImage.jpg");
	ASSERT_EQ(1111,pHash);
}

int main(int argc, char **argv) {
	 BasicConfigurator config;
	 config.configure();
::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

<commit_msg>Updated expected test value<commit_after>/*
 * pHashTest.cpp
 *
 *  Created on: 25 Jul 2013
 *      Author: nicholas
 */

#include <gtest/gtest.h>
#include <iostream>
#include "../../include/hash/ImagePHash.hpp"
#include <GraphicsMagick/Magick++.h>

using namespace Magick;

TEST(ImagePHashTest, hashImage) {
	ImagePHash iph;
	long pHash = iph.getLongHash("src/test/hash/testImage.jpg");
	ASSERT_EQ(7655956633439617023,pHash);
}

int main(int argc, char **argv) {
	 BasicConfigurator config;
	 config.configure();
::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

<|endoftext|>