<commit_before>#include <re2/re2.h>
#include <string>
#include <iostream>
#include <vector>

using namespace std;

static int maxMemoryBudget = 128 << 20; // 128 MiB

typedef struct {
    int start;
    int end;
} Range;

typedef struct {
    bool hasMatch;
    int numGroups;
    char** groups;
    Range* ranges;
} REMatchResult;

//clrsb: Number of leading bits equal to the sign bit (which we set to 0)
//clrsb(~b) - clrsb(0) + 8: Number of leading one bits in the byte b
#define count_leading_ones(b) __builtin_clrsb(~(char)(b))  - __builtin_clrsb(0) + 8

/**
 * Builds a lookup table (LUT) that allows mapping a cstring (memory) index
 * of a string to lookup (key: cstring coordinate) the character index in a UTF8 string.
 *
 * Example: abcödef -> 0 1 2 3 3 4 5 6
 * @param s The string to map
 * @param len The length of s
 * @return a new[]-allocated int array of size len, containing the LUT
 */
int* buildUTF8IndexLUT(const char* s, size_t len) {
    int* lut = new int[len];
    int sidx = 0; // Index in the LUT
    for(unsigned int i = 0 ; i < len ; i++) { // i = Current index in s
        if((s[i] & 0x80) == 0) { //Single-byte character
            lut[i] = sidx;
            sidx++;
        } else { //Start of multibyte. This branch handles the entire multibyte
            int multibyteSize = count_leading_ones(s[i]);
            //Set the next <multibyteSize> LUT entries to the current sidx
            for(unsigned int j = i; j < multibyteSize + i; j++) {
                lut[j] = sidx;
            }
            //Advance i to after the multibyte, but advance sidx by only 1
            // as the multibyte is treated as a single character
            i += multibyteSize - 1;
            sidx++;
        }
    }
    return lut;
}
/**
 * A multi match object which contains either:
 *  - A list of group matches (individual groups)
 *  - A list of regular matches (one group per match)
 */
typedef struct {
    /**
     * Length of either groupMatches or matches (depending on value of hasGroupMatches)
     */
    int numMatches;
    /**
     * If this result contains group matches, contains the number of groups,
     * i.e. the number of elements in every groupMatches element.
     * Undefined if groupMatches == NULL
     * At least one (in case )
     */
    int numElements;
    /**
     * Only filled if this result has group matches (else NULL)
     */
    char*** groupMatches;
    /**
     * Match ranges
     */
    Range** ranges;
} REMultiMatchResult;

/**
 * Lookup table that maps the Python anchor arg to actual anchors.
 */
static const re2::RE2::Anchor anchorLUT[] = {
    re2::RE2::UNANCHORED, re2::RE2::ANCHOR_BOTH, re2::RE2::ANCHOR_START};

/**
 * Copy a StringPiece array to a C string list,
 * each level of which is allocated using new[]
 */
char** copyGroups(const re2::StringPiece* groupsSrc, int numGroups) {
    char** groups = new char*[numGroups];
    for (int i = 0; i < numGroups; ++i) {
        char* group = new char[groupsSrc[i].size() + 1];
        group[groupsSrc[i].size()] = 0; //Insert C terminator
        //Copy actual string
        memcpy(group, groupsSrc[i].data(), groupsSrc[i].size());
        groups[i] = group;
    }
    return groups;
}

extern "C" {
    re2::RE2* RE2_new(const char* pattern, bool caseInsensitive) {
        re2::RE2::Options options;
        options.Copy(re2::RE2::Quiet);
        if(caseInsensitive) {
            options.set_case_sensitive(false);
        }
        options.set_max_mem(maxMemoryBudget);
        re2::RE2* ptr = new re2::RE2(pattern, options);
        return ptr;
    }

    int NumCapturingGroups(re2::RE2* re_obj) {
        return re_obj->NumberOfCapturingGroups();
    }

    void FreeREMatchResult(REMatchResult mr) {
        if(mr.groups != NULL) {
            for (int i = 0; i < mr.numGroups; ++i) {
                if(mr.groups[i] != NULL) {
                    delete[] mr.groups[i];
                }
            }
            delete[] mr.groups;
            mr.groups = NULL;
        }
    }

    void FreeREMultiMatchResult(REMultiMatchResult mr) {
        if(mr.groupMatches != NULL) {
            for (int i = 0; i < mr.numMatches; ++i) {
                if(mr.groupMatches[i] != NULL) {
                    for (int j = 0; j < mr.numElements; ++j) {
                        if(mr.groupMatches[i][j] != NULL) {
                            delete[] mr.groupMatches[i][j];
                        }
                    }
                    delete[] mr.groupMatches[i];
                    mr.groupMatches[i] = NULL;
                }
                if(mr.ranges[i] != NULL) {
                    delete[] mr.ranges[i];
                    mr.ranges[i] = NULL;
                }
            }
            delete[] mr.groupMatches;
            mr.groupMatches = NULL;
        }
        if(mr.ranges != NULL) {
            delete[] mr.ranges;
            mr.ranges = NULL;
        }
    }

    REMultiMatchResult FindAllMatches(re2::RE2* re_obj, const char* dataArg, int anchorArg, int startpos) {
        re2::StringPiece data(dataArg);
        if(anchorArg >= 2) {
            anchorArg = 0; //Should not happen
        }
        re2::RE2::Anchor anchor = anchorLUT[anchorArg];
        //Build UTF8 lookup table for string
        int* utf8LUT = buildUTF8IndexLUT(data.data(), data.size());
        //Initialize return arg
        REMultiMatchResult ret;
        ret.numMatches = 0;
        ret.groupMatches = NULL;
        //Map anchor for easier Python iface
        int numGroups = re_obj->NumberOfCapturingGroups();
        ret.numElements = 1 + numGroups;
        int pos = startpos;
        int endidx = data.size();
        //We don't know the size of this in advance, so we'll need to allocate now
        vector<re2::StringPiece*> allMatches;
        vector<Range*> allRanges;
        /**
         * Iterate over all non-overlapping (!) matches
         */
        while(true) {
            //Perform match
            re2::StringPiece* matchTmp = new re2::StringPiece[ret.numElements];
            bool hasMatch = re_obj->Match(data, pos, endidx,
                 anchor, matchTmp, ret.numElements);
            if(!hasMatch) {
                delete[] matchTmp;
                break;
            }
            //Add matchlist
            allMatches.push_back(matchTmp);
            //Increment position pointer so we get the next hit
            // We are returning non-overlapping matches, so this is OK
            if(matchTmp[0].size() == 0) { //Zero-length match
                pos++;
            } else {
                pos += matchTmp[0].data() - dataArg + matchTmp[0].size();
            }
            //Copy range
            Range* rangeTmp = new Range[ret.numElements];
            for (int i = 0; i < ret.numElements; ++i) {
                int rawStart = matchTmp[i].data() - dataArg;
                rangeTmp[i].start = utf8LUT[rawStart];
                rangeTmp[i].end = utf8LUT[rawStart + matchTmp[i].size()];
            }
            allRanges.push_back(rangeTmp);
        }
        //Compute final size
        ret.numMatches = allMatches.size();
        //Convert match vector to group vector (3D)
        ret.groupMatches = new char**[allMatches.size()];
        ret.ranges = new Range*[allMatches.size()];
        for (size_t i = 0; i < allMatches.size(); ++i) {
            /*
             * Always return full match plus all groups
             * This does not match the re group behaviour, but
             *  this is handled in Python code
             */
            ret.groupMatches[i] = copyGroups(allMatches[i], ret.numElements);
            //Copy ranges
            ret.ranges[i] = new Range[ret.numElements];
            memcpy(ret.ranges[i], allRanges[i], sizeof(Range*) * ret.numElements);
        }
        //Cleanup
        delete[] utf8LUT;
        for (size_t i = 0; i < allMatches.size(); ++i) {
            if(allMatches[i] != NULL) {
                delete[] allMatches[i];
            }
            if(allRanges[i] != NULL) {
                delete[] allRanges[i];
            }
        }
        return ret;
    }

    REMatchResult FindSingleMatch(re2::RE2* re_obj, const char* dataArg, bool startAnchored, int startpos) {
        re2::StringPiece data(dataArg);
        REMatchResult ret;
        ret.numGroups = re_obj->NumberOfCapturingGroups() + 1;
        //Declare group target array
        re2::StringPiece* groups = new re2::StringPiece[ret.numGroups]();
        //Perform either
        re2::RE2::Anchor anchor = startAnchored ? re2::RE2::ANCHOR_START : re2::RE2::UNANCHORED;
        ret.hasMatch = re_obj->Match(data, startpos, data.size(),
                anchor, groups, ret.numGroups);
        //Copy groups
        if(ret.hasMatch) {
            ret.groups = copyGroups(groups, ret.numGroups);
        } else {
            ret.groups = NULL;
        }
        //Cleanup
        delete[] groups;
        //Return
        return ret;
    }

    void RE2_delete(re2::RE2* re_obj) {
        delete re_obj;
    }

    string* RE2_GlobalReplace(re2::RE2* re_obj, const char* str, const char* rewrite) {
        string* ptr_s = new string(str);
        re2::StringPiece sp(rewrite);

        re2::RE2::GlobalReplace(ptr_s, *re_obj, sp);
        return ptr_s;
    }

    const char* get_c_str(string* ptr_str) {
        if(ptr_str == NULL) {
            return NULL;
        }
        return ptr_str->c_str();
    }

    void RE2_delete_string_ptr(string* ptr) {
        delete ptr;
    }

    const char* get_error_msg(re2::RE2* re_obj) {
        if(!re_obj) {
            return "";
        }
        string* ptr_s = (string*) &(re_obj->error());
        return get_c_str(ptr_s);
    }

    bool ok(re2::RE2* re_obj) {
        if(!re_obj) {
            return false;
        }
        return re_obj->ok();
    }

    void RE2_SetMaxMemory(int maxmem) {
        maxMemoryBudget = maxmem;
    }

}
<commit_msg>Added ranges for single matches<commit_after>#include <re2/re2.h>
#include <string>
#include <iostream>
#include <vector>

using namespace std;

static int maxMemoryBudget = 128 << 20; // 128 MiB

typedef struct {
    int start;
    int end;
} Range;

typedef struct {
    bool hasMatch;
    int numGroups;
    char** groups;
    Range* ranges;
} REMatchResult;

//clrsb: Number of leading bits equal to the sign bit (which we set to 0)
//clrsb(~b) - clrsb(0) + 8: Number of leading one bits in the byte b
#define count_leading_ones(b) __builtin_clrsb(~(char)(b))  - __builtin_clrsb(0) + 8

/**
 * Builds a lookup table (LUT) that allows mapping a cstring (memory) index
 * of a string to lookup (key: cstring coordinate) the character index in a UTF8 string.
 *
 * Example: abcödef -> 0 1 2 3 3 4 5 6
 * @param s The string to map
 * @param len The length of s
 * @return a new[]-allocated int array of size len, containing the LUT
 */
int* buildUTF8IndexLUT(const char* s, size_t len) {
    int* lut = new int[len];
    int sidx = 0; // Index in the LUT
    for(unsigned int i = 0 ; i < len ; i++) { // i = Current index in s
        if((s[i] & 0x80) == 0) { //Single-byte character
            lut[i] = sidx;
            sidx++;
        } else { //Start of multibyte. This branch handles the entire multibyte
            int multibyteSize = count_leading_ones(s[i]);
            //Set the next <multibyteSize> LUT entries to the current sidx
            for(unsigned int j = i; j < multibyteSize + i; j++) {
                lut[j] = sidx;
            }
            //Advance i to after the multibyte, but advance sidx by only 1
            // as the multibyte is treated as a single character
            i += multibyteSize - 1;
            sidx++;
        }
    }
    return lut;
}
/**
 * A multi match object which contains either:
 *  - A list of group matches (individual groups)
 *  - A list of regular matches (one group per match)
 */
typedef struct {
    /**
     * Length of either groupMatches or matches (depending on value of hasGroupMatches)
     */
    int numMatches;
    /**
     * If this result contains group matches, contains the number of groups,
     * i.e. the number of elements in every groupMatches element.
     * Undefined if groupMatches == NULL
     * At least one (in case )
     */
    int numElements;
    /**
     * Only filled if this result has group matches (else NULL)
     */
    char*** groupMatches;
    /**
     * Match ranges
     */
    Range** ranges;
} REMultiMatchResult;

/**
 * Lookup table that maps the Python anchor arg to actual anchors.
 */
static const re2::RE2::Anchor anchorLUT[] = {
    re2::RE2::UNANCHORED, re2::RE2::ANCHOR_BOTH, re2::RE2::ANCHOR_START};

/**
 * Copy a StringPiece array to a C string list,
 * each level of which is allocated using new[]
 */
char** copyGroups(const re2::StringPiece* groupsSrc, int numGroups) {
    char** groups = new char*[numGroups];
    for (int i = 0; i < numGroups; ++i) {
        char* group = new char[groupsSrc[i].size() + 1];
        group[groupsSrc[i].size()] = 0; //Insert C terminator
        //Copy actual string
        memcpy(group, groupsSrc[i].data(), groupsSrc[i].size());
        groups[i] = group;
    }
    return groups;
}

extern "C" {
    re2::RE2* RE2_new(const char* pattern, bool caseInsensitive) {
        re2::RE2::Options options;
        options.Copy(re2::RE2::Quiet);
        if(caseInsensitive) {
            options.set_case_sensitive(false);
        }
        options.set_max_mem(maxMemoryBudget);
        re2::RE2* ptr = new re2::RE2(pattern, options);
        return ptr;
    }

    int NumCapturingGroups(re2::RE2* re_obj) {
        return re_obj->NumberOfCapturingGroups();
    }

    void FreeREMatchResult(REMatchResult mr) {
        if(mr.groups != NULL) {
            for (int i = 0; i < mr.numGroups; ++i) {
                if(mr.groups[i] != NULL) {
                    delete[] mr.groups[i];
                }
            }
            delete[] mr.groups;
            mr.groups = NULL;
        }
        if(mr.ranges != NULL) {
            delete[] mr.ranges;
            mr.ranges = NULL;
        }
    }

    void FreeREMultiMatchResult(REMultiMatchResult mr) {
        if(mr.groupMatches != NULL) {
            for (int i = 0; i < mr.numMatches; ++i) {
                if(mr.groupMatches[i] != NULL) {
                    for (int j = 0; j < mr.numElements; ++j) {
                        if(mr.groupMatches[i][j] != NULL) {
                            delete[] mr.groupMatches[i][j];
                        }
                    }
                    delete[] mr.groupMatches[i];
                    mr.groupMatches[i] = NULL;
                }
                if(mr.ranges[i] != NULL) {
                    delete[] mr.ranges[i];
                    mr.ranges[i] = NULL;
                }
            }
            delete[] mr.groupMatches;
            mr.groupMatches = NULL;
        }
        if(mr.ranges != NULL) {
            delete[] mr.ranges;
            mr.ranges = NULL;
        }
    }

    REMultiMatchResult FindAllMatches(re2::RE2* re_obj, const char* dataArg, int anchorArg, int startpos) {
        re2::StringPiece data(dataArg);
        if(anchorArg >= 2) {
            anchorArg = 0; //Should not happen
        }
        re2::RE2::Anchor anchor = anchorLUT[anchorArg];
        //Build UTF8 lookup table for string
        int* utf8LUT = buildUTF8IndexLUT(data.data(), data.size());
        //Initialize return arg
        REMultiMatchResult ret;
        ret.numMatches = 0;
        ret.groupMatches = NULL;
        //Map anchor for easier Python iface
        int numGroups = re_obj->NumberOfCapturingGroups();
        ret.numElements = 1 + numGroups;
        int pos = startpos;
        int endidx = data.size();
        //We don't know the size of this in advance, so we'll need to allocate now
        vector<re2::StringPiece*> allMatches;
        vector<Range*> allRanges;
        /**
         * Iterate over all non-overlapping (!) matches
         */
        while(true) {
            //Perform match
            re2::StringPiece* matchTmp = new re2::StringPiece[ret.numElements];
            bool hasMatch = re_obj->Match(data, pos, endidx,
                 anchor, matchTmp, ret.numElements);
            if(!hasMatch) {
                delete[] matchTmp;
                break;
            }
            //Add matchlist
            allMatches.push_back(matchTmp);
            //Increment position pointer so we get the next hit
            // We are returning non-overlapping matches, so this is OK
            if(matchTmp[0].size() == 0) { //Zero-length match
                pos++;
            } else {
                pos += matchTmp[0].data() - dataArg + matchTmp[0].size();
            }
            //Copy range
            Range* rangeTmp = new Range[ret.numElements];
            for (int i = 0; i < ret.numElements; ++i) {
                int rawStart = matchTmp[i].data() - dataArg;
                rangeTmp[i].start = utf8LUT[rawStart];
                rangeTmp[i].end = utf8LUT[rawStart + matchTmp[i].size()];
            }
            allRanges.push_back(rangeTmp);
        }
        //Compute final size
        ret.numMatches = allMatches.size();
        //Convert match vector to group vector (3D)
        ret.groupMatches = new char**[allMatches.size()];
        ret.ranges = new Range*[allMatches.size()];
        for (size_t i = 0; i < allMatches.size(); ++i) {
            /*
             * Always return full match plus all groups
             * This does not match the re group behaviour, but
             *  this is handled in Python code
             */
            ret.groupMatches[i] = copyGroups(allMatches[i], ret.numElements);
            //Copy ranges
            ret.ranges[i] = new Range[ret.numElements];
            memcpy(ret.ranges[i], allRanges[i], sizeof(Range*) * ret.numElements);
        }
        //Cleanup
        delete[] utf8LUT;
        for (size_t i = 0; i < allMatches.size(); ++i) {
            if(allMatches[i] != NULL) {
                delete[] allMatches[i];
            }
            if(allRanges[i] != NULL) {
                delete[] allRanges[i];
            }
        }
        return ret;
    }

    REMatchResult FindSingleMatch(re2::RE2* re_obj, const char* dataArg, bool startAnchored, int startpos) {
        re2::StringPiece data(dataArg);
        REMatchResult ret;
        ret.numGroups = re_obj->NumberOfCapturingGroups() + 1;
        //Declare group target array
        re2::StringPiece* groups = new re2::StringPiece[ret.numGroups]();
        //Build UTF8 lookup table for string
        int* utf8LUT = buildUTF8IndexLUT(data.data(), data.size());
        //Perform either
        re2::RE2::Anchor anchor = startAnchored ? re2::RE2::ANCHOR_START : re2::RE2::UNANCHORED;
        ret.hasMatch = re_obj->Match(data, startpos, data.size(),
                anchor, groups, ret.numGroups);
        //Copy groups
        if(ret.hasMatch) {
            ret.groups = copyGroups(groups, ret.numGroups);
            //Copy ranges
            ret.ranges = new Range[ret.numGroups];
            for (int i = 0; i < ret.numGroups; ++i) {
                int rawStart = groups[i].data() - dataArg;
                ret.ranges[i].start = utf8LUT[rawStart];
                ret.ranges[i].end = utf8LUT[rawStart + groups[i].size()];
            }
        } else {
            ret.groups = NULL;
            ret.ranges = NULL;
        }
        //Cleanup
        delete[] groups;
        delete[] utf8LUT;
        //Return
        return ret;
    }

    void RE2_delete(re2::RE2* re_obj) {
        delete re_obj;
    }

    string* RE2_GlobalReplace(re2::RE2* re_obj, const char* str, const char* rewrite) {
        string* ptr_s = new string(str);
        re2::StringPiece sp(rewrite);

        re2::RE2::GlobalReplace(ptr_s, *re_obj, sp);
        return ptr_s;
    }

    const char* get_c_str(string* ptr_str) {
        if(ptr_str == NULL) {
            return NULL;
        }
        return ptr_str->c_str();
    }

    void RE2_delete_string_ptr(string* ptr) {
        delete ptr;
    }

    const char* get_error_msg(re2::RE2* re_obj) {
        if(!re_obj) {
            return "";
        }
        string* ptr_s = (string*) &(re_obj->error());
        return get_c_str(ptr_s);
    }

    bool ok(re2::RE2* re_obj) {
        if(!re_obj) {
            return false;
        }
        return re_obj->ok();
    }

    void RE2_SetMaxMemory(int maxmem) {
        maxMemoryBudget = maxmem;
    }

}
<|endoftext|>


<commit_before>/*==========================================================================

Portions (c) Copyright 2018 IGSIO

See Doc/copyright/copyright.txt
or http://www.slicer.org/copyright/copyright.txt for details.

Program:   igtlio
Module:    $RCSfile: igtlioConverterUtilities.cxx,v $
Date:      $Date: 2018/07/20 4:08:00 $
Version:   $Revision: 1.0 $

=========================================================================auto=*/

#include "igtlioConverterUtilities.h"

//---------------------------------------------------------------------------
void igtlioConverterUtilities::VTKTransformToIGTLTransform(vtkSmartPointer<vtkMatrix4x4> ijk2ras, const int imageSize[3], const double spacing[3], igtl::Matrix4x4 &matrix)
{
  if (ijk2ras)
    {
    // Transform
    float ntx = ijk2ras->Element[0][0] / (float)spacing[0];
    float nty = ijk2ras->Element[1][0] / (float)spacing[0];
    float ntz = ijk2ras->Element[2][0] / (float)spacing[0];
    float nsx = ijk2ras->Element[0][1] / (float)spacing[1];
    float nsy = ijk2ras->Element[1][1] / (float)spacing[1];
    float nsz = ijk2ras->Element[2][1] / (float)spacing[1];
    float nnx = ijk2ras->Element[0][2] / (float)spacing[2];
    float nny = ijk2ras->Element[1][2] / (float)spacing[2];
    float nnz = ijk2ras->Element[2][2] / (float)spacing[2];
    float px  = ijk2ras->Element[0][3];
    float py  = ijk2ras->Element[1][3];
    float pz  = ijk2ras->Element[2][3];

    // Shift the center
    // NOTE: The center of the image should be shifted due to different
    // definitions of image origin between VTK (Slicer) and OpenIGTLink;
    // OpenIGTLink image has its origin at the center, while VTK image
    // has one at the corner.

    float hfovi = (float)spacing[0] * (float)(imageSize[0] - 1) / 2.0;
    float hfovj = (float)spacing[1] * (float)(imageSize[1] - 1) / 2.0;
    float hfovk = (float)spacing[2] * (float)(imageSize[2] - 1) / 2.0;

    float cx = ntx * hfovi + nsx * hfovj + nnx * hfovk;
    float cy = nty * hfovi + nsy * hfovj + nny * hfovk;
    float cz = ntz * hfovi + nsz * hfovj + nnz * hfovk;

    px = px + cx;
    py = py + cy;
    pz = pz + cz;

    matrix[0][0] = ntx;
    matrix[1][0] = nty;
    matrix[2][0] = ntz;
    matrix[0][1] = nsx;
    matrix[1][1] = nsy;
    matrix[2][1] = nsz;
    matrix[0][2] = nnx;
    matrix[1][2] = nny;
    matrix[2][2] = nnz;
    matrix[0][3] = px;
    matrix[1][3] = py;
    matrix[2][3] = pz;
    }
  else
    {
    igtl::IdentityMatrix(matrix);
    }
}

//---------------------------------------------------------------------------
void igtlioConverterUtilities::IGTLTransformToVTKTransform(const int imageSize[3], const float spacing[3], const igtl::Matrix4x4 matrix, vtkSmartPointer<vtkMatrix4x4> ijk2ras)
{
  float tx = matrix[0][0];
  float ty = matrix[1][0];
  float tz = matrix[2][0];
  float sx = matrix[0][1];
  float sy = matrix[1][1];
  float sz = matrix[2][1];
  float nx = matrix[0][2];
  float ny = matrix[1][2];
  float nz = matrix[2][2];
  float px = matrix[0][3];
  float py = matrix[1][3];
  float pz = matrix[2][3];

  // normalize
  float psi = sqrt(tx*tx + ty*ty + tz*tz);
  float psj = sqrt(sx*sx + sy*sy + sz*sz);
  float psk = sqrt(nx*nx + ny*ny + nz*nz);
  float ntx = tx / psi;
  float nty = ty / psi;
  float ntz = tz / psi;
  float nsx = sx / psj;
  float nsy = sy / psj;
  float nsz = sz / psj;
  float nnx = nx / psk;
  float nny = ny / psk;
  float nnz = nz / psk;

  // Shift the center
  // NOTE: The center of the image should be shifted due to different
  // definitions of image origin between VTK (Slicer) and OpenIGTLink;
  // OpenIGTLink image has its origin at the center, while VTK image
  // has one at the corner.
  float hfovi = spacing[0] * psi * (imageSize[0] - 1) / 2.0;
  float hfovj = spacing[1] * psj * (imageSize[1] - 1) / 2.0;
  float hfovk = spacing[2] * psk * (imageSize[2] - 1) / 2.0;
  //float hfovk = 0;

  float cx = ntx * hfovi + nsx * hfovj + nnx * hfovk;
  float cy = nty * hfovi + nsy * hfovj + nny * hfovk;
  float cz = ntz * hfovi + nsz * hfovj + nnz * hfovk;
  px = px - cx;
  py = py - cy;
  pz = pz - cz;

  // set volume orientation
  ijk2ras->Identity();
  ijk2ras->Element[0][0] = ntx*spacing[0];
  ijk2ras->Element[1][0] = nty*spacing[0];
  ijk2ras->Element[2][0] = ntz*spacing[0];
  ijk2ras->Element[0][1] = nsx*spacing[1];
  ijk2ras->Element[1][1] = nsy*spacing[1];
  ijk2ras->Element[2][1] = nsz*spacing[1];
  ijk2ras->Element[0][2] = nnx*spacing[2];
  ijk2ras->Element[1][2] = nny*spacing[2];
  ijk2ras->Element[2][2] = nnz*spacing[2];
  ijk2ras->Element[0][3] = px;
  ijk2ras->Element[1][3] = py;
  ijk2ras->Element[2][3] = pz;
}

<commit_msg>BUG: cmath header missing from igtlioConverterUtilities<commit_after>/*==========================================================================

Portions (c) Copyright 2018 IGSIO

See Doc/copyright/copyright.txt
or http://www.slicer.org/copyright/copyright.txt for details.

Program:   igtlio
Module:    $RCSfile: igtlioConverterUtilities.cxx,v $
Date:      $Date: 2018/07/20 4:08:00 $
Version:   $Revision: 1.0 $

=========================================================================auto=*/

#include "igtlioConverterUtilities.h"
#include <cmath>

//---------------------------------------------------------------------------
void igtlioConverterUtilities::VTKTransformToIGTLTransform(vtkSmartPointer<vtkMatrix4x4> ijk2ras, const int imageSize[3], const double spacing[3], igtl::Matrix4x4 &matrix)
{
  if (ijk2ras)
    {
    // Transform
    float ntx = ijk2ras->Element[0][0] / (float)spacing[0];
    float nty = ijk2ras->Element[1][0] / (float)spacing[0];
    float ntz = ijk2ras->Element[2][0] / (float)spacing[0];
    float nsx = ijk2ras->Element[0][1] / (float)spacing[1];
    float nsy = ijk2ras->Element[1][1] / (float)spacing[1];
    float nsz = ijk2ras->Element[2][1] / (float)spacing[1];
    float nnx = ijk2ras->Element[0][2] / (float)spacing[2];
    float nny = ijk2ras->Element[1][2] / (float)spacing[2];
    float nnz = ijk2ras->Element[2][2] / (float)spacing[2];
    float px  = ijk2ras->Element[0][3];
    float py  = ijk2ras->Element[1][3];
    float pz  = ijk2ras->Element[2][3];

    // Shift the center
    // NOTE: The center of the image should be shifted due to different
    // definitions of image origin between VTK (Slicer) and OpenIGTLink;
    // OpenIGTLink image has its origin at the center, while VTK image
    // has one at the corner.

    float hfovi = (float)spacing[0] * (float)(imageSize[0] - 1) / 2.0;
    float hfovj = (float)spacing[1] * (float)(imageSize[1] - 1) / 2.0;
    float hfovk = (float)spacing[2] * (float)(imageSize[2] - 1) / 2.0;

    float cx = ntx * hfovi + nsx * hfovj + nnx * hfovk;
    float cy = nty * hfovi + nsy * hfovj + nny * hfovk;
    float cz = ntz * hfovi + nsz * hfovj + nnz * hfovk;

    px = px + cx;
    py = py + cy;
    pz = pz + cz;

    matrix[0][0] = ntx;
    matrix[1][0] = nty;
    matrix[2][0] = ntz;
    matrix[0][1] = nsx;
    matrix[1][1] = nsy;
    matrix[2][1] = nsz;
    matrix[0][2] = nnx;
    matrix[1][2] = nny;
    matrix[2][2] = nnz;
    matrix[0][3] = px;
    matrix[1][3] = py;
    matrix[2][3] = pz;
    }
  else
    {
    igtl::IdentityMatrix(matrix);
    }
}

//---------------------------------------------------------------------------
void igtlioConverterUtilities::IGTLTransformToVTKTransform(const int imageSize[3], const float spacing[3], const igtl::Matrix4x4 matrix, vtkSmartPointer<vtkMatrix4x4> ijk2ras)
{
  float tx = matrix[0][0];
  float ty = matrix[1][0];
  float tz = matrix[2][0];
  float sx = matrix[0][1];
  float sy = matrix[1][1];
  float sz = matrix[2][1];
  float nx = matrix[0][2];
  float ny = matrix[1][2];
  float nz = matrix[2][2];
  float px = matrix[0][3];
  float py = matrix[1][3];
  float pz = matrix[2][3];

  // normalize
  float psi = sqrt(tx*tx + ty*ty + tz*tz);
  float psj = sqrt(sx*sx + sy*sy + sz*sz);
  float psk = sqrt(nx*nx + ny*ny + nz*nz);
  float ntx = tx / psi;
  float nty = ty / psi;
  float ntz = tz / psi;
  float nsx = sx / psj;
  float nsy = sy / psj;
  float nsz = sz / psj;
  float nnx = nx / psk;
  float nny = ny / psk;
  float nnz = nz / psk;

  // Shift the center
  // NOTE: The center of the image should be shifted due to different
  // definitions of image origin between VTK (Slicer) and OpenIGTLink;
  // OpenIGTLink image has its origin at the center, while VTK image
  // has one at the corner.
  float hfovi = spacing[0] * psi * (imageSize[0] - 1) / 2.0;
  float hfovj = spacing[1] * psj * (imageSize[1] - 1) / 2.0;
  float hfovk = spacing[2] * psk * (imageSize[2] - 1) / 2.0;
  //float hfovk = 0;

  float cx = ntx * hfovi + nsx * hfovj + nnx * hfovk;
  float cy = nty * hfovi + nsy * hfovj + nny * hfovk;
  float cz = ntz * hfovi + nsz * hfovj + nnz * hfovk;
  px = px - cx;
  py = py - cy;
  pz = pz - cz;

  // set volume orientation
  ijk2ras->Identity();
  ijk2ras->Element[0][0] = ntx*spacing[0];
  ijk2ras->Element[1][0] = nty*spacing[0];
  ijk2ras->Element[2][0] = ntz*spacing[0];
  ijk2ras->Element[0][1] = nsx*spacing[1];
  ijk2ras->Element[1][1] = nsy*spacing[1];
  ijk2ras->Element[2][1] = nsz*spacing[1];
  ijk2ras->Element[0][2] = nnx*spacing[2];
  ijk2ras->Element[1][2] = nny*spacing[2];
  ijk2ras->Element[2][2] = nnz*spacing[2];
  ijk2ras->Element[0][3] = px;
  ijk2ras->Element[1][3] = py;
  ijk2ras->Element[2][3] = pz;
}

<|endoftext|>


<commit_before>/***********************************************************************************************************************
 **
 ** Copyright (c) 2011, 2015 ETH Zurich
 ** All rights reserved.
 **
 ** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 ** following conditions are met:
 **
 **    * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 **      following disclaimer.
 **    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 **      following disclaimer in the documentation and/or other materials provided with the distribution.
 **    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
 **      derived from this software without specific prior written permission.
 **
 **
 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 **
 **********************************************************************************************************************/

#include "CppExporter.h"

#include "OOModel/src/declarations/Project.h"

#include "Export/src/writer/Exporter.h"
#include "Export/src/writer/FragmentLayouter.h"
#include "Export/src/tree/CompositeFragment.h"
#include "ModelBase/src/model/TreeManager.h"

#include "../CodeUnit.h"
#include "../CodeComposite.h"
#include "../Config.h"

namespace CppExport {

QList<Export::ExportError> CppExporter::exportTree(Model::TreeManager* treeManager,
																	const QString& pathToProjectContainerDirectory)
{
	QList<CodeUnit*> codeUnits;
	units(treeManager->root(), "", codeUnits);

	QList<CodeUnitPart*> allHeaderParts;
	for (auto unit : codeUnits)
	{
		unit->calculateSourceFragments();
		allHeaderParts.append(unit->headerPart());
	}
	for (auto unit : codeUnits) unit->calculateDependencies(allHeaderParts);

	auto directory = new Export::SourceDir(nullptr, pathToProjectContainerDirectory + "/src");
	for (auto codeComposite : mergeUnits(codeUnits))
		createFilesFromComposite(directory, codeComposite);

	auto layout = layouter();
	Export::Exporter::exportToFileSystem("", directory, &layout);

	return {};

}

void CppExporter::createFilesFromComposite(Export::SourceDir* directory, CodeComposite* codeComposite)
{
	Export::SourceFragment* headerFragment{};
	Export::SourceFragment* sourceFragment{};
	codeComposite->fragments(headerFragment, sourceFragment);

	directory->file(codeComposite->name() + ".h").append(headerFragment);
	directory->file(codeComposite->name() + ".cpp").append(sourceFragment);
}

void CppExporter::units(Model::Node* current, QString namespaceName, QList<CodeUnit*>& result)
{
	if (auto ooModule = DCast<OOModel::Module>(current))
	{
		if (ooModule->classes()->size() > 0)
			namespaceName = ooModule->name();
		else
		{
			// macro file
			// TODO: handle non class units
			//result.append(new CodeUnit((namespaceName.isEmpty() ? "" : namespaceName + "/") + ooModule->name(), current));
			return;
		}
	}
	else if (auto ooClass = DCast<OOModel::Class>(current))
	{
		result.append(new CodeUnit((namespaceName.isEmpty() ? "" : namespaceName + "/") + ooClass->name(), current));
		return;
	}

	for (auto child : current->children())
		units(child, namespaceName, result);
}

QList<CodeComposite*> CppExporter::mergeUnits(QList<CodeUnit*>& units)
{
	QHash<QString, QString> mergeMap = Config::instance().dependencyUnitMergeMap();

	QHash<QString, CodeComposite*> nameToCompositeMap;
	for (auto unit : units)
	{
		auto it = mergeMap.find(unit->name());
		auto compositeName = it != mergeMap.end() ? *it : unit->name();

		auto cIt = nameToCompositeMap.find(compositeName);
		if (cIt != nameToCompositeMap.end())
			// case A: the composite that unit is a part of already exists => merge
			(*cIt)->addUnit(unit);
		else
		{
			// case B: the composite that unit is a part of does not yet exist
			auto composite = new CodeComposite(compositeName);
			composite->addUnit(unit);
			nameToCompositeMap.insert(composite->name(), composite);
		}
	}

	return nameToCompositeMap.values();
}

Export::FragmentLayouter CppExporter::layouter()
{
	auto result = Export::FragmentLayouter{"\t"};
	result.addRule("enumerators", Export::FragmentLayouter::SpaceAfterSeparator, "", ",", "");
	result.addRule("vertical", Export::FragmentLayouter::NoIndentation, "", "\n", "");
	result.addRule("sections", Export::FragmentLayouter::NoIndentation, "", "\n", "");
	result.addRule("declarationComment", Export::FragmentLayouter::NoIndentation
							| Export::FragmentLayouter::NewLineAfterPostfix, "", "\n", "");
	result.addRule("spacedSections", Export::FragmentLayouter::NoIndentation, "", "\n\n", "");
	result.addRule("accessorSections", Export::FragmentLayouter::IndentChildFragments, "", "\n", "");
	result.addRule("bodySections", Export::FragmentLayouter::NewLineBefore
						  | Export::FragmentLayouter::IndentChildFragments | Export::FragmentLayouter::NewLineAfterPrefix
						  | Export::FragmentLayouter::NewLineBeforePostfix, "{", "\n", "}");
	result.addRule("space", Export::FragmentLayouter::SpaceAtEnd, "", " ", "");
	result.addRule("comma", Export::FragmentLayouter::SpaceAfterSeparator, "", ",", "");
	result.addRule("baseClasses", Export::FragmentLayouter::SpaceAfterSeparator, " : public ", ",", "");
	result.addRule("initializerList", Export::FragmentLayouter::SpaceAfterSeparator, "{", ",", "}");
	result.addRule("argsList", Export::FragmentLayouter::SpaceAfterSeparator, "(", ",", ")");
	result.addRule("typeArgsList", Export::FragmentLayouter::SpaceAfterSeparator, "<", ",", ">");
	result.addRule("templateArgsList", Export::FragmentLayouter::SpaceAfterSeparator
							| Export::FragmentLayouter::NewLineAfterPostfix, "template<", ",", ">");

	result.addRule("body", Export::FragmentLayouter::NewLineBefore | Export::FragmentLayouter::IndentChildFragments
							| Export::FragmentLayouter::NewLineAfterPrefix | Export::FragmentLayouter::NewLineBeforePostfix,
							"{", "\n", "}");

	return result;
}

Export::ExportMapContainer& CppExporter::exportMaps()
{
	static Export::ExportMapContainer* container = new Export::ExportMapContainer();
	return *container;
}

}
<commit_msg>export source fragments only if not empty<commit_after>/***********************************************************************************************************************
 **
 ** Copyright (c) 2011, 2015 ETH Zurich
 ** All rights reserved.
 **
 ** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 ** following conditions are met:
 **
 **    * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 **      following disclaimer.
 **    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 **      following disclaimer in the documentation and/or other materials provided with the distribution.
 **    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
 **      derived from this software without specific prior written permission.
 **
 **
 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 **
 **********************************************************************************************************************/

#include "CppExporter.h"

#include "OOModel/src/declarations/Project.h"

#include "Export/src/writer/Exporter.h"
#include "Export/src/writer/FragmentLayouter.h"
#include "Export/src/tree/CompositeFragment.h"
#include "ModelBase/src/model/TreeManager.h"

#include "../CodeUnit.h"
#include "../CodeComposite.h"
#include "../Config.h"

namespace CppExport {

QList<Export::ExportError> CppExporter::exportTree(Model::TreeManager* treeManager,
																	const QString& pathToProjectContainerDirectory)
{
	QList<CodeUnit*> codeUnits;
	units(treeManager->root(), "", codeUnits);

	QList<CodeUnitPart*> allHeaderParts;
	for (auto unit : codeUnits)
	{
		unit->calculateSourceFragments();
		allHeaderParts.append(unit->headerPart());
	}
	for (auto unit : codeUnits) unit->calculateDependencies(allHeaderParts);

	auto directory = new Export::SourceDir(nullptr, pathToProjectContainerDirectory + "/src");
	for (auto codeComposite : mergeUnits(codeUnits))
		createFilesFromComposite(directory, codeComposite);

	auto layout = layouter();
	Export::Exporter::exportToFileSystem("", directory, &layout);

	return {};

}

void CppExporter::createFilesFromComposite(Export::SourceDir* directory, CodeComposite* codeComposite)
{
	Export::SourceFragment* headerFragment{};
	Export::SourceFragment* sourceFragment{};
	codeComposite->fragments(headerFragment, sourceFragment);

	if (headerFragment) directory->file(codeComposite->name() + ".h").append(headerFragment);
	if (sourceFragment) directory->file(codeComposite->name() + ".cpp").append(sourceFragment);
}

void CppExporter::units(Model::Node* current, QString namespaceName, QList<CodeUnit*>& result)
{
	if (auto ooModule = DCast<OOModel::Module>(current))
	{
		if (ooModule->classes()->size() > 0)
			namespaceName = ooModule->name();
		else
		{
			// macro file
			// TODO: handle non class units
			//result.append(new CodeUnit((namespaceName.isEmpty() ? "" : namespaceName + "/") + ooModule->name(), current));
			return;
		}
	}
	else if (auto ooClass = DCast<OOModel::Class>(current))
	{
		result.append(new CodeUnit((namespaceName.isEmpty() ? "" : namespaceName + "/") + ooClass->name(), current));
		return;
	}

	for (auto child : current->children())
		units(child, namespaceName, result);
}

QList<CodeComposite*> CppExporter::mergeUnits(QList<CodeUnit*>& units)
{
	QHash<QString, QString> mergeMap = Config::instance().dependencyUnitMergeMap();

	QHash<QString, CodeComposite*> nameToCompositeMap;
	for (auto unit : units)
	{
		auto it = mergeMap.find(unit->name());
		auto compositeName = it != mergeMap.end() ? *it : unit->name();

		auto cIt = nameToCompositeMap.find(compositeName);
		if (cIt != nameToCompositeMap.end())
			// case A: the composite that unit is a part of already exists => merge
			(*cIt)->addUnit(unit);
		else
		{
			// case B: the composite that unit is a part of does not yet exist
			auto composite = new CodeComposite(compositeName);
			composite->addUnit(unit);
			nameToCompositeMap.insert(composite->name(), composite);
		}
	}

	return nameToCompositeMap.values();
}

Export::FragmentLayouter CppExporter::layouter()
{
	auto result = Export::FragmentLayouter{"\t"};
	result.addRule("enumerators", Export::FragmentLayouter::SpaceAfterSeparator, "", ",", "");
	result.addRule("vertical", Export::FragmentLayouter::NoIndentation, "", "\n", "");
	result.addRule("sections", Export::FragmentLayouter::NoIndentation, "", "\n", "");
	result.addRule("declarationComment", Export::FragmentLayouter::NoIndentation
							| Export::FragmentLayouter::NewLineAfterPostfix, "", "\n", "");
	result.addRule("spacedSections", Export::FragmentLayouter::NoIndentation, "", "\n\n", "");
	result.addRule("accessorSections", Export::FragmentLayouter::IndentChildFragments, "", "\n", "");
	result.addRule("bodySections", Export::FragmentLayouter::NewLineBefore
						  | Export::FragmentLayouter::IndentChildFragments | Export::FragmentLayouter::NewLineAfterPrefix
						  | Export::FragmentLayouter::NewLineBeforePostfix, "{", "\n", "}");
	result.addRule("space", Export::FragmentLayouter::SpaceAtEnd, "", " ", "");
	result.addRule("comma", Export::FragmentLayouter::SpaceAfterSeparator, "", ",", "");
	result.addRule("baseClasses", Export::FragmentLayouter::SpaceAfterSeparator, " : public ", ",", "");
	result.addRule("initializerList", Export::FragmentLayouter::SpaceAfterSeparator, "{", ",", "}");
	result.addRule("argsList", Export::FragmentLayouter::SpaceAfterSeparator, "(", ",", ")");
	result.addRule("typeArgsList", Export::FragmentLayouter::SpaceAfterSeparator, "<", ",", ">");
	result.addRule("templateArgsList", Export::FragmentLayouter::SpaceAfterSeparator
							| Export::FragmentLayouter::NewLineAfterPostfix, "template<", ",", ">");

	result.addRule("body", Export::FragmentLayouter::NewLineBefore | Export::FragmentLayouter::IndentChildFragments
							| Export::FragmentLayouter::NewLineAfterPrefix | Export::FragmentLayouter::NewLineBeforePostfix,
							"{", "\n", "}");

	return result;
}

Export::ExportMapContainer& CppExporter::exportMaps()
{
	static Export::ExportMapContainer* container = new Export::ExportMapContainer();
	return *container;
}

}
<|endoftext|>


<commit_before>#include <cstring>
#include <cassert>
#include <string>
#include <atomic>
#include <memory>
#include <set>
#include <boost/asio.hpp>
#include <mutex>

#include "I2PService.h"
#include "Destination.h"
#include "HTTPProxy.h"
#include "util.h"
#include "Identity.h"
#include "Streaming.h"
#include "Destination.h"
#include "ClientContext.h"
#include "I2PEndian.h"
#include "I2PTunnel.h"
#include "Config.h"
#include "HTTP.h"

namespace i2p {
namespace proxy {
	bool str_rmatch(std::string & str, const char *suffix) {
		auto pos = str.rfind (suffix);
		if (pos == std::string::npos)
			return false; /* not found */
		if (str.length() == (pos + std::strlen(suffix)))
			return true; /* match */
		return false;
	}

	static const size_t http_buffer_size = 8192;
	class HTTPReqHandler: public i2p::client::I2PServiceHandler, public std::enable_shared_from_this<HTTPReqHandler>
	{
		private:
			enum state
			{
				GET_METHOD,
				GET_HOSTNAME,
				GET_HTTPV,
				GET_HTTPVNL, //TODO: fallback to finding HOst: header if needed
				DONE
			};

			void EnterState(state nstate);
			bool HandleData(uint8_t *http_buff, std::size_t len);
			void HandleSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered);
			void Terminate();
			void AsyncSockRead();
			void HTTPRequestFailed(const char *message);
			void RedirectToJumpService(std::string & host);
			bool ValidateHTTPRequest();
			void HandleJumpServices();
			bool CreateHTTPRequest(uint8_t *http_buff, std::size_t len);
			void SentHTTPFailed(const boost::system::error_code & ecode);
			void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);

			uint8_t m_http_buff[http_buffer_size];
			std::shared_ptr<boost::asio::ip::tcp::socket> m_sock;
			std::string m_request; //Data left to be sent
			std::string m_url; //URL
			std::string m_method; //Method
			std::string m_version; //HTTP version
			std::string m_address; //Address
			std::string m_path; //Path
			int m_port; //Port
			state m_state;//Parsing state

		public:

			HTTPReqHandler(HTTPProxy * parent, std::shared_ptr<boost::asio::ip::tcp::socket> sock) :
				I2PServiceHandler(parent), m_sock(sock)
				{ EnterState(GET_METHOD); }
			~HTTPReqHandler() { Terminate(); }
			void Handle () { AsyncSockRead(); }
	};

	void HTTPReqHandler::AsyncSockRead()
	{
		LogPrint(eLogDebug, "HTTPProxy: async sock read");
		if (!m_sock) {
			LogPrint(eLogError, "HTTPProxy: no socket for read");
			return;
		}
		m_sock->async_receive(boost::asio::buffer(m_http_buff, http_buffer_size),
					std::bind(&HTTPReqHandler::HandleSockRecv, shared_from_this(),
							std::placeholders::_1, std::placeholders::_2));
	}

	void HTTPReqHandler::Terminate() {
		if (Kill()) return;
		if (m_sock)
		{
			LogPrint(eLogDebug, "HTTPProxy: close sock");
			m_sock->close();
			m_sock = nullptr;
		}
		Done(shared_from_this());
	}

	/* All hope is lost beyond this point */
	//TODO: handle this apropriately
	void HTTPReqHandler::HTTPRequestFailed(const char *message)
	{
		i2p::http::HTTPRes res;
		res.code = 500;
		res.add_header("Content-Type", "text/plain");
		res.add_header("Connection", "close");
		res.body = message;
		res.body += "\r\n";
		std::string response = res.to_string();
		boost::asio::async_write(*m_sock, boost::asio::buffer(response),
					 std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
	}

	void HTTPReqHandler::RedirectToJumpService(std::string & host)
	{
		i2p::http::HTTPRes res;
		i2p::http::URL url;

		/* TODO: don't redirect to webconsole, it's not always work, handle jumpservices here */
		i2p::config::GetOption("http.address", url.host);
		i2p::config::GetOption("http.port",    url.port);
		url.path  = "/";
		url.query = "page=jumpservices&address=";
		url.query += host;

		res.code = 302; /* redirect */
		res.add_header("Location", url.to_string().c_str());

		std::string response = res.to_string();
		boost::asio::async_write(*m_sock, boost::asio::buffer(response),
					 std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
	}

	void HTTPReqHandler::EnterState(HTTPReqHandler::state nstate)
	{
		m_state = nstate;
	}

	bool HTTPReqHandler::ValidateHTTPRequest()
	{
		if ( m_version != "HTTP/1.0" && m_version != "HTTP/1.1" )
		{
			LogPrint(eLogError, "HTTPProxy: unsupported version: ", m_version);
			HTTPRequestFailed("unsupported HTTP version");
			return false;
		}
		return true;
	}

	void HTTPReqHandler::HandleJumpServices()
	{
		static const char * helpermark1 = "?i2paddresshelper=";
		static const char * helpermark2 = "&i2paddresshelper=";
		size_t addressHelperPos1 = m_path.rfind (helpermark1);
		size_t addressHelperPos2 = m_path.rfind (helpermark2);
		size_t addressHelperPos;
		if (addressHelperPos1 == std::string::npos)
		{
			if (addressHelperPos2 == std::string::npos)
				return; //Not a jump service
			else
				addressHelperPos = addressHelperPos2;
		}
		else
		{
			if (addressHelperPos2 == std::string::npos)
				addressHelperPos = addressHelperPos1;
			else if ( addressHelperPos1 > addressHelperPos2 )
				addressHelperPos = addressHelperPos1;
			else
				addressHelperPos = addressHelperPos2;
		}
		auto base64 = m_path.substr (addressHelperPos + strlen(helpermark1));
		base64 = i2p::util::http::urlDecode(base64); //Some of the symbols may be urlencoded
		LogPrint (eLogInfo, "HTTPProxy: jump service for ", m_address, ", inserting to address book");
		//TODO: this is very dangerous and broken. We should ask the user before doing anything see http://pastethis.i2p/raw/pn5fL4YNJL7OSWj3Sc6N/
		//TODO: we could redirect the user again to avoid dirtiness in the browser
		i2p::client::context.GetAddressBook ().InsertAddress (m_address, base64);
		m_path.erase(addressHelperPos);
	}

	bool HTTPReqHandler::CreateHTTPRequest(uint8_t *http_buff, std::size_t len)
	{
		i2p::http::URL url;
		url.parse(m_url);
		m_address = url.host; /* < compatibility */
		m_port    = url.port; /* < compatibility */
		if (!m_port) {
			m_port = (url.schema == "https") ? 443 : 80;
		}
		url.schema = "";
		url.host   = "";
		m_path    = url.to_string(); /* < compatibility */
		if (!ValidateHTTPRequest()) return false;
		HandleJumpServices();

		i2p::data::IdentHash identHash;
		if (str_rmatch(m_address, ".i2p"))
		{
			if (!i2p::client::context.GetAddressBook ().GetIdentHash (m_address, identHash)){
				RedirectToJumpService(m_address);
				return false;
			}
		}

		m_request = m_method;
		m_request.push_back(' ');
		m_request += m_path;
		m_request.push_back(' ');
		m_request += m_version;
		m_request.push_back('\r');
		m_request.push_back('\n');
		m_request.append("Connection: close\r\n");
		// TODO: temporary shortcut. Must be implemented properly
		uint8_t * eol = nullptr;
		bool isEndOfHeader = false;
		while (!isEndOfHeader && len && (eol = (uint8_t *)memchr (http_buff, '\r', len)))
		{
			if (eol)
			{
				*eol = 0; eol++;
				if (strncmp ((const char *)http_buff, "Referer", 7) && strncmp ((const char *)http_buff, "Connection", 10)) // strip out referer and connection
				{
					if (!strncmp ((const char *)http_buff, "User-Agent", 10)) // replace UserAgent
						m_request.append("User-Agent: MYOB/6.66 (AN/ON)");
					else
						m_request.append ((const char *)http_buff);
					m_request.append ("\r\n");
				}
				isEndOfHeader = !http_buff[0];
				auto l = eol - http_buff;
				http_buff = eol;
				len -= l;
				if (len > 0) // \r
				{
					http_buff++;
					len--;
				}
			}
		}
		m_request.append(reinterpret_cast<const char *>(http_buff),len);
		return true;
	}

	bool HTTPReqHandler::HandleData(uint8_t *http_buff, std::size_t len)
	{
		while (len > 0)
		{
			//TODO: fallback to finding HOst: header if needed
			switch (m_state)
			{
				case GET_METHOD:
					switch (*http_buff)
					{
						case ' ': EnterState(GET_HOSTNAME); break;
						default: m_method.push_back(*http_buff); break;
					}
				break;
				case GET_HOSTNAME:
					switch (*http_buff)
					{
						case ' ': EnterState(GET_HTTPV); break;
						default: m_url.push_back(*http_buff); break;
					}
				break;
				case GET_HTTPV:
					switch (*http_buff)
					{
						case '\r': EnterState(GET_HTTPVNL); break;
						default: m_version.push_back(*http_buff); break;
					}
				break;
				case GET_HTTPVNL:
					switch (*http_buff)
					{
						case '\n': EnterState(DONE); break;
						default:
							LogPrint(eLogError, "HTTPProxy: rejected invalid request ending with: ", ((int)*http_buff));
							HTTPRequestFailed("rejected invalid request");
							return false;
					}
				break;
				default:
					LogPrint(eLogError, "HTTPProxy: invalid state: ", m_state);
					HTTPRequestFailed("invalid parser state");
					return false;
			}
			http_buff++;
			len--;
			if (m_state == DONE)
				return CreateHTTPRequest(http_buff,len);
		}
		return true;
	}

	void HTTPReqHandler::HandleSockRecv(const boost::system::error_code & ecode, std::size_t len)
	{
		LogPrint(eLogDebug, "HTTPProxy: sock recv: ", len, " bytes");
		if(ecode)
		{
			LogPrint(eLogWarning, "HTTPProxy: sock recv got error: ", ecode);
			Terminate();
			return;
		}

		if (HandleData(m_http_buff, len))
		{
			if (m_state == DONE)
			{
				LogPrint(eLogDebug, "HTTPProxy: requested: ", m_url);
				GetOwner()->CreateStream (std::bind (&HTTPReqHandler::HandleStreamRequestComplete,
						shared_from_this(), std::placeholders::_1), m_address, m_port);
			}
			else
				AsyncSockRead();
		}
	}

	void HTTPReqHandler::SentHTTPFailed(const boost::system::error_code & ecode)
	{
		if (ecode)
			LogPrint (eLogError, "HTTPProxy: Closing socket after sending failure because: ", ecode.message ());
		Terminate();
	}

	void HTTPReqHandler::HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream)
	{
		if (!stream) {
			LogPrint (eLogError, "HTTPProxy: error when creating the stream, check the previous warnings for more info");
			HTTPRequestFailed("error when creating the stream, check logs");
			return;
		}
		if (Kill())
			return;
		LogPrint (eLogDebug, "HTTPProxy: New I2PTunnel connection");
		auto connection = std::make_shared<i2p::client::I2PTunnelConnection>(GetOwner(), m_sock, stream);
		GetOwner()->AddHandler (connection);
		connection->I2PConnect (reinterpret_cast<const uint8_t*>(m_request.data()), m_request.size());
		Done (shared_from_this());
	}

	HTTPProxy::HTTPProxy(const std::string& address, int port, std::shared_ptr<i2p::client::ClientDestination> localDestination):
		TCPIPAcceptor(address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ())
	{
	}

	std::shared_ptr<i2p::client::I2PServiceHandler> HTTPProxy::CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket)
	{
		return std::make_shared<HTTPReqHandler> (this, socket);
	}
} // http
} // i2p
<commit_msg>* HTTPProxy.cpp : HandleJumpServices() -> ExtractAddressHelper()<commit_after>#include <cstring>
#include <cassert>
#include <string>
#include <atomic>
#include <memory>
#include <set>
#include <boost/asio.hpp>
#include <mutex>

#include "I2PService.h"
#include "Destination.h"
#include "HTTPProxy.h"
#include "util.h"
#include "Identity.h"
#include "Streaming.h"
#include "Destination.h"
#include "ClientContext.h"
#include "I2PEndian.h"
#include "I2PTunnel.h"
#include "Config.h"
#include "HTTP.h"

namespace i2p {
namespace proxy {
	bool str_rmatch(std::string & str, const char *suffix) {
		auto pos = str.rfind (suffix);
		if (pos == std::string::npos)
			return false; /* not found */
		if (str.length() == (pos + std::strlen(suffix)))
			return true; /* match */
		return false;
	}

	static const size_t http_buffer_size = 8192;
	class HTTPReqHandler: public i2p::client::I2PServiceHandler, public std::enable_shared_from_this<HTTPReqHandler>
	{
		private:
			enum state
			{
				GET_METHOD,
				GET_HOSTNAME,
				GET_HTTPV,
				GET_HTTPVNL, //TODO: fallback to finding HOst: header if needed
				DONE
			};

			void EnterState(state nstate);
			bool HandleData(uint8_t *http_buff, std::size_t len);
			void HandleSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered);
			void Terminate();
			void AsyncSockRead();
			void HTTPRequestFailed(const char *message);
			void RedirectToJumpService(std::string & host);
			bool ValidateHTTPRequest();
			bool ExtractAddressHelper(i2p::http::URL & url, std::string & b64);
			bool CreateHTTPRequest(uint8_t *http_buff, std::size_t len);
			void SentHTTPFailed(const boost::system::error_code & ecode);
			void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);

			uint8_t m_http_buff[http_buffer_size];
			std::shared_ptr<boost::asio::ip::tcp::socket> m_sock;
			std::string m_request; //Data left to be sent
			std::string m_url; //URL
			std::string m_method; //Method
			std::string m_version; //HTTP version
			std::string m_address; //Address
			std::string m_path; //Path
			int m_port; //Port
			state m_state;//Parsing state

		public:

			HTTPReqHandler(HTTPProxy * parent, std::shared_ptr<boost::asio::ip::tcp::socket> sock) :
				I2PServiceHandler(parent), m_sock(sock)
				{ EnterState(GET_METHOD); }
			~HTTPReqHandler() { Terminate(); }
			void Handle () { AsyncSockRead(); }
	};

	void HTTPReqHandler::AsyncSockRead()
	{
		LogPrint(eLogDebug, "HTTPProxy: async sock read");
		if (!m_sock) {
			LogPrint(eLogError, "HTTPProxy: no socket for read");
			return;
		}
		m_sock->async_receive(boost::asio::buffer(m_http_buff, http_buffer_size),
					std::bind(&HTTPReqHandler::HandleSockRecv, shared_from_this(),
							std::placeholders::_1, std::placeholders::_2));
	}

	void HTTPReqHandler::Terminate() {
		if (Kill()) return;
		if (m_sock)
		{
			LogPrint(eLogDebug, "HTTPProxy: close sock");
			m_sock->close();
			m_sock = nullptr;
		}
		Done(shared_from_this());
	}

	/* All hope is lost beyond this point */
	//TODO: handle this apropriately
	void HTTPReqHandler::HTTPRequestFailed(const char *message)
	{
		i2p::http::HTTPRes res;
		res.code = 500;
		res.add_header("Content-Type", "text/plain");
		res.add_header("Connection", "close");
		res.body = message;
		res.body += "\r\n";
		std::string response = res.to_string();
		boost::asio::async_write(*m_sock, boost::asio::buffer(response),
					 std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
	}

	void HTTPReqHandler::RedirectToJumpService(std::string & host)
	{
		i2p::http::HTTPRes res;
		i2p::http::URL url;

		/* TODO: don't redirect to webconsole, it's not always work, handle jumpservices here */
		i2p::config::GetOption("http.address", url.host);
		i2p::config::GetOption("http.port",    url.port);
		url.schema = "http";
		url.path  = "/";
		url.query = "page=jumpservices&address=";
		url.query += host;

		res.code = 302; /* redirect */
		res.add_header("Location", url.to_string().c_str());
		res.add_header("Connection", "close");

		std::string response = res.to_string();
		boost::asio::async_write(*m_sock, boost::asio::buffer(response),
					 std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
	}

	void HTTPReqHandler::EnterState(HTTPReqHandler::state nstate)
	{
		m_state = nstate;
	}

	bool HTTPReqHandler::ValidateHTTPRequest()
	{
		if ( m_version != "HTTP/1.0" && m_version != "HTTP/1.1" )
		{
			LogPrint(eLogError, "HTTPProxy: unsupported version: ", m_version);
			HTTPRequestFailed("unsupported HTTP version");
			return false;
		}
		return true;
	}

	bool HTTPReqHandler::ExtractAddressHelper(i2p::http::URL & url, std::string & b64)
	{
		const char *param = "i2paddresshelper=";
		std::size_t pos = url.query.find(param);
		std::size_t len = std::strlen(param);
		std::map<std::string, std::string> params;

		if (pos == std::string::npos)
			return false; /* not found */
		if (!url.parse_query(params))
			return false;

		std::string value = params["i2paddresshelper"];
		len += value.length();
		b64 = i2p::http::UrlDecode(value);
		url.query.replace(pos, len, "");
		return true;
	}

	bool HTTPReqHandler::CreateHTTPRequest(uint8_t *http_buff, std::size_t len)
	{
		std::string b64;
		i2p::http::URL url;
		url.parse(m_url);
		m_address = url.host; /* < compatibility */
		m_port    = url.port; /* < compatibility */
		if (!m_port) {
			m_port = (url.schema == "https") ? 443 : 80;
		}
		url.schema = "";
		url.host   = "";
		m_path    = url.to_string(); /* < compatibility */
		if (!ValidateHTTPRequest()) return false;

		/* TODO: notify user */
		if (ExtractAddressHelper(url, b64)) {
			i2p::client::context.GetAddressBook ().InsertAddress (url.host, b64);
			LogPrint (eLogInfo, "HTTPProxy: added b64 from addresshelper for ", url.host, " to address book");
		}

		i2p::data::IdentHash identHash;
		if (str_rmatch(m_address, ".i2p"))
		{
			if (!i2p::client::context.GetAddressBook ().GetIdentHash (m_address, identHash)){
				RedirectToJumpService(m_address);
				return false;
			}
		}

		m_request = m_method;
		m_request.push_back(' ');
		m_request += m_path;
		m_request.push_back(' ');
		m_request += m_version;
		m_request.push_back('\r');
		m_request.push_back('\n');
		m_request.append("Connection: close\r\n");
		// TODO: temporary shortcut. Must be implemented properly
		uint8_t * eol = nullptr;
		bool isEndOfHeader = false;
		while (!isEndOfHeader && len && (eol = (uint8_t *)memchr (http_buff, '\r', len)))
		{
			if (eol)
			{
				*eol = 0; eol++;
				if (strncmp ((const char *)http_buff, "Referer", 7) && strncmp ((const char *)http_buff, "Connection", 10)) // strip out referer and connection
				{
					if (!strncmp ((const char *)http_buff, "User-Agent", 10)) // replace UserAgent
						m_request.append("User-Agent: MYOB/6.66 (AN/ON)");
					else
						m_request.append ((const char *)http_buff);
					m_request.append ("\r\n");
				}
				isEndOfHeader = !http_buff[0];
				auto l = eol - http_buff;
				http_buff = eol;
				len -= l;
				if (len > 0) // \r
				{
					http_buff++;
					len--;
				}
			}
		}
		m_request.append(reinterpret_cast<const char *>(http_buff),len);
		return true;
	}

	bool HTTPReqHandler::HandleData(uint8_t *http_buff, std::size_t len)
	{
		while (len > 0)
		{
			//TODO: fallback to finding HOst: header if needed
			switch (m_state)
			{
				case GET_METHOD:
					switch (*http_buff)
					{
						case ' ': EnterState(GET_HOSTNAME); break;
						default: m_method.push_back(*http_buff); break;
					}
				break;
				case GET_HOSTNAME:
					switch (*http_buff)
					{
						case ' ': EnterState(GET_HTTPV); break;
						default: m_url.push_back(*http_buff); break;
					}
				break;
				case GET_HTTPV:
					switch (*http_buff)
					{
						case '\r': EnterState(GET_HTTPVNL); break;
						default: m_version.push_back(*http_buff); break;
					}
				break;
				case GET_HTTPVNL:
					switch (*http_buff)
					{
						case '\n': EnterState(DONE); break;
						default:
							LogPrint(eLogError, "HTTPProxy: rejected invalid request ending with: ", ((int)*http_buff));
							HTTPRequestFailed("rejected invalid request");
							return false;
					}
				break;
				default:
					LogPrint(eLogError, "HTTPProxy: invalid state: ", m_state);
					HTTPRequestFailed("invalid parser state");
					return false;
			}
			http_buff++;
			len--;
			if (m_state == DONE)
				return CreateHTTPRequest(http_buff,len);
		}
		return true;
	}

	void HTTPReqHandler::HandleSockRecv(const boost::system::error_code & ecode, std::size_t len)
	{
		LogPrint(eLogDebug, "HTTPProxy: sock recv: ", len, " bytes");
		if(ecode)
		{
			LogPrint(eLogWarning, "HTTPProxy: sock recv got error: ", ecode);
			Terminate();
			return;
		}

		if (HandleData(m_http_buff, len))
		{
			if (m_state == DONE)
			{
				LogPrint(eLogDebug, "HTTPProxy: requested: ", m_url);
				GetOwner()->CreateStream (std::bind (&HTTPReqHandler::HandleStreamRequestComplete,
						shared_from_this(), std::placeholders::_1), m_address, m_port);
			}
			else
				AsyncSockRead();
		}
	}

	void HTTPReqHandler::SentHTTPFailed(const boost::system::error_code & ecode)
	{
		if (ecode)
			LogPrint (eLogError, "HTTPProxy: Closing socket after sending failure because: ", ecode.message ());
		Terminate();
	}

	void HTTPReqHandler::HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream)
	{
		if (!stream) {
			LogPrint (eLogError, "HTTPProxy: error when creating the stream, check the previous warnings for more info");
			HTTPRequestFailed("error when creating the stream, check logs");
			return;
		}
		if (Kill())
			return;
		LogPrint (eLogDebug, "HTTPProxy: New I2PTunnel connection");
		auto connection = std::make_shared<i2p::client::I2PTunnelConnection>(GetOwner(), m_sock, stream);
		GetOwner()->AddHandler (connection);
		connection->I2PConnect (reinterpret_cast<const uint8_t*>(m_request.data()), m_request.size());
		Done (shared_from_this());
	}

	HTTPProxy::HTTPProxy(const std::string& address, int port, std::shared_ptr<i2p::client::ClientDestination> localDestination):
		TCPIPAcceptor(address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ())
	{
	}

	std::shared_ptr<i2p::client::I2PServiceHandler> HTTPProxy::CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket)
	{
		return std::make_shared<HTTPReqHandler> (this, socket);
	}
} // http
} // i2p
<|endoftext|>


<commit_before>// ---------------------------------------------------------------------
//
// Copyright (C) 2003 - 2016 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, redistribute
// it, and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE at
// the top level of the deal.II distribution.
//
// ---------------------------------------------------------------------

// test escaping of underscores in ParameterHandler::print_parameters(LaTeX)

#include "../tests.h"
#include <deal.II/base/parameter_handler.h>

int main ()
{
  initlog();

  // latex header to make it easy to check the .tex output:
  deallog.get_file_stream() << "\\documentclass{article}\n"
                            "\\usepackage{amsmath}\n"
                            "\\usepackage{imakeidx}\n"
                            "\\makeindex[name=prmindex, title=Index of run-time parameter entries]\n"
                            "\\makeindex[name=prmindexfull, title=Index of run-time parameters with section names]\n"
                            "\\usepackage[colorlinks,linkcolor=blue,urlcolor=blue,citecolor=blue,baseurl=../]{hyperref}\n"
                            "\\begin{document}\n" << std::endl;

  ParameterHandler prm;
  prm.enter_subsection ("section_1");
  {
    prm.enter_subsection ("section_2&3");
    {
      prm.declare_entry ("list",
                         "default_1",
                         Patterns::List(Patterns::Selection("default_1|b|c|d|e|f|g|h")),
                         "docs 1");
      prm.declare_entry ("int_hello",
                         "1",
                         Patterns::Integer());
      prm.declare_entry ("text",
                         "default text with _ ~ \\ # & { }",
                         Patterns::Anything(),
                         "documentation with formulas: $x_3$");
    }
    prm.leave_subsection ();
    prm.declare_entry ("some other entry with {%}",
                       "3.1415926",
                       Patterns::Double(),
                       "documentation");
  }
  prm.leave_subsection ();

  prm.print_parameters (deallog.get_file_stream(), ParameterHandler::LaTeX);

  deallog.get_file_stream() << "\n\n"
                            "\\printindex[prmindex]\n"
                            "\\printindex[prmindexfull]\n"
                            "\\end{document}" << std::endl;
}
<commit_msg>copyright year<commit_after>// ---------------------------------------------------------------------
//
// Copyright (C) 2017 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, redistribute
// it, and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE at
// the top level of the deal.II distribution.
//
// ---------------------------------------------------------------------

// test escaping of underscores in ParameterHandler::print_parameters(LaTeX)

#include "../tests.h"
#include <deal.II/base/parameter_handler.h>

int main ()
{
  initlog();

  // latex header to make it easy to check the .tex output:
  deallog.get_file_stream() << "\\documentclass{article}\n"
                            "\\usepackage{amsmath}\n"
                            "\\usepackage{imakeidx}\n"
                            "\\makeindex[name=prmindex, title=Index of run-time parameter entries]\n"
                            "\\makeindex[name=prmindexfull, title=Index of run-time parameters with section names]\n"
                            "\\usepackage[colorlinks,linkcolor=blue,urlcolor=blue,citecolor=blue,baseurl=../]{hyperref}\n"
                            "\\begin{document}\n" << std::endl;

  ParameterHandler prm;
  prm.enter_subsection ("section_1");
  {
    prm.enter_subsection ("section_2&3");
    {
      prm.declare_entry ("list",
                         "default_1",
                         Patterns::List(Patterns::Selection("default_1|b|c|d|e|f|g|h")),
                         "docs 1");
      prm.declare_entry ("int_hello",
                         "1",
                         Patterns::Integer());
      prm.declare_entry ("text",
                         "default text with _ ~ \\ # & { }",
                         Patterns::Anything(),
                         "documentation with formulas: $x_3$");
    }
    prm.leave_subsection ();
    prm.declare_entry ("some other entry with {%}",
                       "3.1415926",
                       Patterns::Double(),
                       "documentation");
  }
  prm.leave_subsection ();

  prm.print_parameters (deallog.get_file_stream(), ParameterHandler::LaTeX);

  deallog.get_file_stream() << "\n\n"
                            "\\printindex[prmindex]\n"
                            "\\printindex[prmindexfull]\n"
                            "\\end{document}" << std::endl;
}
<|endoftext|>


<commit_before>// trap.cpp
// Implementation of trapezoidal integration scheme
//
// Oliver W. Laslett (2016)
// O.Laslett@soton.ac.uk
#include "../include/trap.hpp"
double trap::trapezoidal( double *x, double *y, size_t N )
{
    double sum;
    unsigned int i;
    for( sum=0.0, i=1; i<N; i++ )
        sum += ( x[i]-x[i-1] ) * ( y[i]+y[i-1] );
    sum /= 2.0;
    return sum;
};
<commit_msg>remove trailing semicolon<commit_after>// trap.cpp
// Implementation of trapezoidal integration scheme
//
// Oliver W. Laslett (2016)
// O.Laslett@soton.ac.uk
#include "../include/trap.hpp"
double trap::trapezoidal( double *x, double *y, size_t N )
{
    double sum;
    unsigned int i;
    for( sum=0.0, i=1; i<N; i++ )
        sum += ( x[i]-x[i-1] ) * ( y[i]+y[i-1] );
    sum /= 2.0;
    return sum;
}
<|endoftext|>


<commit_before>#include "frames.h"

frameGPUi::frameGPUi (int w, int h, bool full) {
	glGenTextures (1, &plane);
	glBindTexture (GL_TEXTURE_2D, plane);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	//glTexImage2D (GL_TEXTURE_2D, 0, full ? GL_RGBA32F : GL_RGBA16F, w, h, 0, GL_RGBA, full ? GL_FLOAT : GL_HALF_FLOAT, NULL);
	glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB10_A2, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, NULL);
	timecode = 0;
}

frameGPUi::~frameGPUi () {
	glDeleteTextures (1, &plane);
}
<commit_msg>Revert "10-bit normalased internal frames"<commit_after>#include "frames.h"

frameGPUi::frameGPUi (int w, int h, bool full) {
	glGenTextures (1, &plane);
	glBindTexture (GL_TEXTURE_2D, plane);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexImage2D (GL_TEXTURE_2D, 0, full ? GL_RGBA32F : GL_RGBA16F, w, h, 0, GL_RGBA, full ? GL_FLOAT : GL_HALF_FLOAT, NULL);

	timecode = 0;
}

frameGPUi::~frameGPUi () {
	glDeleteTextures (1, &plane);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: unowrapper.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 22:57:32 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _TOOLKIT_HELPER_UNOWRAPPER_HXX_
#define _TOOLKIT_HELPER_UNOWRAPPER_HXX_

#ifndef _COM_SUN_STAR_AWT_XTOOLKIT_HPP_
#include <com/sun/star/awt/XToolkit.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XGRAPHICS_HPP_
#include <com/sun/star/awt/XGraphics.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XWINDOWPEER_HPP_
#include <com/sun/star/awt/XWindowPeer.hpp>
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLE_HPP_
#include <com/sun/star/accessibility/XAccessible.hpp>
#endif

#include <vcl/unowrap.hxx>
#include <vcl/window.hxx>

//  ----------------------------------------------------
//  class UnoWrapper
//  ----------------------------------------------------

class UnoWrapper : public UnoWrapperBase
{
private:
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit> mxToolkit;

public:
    UnoWrapper( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit>& rxToolkit );
    virtual ~UnoWrapper();

    void                                Destroy();

    // Toolkit
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit> GetVCLToolkit();

    // Graphics
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics> CreateGraphics( OutputDevice* pOutDev );
    virtual void                ReleaseAllGraphics( OutputDevice* pOutDev );

    // Window
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> GetWindowInterface( Window* pWindow, BOOL bCreate );
    virtual void                SetWindowInterface( Window* pWindow, ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xIFace );

    void                WindowDestroyed( Window* pWindow );
    void                WindowEvent_Move( Window* pWindow );
    void                WindowEvent_Resize( Window* pWindow );
    void                WindowEvent_Show( Window* pWindow, BOOL bShow );
    void                WindowEvent_Close( Window* pWindow );
    void                WindowEvent_Minimize( Window* pWindow );
    void                WindowEvent_Normalize( Window* pWindow );
    void                WindowEvent_Activate( Window* pWindow, BOOL bActivated );
    void                WindowEvent_MouseButtonUp( Window* pWindow, const MouseEvent& rEvt );
    void                WindowEvent_MouseButtonDown( Window* pWindow, const MouseEvent& rEvt );
    void                WindowEvent_MouseMove( Window* pWindow, const MouseEvent& rEvt );
    void                WindowEvent_Command( Window* pWindow, const CommandEvent& rCEvt );
    void                WindowEvent_KeyInput( Window* pWindow, const KeyEvent& rEvt );
    void                WindowEvent_KeyUp( Window* pWindow, const KeyEvent& rEvt );
    void                WindowEvent_GetFocus( Window* pWindow );
    void                WindowEvent_LoseFocus( Window* pWindow );
    void                WindowEvent_Paint( Window* pWindow, const Rectangle& rRect );

    // Accessibility
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
                                CreateAccessible( Menu* pMenu, sal_Bool bIsMenuBar );
};

#endif // _TOOLKIT_HELPER_UNOWRAPPER_HXX_

<commit_msg>INTEGRATION: CWS a11ysep (1.7.264); FILE MERGED 2006/10/05 11:27:14 fs 1.7.264.4: #i10000# post-resync problem 2006/09/21 21:23:06 fs 1.7.264.3: RESYNC: (1.8-1.9); FILE MERGED 2005/09/27 06:21:03 fs 1.7.264.2: RESYNC: (1.7-1.8); FILE MERGED 2005/03/07 07:53:20 fs 1.7.264.1: #i44293# +maAccessibleFactoryAccess<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: unowrapper.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 15:06:01 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _TOOLKIT_HELPER_UNOWRAPPER_HXX_
#define _TOOLKIT_HELPER_UNOWRAPPER_HXX_

#ifndef _COM_SUN_STAR_AWT_XTOOLKIT_HPP_
#include <com/sun/star/awt/XToolkit.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XGRAPHICS_HPP_
#include <com/sun/star/awt/XGraphics.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XWINDOWPEER_HPP_
#include <com/sun/star/awt/XWindowPeer.hpp>
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLE_HPP_
#include <com/sun/star/accessibility/XAccessible.hpp>
#endif
#ifndef TOOLKIT_HELPER_ACCESSIBILITY_CLIENT_HXX
#include <toolkit/helper/accessibilityclient.hxx>
#endif

#include <vcl/unowrap.hxx>
#include <vcl/window.hxx>

//  ----------------------------------------------------
//  class UnoWrapper
//  ----------------------------------------------------

class UnoWrapper : public UnoWrapperBase
{
private:
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit>  mxToolkit;
    ::toolkit::AccessibilityClient                                      maAccessibleFactoryAccess;

public:
    UnoWrapper( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit>& rxToolkit );

    virtual void        Destroy();

    // Toolkit
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit> GetVCLToolkit();

    // Graphics
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics> CreateGraphics( OutputDevice* pOutDev );
    virtual void                ReleaseAllGraphics( OutputDevice* pOutDev );

    // Window
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> GetWindowInterface( Window* pWindow, BOOL bCreate );
    virtual void                SetWindowInterface( Window* pWindow, ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xIFace );

    void                WindowDestroyed( Window* pWindow );
    void                WindowEvent_Move( Window* pWindow );
    void                WindowEvent_Resize( Window* pWindow );
    void                WindowEvent_Show( Window* pWindow, BOOL bShow );
    void                WindowEvent_Close( Window* pWindow );
    void                WindowEvent_Minimize( Window* pWindow );
    void                WindowEvent_Normalize( Window* pWindow );
    void                WindowEvent_Activate( Window* pWindow, BOOL bActivated );
    void                WindowEvent_MouseButtonUp( Window* pWindow, const MouseEvent& rEvt );
    void                WindowEvent_MouseButtonDown( Window* pWindow, const MouseEvent& rEvt );
    void                WindowEvent_MouseMove( Window* pWindow, const MouseEvent& rEvt );
    void                WindowEvent_Command( Window* pWindow, const CommandEvent& rCEvt );
    void                WindowEvent_KeyInput( Window* pWindow, const KeyEvent& rEvt );
    void                WindowEvent_KeyUp( Window* pWindow, const KeyEvent& rEvt );
    void                WindowEvent_GetFocus( Window* pWindow );
    void                WindowEvent_LoseFocus( Window* pWindow );
    void                WindowEvent_Paint( Window* pWindow, const Rectangle& rRect );

    // Accessibility
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
                        CreateAccessible( Menu* pMenu, sal_Bool bIsMenuBar );

private:
    virtual ~UnoWrapper();
};

#endif // _TOOLKIT_HELPER_UNOWRAPPER_HXX_

<|endoftext|>