<commit_before>//
//  Executor.hpp
//  Clock Signal
//
//  Created by Thomas Harte on 29/04/2022.
//  Copyright © 2022 Thomas Harte. All rights reserved.
//

#ifndef InstructionSets_M68k_Executor_hpp
#define InstructionSets_M68k_Executor_hpp

#include "Decoder.hpp"
#include "Instruction.hpp"
#include "Model.hpp"
#include "Perform.hpp"
#include "Sequence.hpp"
#include "Status.hpp"

namespace InstructionSet {
namespace M68k {

struct BusHandler {
	template <typename IntT> void write(uint32_t address, IntT value);
	template <typename IntT> IntT read(uint32_t address);
};

/// Ties together the decoder, sequencer and performer to provide an executor for 680x0 instruction streams.
/// As is standard for these executors, no bus- or cache-level fidelity to any real 680x0 is attempted. This is
/// simply an executor of 680x0 code.
template <Model model, typename BusHandler> class Executor {
	public:
		Executor(BusHandler &);

		/// Executes the number of instructions specified;
		/// other events — such as initial reset or branching
		/// to exceptions — may be zero costed, and interrupts
		/// will not necessarily take effect immediately when signalled.
		void run_for_instructions(int);

	private:
		BusHandler &bus_handler_;
		Predecoder<model> decoder_;

		void reset();

		// Processor state.
		Status status_;
		CPU::SlicedInt32 program_counter_;
};

}
}

#endif /* InstructionSets_M68k_Executor_hpp */
<commit_msg>Add basic status.<commit_after>//
//  Executor.hpp
//  Clock Signal
//
//  Created by Thomas Harte on 29/04/2022.
//  Copyright © 2022 Thomas Harte. All rights reserved.
//

#ifndef InstructionSets_M68k_Executor_hpp
#define InstructionSets_M68k_Executor_hpp

#include "Decoder.hpp"
#include "Instruction.hpp"
#include "Model.hpp"
#include "Perform.hpp"
#include "Sequence.hpp"
#include "Status.hpp"

namespace InstructionSet {
namespace M68k {

struct BusHandler {
	template <typename IntT> void write(uint32_t address, IntT value);
	template <typename IntT> IntT read(uint32_t address);
};

/// Ties together the decoder, sequencer and performer to provide an executor for 680x0 instruction streams.
/// As is standard for these executors, no bus- or cache-level fidelity to any real 680x0 is attempted. This is
/// simply an executor of 680x0 code.
template <Model model, typename BusHandler> class Executor {
	public:
		Executor(BusHandler &);

		/// Executes the number of instructions specified;
		/// other events — such as initial reset or branching
		/// to exceptions — may be zero costed, and interrupts
		/// will not necessarily take effect immediately when signalled.
		void run_for_instructions(int);

	private:
		BusHandler &bus_handler_;
		Predecoder<model> decoder_;

		void reset();

		// Processor state.
		Status status_;
		CPU::SlicedInt32 program_counter_;
		CPU::SlicedInt32 data_[8], address_[8];
		CPU::SlicedInt32 stack_pointers_[2];
};

}
}

#endif /* InstructionSets_M68k_Executor_hpp */
<|endoftext|>


<commit_before>/*****************************************************************************
  intersectMain.cpp

  (c) 2009 - Aaron Quinlan
  Hall Laboratory
  Department of Biochemistry and Molecular Genetics
  University of Virginia
  aaronquinlan@gmail.com

  Licenced under the GNU General Public License 2.0 license.
******************************************************************************/
#include "intersectBed.h"
#include "version.h"

using namespace std;

// define our program name
#define PROGRAM_NAME "bedtools intersect"

// define our parameter checking macro
#define PARAMETER_CHECK(param, paramLen, actualLen) (strncmp(argv[i], param, min(actualLen, paramLen))== 0) && (actualLen == paramLen)

// function declarations
void intersect_help(void);

int intersect_main(int argc, char* argv[]) {

    // our configuration variables
    bool showHelp = false;

    // input files
    string bedAFile;
    string bedBFile;

    // input arguments
    float overlapFraction = 1E-9;

    bool haveBedA           = false;
    bool haveBedB           = false;
    bool noHit              = false;
    bool leftJoin           = false;
    bool anyHit             = false;
    bool writeA             = false;
    bool writeB             = false;
    bool writeCount         = false;
    bool writeOverlap       = false;
    bool writeAllOverlap    = false;
    bool haveFraction       = false;
    bool reciprocalFraction = false;
    bool sameStrand         = false;
    bool diffStrand         = false;
    bool obeySplits         = false;
    bool inputIsBam         = false;
    bool outputIsBam        = true;
    bool uncompressedBam    = false;
    bool sortedInput        = false;
    bool printHeader        = false;

    // check to see if we should print out some help
    if(argc <= 1) showHelp = true;

    for(int i = 1; i < argc; i++) {
        int parameterLength = (int)strlen(argv[i]);

        if((PARAMETER_CHECK("-h", 2, parameterLength)) ||
        (PARAMETER_CHECK("--help", 5, parameterLength))) {
            showHelp = true;
        }
    }

    if(showHelp) intersect_help();

    // do some parsing (all of these parameters require 2 strings)
    for(int i = 1; i < argc; i++) {

        int parameterLength = (int)strlen(argv[i]);

        if(PARAMETER_CHECK("-a", 2, parameterLength)) {
            if ((i+1) < argc) {
                haveBedA = true;
                outputIsBam = false;
                bedAFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-abam", 5, parameterLength)) {
            if ((i+1) < argc) {
                haveBedA = true;
                inputIsBam = true;
                bedAFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-b", 2, parameterLength)) {
            if ((i+1) < argc) {
                haveBedB = true;
                bedBFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-bed", 4, parameterLength)) {
            outputIsBam = false;
        }
        else if(PARAMETER_CHECK("-u", 2, parameterLength)) {
            anyHit = true;
        }
        else if(PARAMETER_CHECK("-f", 2, parameterLength)) {
            if ((i+1) < argc) {
                haveFraction = true;
                overlapFraction = atof(argv[i + 1]);
                i++;
            }
        }
        else if(PARAMETER_CHECK("-wa", 3, parameterLength)) {
            writeA = true;
        }
        else if(PARAMETER_CHECK("-wb", 3, parameterLength)) {
            writeB = true;
        }
        else if(PARAMETER_CHECK("-wo", 3, parameterLength)) {
            writeOverlap = true;
        }
        else if(PARAMETER_CHECK("-wao", 4, parameterLength)) {
            writeAllOverlap = true;
            writeOverlap = true;
        }
        else if(PARAMETER_CHECK("-c", 2, parameterLength)) {
            writeCount = true;
        }
        else if(PARAMETER_CHECK("-r", 2, parameterLength)) {
            reciprocalFraction = true;
        }
        else if (PARAMETER_CHECK("-v", 2, parameterLength)) {
            noHit = true;
        }
        else if (PARAMETER_CHECK("-s", 2, parameterLength)) {
            sameStrand = true;
        }
        else if (PARAMETER_CHECK("-S", 2, parameterLength)) {
            diffStrand = true;
        }
        else if (PARAMETER_CHECK("-split", 6, parameterLength)) {
            obeySplits = true;
        }
        else if (PARAMETER_CHECK("-loj", 4, parameterLength)) {
            leftJoin = true;
        }
        else if(PARAMETER_CHECK("-ubam", 5, parameterLength)) {
            uncompressedBam = true;
        }
        else if(PARAMETER_CHECK("-sorted", 7, parameterLength)) {
            sortedInput = true;
        }
        else if(PARAMETER_CHECK("-header", 7, parameterLength)) {
            printHeader = true;
        }
        else {
            cerr << endl << "*****ERROR: Unrecognized parameter: " << argv[i] << " *****" << endl << endl;
            showHelp = true;
        }
    }

    // make sure we have both input files
    if (!haveBedA || !haveBedB) {
        cerr << endl << "*****" << endl << "*****ERROR: Need -a and -b files. " << endl << "*****" << endl;
        showHelp = true;
    }

    if (anyHit && noHit) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -u OR -v, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (writeB && writeCount) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -wb OR -c, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (writeCount && writeOverlap) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -wb OR -wo, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (writeA && writeOverlap) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -wa OR -wo, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (writeB && writeOverlap) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -wb OR -wo, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (reciprocalFraction && !haveFraction) {
        cerr << endl << "*****" << endl << "*****ERROR: If using -r, you need to define -f." << endl << "*****" << endl;
        showHelp = true;
    }

    if (anyHit && writeCount) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -u OR -c, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (anyHit && writeB) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -u OR -wb, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (anyHit && writeOverlap) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -u OR -wo, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (sameStrand && diffStrand) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -s OR -S, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (inputIsBam && writeB && outputIsBam) {
        cerr << endl << "*****" << endl << "*****WARNING: -wb is ignored with -abam" << endl << "*****" << endl;
    }

    if (inputIsBam && leftJoin) {
        cerr << endl << "*****" << endl << "*****WARNING: -loj is ignored with -abam" << endl << "*****" << endl;
    }

    if (inputIsBam && writeCount) {
        cerr << endl << "*****" << endl << "*****WARNING: -c is ignored with -abam" << endl << "*****" << endl;
    }

    if (inputIsBam && writeOverlap) {
        cerr << endl << "*****" << endl << "*****WARNING: -wo is ignored with -abam" << endl << "*****" << endl;
    }

    if (inputIsBam && writeAllOverlap) {
        cerr << endl << "*****" << endl << "*****WARNING: -wao is ignored with -abam" << endl << "*****" << endl;
    }

    if (!showHelp) {

        BedIntersect *bi = new BedIntersect(bedAFile, bedBFile, anyHit, writeA, writeB, writeOverlap,
                                            writeAllOverlap, overlapFraction, noHit, leftJoin, writeCount, sameStrand, diffStrand,
                                            reciprocalFraction, obeySplits, inputIsBam, outputIsBam, uncompressedBam,
                                            sortedInput, printHeader);
        delete bi;
        return 0;
    }
    else {
        intersect_help();
        return 0;
    }
}

void intersect_help(void) {

    cerr << "\nTool:    bedtools intersect (aka intersectBed)" << endl;
    cerr << "Version: " << VERSION << "\n";
    cerr << "Summary: Report overlaps between two feature files." << endl << endl;

    cerr << "Usage:   " << PROGRAM_NAME << " [OPTIONS] -a <bed/gff/vcf> -b <bed/gff/vcf>" << endl << endl;

    cerr << "Options: " << endl;

    cerr << "\t-abam\t"         << "The A input file is in BAM format.  Output will be BAM as well." << endl << endl;

    cerr << "\t-ubam\t"         << "Write uncompressed BAM output. Default writes compressed BAM." << endl << endl;

    cerr << "\t-bed\t"          << "When using BAM input (-abam), write output as BED. The default" << endl;
    cerr                        << "\t\tis to write output in BAM when using -abam." << endl << endl;

    cerr << "\t-wa\t"           << "Write the original entry in A for each overlap." << endl << endl;

    cerr << "\t-wb\t"           << "Write the original entry in B for each overlap." << endl;
    cerr                        << "\t\t- Useful for knowing _what_ A overlaps. Restricted by -f and -r." << endl << endl;

    cerr << "\t-loj\t"          << "Perform a \"left outer join\". That is, for each feature in A" << endl;
    cerr                        << "\t\treport each overlap with B.  If no overlaps are found, " << endl;
    cerr                        << "\t\treport a NULL feature for B." << endl << endl;

    cerr << "\t-wo\t"           << "Write the original A and B entries plus the number of base" << endl;
    cerr                        << "\t\tpairs of overlap between the two features." << endl;
    cerr                        << "\t\t- Overlaps restricted by -f and -r." << endl;
    cerr                        << "\t\t  Only A features with overlap are reported." << endl << endl;

    cerr << "\t-wao\t"          << "Write the original A and B entries plus the number of base" << endl;
    cerr                        << "\t\tpairs of overlap between the two features." << endl;
    cerr                        << "\t\t- Overlapping features restricted by -f and -r." << endl;
    cerr                        << "\t\t  However, A features w/o overlap are also reported" << endl;
    cerr                        << "\t\t  with a NULL B feature and overlap = 0." << endl << endl;

    cerr << "\t-u\t"            << "Write the original A entry _once_ if _any_ overlaps found in B." << endl;
    cerr                        << "\t\t- In other words, just report the fact >=1 hit was found." << endl;
    cerr                        << "\t\t- Overlaps restricted by -f and -r." << endl << endl;

    cerr << "\t-c\t"            << "For each entry in A, report the number of overlaps with B." << endl;
    cerr                        << "\t\t- Reports 0 for A entries that have no overlap with B." << endl;
    cerr                        << "\t\t- Overlaps restricted by -f and -r." << endl << endl;

    cerr << "\t-v\t"            << "Only report those entries in A that have _no overlaps_ with B." << endl;
    cerr                        << "\t\t- Similar to \"grep -v\" (an homage)." << endl << endl;

    cerr << "\t-f\t"            << "Minimum overlap required as a fraction of A." << endl;
    cerr                        << "\t\t- Default is 1E-9 (i.e., 1bp)." << endl;
    cerr                        << "\t\t- FLOAT (e.g. 0.50)" << endl << endl;

    cerr << "\t-r\t"            << "Require that the fraction overlap be reciprocal for A and B." << endl;
    cerr                        << "\t\t- In other words, if -f is 0.90 and -r is used, this requires" << endl;
    cerr                        << "\t\t  that B overlap 90% of A and A _also_ overlaps 90% of B." << endl << endl;

    cerr << "\t-s\t"            << "Require same strandedness.  That is, only report hits in B" << endl;
    cerr                        << "\t\tthat overlap A on the _same_ strand." << endl;
    cerr                        << "\t\t- By default, overlaps are reported without respect to strand." << endl << endl;

    cerr << "\t-S\t"            << "Require different strandedness.  That is, only report hits in B" << endl;
    cerr                        << "\t\tthat overlap A on the _opposite_ strand." << endl;
    cerr                        << "\t\t- By default, overlaps are reported without respect to strand." << endl << endl;

    cerr << "\t-split\t"        << "Treat \"split\" BAM or BED12 entries as distinct BED intervals." << endl << endl;

    cerr << "\t-sorted\t"       << "Use the \"chromsweep\" algorithm for sorted (-k1,1 -k2,2n) input" << endl << endl;

    cerr << "\t-header\t"       << "Print the header from the A file prior to results." << endl << endl;

    cerr << "Notes: " << endl;
    cerr << "\t(1) When a BAM file is used for the A file, the alignment is retained if overlaps exist," << endl;
    cerr << "\tand exlcuded if an overlap cannot be found.  If multiple overlaps exist, they are not" << endl;
    cerr << "\treported, as we are only testing for one or more overlaps." << endl << endl;

    // end the program here
    exit(1);

}
<commit_msg>-wo -wao -c with -abam force BED output. Thanks to @agordon.<commit_after>/*****************************************************************************
  intersectMain.cpp

  (c) 2009 - Aaron Quinlan
  Hall Laboratory
  Department of Biochemistry and Molecular Genetics
  University of Virginia
  aaronquinlan@gmail.com

  Licenced under the GNU General Public License 2.0 license.
******************************************************************************/
#include "intersectBed.h"
#include "version.h"

using namespace std;

// define our program name
#define PROGRAM_NAME "bedtools intersect"

// define our parameter checking macro
#define PARAMETER_CHECK(param, paramLen, actualLen) (strncmp(argv[i], param, min(actualLen, paramLen))== 0) && (actualLen == paramLen)

// function declarations
void intersect_help(void);

int intersect_main(int argc, char* argv[]) {

    // our configuration variables
    bool showHelp = false;

    // input files
    string bedAFile;
    string bedBFile;

    // input arguments
    float overlapFraction = 1E-9;

    bool haveBedA           = false;
    bool haveBedB           = false;
    bool noHit              = false;
    bool leftJoin           = false;
    bool anyHit             = false;
    bool writeA             = false;
    bool writeB             = false;
    bool writeCount         = false;
    bool writeOverlap       = false;
    bool writeAllOverlap    = false;
    bool haveFraction       = false;
    bool reciprocalFraction = false;
    bool sameStrand         = false;
    bool diffStrand         = false;
    bool obeySplits         = false;
    bool inputIsBam         = false;
    bool outputIsBam        = true;
    bool uncompressedBam    = false;
    bool sortedInput        = false;
    bool printHeader        = false;

    // check to see if we should print out some help
    if(argc <= 1) showHelp = true;

    for(int i = 1; i < argc; i++) {
        int parameterLength = (int)strlen(argv[i]);

        if((PARAMETER_CHECK("-h", 2, parameterLength)) ||
        (PARAMETER_CHECK("--help", 5, parameterLength))) {
            showHelp = true;
        }
    }

    if(showHelp) intersect_help();

    // do some parsing (all of these parameters require 2 strings)
    for(int i = 1; i < argc; i++) {

        int parameterLength = (int)strlen(argv[i]);

        if(PARAMETER_CHECK("-a", 2, parameterLength)) {
            if ((i+1) < argc) {
                haveBedA = true;
                outputIsBam = false;
                bedAFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-abam", 5, parameterLength)) {
            if ((i+1) < argc) {
                haveBedA = true;
                inputIsBam = true;
                bedAFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-b", 2, parameterLength)) {
            if ((i+1) < argc) {
                haveBedB = true;
                bedBFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-bed", 4, parameterLength)) {
            outputIsBam = false;
        }
        else if(PARAMETER_CHECK("-u", 2, parameterLength)) {
            anyHit = true;
        }
        else if(PARAMETER_CHECK("-f", 2, parameterLength)) {
            if ((i+1) < argc) {
                haveFraction = true;
                overlapFraction = atof(argv[i + 1]);
                i++;
            }
        }
        else if(PARAMETER_CHECK("-wa", 3, parameterLength)) {
            writeA = true;
        }
        else if(PARAMETER_CHECK("-wb", 3, parameterLength)) {
            writeB = true;
        }
        else if(PARAMETER_CHECK("-wo", 3, parameterLength)) {
            writeOverlap = true;
        }
        else if(PARAMETER_CHECK("-wao", 4, parameterLength)) {
            writeAllOverlap = true;
            writeOverlap = true;
        }
        else if(PARAMETER_CHECK("-c", 2, parameterLength)) {
            writeCount = true;
        }
        else if(PARAMETER_CHECK("-r", 2, parameterLength)) {
            reciprocalFraction = true;
        }
        else if (PARAMETER_CHECK("-v", 2, parameterLength)) {
            noHit = true;
        }
        else if (PARAMETER_CHECK("-s", 2, parameterLength)) {
            sameStrand = true;
        }
        else if (PARAMETER_CHECK("-S", 2, parameterLength)) {
            diffStrand = true;
        }
        else if (PARAMETER_CHECK("-split", 6, parameterLength)) {
            obeySplits = true;
        }
        else if (PARAMETER_CHECK("-loj", 4, parameterLength)) {
            leftJoin = true;
        }
        else if(PARAMETER_CHECK("-ubam", 5, parameterLength)) {
            uncompressedBam = true;
        }
        else if(PARAMETER_CHECK("-sorted", 7, parameterLength)) {
            sortedInput = true;
        }
        else if(PARAMETER_CHECK("-header", 7, parameterLength)) {
            printHeader = true;
        }
        else {
            cerr << endl << "*****ERROR: Unrecognized parameter: " << argv[i] << " *****" << endl << endl;
            showHelp = true;
        }
    }

    // make sure we have both input files
    if (!haveBedA || !haveBedB) {
        cerr << endl << "*****" << endl << "*****ERROR: Need -a and -b files. " << endl << "*****" << endl;
        showHelp = true;
    }

    if (anyHit && noHit) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -u OR -v, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (writeB && writeCount) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -wb OR -c, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (writeCount && writeOverlap) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -wb OR -wo, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (writeA && writeOverlap) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -wa OR -wo, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (writeB && writeOverlap) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -wb OR -wo, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (reciprocalFraction && !haveFraction) {
        cerr << endl << "*****" << endl << "*****ERROR: If using -r, you need to define -f." << endl << "*****" << endl;
        showHelp = true;
    }

    if (anyHit && writeCount) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -u OR -c, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (anyHit && writeB) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -u OR -wb, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (anyHit && writeOverlap) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -u OR -wo, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (sameStrand && diffStrand) {
        cerr << endl << "*****" << endl << "*****ERROR: Request either -s OR -S, not both." << endl << "*****" << endl;
        showHelp = true;
    }

    if (inputIsBam && writeB && outputIsBam) {
        cerr << endl << "*****" << endl << "*****WARNING: -wb is ignored with -abam" << endl << "*****" << endl;
    }

    if (inputIsBam && leftJoin) {
        cerr << endl << "*****" << endl << "*****WARNING: -loj is ignored with -abam" << endl << "*****" << endl;
    }

    if (outputIsBam && (writeCount || writeOverlap || writeAllOverlap))
    {
        outputIsBam = false;
    }

    if (!showHelp) {

        BedIntersect *bi = new BedIntersect(bedAFile, bedBFile, anyHit, writeA, writeB, writeOverlap,
                                            writeAllOverlap, overlapFraction, noHit, leftJoin, writeCount, sameStrand, diffStrand,
                                            reciprocalFraction, obeySplits, inputIsBam, outputIsBam, uncompressedBam,
                                            sortedInput, printHeader);
        delete bi;
        return 0;
    }
    else {
        intersect_help();
        return 0;
    }
}

void intersect_help(void) {

    cerr << "\nTool:    bedtools intersect (aka intersectBed)" << endl;
    cerr << "Version: " << VERSION << "\n";
    cerr << "Summary: Report overlaps between two feature files." << endl << endl;

    cerr << "Usage:   " << PROGRAM_NAME << " [OPTIONS] -a <bed/gff/vcf> -b <bed/gff/vcf>" << endl << endl;

    cerr << "Options: " << endl;

    cerr << "\t-abam\t"         << "The A input file is in BAM format.  Output will be BAM as well." << endl << endl;

    cerr << "\t-ubam\t"         << "Write uncompressed BAM output. Default writes compressed BAM." << endl << endl;

    cerr << "\t-bed\t"          << "When using BAM input (-abam), write output as BED. The default" << endl;
    cerr                        << "\t\tis to write output in BAM when using -abam." << endl << endl;

    cerr << "\t-wa\t"           << "Write the original entry in A for each overlap." << endl << endl;

    cerr << "\t-wb\t"           << "Write the original entry in B for each overlap." << endl;
    cerr                        << "\t\t- Useful for knowing _what_ A overlaps. Restricted by -f and -r." << endl << endl;

    cerr << "\t-loj\t"          << "Perform a \"left outer join\". That is, for each feature in A" << endl;
    cerr                        << "\t\treport each overlap with B.  If no overlaps are found, " << endl;
    cerr                        << "\t\treport a NULL feature for B." << endl << endl;

    cerr << "\t-wo\t"           << "Write the original A and B entries plus the number of base" << endl;
    cerr                        << "\t\tpairs of overlap between the two features." << endl;
    cerr                        << "\t\t- Overlaps restricted by -f and -r." << endl;
    cerr                        << "\t\t  Only A features with overlap are reported." << endl << endl;

    cerr << "\t-wao\t"          << "Write the original A and B entries plus the number of base" << endl;
    cerr                        << "\t\tpairs of overlap between the two features." << endl;
    cerr                        << "\t\t- Overlapping features restricted by -f and -r." << endl;
    cerr                        << "\t\t  However, A features w/o overlap are also reported" << endl;
    cerr                        << "\t\t  with a NULL B feature and overlap = 0." << endl << endl;

    cerr << "\t-u\t"            << "Write the original A entry _once_ if _any_ overlaps found in B." << endl;
    cerr                        << "\t\t- In other words, just report the fact >=1 hit was found." << endl;
    cerr                        << "\t\t- Overlaps restricted by -f and -r." << endl << endl;

    cerr << "\t-c\t"            << "For each entry in A, report the number of overlaps with B." << endl;
    cerr                        << "\t\t- Reports 0 for A entries that have no overlap with B." << endl;
    cerr                        << "\t\t- Overlaps restricted by -f and -r." << endl << endl;

    cerr << "\t-v\t"            << "Only report those entries in A that have _no overlaps_ with B." << endl;
    cerr                        << "\t\t- Similar to \"grep -v\" (an homage)." << endl << endl;

    cerr << "\t-f\t"            << "Minimum overlap required as a fraction of A." << endl;
    cerr                        << "\t\t- Default is 1E-9 (i.e., 1bp)." << endl;
    cerr                        << "\t\t- FLOAT (e.g. 0.50)" << endl << endl;

    cerr << "\t-r\t"            << "Require that the fraction overlap be reciprocal for A and B." << endl;
    cerr                        << "\t\t- In other words, if -f is 0.90 and -r is used, this requires" << endl;
    cerr                        << "\t\t  that B overlap 90% of A and A _also_ overlaps 90% of B." << endl << endl;

    cerr << "\t-s\t"            << "Require same strandedness.  That is, only report hits in B" << endl;
    cerr                        << "\t\tthat overlap A on the _same_ strand." << endl;
    cerr                        << "\t\t- By default, overlaps are reported without respect to strand." << endl << endl;

    cerr << "\t-S\t"            << "Require different strandedness.  That is, only report hits in B" << endl;
    cerr                        << "\t\tthat overlap A on the _opposite_ strand." << endl;
    cerr                        << "\t\t- By default, overlaps are reported without respect to strand." << endl << endl;

    cerr << "\t-split\t"        << "Treat \"split\" BAM or BED12 entries as distinct BED intervals." << endl << endl;

    cerr << "\t-sorted\t"       << "Use the \"chromsweep\" algorithm for sorted (-k1,1 -k2,2n) input" << endl << endl;

    cerr << "\t-header\t"       << "Print the header from the A file prior to results." << endl << endl;

    cerr << "Notes: " << endl;
    cerr << "\t(1) When a BAM file is used for the A file, the alignment is retained if overlaps exist," << endl;
    cerr << "\tand exlcuded if an overlap cannot be found.  If multiple overlaps exist, they are not" << endl;
    cerr << "\treported, as we are only testing for one or more overlaps." << endl << endl;

    // end the program here
    exit(1);

}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkCleanPolyData.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1996 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkCleanPolyData.h"
#include "vtkMergePoints.h"

// Description:
// Construct object with initial tolerance of 0.0.
vtkCleanPolyData::vtkCleanPolyData()
{
  this->Tolerance = 0.0;
  this->Locator = NULL;
  this->SelfCreatedLocator = 0;
}

vtkCleanPolyData::~vtkCleanPolyData()
{
  if ( this->SelfCreatedLocator && this->Locator != NULL)
    this->Locator->Delete();
}

void vtkCleanPolyData::Execute()
{
  vtkPolyData *input=(vtkPolyData *)this->Input;
  vtkPointData *pd=input->GetPointData();
  int numPts=input->GetNumberOfPoints();
  vtkPoints *inPts;
  vtkFloatPoints *newPts;
  int numNewPts;
  int *updatedPts= new int[input->GetMaxCellSize()];
  int i, ptId;
  int npts, *pts;
  float *x;
  vtkCellArray *inVerts=input->GetVerts(), *newVerts=NULL;
  vtkCellArray *inLines=input->GetLines(), *newLines=NULL;
  vtkCellArray *inPolys=input->GetPolys(), *newPolys=NULL;
  vtkCellArray *inStrips=input->GetStrips(), *newStrips=NULL;
  vtkPolyData *output = this->GetOutput();
  vtkPointData *outputPD = output->GetPointData();

  vtkDebugMacro(<<"Cleaning data");

  if ( numPts < 1 || (inPts=input->GetPoints()) == NULL )
    {
    vtkErrorMacro(<<"No data to clean!");
    return;
    }

  outputPD->CopyAllocate(pd);
  if ( this->Locator == NULL ) this->CreateDefaultLocator();

  // Initialize; compute absolute tolerance from relative given
  this->Locator->SetTolerance(this->Tolerance*input->GetLength());
  newPts = vtkFloatPoints::New();
  newPts->Allocate(numPts);
  this->Locator->InitPointInsertion (newPts, this->Input->GetBounds());

  //
  // Begin to adjust topology.
  //
  // Vertices are renumbered and we remove duplicate vertices
  if ( inVerts->GetNumberOfCells() > 0 )
    {
    newVerts = vtkCellArray::New();
    newVerts->Allocate(inVerts->GetSize());

    for (inVerts->InitTraversal(); inVerts->GetNextCell(npts,pts); )
      {
      for ( numNewPts=0, i=0; i < npts; i++ )
        {
        x = inPts->GetPoint(pts[i]);

        if ( (ptId=this->Locator->IsInsertedPoint(x)) < 0 )
          {
          ptId = this->Locator->InsertNextPoint(x);
          updatedPts[numNewPts++] = ptId;
          outputPD->CopyData(pd,pts[i],ptId);
          }
        }
      if ( numNewPts > 0 ) newVerts->InsertNextCell(numNewPts,updatedPts);
      }
    newVerts->Squeeze();
    }

  // lines reduced to one point are eliminated
  if ( inLines->GetNumberOfCells() > 0 )
    {
    newLines = vtkCellArray::New();
    newLines->Allocate(inLines->GetSize());

    for (inLines->InitTraversal(); inLines->GetNextCell(npts,pts); )
      {
      for ( numNewPts=0, i=0; i < npts; i++ )
        {
        x = inPts->GetPoint(pts[i]);

        if ( (ptId=this->Locator->IsInsertedPoint(x)) < 0 )
          {
          ptId = this->Locator->InsertNextPoint(x);
          outputPD->CopyData(pd,pts[i],ptId);
          }

        if ( i == 0 || ptId != updatedPts[numNewPts-1] )
          {
          updatedPts[numNewPts++] = ptId;
          }
        }

      if ( numNewPts > 1 ) newLines->InsertNextCell(numNewPts,updatedPts);
      }
    newLines->Squeeze();
    vtkDebugMacro(<<"Removed " << inLines->GetNumberOfCells() -
                 newLines->GetNumberOfCells() << " lines");
    }

  // polygons reduced to two points or less are eliminated
  if ( inPolys->GetNumberOfCells() > 0 )
    {
    newPolys = vtkCellArray::New();
    newPolys->Allocate(inPolys->GetSize());
    for (inPolys->InitTraversal(); inPolys->GetNextCell(npts,pts); )
      {
      for ( numNewPts=0, i=0; i < npts; i++ )
        {
        x = inPts->GetPoint(pts[i]);

        if ( (ptId=this->Locator->IsInsertedPoint(x)) < 0 )
          {
          ptId = this->Locator->InsertNextPoint(x);
          outputPD->CopyData(pd,pts[i],ptId);
          }

        if ( i == 0 || ptId != updatedPts[numNewPts-1] )
          {
          updatedPts[numNewPts++] = ptId;
          }
        }
      if ( numNewPts > 2 ) newPolys->InsertNextCell(numNewPts,updatedPts);
      }

    newPolys->Squeeze();
    vtkDebugMacro(<<"Removed " << inPolys->GetNumberOfCells() -
                 newPolys->GetNumberOfCells() << " polys");
    }

  // triangle strips reduced to two points or less are eliminated
  if ( inStrips->GetNumberOfCells() > 0 )
    {
    newStrips = vtkCellArray::New();
    newStrips->Allocate(inStrips->GetSize());

    for (inStrips->InitTraversal(); inStrips->GetNextCell(npts,pts); )
      {
      for ( numNewPts=0, i=0; i < npts; i++ )
        {
        x = inPts->GetPoint(pts[i]);

        if ( (ptId=this->Locator->IsInsertedPoint(x)) < 0 )
          {
          ptId = this->Locator->InsertNextPoint(x);
          outputPD->CopyData(pd,pts[i],ptId);
          }

        if ( i == 0 || ptId != updatedPts[numNewPts-1] )
          {
          updatedPts[numNewPts++] = ptId;
          }
        }

      if ( numNewPts > 2 ) newStrips->InsertNextCell(numNewPts,updatedPts);
      }

    newStrips->Squeeze();
    vtkDebugMacro(<<"Removed " << inStrips->GetNumberOfCells() -
                 newStrips->GetNumberOfCells() << " strips");
    }

  //
  // Update ourselves and release memory
  //
  delete [] updatedPts;
  this->Locator->Initialize(); //release memory.

  output->SetPoints(newPts);
  newPts->Delete();
  if (newVerts)
    {
    output->SetVerts(newVerts);
    newVerts->Delete();
    }
  if (newLines)
    {
    output->SetLines(newLines);
    newLines->Delete();
    }
  if (newPolys)
    {
    output->SetPolys(newPolys);
    newPolys->Delete();
    }
  if (newStrips)
    {
    output->SetStrips(newStrips);
    newStrips->Delete();
    }
}

// Description:
// Specify a spatial locator for speeding the search process. By
// default an instance of vtkLocator is used.
void vtkCleanPolyData::SetLocator(vtkPointLocator *locator)
{
  if ( this->Locator != locator )
    {
    if ( this->SelfCreatedLocator ) this->Locator->Delete();
    this->SelfCreatedLocator = 0;
    this->Locator = locator;
    this->Modified();
    }
}

void vtkCleanPolyData::CreateDefaultLocator()
{
  if ( this->SelfCreatedLocator ) this->Locator->Delete();

  if ( this->Tolerance <= 0.0 )
    this->Locator = vtkMergePoints::New();
  else
    this->Locator = vtkPointLocator::New();

  this->SelfCreatedLocator = 1;
}

void vtkCleanPolyData::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkPolyDataToPolyDataFilter::PrintSelf(os,indent);

  os << indent << "Tolerance: " << this->Tolerance << "\n";
}

<commit_msg>ERR:Fixed bug when changing tolerance from 0.0<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkCleanPolyData.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1996 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkCleanPolyData.h"
#include "vtkMergePoints.h"

// Description:
// Construct object with initial tolerance of 0.0.
vtkCleanPolyData::vtkCleanPolyData()
{
  this->Tolerance = 0.0;
  this->Locator = NULL;
  this->SelfCreatedLocator = 0;
}

vtkCleanPolyData::~vtkCleanPolyData()
{
  if ( this->SelfCreatedLocator && this->Locator != NULL)
    this->Locator->Delete();
}

void vtkCleanPolyData::Execute()
{
  vtkPolyData *input=(vtkPolyData *)this->Input;
  vtkPointData *pd=input->GetPointData();
  int numPts=input->GetNumberOfPoints();
  vtkPoints *inPts;
  vtkFloatPoints *newPts;
  int numNewPts;
  int *updatedPts= new int[input->GetMaxCellSize()];
  int i, ptId;
  int npts, *pts;
  float *x;
  vtkCellArray *inVerts=input->GetVerts(), *newVerts=NULL;
  vtkCellArray *inLines=input->GetLines(), *newLines=NULL;
  vtkCellArray *inPolys=input->GetPolys(), *newPolys=NULL;
  vtkCellArray *inStrips=input->GetStrips(), *newStrips=NULL;
  vtkPolyData *output = this->GetOutput();
  vtkPointData *outputPD = output->GetPointData();

  vtkDebugMacro(<<"Cleaning data");

  if ( numPts < 1 || (inPts=input->GetPoints()) == NULL )
    {
    vtkErrorMacro(<<"No data to clean!");
    return;
    }

  outputPD->CopyAllocate(pd);
  this->CreateDefaultLocator();

  // Initialize; compute absolute tolerance from relative given
  this->Locator->SetTolerance(this->Tolerance*input->GetLength());
  newPts = vtkFloatPoints::New();
  newPts->Allocate(numPts);
  this->Locator->InitPointInsertion (newPts, this->Input->GetBounds());

  //
  // Begin to adjust topology.
  //
  // Vertices are renumbered and we remove duplicate vertices
  if ( inVerts->GetNumberOfCells() > 0 )
    {
    newVerts = vtkCellArray::New();
    newVerts->Allocate(inVerts->GetSize());

    for (inVerts->InitTraversal(); inVerts->GetNextCell(npts,pts); )
      {
      for ( numNewPts=0, i=0; i < npts; i++ )
        {
        x = inPts->GetPoint(pts[i]);

        if ( (ptId=this->Locator->IsInsertedPoint(x)) < 0 )
          {
          ptId = this->Locator->InsertNextPoint(x);
          updatedPts[numNewPts++] = ptId;
          outputPD->CopyData(pd,pts[i],ptId);
          }
        }
      if ( numNewPts > 0 ) newVerts->InsertNextCell(numNewPts,updatedPts);
      }
    newVerts->Squeeze();
    }

  // lines reduced to one point are eliminated
  if ( inLines->GetNumberOfCells() > 0 )
    {
    newLines = vtkCellArray::New();
    newLines->Allocate(inLines->GetSize());

    for (inLines->InitTraversal(); inLines->GetNextCell(npts,pts); )
      {
      for ( numNewPts=0, i=0; i < npts; i++ )
        {
        x = inPts->GetPoint(pts[i]);

        if ( (ptId=this->Locator->IsInsertedPoint(x)) < 0 )
          {
          ptId = this->Locator->InsertNextPoint(x);
          outputPD->CopyData(pd,pts[i],ptId);
          }

        if ( i == 0 || ptId != updatedPts[numNewPts-1] )
          {
          updatedPts[numNewPts++] = ptId;
          }
        }

      if ( numNewPts > 1 ) newLines->InsertNextCell(numNewPts,updatedPts);
      }
    newLines->Squeeze();
    vtkDebugMacro(<<"Removed " << inLines->GetNumberOfCells() -
                 newLines->GetNumberOfCells() << " lines");
    }

  // polygons reduced to two points or less are eliminated
  if ( inPolys->GetNumberOfCells() > 0 )
    {
    newPolys = vtkCellArray::New();
    newPolys->Allocate(inPolys->GetSize());
    for (inPolys->InitTraversal(); inPolys->GetNextCell(npts,pts); )
      {
      for ( numNewPts=0, i=0; i < npts; i++ )
        {
        x = inPts->GetPoint(pts[i]);

        if ( (ptId=this->Locator->IsInsertedPoint(x)) < 0 )
          {
          ptId = this->Locator->InsertNextPoint(x);
          outputPD->CopyData(pd,pts[i],ptId);
          }

        if ( i == 0 || ptId != updatedPts[numNewPts-1] )
          {
          updatedPts[numNewPts++] = ptId;
          }
        }
      if ( numNewPts > 2 ) newPolys->InsertNextCell(numNewPts,updatedPts);
      }

    newPolys->Squeeze();
    vtkDebugMacro(<<"Removed " << inPolys->GetNumberOfCells() -
                 newPolys->GetNumberOfCells() << " polys");
    }

  // triangle strips reduced to two points or less are eliminated
  if ( inStrips->GetNumberOfCells() > 0 )
    {
    newStrips = vtkCellArray::New();
    newStrips->Allocate(inStrips->GetSize());

    for (inStrips->InitTraversal(); inStrips->GetNextCell(npts,pts); )
      {
      for ( numNewPts=0, i=0; i < npts; i++ )
        {
        x = inPts->GetPoint(pts[i]);

        if ( (ptId=this->Locator->IsInsertedPoint(x)) < 0 )
          {
          ptId = this->Locator->InsertNextPoint(x);
          outputPD->CopyData(pd,pts[i],ptId);
          }

        if ( i == 0 || ptId != updatedPts[numNewPts-1] )
          {
          updatedPts[numNewPts++] = ptId;
          }
        }

      if ( numNewPts > 2 ) newStrips->InsertNextCell(numNewPts,updatedPts);
      }

    newStrips->Squeeze();
    vtkDebugMacro(<<"Removed " << inStrips->GetNumberOfCells() -
                 newStrips->GetNumberOfCells() << " strips");
    }

  //
  // Update ourselves and release memory
  //
  delete [] updatedPts;
  this->Locator->Initialize(); //release memory.

  output->SetPoints(newPts);
  newPts->Delete();
  if (newVerts)
    {
    output->SetVerts(newVerts);
    newVerts->Delete();
    }
  if (newLines)
    {
    output->SetLines(newLines);
    newLines->Delete();
    }
  if (newPolys)
    {
    output->SetPolys(newPolys);
    newPolys->Delete();
    }
  if (newStrips)
    {
    output->SetStrips(newStrips);
    newStrips->Delete();
    }
}

// Description:
// Specify a spatial locator for speeding the search process. By
// default an instance of vtkLocator is used.
void vtkCleanPolyData::SetLocator(vtkPointLocator *locator)
{
  if ( this->Locator != locator )
    {
    if ( this->SelfCreatedLocator ) this->Locator->Delete();
    this->SelfCreatedLocator = 0;
    this->Locator = locator;
    this->Modified();
    }
}

// Method manages creation of locators. It takes into account the potential
// change of tolerance (zero to non-zero).
void vtkCleanPolyData::CreateDefaultLocator()
{
  if ( this->SelfCreatedLocator || !this->Locator )
    {
    if ( this->Locator ) this->Locator->Delete();

    if ( this->Tolerance <= 0.0 )
      this->Locator = vtkMergePoints::New();
    else
      this->Locator = vtkPointLocator::New();

    this->SelfCreatedLocator = 1;
    }

  else
    {
    if ( !strcmp(this->Locator->GetClassName(),"vtkMergePoints") &&
    this->Tolerance > 0.0 )
      {
      vtkWarningMacro(<<"Trying to merge points with non-zero tolerance using vtkMergePoints");
      }
    }
}

void vtkCleanPolyData::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkPolyDataToPolyDataFilter::PrintSelf(os,indent);

  os << indent << "Tolerance: " << this->Tolerance << "\n";
}

<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkDataSetReader.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2000 Ken Martin, Will Schroeder, Bill Lorensen
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 name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

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 REGENTS 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 "vtkDataSetReader.h"
#include "vtkPolyDataReader.h"
#include "vtkStructuredPointsReader.h"
#include "vtkStructuredGridReader.h"
#include "vtkRectilinearGridReader.h"
#include "vtkUnstructuredGridReader.h"
#include "vtkObjectFactory.h"

//------------------------------------------------------------------------------
vtkDataSetReader* vtkDataSetReader::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkDataSetReader");
  if(ret)
    {
    return (vtkDataSetReader*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkDataSetReader;
}

vtkDataSetReader::vtkDataSetReader()
{
  this->Reader = vtkDataReader::New();
  this->Reader->SetSource(this);
}

vtkDataSetReader::~vtkDataSetReader()
{
  this->Reader->Delete();
  this->Reader = NULL;
}

vtkDataSet * vtkDataSetReader::GetOutput()
{
  // check to see if an execute is necessary.
  if (this->Outputs && this->Outputs[0] &&
      this->Outputs[0]->GetUpdateTime() > this->GetMTime())
    {
    return (vtkDataSet *)(this->Outputs[0]);
    }

  // The filename might have changed (changing the output).
  // We need to re execute.
  if (this->Reader->GetFileName() == NULL &&
      (this->Reader->GetReadFromInputString() == 0 ||
       this->Reader->GetInputString() == NULL))
    {
    vtkWarningMacro(<< "FileName must be set");
    return (vtkDataSet *) NULL;
    }

  this->Execute();
  if (this->Outputs == NULL)
    {
    return NULL;
    }
  else
    {
    return (vtkDataSet *)this->Outputs[0];
    }
}

unsigned long int vtkDataSetReader::GetMTime()
{
  unsigned long int t1, t2;

  t1 = this->vtkSource::GetMTime();
  t2 = this->Reader->GetMTime();
  if (t2 > t1)
    {
    t1 = t2;
    }
  return t1;
}

// Specify file name of vtk data file to read.
void vtkDataSetReader::SetFileName(const char *name)
{
  this->Reader->SetFileName(name);
}

char *vtkDataSetReader::GetFileName()
{
  return this->Reader->GetFileName();
}

// Get the type of file (VTK_ASCII or VTK_BINARY).
int vtkDataSetReader::GetFileType()
{
  return this->Reader->GetFileType();
}

// Set the name of the scalar data to extract. If not specified, first
// scalar data encountered is extracted.
void vtkDataSetReader::SetScalarsName(char *name)
{
  this->Reader->SetScalarsName(name);
}
char *vtkDataSetReader::GetScalarsName()
{
  return this->Reader->GetScalarsName();
}

// Set the name of the vector data to extract. If not specified, first
// vector data encountered is extracted.
void vtkDataSetReader::SetVectorsName(char *name)
{
  this->Reader->SetVectorsName(name);
}
char *vtkDataSetReader::GetVectorsName()
{
  return this->Reader->GetVectorsName();
}

// Set the name of the tensor data to extract. If not specified, first
// tensor data encountered is extracted.
void vtkDataSetReader::SetTensorsName(char *name)
{
  this->Reader->SetTensorsName(name);
}
char *vtkDataSetReader::GetTensorsName()
{
  return this->Reader->GetTensorsName();
}

// Set the name of the normal data to extract. If not specified, first
// normal data encountered is extracted.
void vtkDataSetReader::SetNormalsName(char *name)
{
  this->Reader->SetNormalsName(name);
}
char *vtkDataSetReader::GetNormalsName()
{
  return this->Reader->GetNormalsName();
}

// Set the name of the texture coordinate data to extract. If not specified,
// first texture coordinate data encountered is extracted.
void vtkDataSetReader::SetTCoordsName(char *name)
{
  this->Reader->SetTCoordsName(name);
}
char *vtkDataSetReader::GetTCoordsName()
{
  return this->Reader->GetTCoordsName();
}

// Set the name of the lookup table data to extract. If not specified, uses
// lookup table named by scalar. Otherwise, this specification supersedes.
void vtkDataSetReader::SetLookupTableName(char *name)
{
  this->Reader->SetLookupTableName(name);
}
char *vtkDataSetReader::GetLookupTableName()
{
  return this->Reader->GetLookupTableName();
}

// Set the name of the field data to extract. If not specified, uses
// first field data encountered in file.
void vtkDataSetReader::SetFieldDataName(char *name)
{
  this->Reader->SetFieldDataName(name);
}
char *vtkDataSetReader::GetFieldDataName()
{
  return this->Reader->GetFieldDataName();
}

void vtkDataSetReader::Execute()
{
  char line[256];
  vtkDataObject *output;

  vtkDebugMacro(<<"Reading vtk dataset...");

  if ( this->Debug )
    {
    this->Reader->DebugOn();
    }
  else
    {
    this->Reader->DebugOff();
    }
  if (!this->Reader->OpenVTKFile() || !this->Reader->ReadHeader())
    {
    return;
    }

  // Determine dataset type
  //
  if (!this->Reader->ReadString(line))
    {
    vtkErrorMacro(<< "Premature EOF reading dataset keyword");
    return;
    }

  if ( !strncmp(this->Reader->LowerCase(line),"dataset",(unsigned long)7) )
    {

    // See if type is recognized.
    //
    if (!this->Reader->ReadString(line))
      {
      vtkErrorMacro(<< "Premature EOF reading type");
      this->Reader->CloseVTKFile ();
      return;
      }

    this->Reader->CloseVTKFile();
    if ( ! strncmp(this->Reader->LowerCase(line),"polydata",8) )
      {
      vtkPolyDataReader *preader = vtkPolyDataReader::New();
      // Can we use the old output?
      output = this->Outputs ? this->Outputs[0] : NULL;
      if (output && strcmp(output->GetClassName(), "vtkPolyData") == 0)
	{
	preader->SetOutput((vtkPolyData *)(output));
	}
      preader->SetFileName(this->Reader->GetFileName());
      preader->SetInputString(this->Reader->GetInputString(),
			      this->Reader->GetInputStringLength());
      preader->SetReadFromInputString(this->Reader->GetReadFromInputString());
      preader->SetScalarsName(this->Reader->GetScalarsName());
      preader->SetVectorsName(this->Reader->GetVectorsName());
      preader->SetNormalsName(this->Reader->GetNormalsName());
      preader->SetTensorsName(this->Reader->GetTensorsName());
      preader->SetTCoordsName(this->Reader->GetTCoordsName());
      preader->SetLookupTableName(this->Reader->GetLookupTableName());
      preader->SetFieldDataName(this->Reader->GetFieldDataName());
      preader->Update();
      // whether we used the old output or not, we need to set the output.
      this->SetNthOutput(0, preader->GetOutput());
      preader->Delete();
      }

    else if ( ! strncmp(line,"structured_points",17) )
      {
      vtkStructuredPointsReader *preader = vtkStructuredPointsReader::New();
      // Can we use the old output?
      output = this->Outputs ? this->Outputs[0] : NULL;
      if (output && strcmp(output->GetClassName(), "vtkStructuredPoints") == 0)
	{
	preader->SetOutput((vtkStructuredPoints *)(output));
	}
      preader->SetFileName(this->Reader->GetFileName());
      preader->SetInputString(this->Reader->GetInputString(),
			      this->Reader->GetInputStringLength());
      preader->SetReadFromInputString(this->Reader->GetReadFromInputString());
      preader->SetScalarsName(this->Reader->GetScalarsName());
      preader->SetVectorsName(this->Reader->GetVectorsName());
      preader->SetNormalsName(this->Reader->GetNormalsName());
      preader->SetTensorsName(this->Reader->GetTensorsName());
      preader->SetTCoordsName(this->Reader->GetTCoordsName());
      preader->SetLookupTableName(this->Reader->GetLookupTableName());
      preader->SetFieldDataName(this->Reader->GetFieldDataName());
      preader->Update();
      // whether we used the old output or not, we need to set the output.
      this->SetNthOutput(0, preader->GetOutput());
      preader->Delete();
      }

    else if ( ! strncmp(line,"structured_grid",15) )
      {
      vtkStructuredGridReader *preader = vtkStructuredGridReader::New();
      // Can we use the old output?
      output = this->Outputs ? this->Outputs[0] : NULL;
      if (output && strcmp(output->GetClassName(), "vtkStructuredGrid") == 0)
	{
	preader->SetOutput((vtkStructuredGrid *)(output));
	}
      preader->SetFileName(this->Reader->GetFileName());
      preader->SetInputString(this->Reader->GetInputString(),
			      this->Reader->GetInputStringLength());
      preader->SetReadFromInputString(this->Reader->GetReadFromInputString());
      preader->SetScalarsName(this->Reader->GetScalarsName());
      preader->SetVectorsName(this->Reader->GetVectorsName());
      preader->SetNormalsName(this->Reader->GetNormalsName());
      preader->SetTensorsName(this->Reader->GetTensorsName());
      preader->SetTCoordsName(this->Reader->GetTCoordsName());
      preader->SetLookupTableName(this->Reader->GetLookupTableName());
      preader->SetFieldDataName(this->Reader->GetFieldDataName());
      preader->Update();
      // whether we used the old output or not, we need to set the output.
      this->SetNthOutput(0, preader->GetOutput());
      preader->Delete();
      }

    else if ( ! strncmp(line,"rectilinear_grid",16) )
      {
      vtkRectilinearGridReader *preader = vtkRectilinearGridReader::New();
      // Can we use the old output?
      output = this->Outputs ? this->Outputs[0] : NULL;
      if (output && strcmp(output->GetClassName(), "vtkRectilinearGrid") == 0)
	{
	preader->SetOutput((vtkRectilinearGrid *)(output));
	}
      preader->SetFileName(this->Reader->GetFileName());
      preader->SetInputString(this->Reader->GetInputString());
      preader->SetInputString(this->Reader->GetInputString(),
			      this->Reader->GetInputStringLength());
      preader->SetScalarsName(this->Reader->GetScalarsName());
      preader->SetVectorsName(this->Reader->GetVectorsName());
      preader->SetNormalsName(this->Reader->GetNormalsName());
      preader->SetTensorsName(this->Reader->GetTensorsName());
      preader->SetTCoordsName(this->Reader->GetTCoordsName());
      preader->SetLookupTableName(this->Reader->GetLookupTableName());
      preader->SetFieldDataName(this->Reader->GetFieldDataName());
      preader->Update();
      // whether we used the old output or not, we need to set the output.
      this->SetNthOutput(0, preader->GetOutput());
      preader->Delete();
      }

    else if ( ! strncmp(line,"unstructured_grid",17) )
      {
      vtkUnstructuredGridReader *preader = vtkUnstructuredGridReader::New();
      // Can we use the old output?
      output = this->Outputs ? this->Outputs[0] : NULL;
      if (output && strcmp(output->GetClassName(), "vtkUnstructuredGrid") == 0)
	{
	preader->SetOutput((vtkUnstructuredGrid *)(output));
	}
      preader->SetFileName(this->Reader->GetFileName());
      preader->SetInputString(this->Reader->GetInputString());
      preader->SetInputString(this->Reader->GetInputString(),
			      this->Reader->GetInputStringLength());
      preader->SetScalarsName(this->Reader->GetScalarsName());
      preader->SetVectorsName(this->Reader->GetVectorsName());
      preader->SetNormalsName(this->Reader->GetNormalsName());
      preader->SetTensorsName(this->Reader->GetTensorsName());
      preader->SetTCoordsName(this->Reader->GetTCoordsName());
      preader->SetLookupTableName(this->Reader->GetLookupTableName());
      preader->SetFieldDataName(this->Reader->GetFieldDataName());
      preader->Update();
      // whether we used the old output or not, we need to set the output.
      this->SetNthOutput(0, preader->GetOutput());
      preader->Delete();
      }

    else
      {
      vtkErrorMacro(<< "Cannot read dataset type: " << line);
      return;
      }
    }

  else if ( !strncmp(this->Reader->LowerCase(line),"field",(unsigned long)5) )
    {
    vtkErrorMacro(<<"This object can only read datasets, not fields");
    }

  else
    {
    vtkErrorMacro(<<"Expecting DATASET keyword, got " << line << " instead");
    }

  return;
}

vtkPolyData *vtkDataSetReader::GetPolyDataOutput()
{
  return vtkPolyData::SafeDownCast(this->GetOutput());
}

vtkStructuredPoints *vtkDataSetReader::GetStructuredPointsOutput()
{
  return vtkStructuredPoints::SafeDownCast(this->GetOutput());
}

vtkStructuredGrid *vtkDataSetReader::GetStructuredGridOutput()
{
  return vtkStructuredGrid::SafeDownCast(this->GetOutput());
}

vtkUnstructuredGrid *vtkDataSetReader::GetUnstructuredGridOutput()
{
  return vtkUnstructuredGrid::SafeDownCast(this->GetOutput());
}

vtkRectilinearGrid *vtkDataSetReader::GetRectilinearGridOutput()
{
  return vtkRectilinearGrid::SafeDownCast(this->GetOutput());
}

//----------------------------------------------------------------------------
void vtkDataSetReader::Update()
{
  if (this->GetOutput())
    {
    this->GetOutput()->Update();
    }
}

static int recursing = 0;
void vtkDataSetReader::PrintSelf(ostream& os, vtkIndent indent)
{
  // the reader ivar's source will be this reader. we must do this to prevent infinite printing
  if (!recursing)
    {
    vtkSource::PrintSelf(os,indent);
    recursing = 1;
    os << indent << "Reader:\n";
    this->Reader->PrintSelf(os,indent.GetNextIndent());
    }
    recursing = 0;
}
<commit_msg>Flag indicating that the reader should read from a string was not being passed on to rectilinear or unstructured readers.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDataSetReader.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2000 Ken Martin, Will Schroeder, Bill Lorensen
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 name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

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 REGENTS 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 "vtkDataSetReader.h"
#include "vtkPolyDataReader.h"
#include "vtkStructuredPointsReader.h"
#include "vtkStructuredGridReader.h"
#include "vtkRectilinearGridReader.h"
#include "vtkUnstructuredGridReader.h"
#include "vtkObjectFactory.h"

//------------------------------------------------------------------------------
vtkDataSetReader* vtkDataSetReader::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkDataSetReader");
  if(ret)
    {
    return (vtkDataSetReader*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkDataSetReader;
}

vtkDataSetReader::vtkDataSetReader()
{
  this->Reader = vtkDataReader::New();
  this->Reader->SetSource(this);
}

vtkDataSetReader::~vtkDataSetReader()
{
  this->Reader->Delete();
  this->Reader = NULL;
}

vtkDataSet * vtkDataSetReader::GetOutput()
{
  // check to see if an execute is necessary.
  if (this->Outputs && this->Outputs[0] &&
      this->Outputs[0]->GetUpdateTime() > this->GetMTime())
    {
    return (vtkDataSet *)(this->Outputs[0]);
    }

  // The filename might have changed (changing the output).
  // We need to re execute.
  if (this->Reader->GetFileName() == NULL &&
      (this->Reader->GetReadFromInputString() == 0 ||
       this->Reader->GetInputString() == NULL))
    {
    vtkWarningMacro(<< "FileName must be set");
    return (vtkDataSet *) NULL;
    }

  this->Execute();
  if (this->Outputs == NULL)
    {
    return NULL;
    }
  else
    {
    return (vtkDataSet *)this->Outputs[0];
    }
}

unsigned long int vtkDataSetReader::GetMTime()
{
  unsigned long int t1, t2;

  t1 = this->vtkSource::GetMTime();
  t2 = this->Reader->GetMTime();
  if (t2 > t1)
    {
    t1 = t2;
    }
  return t1;
}

// Specify file name of vtk data file to read.
void vtkDataSetReader::SetFileName(const char *name)
{
  this->Reader->SetFileName(name);
}

char *vtkDataSetReader::GetFileName()
{
  return this->Reader->GetFileName();
}

// Get the type of file (VTK_ASCII or VTK_BINARY).
int vtkDataSetReader::GetFileType()
{
  return this->Reader->GetFileType();
}

// Set the name of the scalar data to extract. If not specified, first
// scalar data encountered is extracted.
void vtkDataSetReader::SetScalarsName(char *name)
{
  this->Reader->SetScalarsName(name);
}
char *vtkDataSetReader::GetScalarsName()
{
  return this->Reader->GetScalarsName();
}

// Set the name of the vector data to extract. If not specified, first
// vector data encountered is extracted.
void vtkDataSetReader::SetVectorsName(char *name)
{
  this->Reader->SetVectorsName(name);
}
char *vtkDataSetReader::GetVectorsName()
{
  return this->Reader->GetVectorsName();
}

// Set the name of the tensor data to extract. If not specified, first
// tensor data encountered is extracted.
void vtkDataSetReader::SetTensorsName(char *name)
{
  this->Reader->SetTensorsName(name);
}
char *vtkDataSetReader::GetTensorsName()
{
  return this->Reader->GetTensorsName();
}

// Set the name of the normal data to extract. If not specified, first
// normal data encountered is extracted.
void vtkDataSetReader::SetNormalsName(char *name)
{
  this->Reader->SetNormalsName(name);
}
char *vtkDataSetReader::GetNormalsName()
{
  return this->Reader->GetNormalsName();
}

// Set the name of the texture coordinate data to extract. If not specified,
// first texture coordinate data encountered is extracted.
void vtkDataSetReader::SetTCoordsName(char *name)
{
  this->Reader->SetTCoordsName(name);
}
char *vtkDataSetReader::GetTCoordsName()
{
  return this->Reader->GetTCoordsName();
}

// Set the name of the lookup table data to extract. If not specified, uses
// lookup table named by scalar. Otherwise, this specification supersedes.
void vtkDataSetReader::SetLookupTableName(char *name)
{
  this->Reader->SetLookupTableName(name);
}
char *vtkDataSetReader::GetLookupTableName()
{
  return this->Reader->GetLookupTableName();
}

// Set the name of the field data to extract. If not specified, uses
// first field data encountered in file.
void vtkDataSetReader::SetFieldDataName(char *name)
{
  this->Reader->SetFieldDataName(name);
}
char *vtkDataSetReader::GetFieldDataName()
{
  return this->Reader->GetFieldDataName();
}

void vtkDataSetReader::Execute()
{
  char line[256];
  vtkDataObject *output;

  vtkDebugMacro(<<"Reading vtk dataset...");

  if ( this->Debug )
    {
    this->Reader->DebugOn();
    }
  else
    {
    this->Reader->DebugOff();
    }
  if (!this->Reader->OpenVTKFile() || !this->Reader->ReadHeader())
    {
    return;
    }

  // Determine dataset type
  //
  if (!this->Reader->ReadString(line))
    {
    vtkErrorMacro(<< "Premature EOF reading dataset keyword");
    return;
    }

  if ( !strncmp(this->Reader->LowerCase(line),"dataset",(unsigned long)7) )
    {

    // See if type is recognized.
    //
    if (!this->Reader->ReadString(line))
      {
      vtkErrorMacro(<< "Premature EOF reading type");
      this->Reader->CloseVTKFile ();
      return;
      }

    this->Reader->CloseVTKFile();
    if ( ! strncmp(this->Reader->LowerCase(line),"polydata",8) )
      {
      vtkPolyDataReader *preader = vtkPolyDataReader::New();
      // Can we use the old output?
      output = this->Outputs ? this->Outputs[0] : NULL;
      if (output && strcmp(output->GetClassName(), "vtkPolyData") == 0)
	{
	preader->SetOutput((vtkPolyData *)(output));
	}
      preader->SetFileName(this->Reader->GetFileName());
      preader->SetInputString(this->Reader->GetInputString(),
			      this->Reader->GetInputStringLength());
      preader->SetReadFromInputString(this->Reader->GetReadFromInputString());
      preader->SetScalarsName(this->Reader->GetScalarsName());
      preader->SetVectorsName(this->Reader->GetVectorsName());
      preader->SetNormalsName(this->Reader->GetNormalsName());
      preader->SetTensorsName(this->Reader->GetTensorsName());
      preader->SetTCoordsName(this->Reader->GetTCoordsName());
      preader->SetLookupTableName(this->Reader->GetLookupTableName());
      preader->SetFieldDataName(this->Reader->GetFieldDataName());
      preader->Update();
      // whether we used the old output or not, we need to set the output.
      this->SetNthOutput(0, preader->GetOutput());
      preader->Delete();
      }

    else if ( ! strncmp(line,"structured_points",17) )
      {
      vtkStructuredPointsReader *preader = vtkStructuredPointsReader::New();
      // Can we use the old output?
      output = this->Outputs ? this->Outputs[0] : NULL;
      if (output && strcmp(output->GetClassName(), "vtkStructuredPoints") == 0)
	{
	preader->SetOutput((vtkStructuredPoints *)(output));
	}
      preader->SetFileName(this->Reader->GetFileName());
      preader->SetInputString(this->Reader->GetInputString(),
			      this->Reader->GetInputStringLength());
      preader->SetReadFromInputString(this->Reader->GetReadFromInputString());
      preader->SetScalarsName(this->Reader->GetScalarsName());
      preader->SetVectorsName(this->Reader->GetVectorsName());
      preader->SetNormalsName(this->Reader->GetNormalsName());
      preader->SetTensorsName(this->Reader->GetTensorsName());
      preader->SetTCoordsName(this->Reader->GetTCoordsName());
      preader->SetLookupTableName(this->Reader->GetLookupTableName());
      preader->SetFieldDataName(this->Reader->GetFieldDataName());
      preader->Update();
      // whether we used the old output or not, we need to set the output.
      this->SetNthOutput(0, preader->GetOutput());
      preader->Delete();
      }

    else if ( ! strncmp(line,"structured_grid",15) )
      {
      vtkStructuredGridReader *preader = vtkStructuredGridReader::New();
      // Can we use the old output?
      output = this->Outputs ? this->Outputs[0] : NULL;
      if (output && strcmp(output->GetClassName(), "vtkStructuredGrid") == 0)
	{
	preader->SetOutput((vtkStructuredGrid *)(output));
	}
      preader->SetFileName(this->Reader->GetFileName());
      preader->SetInputString(this->Reader->GetInputString(),
			      this->Reader->GetInputStringLength());
      preader->SetReadFromInputString(this->Reader->GetReadFromInputString());
      preader->SetScalarsName(this->Reader->GetScalarsName());
      preader->SetVectorsName(this->Reader->GetVectorsName());
      preader->SetNormalsName(this->Reader->GetNormalsName());
      preader->SetTensorsName(this->Reader->GetTensorsName());
      preader->SetTCoordsName(this->Reader->GetTCoordsName());
      preader->SetLookupTableName(this->Reader->GetLookupTableName());
      preader->SetFieldDataName(this->Reader->GetFieldDataName());
      preader->Update();
      // whether we used the old output or not, we need to set the output.
      this->SetNthOutput(0, preader->GetOutput());
      preader->Delete();
      }

    else if ( ! strncmp(line,"rectilinear_grid",16) )
      {
      vtkRectilinearGridReader *preader = vtkRectilinearGridReader::New();
      // Can we use the old output?
      output = this->Outputs ? this->Outputs[0] : NULL;
      if (output && strcmp(output->GetClassName(), "vtkRectilinearGrid") == 0)
	{
	preader->SetOutput((vtkRectilinearGrid *)(output));
	}
      preader->SetFileName(this->Reader->GetFileName());
      preader->SetInputString(this->Reader->GetInputString(),
			      this->Reader->GetInputStringLength());
      preader->SetReadFromInputString(this->Reader->GetReadFromInputString());
      preader->SetScalarsName(this->Reader->GetScalarsName());
      preader->SetVectorsName(this->Reader->GetVectorsName());
      preader->SetNormalsName(this->Reader->GetNormalsName());
      preader->SetTensorsName(this->Reader->GetTensorsName());
      preader->SetTCoordsName(this->Reader->GetTCoordsName());
      preader->SetLookupTableName(this->Reader->GetLookupTableName());
      preader->SetFieldDataName(this->Reader->GetFieldDataName());
      preader->Update();
      // whether we used the old output or not, we need to set the output.
      this->SetNthOutput(0, preader->GetOutput());
      preader->Delete();
      }

    else if ( ! strncmp(line,"unstructured_grid",17) )
      {
      vtkUnstructuredGridReader *preader = vtkUnstructuredGridReader::New();
      // Can we use the old output?
      output = this->Outputs ? this->Outputs[0] : NULL;
      if (output && strcmp(output->GetClassName(), "vtkUnstructuredGrid") == 0)
	{
	preader->SetOutput((vtkUnstructuredGrid *)(output));
	}
      preader->SetFileName(this->Reader->GetFileName());
      preader->SetInputString(this->Reader->GetInputString(),
			      this->Reader->GetInputStringLength());
      preader->SetReadFromInputString(this->Reader->GetReadFromInputString());
      preader->SetScalarsName(this->Reader->GetScalarsName());
      preader->SetVectorsName(this->Reader->GetVectorsName());
      preader->SetNormalsName(this->Reader->GetNormalsName());
      preader->SetTensorsName(this->Reader->GetTensorsName());
      preader->SetTCoordsName(this->Reader->GetTCoordsName());
      preader->SetLookupTableName(this->Reader->GetLookupTableName());
      preader->SetFieldDataName(this->Reader->GetFieldDataName());
      preader->Update();
      // whether we used the old output or not, we need to set the output.
      this->SetNthOutput(0, preader->GetOutput());
      preader->Delete();
      }

    else
      {
      vtkErrorMacro(<< "Cannot read dataset type: " << line);
      return;
      }
    }

  else if ( !strncmp(this->Reader->LowerCase(line),"field",(unsigned long)5) )
    {
    vtkErrorMacro(<<"This object can only read datasets, not fields");
    }

  else
    {
    vtkErrorMacro(<<"Expecting DATASET keyword, got " << line << " instead");
    }

  return;
}

vtkPolyData *vtkDataSetReader::GetPolyDataOutput()
{
  return vtkPolyData::SafeDownCast(this->GetOutput());
}

vtkStructuredPoints *vtkDataSetReader::GetStructuredPointsOutput()
{
  return vtkStructuredPoints::SafeDownCast(this->GetOutput());
}

vtkStructuredGrid *vtkDataSetReader::GetStructuredGridOutput()
{
  return vtkStructuredGrid::SafeDownCast(this->GetOutput());
}

vtkUnstructuredGrid *vtkDataSetReader::GetUnstructuredGridOutput()
{
  return vtkUnstructuredGrid::SafeDownCast(this->GetOutput());
}

vtkRectilinearGrid *vtkDataSetReader::GetRectilinearGridOutput()
{
  return vtkRectilinearGrid::SafeDownCast(this->GetOutput());
}

//----------------------------------------------------------------------------
void vtkDataSetReader::Update()
{
  if (this->GetOutput())
    {
    this->GetOutput()->Update();
    }
}

static int recursing = 0;
void vtkDataSetReader::PrintSelf(ostream& os, vtkIndent indent)
{
  // the reader ivar's source will be this reader. we must do this to prevent infinite printing
  if (!recursing)
    {
    vtkSource::PrintSelf(os,indent);
    recursing = 1;
    os << indent << "Reader:\n";
    this->Reader->PrintSelf(os,indent.GetNextIndent());
    }
    recursing = 0;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice 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 <cwchar>
#ifdef _MSC_VER
#pragma warning(push, 1) /* disable warnings within system headers */
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <msiquery.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "com/sun/star/uno/Any.hxx"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
#include "com/sun/star/uno/XInterface.hpp"
#include "rtl/ustring.hxx"
#include "osl/file.h"
#include "osl/file.hxx"
#include "winreg.hxx"
#include "writemodfile.hxx"

#define MAX_KEY_LENGTH 255

namespace configmgr {

namespace {
// This is not a generic registry reader. We assume the following structure:
// Last element of Key becomes prop, first part is the path.
// Values can be the following: Value (string) and Final (dword, optional)
// For example the following registry setting:
// [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\LibreOffice\org.openoffice.UserProfile\Data\o]
// "Value"="Example Corp."
// "Final"=dword:00000001
// becomes the following in configuration:
// <item oor:path="/org.openoffice.UserProfile/Data">
//     <prop oor:name="o" oor:finalized="true">
//         <value>Example Corp.</value>
//     </prop>
// </item>
void dumpWindowsRegistryKey(HKEY hKey, OUString aKeyName, oslFileHandle aFileHandle)
{
    HKEY hCurKey;

    if(RegOpenKeyExW(hKey, aKeyName.getStr(), 0, KEY_READ, &hCurKey) == ERROR_SUCCESS)
    {
        DWORD nSubKeys = 0;
        DWORD nValues = 0;
        DWORD nLongestValueNameLen, nLongestValueLen;
        // Query the number of subkeys
        RegQueryInfoKeyW(hCurKey, NULL, NULL, NULL, &nSubKeys, NULL, NULL, &nValues, &nLongestValueNameLen, &nLongestValueLen, NULL, NULL);
        if(nSubKeys)
        {
            //Look for subkeys in this key
            for(DWORD i = 0; i < nSubKeys; i++)
            {
                wchar_t buffKeyName[MAX_KEY_LENGTH];
                buffKeyName[0] = '\0';
                DWORD buffSize=MAX_KEY_LENGTH;
                OUString aSubkeyName;
                //Get subkey name
                RegEnumKeyExW(hCurKey, i, buffKeyName, &buffSize, NULL, NULL, NULL, NULL);

                //Make up full key name
                if(aKeyName.isEmpty())
                    aSubkeyName = aKeyName + OUString(buffKeyName);
                else
                    aSubkeyName = aKeyName + "\\" + OUString(buffKeyName);

                //Recursion, until no more subkeys are found
                dumpWindowsRegistryKey(hKey, aSubkeyName, aFileHandle);
            }
        }
        else if(nValues)
        {
            // No more subkeys, we are at a leaf
            wchar_t* pValueName = new wchar_t[nLongestValueNameLen + 1];
            wchar_t* pValue = new wchar_t[nLongestValueLen + 1];

            if(pValueName && pValue)
            {
                bool bFinal = false;
                OUString aValue;

                for(DWORD i = 0; i < nValues; ++i)
                {
                    DWORD nValueNameLen = nLongestValueNameLen + 1;
                    DWORD nValueLen = nLongestValueLen + 1;

                    RegEnumValueW(hCurKey, i, pValueName, &nValueNameLen, NULL, NULL, (LPBYTE)pValue, &nValueLen);
                    const wchar_t wsValue[] = L"Value";
                    const wchar_t wsFinal[] = L"Final";

                    if(!wcscmp(pValueName, wsValue))
                        aValue = OUString(pValue);
                    if(!wcscmp(pValueName, wsFinal) && *(DWORD*)pValue == 1)
                        bFinal = true;
                }
                sal_Int32 aLastSeparator = aKeyName.lastIndexOf('\\');
                OUString aPath = aKeyName.replaceAll("\\","/").copy(0, aLastSeparator);
                OUString aProp = aKeyName.copy(aLastSeparator + 1);

                writeData(aFileHandle, "<item oor:path=\"/");
                writeAttributeValue(aFileHandle, aPath);
                writeData(aFileHandle, "\"><prop oor:name=\"");
                writeAttributeValue(aFileHandle, aProp);
                writeData(aFileHandle, "\"");
                if(bFinal)
                    writeData(aFileHandle, " oor:finalized=\"true\"");
                writeData(aFileHandle, "><value>");
                writeValueContent(aFileHandle, aValue);
                writeData(aFileHandle, "</value></prop></item>\n");
                delete[] pValueName;
                delete[] pValue;
            }
        }
        RegCloseKey(hCurKey);
    }
}
}

bool dumpWindowsRegistry(OUString* pFileURL)
{
    HKEY hKey;
    if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Policies\\LibreOffice", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
    {
        SAL_INFO(
            "configmgr",
            ("Windows registry settings do not exist in HKLM\\SOFTWARE\\Policies\\LibreOffice"));
        return false;
    }

    oslFileHandle aFileHandle;
    switch (osl::FileBase::createTempFile(0, &aFileHandle, pFileURL)) {
    case osl::FileBase::E_None:
        break;
    case osl::FileBase::E_ACCES:
        SAL_INFO(
            "configmgr",
            ("cannot create temp Windows registry dump (E_ACCES)"));
        return false;
    default:
        throw css::uno::RuntimeException(
            "cannot create temporary file",
            css::uno::Reference< css::uno::XInterface >());
    }
    writeData(
        aFileHandle,
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<oor:items"
            " xmlns:oor=\"http://openoffice.org/2001/registry\""
            " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
            " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n");
    dumpWindowsRegistryKey(hKey, "", aFileHandle);
    writeData(aFileHandle, "</oor:items>");
    oslFileError e = osl_closeFile(aFileHandle);
    if (e != osl_File_E_None)
        SAL_WARN("configmgr", "osl_closeFile failed with " << +e);
    RegCloseKey(hKey);
    return true;
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>winreg backend: add support for oor:op in config nodes<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice 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 <cwchar>
#ifdef _MSC_VER
#pragma warning(push, 1) /* disable warnings within system headers */
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <msiquery.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "com/sun/star/uno/Any.hxx"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
#include "com/sun/star/uno/XInterface.hpp"
#include "rtl/ustring.hxx"
#include "osl/file.h"
#include "osl/file.hxx"
#include "winreg.hxx"
#include "writemodfile.hxx"

#define MAX_KEY_LENGTH 255

namespace configmgr {

namespace {
// This is not a generic registry reader. We assume the following structure:
// Last element of Key becomes prop, first part is the path and optionally nodes,
// when the node has oor:op attribute.
// Values can be the following: Value (string) and Final (dword, optional)
//
// For example the following registry setting:
// [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\LibreOffice\org.openoffice.UserProfile\Data\o]
// "Value"="Example Corp."
// "Final"=dword:00000001
// becomes the following in configuration:
// <!-- set the Company name -->
// <item oor:path="/org.openoffice.UserProfile/Data">
//     <prop oor:name="o" oor:finalized="true">
//         <value>Example Corp.</value>
//     </prop>
// </item>
//
// Another example:
// [HKEY_LOCAL_MACHINE\Policies\LibreOffice\org.openoffice.Office.OptionsDialog\OptionsDialogGroups\ProductName/#fuse\Pages\AboutConfig/#fuse\Hide]
// "Value"="true"
// becomes the following in configuration:
// <!-- Hide Tools - Options - LibreOffice - Expert Config panel -->
// <item oor:path="/org.openoffice.Office.OptionsDialog/OptionsDialogGroups">
//     <node oor:name="ProductName" oor:op="fuse">
//         <node oor:name="Pages">
//             <node oor:name="AboutConfig" oor:op="fuse">
//                 <prop oor:name="Hide">
//                     <value>true</value>
//                 </prop>
//             </node>
//         </node>
//     </node>
// </item>

void dumpWindowsRegistryKey(HKEY hKey, OUString aKeyName, oslFileHandle aFileHandle)
{
    HKEY hCurKey;

    if(RegOpenKeyExW(hKey, aKeyName.getStr(), 0, KEY_READ, &hCurKey) == ERROR_SUCCESS)
    {
        DWORD nSubKeys = 0;
        DWORD nValues = 0;
        DWORD nLongestValueNameLen, nLongestValueLen;
        // Query the number of subkeys
        RegQueryInfoKeyW(hCurKey, NULL, NULL, NULL, &nSubKeys, NULL, NULL, &nValues, &nLongestValueNameLen, &nLongestValueLen, NULL, NULL);
        if(nSubKeys)
        {
            //Look for subkeys in this key
            for(DWORD i = 0; i < nSubKeys; i++)
            {
                wchar_t buffKeyName[MAX_KEY_LENGTH];
                buffKeyName[0] = '\0';
                DWORD buffSize=MAX_KEY_LENGTH;
                OUString aSubkeyName;
                //Get subkey name
                RegEnumKeyExW(hCurKey, i, buffKeyName, &buffSize, NULL, NULL, NULL, NULL);

                //Make up full key name
                if(aKeyName.isEmpty())
                    aSubkeyName = aKeyName + OUString(buffKeyName);
                else
                    aSubkeyName = aKeyName + "\\" + OUString(buffKeyName);

                //Recursion, until no more subkeys are found
                dumpWindowsRegistryKey(hKey, aSubkeyName, aFileHandle);
            }
        }
        else if(nValues)
        {
            // No more subkeys, we are at a leaf
            wchar_t* pValueName = new wchar_t[nLongestValueNameLen + 1];
            wchar_t* pValue = new wchar_t[nLongestValueLen + 1];

            if(pValueName && pValue)
            {
                bool bFinal = false;
                OUString aValue;

                for(DWORD i = 0; i < nValues; ++i)
                {
                    DWORD nValueNameLen = nLongestValueNameLen + 1;
                    DWORD nValueLen = nLongestValueLen + 1;

                    RegEnumValueW(hCurKey, i, pValueName, &nValueNameLen, NULL, NULL, (LPBYTE)pValue, &nValueLen);
                    const wchar_t wsValue[] = L"Value";
                    const wchar_t wsFinal[] = L"Final";

                    if(!wcscmp(pValueName, wsValue))
                        aValue = OUString(pValue);
                    if(!wcscmp(pValueName, wsFinal) && *(DWORD*)pValue == 1)
                        bFinal = true;
                }
                sal_Int32 aLastSeparator = aKeyName.lastIndexOf('\\');
                OUString aPathAndNodes = aKeyName.copy(0, aLastSeparator);
                OUString aProp = aKeyName.copy(aLastSeparator + 1);
                bool bHasNode = false;
                sal_Int32 nCloseNode = 0;

                writeData(aFileHandle, "<item oor:path=\"");
                for(sal_Int32 nIndex = 0;; ++nIndex)
                {
                    OUString aNextPathPart = aPathAndNodes.getToken(nIndex, '\\');

                    if(!aNextPathPart.isEmpty())
                    {
                        if((aNextPathPart.lastIndexOf("/#") != -1) || bHasNode)
                        {
                            bHasNode = true;
                            nCloseNode++;
                            writeData(aFileHandle, "\"><node oor:name=\"");
                            sal_Int32 nCommandSeparator = aNextPathPart.lastIndexOf('#');
                            if(nCommandSeparator != -1)
                            {
                                OUString aNodeOp = aNextPathPart.copy(nCommandSeparator + 1);
                                writeAttributeValue(aFileHandle, aNextPathPart.copy(0, nCommandSeparator - 1));
                                writeData(aFileHandle, "\" oor:op=\"");
                                writeAttributeValue(aFileHandle, aNodeOp);
                            }
                            else
                            {
                                writeAttributeValue(aFileHandle, aNextPathPart);
                            }
                        }
                        else
                        {
                            writeAttributeValue(aFileHandle, "/" + aNextPathPart);
                        }
                    }
                    else
                    {
                        writeData(aFileHandle, "\">");
                        break;
                    }
                }

                writeData(aFileHandle, "<prop oor:name=\"");
                writeAttributeValue(aFileHandle, aProp);
                writeData(aFileHandle, "\"");
                if(bFinal)
                    writeData(aFileHandle, " oor:finalized=\"true\"");
                writeData(aFileHandle, "><value>");
                writeValueContent(aFileHandle, aValue);
                writeData(aFileHandle, "</value></prop>");
                for(; nCloseNode > 0; nCloseNode--)
                    writeData(aFileHandle, "</node>");
                writeData(aFileHandle, "</item>\n");
                delete[] pValueName;
                delete[] pValue;
            }
        }
        RegCloseKey(hCurKey);
    }
}
}

bool dumpWindowsRegistry(OUString* pFileURL)
{
    HKEY hKey;
    if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Policies\\LibreOffice", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
    {
        SAL_INFO(
            "configmgr",
            ("Windows registry settings do not exist in HKLM\\SOFTWARE\\Policies\\LibreOffice"));
        return false;
    }

    oslFileHandle aFileHandle;
    switch (osl::FileBase::createTempFile(0, &aFileHandle, pFileURL)) {
    case osl::FileBase::E_None:
        break;
    case osl::FileBase::E_ACCES:
        SAL_INFO(
            "configmgr",
            ("cannot create temp Windows registry dump (E_ACCES)"));
        return false;
    default:
        throw css::uno::RuntimeException(
            "cannot create temporary file",
            css::uno::Reference< css::uno::XInterface >());
    }
    writeData(
        aFileHandle,
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<oor:items"
            " xmlns:oor=\"http://openoffice.org/2001/registry\""
            " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
            " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n");
    dumpWindowsRegistryKey(hKey, "", aFileHandle);
    writeData(aFileHandle, "</oor:items>");
    oslFileError e = osl_closeFile(aFileHandle);
    if (e != osl_File_E_None)
        SAL_WARN("configmgr", "osl_closeFile failed with " << +e);
    RegCloseKey(hKey);
    return true;
}

}

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


<commit_before>/******************************************************************************\
* File:          config.cpp
* Purpose:       Implementation of wxExtension config class
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/extension/config.h>
#include <wx/extension/frd.h>

using namespace std;

wxExConfig::wxExConfig(
  const wxString& filename,
  long style)
#ifdef wxExUSE_PORTABLE
  : wxFileConfig(
#else
  : wxConfig(
#endif
      wxEmptyString,
      wxEmptyString,
      filename,
      wxEmptyString,
      style)
{
  m_FindReplaceData = new wxExFindReplaceData(this);
}

wxExConfig::~wxExConfig()
{
  delete m_FindReplaceData;

  for (
    map<wxString, wxVariant>::const_iterator it = m_Values.begin();
    it != m_Values.end();
    ++it)
  {
    const wxVariant var = it->second;

    if (var.GetType() == "bool")
      Write(it->first, var.GetBool());
    else if (var.GetType() == "long")
      Write(it->first, var.GetLong());
    else if (var.GetType() == "string")
      Write(it->first, var.GetString());
    else wxFAIL;
  }
}

const wxString wxExConfig::GetKeys() const
{
  wxString text;

  for (
    map<wxString, wxVariant>::const_iterator it = m_Values.begin();
    it != m_Values.end();
    ++it)
  {
    text += it->first + "\t" + it->second.GetString() + "\n";
  }

  return text;
}

void wxExConfig::Toggle(const wxString& key)
{
  m_Values[key] = !m_Values[key].ReadBool();
}
<commit_msg>fixed compile errors<commit_after>/******************************************************************************\
* File:          config.cpp
* Purpose:       Implementation of wxExtension config class
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/extension/config.h>
#include <wx/extension/frd.h>

using namespace std;

wxExConfig::wxExConfig(
  const wxString& filename,
  long style)
#ifdef wxExUSE_PORTABLE
  : wxFileConfig(
#else
  : wxConfig(
#endif
      wxEmptyString,
      wxEmptyString,
      filename,
      wxEmptyString,
      style)
{
  m_FindReplaceData = new wxExFindReplaceData(this);
}

wxExConfig::~wxExConfig()
{
  delete m_FindReplaceData;

  for (
    map<wxString, wxVariant>::const_iterator it = m_Values.begin();
    it != m_Values.end();
    ++it)
  {
    const wxVariant var = it->second;

    if (var.GetType() == "bool")
      Write(it->first, var.GetBool());
    else if (var.GetType() == "long")
      Write(it->first, var.GetLong());
    else if (var.GetType() == "string")
      Write(it->first, var.GetString());
    else wxFAIL;
  }
}

const wxString wxExConfig::GetKeys() const
{
  wxString text;

  for (
    map<wxString, wxVariant>::const_iterator it = m_Values.begin();
    it != m_Values.end();
    ++it)
  {
    text += it->first + "\t" + it->second.GetString() + "\n";
  }

  return text;
}

void wxExConfig::Toggle(const wxString& key)
{
  m_Values[key] = !m_Values[key].GetBool();
}
<|endoftext|>