<commit_before>/* Copyright 2014 Google Inc. All Rights Reserved.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

   Example main() function for Brotli library.
*/

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include <string>

#include "../dec/decode.h"
#include "../enc/encode.h"
#include "../enc/streams.h"

static bool ParseQuality(const char* s, int* quality) {
  if (s[0] >= '0' && s[0] <= '9') {
    *quality = s[0] - '0';
    if (s[1] >= '0' && s[1] <= '9') {
      *quality = *quality * 10 + s[1] - '0';
      return s[2] == 0;
    }
    return s[1] == 0;
  }
  return false;
}

static void ParseArgv(int argc, char **argv,
                      char **input_path,
                      char **output_path,
                      int *force,
                      int *quality,
                      int *decompress,
                      int *repeat,
                      int *verbose,
                      int *lgwin) {
  *force = 0;
  *input_path = 0;
  *output_path = 0;
  *repeat = 1;
  *verbose = 0;
  *lgwin = 22;
  {
    size_t argv0_len = strlen(argv[0]);
    *decompress =
        argv0_len >= 5 && strcmp(&argv[0][argv0_len - 5], "unbro") == 0;
  }
  for (int k = 1; k < argc; ++k) {
    if (!strcmp("--force", argv[k]) ||
        !strcmp("-f", argv[k])) {
      if (*force != 0) {
        goto error;
      }
      *force = 1;
      continue;
    } else if (!strcmp("--decompress", argv[k]) ||
               !strcmp("--uncompress", argv[k]) ||
               !strcmp("-d", argv[k])) {
      *decompress = 1;
      continue;
    } else if (!strcmp("--verbose", argv[k]) ||
               !strcmp("-v", argv[k])) {
      if (*verbose != 0) {
        goto error;
      }
      *verbose = 1;
      continue;
    }
    if (k < argc - 1) {
      if (!strcmp("--input", argv[k]) ||
          !strcmp("--in", argv[k]) ||
          !strcmp("-i", argv[k])) {
        if (*input_path != 0) {
          goto error;
        }
        *input_path = argv[k + 1];
        ++k;
        continue;
      } else if (!strcmp("--output", argv[k]) ||
                 !strcmp("--out", argv[k]) ||
                 !strcmp("-o", argv[k])) {
        if (*output_path != 0) {
          goto error;
        }
        *output_path = argv[k + 1];
        ++k;
        continue;
      } else if (!strcmp("--quality", argv[k]) ||
                 !strcmp("-q", argv[k])) {
        if (!ParseQuality(argv[k + 1], quality)) {
          goto error;
        }
        ++k;
        continue;
      } else if (!strcmp("--repeat", argv[k]) ||
                 !strcmp("-r", argv[k])) {
        if (!ParseQuality(argv[k + 1], repeat)) {
          goto error;
        }
        ++k;
        continue;
      }  else if (!strcmp("--window", argv[k]) ||
                  !strcmp("-w", argv[k])) {
        if (!ParseQuality(argv[k + 1], lgwin)) {
          goto error;
        }
        if (*lgwin < 10 || *lgwin >= 25) {
          goto error;
        }
        ++k;
        continue;
      }
    }
    goto error;
  }
  return;
error:
  fprintf(stderr,
          "Usage: %s [--force] [--quality n] [--decompress]"
          " [--input filename] [--output filename] [--repeat iters]"
          " [--verbose] [--window n]\n",
          argv[0]);
  exit(1);
}

static FILE* OpenInputFile(const char* input_path) {
  if (input_path == 0) {
    return fdopen(STDIN_FILENO, "rb");
  }
  FILE* f = fopen(input_path, "rb");
  if (f == 0) {
    perror("fopen");
    exit(1);
  }
  return f;
}

static FILE *OpenOutputFile(const char *output_path, const int force) {
  if (output_path == 0) {
    return fdopen(STDOUT_FILENO, "wb");
  }
  int excl = force ? 0 : O_EXCL;
  int fd = open(output_path, O_CREAT | excl | O_WRONLY | O_TRUNC,
                S_IRUSR | S_IWUSR);
  if (fd < 0) {
    if (!force) {
      struct stat statbuf;
      if (stat(output_path, &statbuf) == 0) {
        fprintf(stderr, "output file exists\n");
        exit(1);
      }
    }
    perror("open");
    exit(1);
  }
  return fdopen(fd, "wb");
}

int64_t FileSize(char *path) {
  FILE *f = fopen(path, "rb");
  if (f == NULL) {
    return -1;
  }
  if (fseek(f, 0L, SEEK_END) != 0) {
    fclose(f);
    return -1;
  }
  int64_t retval = ftell(f);
  fclose(f);
  return retval;
}

int main(int argc, char** argv) {
  char *input_path = 0;
  char *output_path = 0;
  int force = 0;
  int quality = 11;
  int decompress = 0;
  int repeat = 1;
  int verbose = 0;
  int lgwin = 0;
  ParseArgv(argc, argv, &input_path, &output_path, &force,
            &quality, &decompress, &repeat, &verbose, &lgwin);
  const clock_t clock_start = clock();
  for (int i = 0; i < repeat; ++i) {
    FILE* fin = OpenInputFile(input_path);
    FILE* fout = OpenOutputFile(output_path, force);
    if (decompress) {
      BrotliInput in = BrotliFileInput(fin);
      BrotliOutput out = BrotliFileOutput(fout);
      if (!BrotliDecompress(in, out)) {
        fprintf(stderr, "corrupt input\n");
        exit(1);
      }
    } else {
      brotli::BrotliParams params;
      params.lgwin = lgwin;
      params.quality = quality;
      try {
        brotli::BrotliFileIn in(fin, 1 << 16);
        brotli::BrotliFileOut out(fout);
        if (!BrotliCompress(params, &in, &out)) {
          fprintf(stderr, "compression failed\n");
          unlink(output_path);
          exit(1);
        }
      } catch (std::bad_alloc&) {
        fprintf(stderr, "not enough memory\n");
        unlink(output_path);
        exit(1);
      }
    }
    if (fclose(fin) != 0) {
      perror("fclose");
      exit(1);
    }
    if (fclose(fout) != 0) {
      perror("fclose");
      exit(1);
    }
  }
  if (verbose) {
    const clock_t clock_end = clock();
    double duration =
        static_cast<double>(clock_end - clock_start) / CLOCKS_PER_SEC;
    if (duration < 1e-9) {
      duration = 1e-9;
    }
    int64_t uncompressed_bytes = repeat *
        FileSize(decompress ? output_path : input_path);
    double uncompressed_bytes_in_MB = uncompressed_bytes / (1024.0 * 1024.0);
    if (decompress) {
      printf("Brotli decompression speed: ");
    } else {
      printf("Brotli compression speed: ");
    }
    printf("%g MB/s\n", uncompressed_bytes_in_MB / duration);
  }
  return 0;
}
<commit_msg>Add more error handling to the command-line tool.<commit_after>/* Copyright 2014 Google Inc. All Rights Reserved.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

   Example main() function for Brotli library.
*/

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include <string>

#include "../dec/decode.h"
#include "../enc/encode.h"
#include "../enc/streams.h"

static bool ParseQuality(const char* s, int* quality) {
  if (s[0] >= '0' && s[0] <= '9') {
    *quality = s[0] - '0';
    if (s[1] >= '0' && s[1] <= '9') {
      *quality = *quality * 10 + s[1] - '0';
      return s[2] == 0;
    }
    return s[1] == 0;
  }
  return false;
}

static void ParseArgv(int argc, char **argv,
                      char **input_path,
                      char **output_path,
                      int *force,
                      int *quality,
                      int *decompress,
                      int *repeat,
                      int *verbose,
                      int *lgwin) {
  *force = 0;
  *input_path = 0;
  *output_path = 0;
  *repeat = 1;
  *verbose = 0;
  *lgwin = 22;
  {
    size_t argv0_len = strlen(argv[0]);
    *decompress =
        argv0_len >= 5 && strcmp(&argv[0][argv0_len - 5], "unbro") == 0;
  }
  for (int k = 1; k < argc; ++k) {
    if (!strcmp("--force", argv[k]) ||
        !strcmp("-f", argv[k])) {
      if (*force != 0) {
        goto error;
      }
      *force = 1;
      continue;
    } else if (!strcmp("--decompress", argv[k]) ||
               !strcmp("--uncompress", argv[k]) ||
               !strcmp("-d", argv[k])) {
      *decompress = 1;
      continue;
    } else if (!strcmp("--verbose", argv[k]) ||
               !strcmp("-v", argv[k])) {
      if (*verbose != 0) {
        goto error;
      }
      *verbose = 1;
      continue;
    }
    if (k < argc - 1) {
      if (!strcmp("--input", argv[k]) ||
          !strcmp("--in", argv[k]) ||
          !strcmp("-i", argv[k])) {
        if (*input_path != 0) {
          goto error;
        }
        *input_path = argv[k + 1];
        ++k;
        continue;
      } else if (!strcmp("--output", argv[k]) ||
                 !strcmp("--out", argv[k]) ||
                 !strcmp("-o", argv[k])) {
        if (*output_path != 0) {
          goto error;
        }
        *output_path = argv[k + 1];
        ++k;
        continue;
      } else if (!strcmp("--quality", argv[k]) ||
                 !strcmp("-q", argv[k])) {
        if (!ParseQuality(argv[k + 1], quality)) {
          goto error;
        }
        ++k;
        continue;
      } else if (!strcmp("--repeat", argv[k]) ||
                 !strcmp("-r", argv[k])) {
        if (!ParseQuality(argv[k + 1], repeat)) {
          goto error;
        }
        ++k;
        continue;
      }  else if (!strcmp("--window", argv[k]) ||
                  !strcmp("-w", argv[k])) {
        if (!ParseQuality(argv[k + 1], lgwin)) {
          goto error;
        }
        if (*lgwin < 10 || *lgwin >= 25) {
          goto error;
        }
        ++k;
        continue;
      }
    }
    goto error;
  }
  return;
error:
  fprintf(stderr,
          "Usage: %s [--force] [--quality n] [--decompress]"
          " [--input filename] [--output filename] [--repeat iters]"
          " [--verbose] [--window n]\n",
          argv[0]);
  exit(1);
}

static FILE* OpenInputFile(const char* input_path) {
  if (input_path == 0) {
    return fdopen(STDIN_FILENO, "rb");
  }
  FILE* f = fopen(input_path, "rb");
  if (f == 0) {
    perror("fopen");
    exit(1);
  }
  return f;
}

static FILE *OpenOutputFile(const char *output_path, const int force) {
  if (output_path == 0) {
    return fdopen(STDOUT_FILENO, "wb");
  }
  int excl = force ? 0 : O_EXCL;
  int fd = open(output_path, O_CREAT | excl | O_WRONLY | O_TRUNC,
                S_IRUSR | S_IWUSR);
  if (fd < 0) {
    if (!force) {
      struct stat statbuf;
      if (stat(output_path, &statbuf) == 0) {
        fprintf(stderr, "output file exists\n");
        exit(1);
      }
    }
    perror("open");
    exit(1);
  }
  return fdopen(fd, "wb");
}

int64_t FileSize(char *path) {
  FILE *f = fopen(path, "rb");
  if (f == NULL) {
    return -1;
  }
  if (fseek(f, 0L, SEEK_END) != 0) {
    fclose(f);
    return -1;
  }
  int64_t retval = ftell(f);
  if (fclose(f) != 0) {
    return -1;
  }
  return retval;
}

int main(int argc, char** argv) {
  char *input_path = 0;
  char *output_path = 0;
  int force = 0;
  int quality = 11;
  int decompress = 0;
  int repeat = 1;
  int verbose = 0;
  int lgwin = 0;
  ParseArgv(argc, argv, &input_path, &output_path, &force,
            &quality, &decompress, &repeat, &verbose, &lgwin);
  const clock_t clock_start = clock();
  for (int i = 0; i < repeat; ++i) {
    FILE* fin = OpenInputFile(input_path);
    FILE* fout = OpenOutputFile(output_path, force);
    if (decompress) {
      BrotliInput in = BrotliFileInput(fin);
      BrotliOutput out = BrotliFileOutput(fout);
      if (!BrotliDecompress(in, out)) {
        fprintf(stderr, "corrupt input\n");
        exit(1);
      }
    } else {
      brotli::BrotliParams params;
      params.lgwin = lgwin;
      params.quality = quality;
      try {
        brotli::BrotliFileIn in(fin, 1 << 16);
        brotli::BrotliFileOut out(fout);
        if (!BrotliCompress(params, &in, &out)) {
          fprintf(stderr, "compression failed\n");
          unlink(output_path);
          exit(1);
        }
      } catch (std::bad_alloc&) {
        fprintf(stderr, "not enough memory\n");
        unlink(output_path);
        exit(1);
      }
    }
    if (fclose(fin) != 0) {
      perror("fclose");
      exit(1);
    }
    if (fclose(fout) != 0) {
      perror("fclose");
      exit(1);
    }
  }
  if (verbose) {
    const clock_t clock_end = clock();
    double duration =
        static_cast<double>(clock_end - clock_start) / CLOCKS_PER_SEC;
    if (duration < 1e-9) {
      duration = 1e-9;
    }
    int64_t uncompressed_size = FileSize(decompress ? output_path : input_path);
    if (uncompressed_size == -1) {
      fprintf(stderr, "failed to determine uncompressed file size\n");
      exit(1);
    }
    double uncompressed_bytes_in_MB =
        (repeat * uncompressed_size) / (1024.0 * 1024.0);
    if (decompress) {
      printf("Brotli decompression speed: ");
    } else {
      printf("Brotli compression speed: ");
    }
    printf("%g MB/s\n", uncompressed_bytes_in_MB / duration);
  }
  return 0;
}
<|endoftext|>


<commit_before>
// ---------------------------------------------------------------
// server.cpp
//
//  multi-threaded router server done right !
//
//
//  -> ROUTER socket -> main-thread -> in-proc socket -> delegate to worker
//
/*
 * ON MULTITHREADING WITH ZeroMQ
 *
 * Remember:
 *
 *       Do not use or close sockets except in the thread that created them.
 *
 *       Don't share ZeroMQ sockets between threads.
 *       ZeroMQ sockets are not threadsafe.
 *
 *       Isolate data privately within its thread and never share data
 *       in multiple threads. The only exception to this are ZeroMQ contexts,
 *       which are threadsafe.
 *
 *       Stay away from the classic concurrency mechanisms like as mutexes,
 *       critical sections, semaphores, etc. These are an anti-pattern
 *       in ZeroMQ applications.
 *
 *       Create one ZeroMQ context at the start of your process,
 *       and pass that to all threads that you want to connect via inproc sockets.
 *
 *
 *
 * If you need to start more than one proxy in an application,
 * for example, you will want to run each in their own thread.
 * It is easy to make the error of creating the proxy frontend
 * and backend sockets in one thread, and then passing the sockets
 * to the proxy in another thread. This may appear to work at first
 * but will fail randomly in real use.
 *
 * Some widely used models, despite being the basis for entire
 * industries, are fundamentally broken, and shared state concurrency
 * is one of them. Code that wants to scale without limit does it
 * like the Internet does, by sending messages and sharing nothing
 *
 */

/*
 *
 * ON CONTEXTS
 *
 * ZeroMQ applications always start by creating a context,
 * and then using that for creating sockets.
 * In C, it's the zmq_ctx_new() call.
 * You should create and use exactly one context in your process.
 * Technically, the context is the container for all sockets
 * in a single process, and acts as the transport for inproc sockets,
 * which are the fastest way to connect threads in one process.
 * If at runtime a process has two contexts,
 * these are like separate ZeroMQ instances.
 * If that's explicitly what you want, OK, but otherwise remember:
 *
 * Do one zmq_ctx_new() at the start of your main line code,
 * and one zmq_ctx_destroy() at the end.
 */
// ---------------------------------------------------------------
#include <iostream>
#include <future>
#include <thread>

#include <string>
#include <vector>
#include <stdlib.h>

#include "../../zmqHelper.hpp"

// ---------------------------------------------------------------
// ---------------------------------------------------------------
const std::string PORT_NUMBER = "5580";

// ---------------------------------------------------------------
// ---------------------------------------------------------------
template <typename ITERABLE>
void showLines (const std::string & msg, ITERABLE & it) {
  std::cout <<  msg << ":  message: |";
  for (auto item : it) {
	std::cout << item << "|";
  }
  std::cout << "\n";
}

// ---------------------------------------------------------------
// ---------------------------------------------------------------

// ---------------------------------------------------------------
// ---------------------------------------------------------------
class Worker {

private:

  //
  //
  //
  zmqHelper::SocketAdaptor< ZMQ_REP > internalRepSocket;

  //
  //
  //
  std::thread * theThread = nullptr;

  // -------------------------------------------------------------
  // -------------------------------------------------------------
  void main (){

	//
	//
	//
	std::cout << " ***** worker main " << this
			  << " starts **** \n";

	//
	//
	//
	while (true) {
	  std::cout << " worker waiting for socket \n";
	  auto lines = internalRepSocket.receiveText ();

	  std::cout << " ** worker: " << this;
	  showLines (" worker ", lines);

	  //
	  // do some work !
	  //
	  sleep (1);

	  //
	  //  reply
	  //
	  internalRepSocket.sendText ("echo of: " + lines[0] + " " + lines[1] );

	} // while
  }

public:

  // -------------------------------------------------------------
  // -------------------------------------------------------------
  Worker ( zmq::context_t & sharedContext_) :
	internalRepSocket {sharedContext_}
  {
	//
	//
	//
	internalRepSocket.connect ("inproc://innerChannel");

	//
	//
	//
	theThread = new std::thread (&Worker::main, this);

  }

  // -------------------------------------------------------------
  // -------------------------------------------------------------
  ~Worker ( ) {
	std::cerr << " worker destructor \n";
	if (theThread == nullptr) {
	  return;
	}

	theThread->join ();
	delete (theThread);
	theThread = nullptr;
  }

};

// ---------------------------------------------------------------
// ---------------------------------------------------------------
int main () {

  std::cout << " main stars \n";

  //
  // create internal socket to talk to workers
  //
  zmqHelper::SocketAdaptor< ZMQ_DEALER > innerDealerSocket;
  innerDealerSocket.bind ("inproc://innerChannel");

  //
  // 4 workers, you can experience with the
  // number of workers, timing run.client
  //
  Worker wk1 {innerDealerSocket.getContext()};
  Worker wk2 {innerDealerSocket.getContext()};
  Worker wk3 {innerDealerSocket.getContext()};
  Worker wk4 {innerDealerSocket.getContext()};

  std::cerr << "main(): workers created\n";

  //
  // create external socket to talk with clients
  //
  zmqHelper::SocketAdaptor< ZMQ_ROUTER > outerRouterSocket;
  outerRouterSocket.bind ("tcp://*:" + PORT_NUMBER);

  //
  // for ever ...
  //
  while (true) {

	std::cout << "\n\n while(true): waitinf for clients ... \n";

	std::vector<std::string>  lines;

	//
	//  wait (blocking poll) for data in either of the sockets
	//
	std::vector< zmqHelper::ZmqSocketType * > list
	  = { & outerRouterSocket.getZmqSocket(), & innerDealerSocket.getZmqSocket() };

	zmqHelper::ZmqSocketType *  who = zmqHelper::waitForDataInSockets ( list );

        //
        //  there is data
        //
        if ( who == & outerRouterSocket.getZmqSocket() ) {
          //
          // from client
          //
          lines = outerRouterSocket.receiveText ();

          //
          // delegate to worker
          //
          innerDealerSocket.sendText( lines );

        }
        else if ( who == & innerDealerSocket.getZmqSocket() ) {
          //
          // reply from worker
          //
          lines = innerDealerSocket.receiveText ();

          //
          //  answer the client
          //
          outerRouterSocket.sendText( lines );
        } else {
          std::cout << " server: error in polling? \n";
        }

  } // while

} // main ()

<commit_msg>Now the thread creating and using the socket is the same (in Worker::main())<commit_after>
// ---------------------------------------------------------------
// server.cpp
//
//  multi-threaded router server done right !
//
//
//  -> ROUTER socket -> main-thread -> in-proc socket -> delegate to worker
//
/*
 * ON MULTITHREADING WITH ZeroMQ
 *
 * Remember:
 *
 *       Do not use or close sockets except in the thread that created them.
 *
 *       Don't share ZeroMQ sockets between threads.
 *       ZeroMQ sockets are not threadsafe.
 *
 *       Isolate data privately within its thread and never share data
 *       in multiple threads. The only exception to this are ZeroMQ contexts,
 *       which are threadsafe.
 *
 *       Stay away from the classic concurrency mechanisms like as mutexes,
 *       critical sections, semaphores, etc. These are an anti-pattern
 *       in ZeroMQ applications.
 *
 *       Create one ZeroMQ context at the start of your process,
 *       and pass that to all threads that you want to connect via inproc sockets.
 *
 *
 *
 * If you need to start more than one proxy in an application,
 * for example, you will want to run each in their own thread.
 * It is easy to make the error of creating the proxy frontend
 * and backend sockets in one thread, and then passing the sockets
 * to the proxy in another thread. This may appear to work at first
 * but will fail randomly in real use.
 *
 * Some widely used models, despite being the basis for entire
 * industries, are fundamentally broken, and shared state concurrency
 * is one of them. Code that wants to scale without limit does it
 * like the Internet does, by sending messages and sharing nothing
 *
 */

/*
 *
 * ON CONTEXTS
 *
 * ZeroMQ applications always start by creating a context,
 * and then using that for creating sockets.
 * In C, it's the zmq_ctx_new() call.
 * You should create and use exactly one context in your process.
 * Technically, the context is the container for all sockets
 * in a single process, and acts as the transport for inproc sockets,
 * which are the fastest way to connect threads in one process.
 * If at runtime a process has two contexts,
 * these are like separate ZeroMQ instances.
 * If that's explicitly what you want, OK, but otherwise remember:
 *
 * Do one zmq_ctx_new() at the start of your main line code,
 * and one zmq_ctx_destroy() at the end.
 */
// ---------------------------------------------------------------
#include <iostream>
#include <future>
#include <thread>

#include <string>
#include <vector>
#include <stdlib.h>

#include "../../zmqHelper.hpp"

// ---------------------------------------------------------------
// ---------------------------------------------------------------
const std::string PORT_NUMBER = "5580";

// ---------------------------------------------------------------
// ---------------------------------------------------------------
template <typename ITERABLE>
void showLines (const std::string & msg, ITERABLE & it) {
  std::cout <<  msg << ":  message: |";
  for (auto item : it) {
	std::cout << item << "|";
  }
  std::cout << "\n";
}

// ---------------------------------------------------------------
// ---------------------------------------------------------------

// ---------------------------------------------------------------
// ---------------------------------------------------------------
class Worker {

private:

  //
  //
  //
  zmq::context_t & sharedContext;

  //
  // previous version: the thread in constructor creates
  // the socket but it is used by the thread in main
  //
  // zmqHelper::SocketAdaptor< ZMQ_REP > internalRepSocket;

  //
  //
  //
  std::thread * theThread = nullptr;

  // -------------------------------------------------------------
  // -------------------------------------------------------------
  void main (){
	//
	// a new thread executes this
	//

	//
	// the socket is created and use here
	//
	// remember RAII (resourse adquisition is initialization)
	//
	zmqHelper::SocketAdaptor< ZMQ_REP > internalRepSocket {sharedContext};

	//
	//
	//
	internalRepSocket.connect ("inproc://innerChannel");

	//
	//
	//
	std::cout << " ***** worker main " << this
			  << " starts **** \n";

	//
	//
	//
	while (true) {
	  std::cout << " worker waiting for socket \n";
	  auto lines = internalRepSocket.receiveText ();

	  std::cout << " ** worker: " << this;
	  showLines (" worker ", lines);

	  //
	  // do some work !
	  //
	  sleep (1);

	  //
	  //  reply
	  //
	  internalRepSocket.sendText ("echo of: " + lines[0] + " " + lines[1] );

	} // while
  } // ()

public:

  // -------------------------------------------------------------
  // -------------------------------------------------------------
  Worker ( zmq::context_t & sharedContext_) :
	sharedContext {sharedContext_}
  {
	//
	//
	//
	theThread = new std::thread (&Worker::main, this);

  }

  // -------------------------------------------------------------
  // -------------------------------------------------------------
  ~Worker ( ) {
	std::cerr << " worker destructor \n";
	if (theThread == nullptr) {
	  return;
	}

	theThread->join ();
	delete (theThread);
	theThread = nullptr;
  }

};

// ---------------------------------------------------------------
// ---------------------------------------------------------------
int main () {

  std::cout << " main stars \n";

  //
  // create internal socket to talk to workers
  //
  zmqHelper::SocketAdaptor< ZMQ_DEALER > innerDealerSocket;
  innerDealerSocket.bind ("inproc://innerChannel");

  //
  // 4 workers, you can experience with the
  // number of workers, timing run.client
  //
  Worker wk1 {innerDealerSocket.getContext()};
  Worker wk2 {innerDealerSocket.getContext()};
  Worker wk3 {innerDealerSocket.getContext()};
  Worker wk4 {innerDealerSocket.getContext()};

  std::cerr << "main(): workers created\n";

  //
  // create external socket to talk with clients
  //
  zmqHelper::SocketAdaptor< ZMQ_ROUTER > outerRouterSocket;
  outerRouterSocket.bind ("tcp://*:" + PORT_NUMBER);

  //
  // for ever ...
  //
  while (true) {

	std::cout << "\n\n while(true): waiting for clients ... \n";

	std::vector<std::string>  lines;

	//
	//  wait (blocking poll) for data in either of the sockets
	//
	std::vector< zmqHelper::ZmqSocketType * > list
	  = { & outerRouterSocket.getZmqSocket(), & innerDealerSocket.getZmqSocket() };

	zmqHelper::ZmqSocketType *  who = zmqHelper::waitForDataInSockets ( list );

        //
        //  there is data
        //
        if ( who == & outerRouterSocket.getZmqSocket() ) {
          //
          // from client
          //
          lines = outerRouterSocket.receiveText ();

          //
          // delegate to worker
          //
          innerDealerSocket.sendText( lines );

        }
        else if ( who == & innerDealerSocket.getZmqSocket() ) {
          //
          // reply from worker
          //
          lines = innerDealerSocket.receiveText ();

          //
          //  answer the client
          //
          outerRouterSocket.sendText( lines );
        } else {
          std::cout << " server: error in polling? \n";
        }

  } // while

} // main ()

<|endoftext|>


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

#include "emulatorhandler.h"

#include "../global.h"
#include "../common.h"

#include <QDir>
#include <QFile>
#include <QMessageBox>

#include <quazip5/quazip.h>
#include <quazip5/quazipfile.h>

EmulatorHandler::EmulatorHandler(QWidget *parent) : QObject(parent)
{
    this->parent = parent;

    lastOutput = "";
}

void EmulatorHandler::checkStatus(int status, QProcess::ExitStatus exitStatus)
{
    if (status != 0 || exitStatus != QProcess::NormalExit) {
        QMessageBox exitDialog(parent);
        exitDialog.setWindowTitle(tr("Warning"));
        exitDialog.setText(tr("<ParentName> quit unexpectedly. Check the log for more information.")
                           .replace("<ParentName>",ParentName));
        exitDialog.setIcon(QMessageBox::Warning);
        exitDialog.addButton(QMessageBox::Ok);
        exitDialog.addButton(tr("View Log"), QMessageBox::HelpRole);

        int ret = exitDialog.exec();
        if (ret == 0) emit showLog();
    }
}

void EmulatorHandler::cleanTemp()
{
    QFile::remove(QDir::tempPath() + "/" + AppNameLower + "/" + qgetenv("USER") + "/temp.z64");
}

void EmulatorHandler::emitFinished()
{
    emit finished();
}

QStringList EmulatorHandler::parseArgString(QString argString)
{
    QStringList result;
    QString arg;
    bool inQuote = false;
    bool inApos = false;

    for (int i = 0; i < argString.size(); i++)
    {
        // Check if inside of a quote
        if (argString.at(i) == QLatin1Char('"')) {
            inQuote = !inQuote;

            // Only continue if outside of both quotes and apostrophes
            if (arg.isEmpty() || (!inQuote && !inApos)) continue;
        }

        // Same check for apostrophes
        if (argString.at(i) == QLatin1Char('\'')) {
            inApos = !inApos;
            if (arg.isEmpty() || (!inQuote && !inApos)) continue;
        }

        if (!inQuote && !inApos && argString.at(i).isSpace()) {
            if (!arg.isEmpty()) {
                result += arg;
                arg.clear();
            }
        } else
            arg += argString.at(i);
    }

    if (!arg.isEmpty())
        result += arg;

    return result;
}

void EmulatorHandler::readOutput()
{
    QString output = emulatorProc->readAllStandardOutput();
    if (output != "")
        lastOutput.append(output);
    else
        lastOutput.append("\n" + tr("There was no output. If you were expecting Mupen64Plus to run, try copying")
                          + "\n" + tr("the above command into a command prompt to see if you get an error."));
}

void EmulatorHandler::startEmulator(QDir romDir, QString romFileName, QString zipFileName)
{
    QString completeRomPath;
    bool zip = false;

    if (zipFileName != "") { //If zipped file, extract and write to temp location for loading
        zip = true;

        QString zipFile = romDir.absoluteFilePath(zipFileName);
        QuaZipFile zippedFile(zipFile, romFileName);

        zippedFile.open(QIODevice::ReadOnly);
        QByteArray romData;
        romData.append(zippedFile.readAll());
        zippedFile.close();

        QString tempDir = QDir::tempPath() + "/" + AppNameLower + "-" + qgetenv("USER");
        QDir().mkpath(tempDir);
        completeRomPath = tempDir + "/temp.n64";

        QFile tempRom(completeRomPath);
        tempRom.open(QIODevice::WriteOnly);
        tempRom.write(romData);
        tempRom.close();
    } else
        completeRomPath = romDir.absoluteFilePath(romFileName);

    QString emulatorPath = SETTINGS.value("Paths/mupen64plus", "").toString();
    QString dataPath = SETTINGS.value("Paths/data", "").toString();
    QString configPath = SETTINGS.value("Paths/config", "").toString();
    QString pluginPath = SETTINGS.value("Paths/plugins", "").toString();
    QDir dataDir(dataPath);
    QDir configDir(configPath);
    QDir pluginDir(pluginPath);

    QString emuMode = SETTINGS.value("Emulation/mode", "").toString();

    QString resolution = SETTINGS.value("Graphics/resolution", "").toString();

    QString videoPlugin = SETTINGS.value("Plugins/video", "").toString();
    QString audioPlugin = SETTINGS.value("Plugins/audio", "").toString();
    QString inputPlugin = SETTINGS.value("Plugins/input", "").toString();
    QString rspPlugin = SETTINGS.value("Plugins/rsp", "").toString();

    QFile emulatorFile(emulatorPath);
    QFile romFile(completeRomPath);

    QString gameVideoPlugin = SETTINGS.value(romFileName+"/video", "").toString();
    QString gameAudioPlugin = SETTINGS.value(romFileName+"/audio", "").toString();
    QString gameInputPlugin = SETTINGS.value(romFileName+"/input", "").toString();
    QString gameRSPPlugin = SETTINGS.value(romFileName+"/rsp", "").toString();

    QString gameConfigPath = SETTINGS.value(romFileName+"/config", "").toString();
    QDir gameConfigDir(gameConfigPath);

    //Sanity checks
    if(!emulatorFile.exists() || QFileInfo(emulatorFile).isDir() || !QFileInfo(emulatorFile).isExecutable()) {
        QMessageBox::warning(parent, tr("Warning"),
                             tr("<ParentName> executable not found.").replace("<ParentName>",ParentName));
        if (zip) cleanTemp();
        return;
    }

    if(!romFile.exists() || QFileInfo(romFile).isDir()) {
        QMessageBox::warning(parent, tr("Warning"), tr("ROM file not found."));
        if (zip) cleanTemp();
        return;
    }

    romFile.open(QIODevice::ReadOnly);
    QByteArray romCheck = romFile.read(4);
    romFile.close();

    if (romCheck.toHex() != "80371240" && romCheck.toHex() != "37804012") {
        QMessageBox::warning(parent, tr("Warning"), tr("Not a valid ROM File."));
        if (zip) cleanTemp();
        return;
    }

    QStringList args;

    if (SETTINGS.value("saveoptions", "").toString() == "true")
        args << "--saveoptions";
    else
        args << "--nosaveoptions";

    if (dataPath != "" && dataDir.exists())
        args << "--datadir" << dataPath;
    if (gameConfigPath != "" && gameConfigDir.exists())
        args << "--configdir" << gameConfigPath;
    else if (configPath != "" && configDir.exists())
        args << "--configdir" << configPath;
    if (pluginPath != "" && pluginDir.exists())
        args << "--plugindir" << pluginPath;

    if (emuMode != "")
        args << "--emumode" << emuMode;

    if (SETTINGS.value("Graphics/osd", "").toString() == "true")
        args << "--osd";
    else
        args << "--noosd";

    if (SETTINGS.value("Graphics/fullscreen", "").toString() == "true")
        args << "--fullscreen";
    else
        args << "--windowed";

    if (resolution != "")
        args << "--resolution" << resolution;

    if (gameVideoPlugin != "")
        args << "--gfx" << gameVideoPlugin;
    else if (videoPlugin != "")
        args << "--gfx" << videoPlugin;
    if (gameAudioPlugin != "")
        args << "--audio" << gameAudioPlugin;
    else if (audioPlugin != "")
        args << "--audio" << audioPlugin;
    if (gameInputPlugin != "")
        args << "--input" << gameInputPlugin;
    else if (inputPlugin != "")
        args << "--input" << inputPlugin;
    if (gameRSPPlugin != "")
        args << "--rsp" << gameRSPPlugin;
    else if (rspPlugin != "")
        args << "--rsp" << rspPlugin;

    QString otherParameters = SETTINGS.value("Other/parameters", "").toString();
    if (otherParameters != "")
        args.append(parseArgString(otherParameters));

    QString gameParameters = SETTINGS.value(romFileName+"/parameters").toString();
    if (gameParameters != "")
        args.append(parseArgString(gameParameters));

    args << completeRomPath;

    emulatorProc = new QProcess(this);
    connect(emulatorProc, SIGNAL(finished(int)), this, SLOT(readOutput()));
    connect(emulatorProc, SIGNAL(finished(int)), this, SLOT(emitFinished()));
    connect(emulatorProc, SIGNAL(finished(int, QProcess::ExitStatus)), this,
            SLOT(checkStatus(int, QProcess::ExitStatus)));

    if (zip)
        connect(emulatorProc, SIGNAL(finished(int)), this, SLOT(cleanTemp()));

    // GLideN64 workaround. Can be removed if workaround is no longer needed
    // See: https://github.com/gonetz/GLideN64/issues/454#issuecomment-126853972
    if (SETTINGS.value("Other/forcegl33", "").toString() == "true") {
        QProcessEnvironment emulatorEnv = QProcessEnvironment::systemEnvironment();
        emulatorEnv.insert("MESA_GL_VERSION_OVERRIDE", "3.3COMPAT");
        emulatorProc->setProcessEnvironment(emulatorEnv);
    }

    emulatorProc->setWorkingDirectory(QFileInfo(emulatorFile).dir().canonicalPath());
    emulatorProc->setProcessChannelMode(QProcess::MergedChannels);
    emulatorProc->start(emulatorPath, args);

    //Add command to log
    QString executable = emulatorPath;
    if (executable.contains(" "))
        executable = '"' + executable + '"';

    QString argString;
    foreach(QString arg, args)
    {
        if (arg.contains(" "))
            argString += " \"" + arg + "\"";
        else
            argString += " " + arg;
    }

    lastOutput = executable + argString + "\n\n";

    emit started();
}

void EmulatorHandler::stopEmulator()
{
    emulatorProc->terminate();
}
<commit_msg>Modify temp file cleanup as well (#50)<commit_after>/***
 * Copyright (c) 2013, Dan Hasting
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. Neither the name of the organization nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ***/

#include "emulatorhandler.h"

#include "../global.h"
#include "../common.h"

#include <QDir>
#include <QFile>
#include <QMessageBox>

#include <quazip5/quazip.h>
#include <quazip5/quazipfile.h>

EmulatorHandler::EmulatorHandler(QWidget *parent) : QObject(parent)
{
    this->parent = parent;

    lastOutput = "";
}

void EmulatorHandler::checkStatus(int status, QProcess::ExitStatus exitStatus)
{
    if (status != 0 || exitStatus != QProcess::NormalExit) {
        QMessageBox exitDialog(parent);
        exitDialog.setWindowTitle(tr("Warning"));
        exitDialog.setText(tr("<ParentName> quit unexpectedly. Check the log for more information.")
                           .replace("<ParentName>",ParentName));
        exitDialog.setIcon(QMessageBox::Warning);
        exitDialog.addButton(QMessageBox::Ok);
        exitDialog.addButton(tr("View Log"), QMessageBox::HelpRole);

        int ret = exitDialog.exec();
        if (ret == 0) emit showLog();
    }
}

void EmulatorHandler::cleanTemp()
{
    QFile::remove(QDir::tempPath() + "/" + AppNameLower + "-" + qgetenv("USER") + "/temp.z64");
}

void EmulatorHandler::emitFinished()
{
    emit finished();
}

QStringList EmulatorHandler::parseArgString(QString argString)
{
    QStringList result;
    QString arg;
    bool inQuote = false;
    bool inApos = false;

    for (int i = 0; i < argString.size(); i++)
    {
        // Check if inside of a quote
        if (argString.at(i) == QLatin1Char('"')) {
            inQuote = !inQuote;

            // Only continue if outside of both quotes and apostrophes
            if (arg.isEmpty() || (!inQuote && !inApos)) continue;
        }

        // Same check for apostrophes
        if (argString.at(i) == QLatin1Char('\'')) {
            inApos = !inApos;
            if (arg.isEmpty() || (!inQuote && !inApos)) continue;
        }

        if (!inQuote && !inApos && argString.at(i).isSpace()) {
            if (!arg.isEmpty()) {
                result += arg;
                arg.clear();
            }
        } else
            arg += argString.at(i);
    }

    if (!arg.isEmpty())
        result += arg;

    return result;
}

void EmulatorHandler::readOutput()
{
    QString output = emulatorProc->readAllStandardOutput();
    if (output != "")
        lastOutput.append(output);
    else
        lastOutput.append("\n" + tr("There was no output. If you were expecting Mupen64Plus to run, try copying")
                          + "\n" + tr("the above command into a command prompt to see if you get an error."));
}

void EmulatorHandler::startEmulator(QDir romDir, QString romFileName, QString zipFileName)
{
    QString completeRomPath;
    bool zip = false;

    if (zipFileName != "") { //If zipped file, extract and write to temp location for loading
        zip = true;

        QString zipFile = romDir.absoluteFilePath(zipFileName);
        QuaZipFile zippedFile(zipFile, romFileName);

        zippedFile.open(QIODevice::ReadOnly);
        QByteArray romData;
        romData.append(zippedFile.readAll());
        zippedFile.close();

        QString tempDir = QDir::tempPath() + "/" + AppNameLower + "-" + qgetenv("USER");
        QDir().mkpath(tempDir);
        completeRomPath = tempDir + "/temp.n64";

        QFile tempRom(completeRomPath);
        tempRom.open(QIODevice::WriteOnly);
        tempRom.write(romData);
        tempRom.close();
    } else
        completeRomPath = romDir.absoluteFilePath(romFileName);

    QString emulatorPath = SETTINGS.value("Paths/mupen64plus", "").toString();
    QString dataPath = SETTINGS.value("Paths/data", "").toString();
    QString configPath = SETTINGS.value("Paths/config", "").toString();
    QString pluginPath = SETTINGS.value("Paths/plugins", "").toString();
    QDir dataDir(dataPath);
    QDir configDir(configPath);
    QDir pluginDir(pluginPath);

    QString emuMode = SETTINGS.value("Emulation/mode", "").toString();

    QString resolution = SETTINGS.value("Graphics/resolution", "").toString();

    QString videoPlugin = SETTINGS.value("Plugins/video", "").toString();
    QString audioPlugin = SETTINGS.value("Plugins/audio", "").toString();
    QString inputPlugin = SETTINGS.value("Plugins/input", "").toString();
    QString rspPlugin = SETTINGS.value("Plugins/rsp", "").toString();

    QFile emulatorFile(emulatorPath);
    QFile romFile(completeRomPath);

    QString gameVideoPlugin = SETTINGS.value(romFileName+"/video", "").toString();
    QString gameAudioPlugin = SETTINGS.value(romFileName+"/audio", "").toString();
    QString gameInputPlugin = SETTINGS.value(romFileName+"/input", "").toString();
    QString gameRSPPlugin = SETTINGS.value(romFileName+"/rsp", "").toString();

    QString gameConfigPath = SETTINGS.value(romFileName+"/config", "").toString();
    QDir gameConfigDir(gameConfigPath);

    //Sanity checks
    if(!emulatorFile.exists() || QFileInfo(emulatorFile).isDir() || !QFileInfo(emulatorFile).isExecutable()) {
        QMessageBox::warning(parent, tr("Warning"),
                             tr("<ParentName> executable not found.").replace("<ParentName>",ParentName));
        if (zip) cleanTemp();
        return;
    }

    if(!romFile.exists() || QFileInfo(romFile).isDir()) {
        QMessageBox::warning(parent, tr("Warning"), tr("ROM file not found."));
        if (zip) cleanTemp();
        return;
    }

    romFile.open(QIODevice::ReadOnly);
    QByteArray romCheck = romFile.read(4);
    romFile.close();

    if (romCheck.toHex() != "80371240" && romCheck.toHex() != "37804012") {
        QMessageBox::warning(parent, tr("Warning"), tr("Not a valid ROM File."));
        if (zip) cleanTemp();
        return;
    }

    QStringList args;

    if (SETTINGS.value("saveoptions", "").toString() == "true")
        args << "--saveoptions";
    else
        args << "--nosaveoptions";

    if (dataPath != "" && dataDir.exists())
        args << "--datadir" << dataPath;
    if (gameConfigPath != "" && gameConfigDir.exists())
        args << "--configdir" << gameConfigPath;
    else if (configPath != "" && configDir.exists())
        args << "--configdir" << configPath;
    if (pluginPath != "" && pluginDir.exists())
        args << "--plugindir" << pluginPath;

    if (emuMode != "")
        args << "--emumode" << emuMode;

    if (SETTINGS.value("Graphics/osd", "").toString() == "true")
        args << "--osd";
    else
        args << "--noosd";

    if (SETTINGS.value("Graphics/fullscreen", "").toString() == "true")
        args << "--fullscreen";
    else
        args << "--windowed";

    if (resolution != "")
        args << "--resolution" << resolution;

    if (gameVideoPlugin != "")
        args << "--gfx" << gameVideoPlugin;
    else if (videoPlugin != "")
        args << "--gfx" << videoPlugin;
    if (gameAudioPlugin != "")
        args << "--audio" << gameAudioPlugin;
    else if (audioPlugin != "")
        args << "--audio" << audioPlugin;
    if (gameInputPlugin != "")
        args << "--input" << gameInputPlugin;
    else if (inputPlugin != "")
        args << "--input" << inputPlugin;
    if (gameRSPPlugin != "")
        args << "--rsp" << gameRSPPlugin;
    else if (rspPlugin != "")
        args << "--rsp" << rspPlugin;

    QString otherParameters = SETTINGS.value("Other/parameters", "").toString();
    if (otherParameters != "")
        args.append(parseArgString(otherParameters));

    QString gameParameters = SETTINGS.value(romFileName+"/parameters").toString();
    if (gameParameters != "")
        args.append(parseArgString(gameParameters));

    args << completeRomPath;

    emulatorProc = new QProcess(this);
    connect(emulatorProc, SIGNAL(finished(int)), this, SLOT(readOutput()));
    connect(emulatorProc, SIGNAL(finished(int)), this, SLOT(emitFinished()));
    connect(emulatorProc, SIGNAL(finished(int, QProcess::ExitStatus)), this,
            SLOT(checkStatus(int, QProcess::ExitStatus)));

    if (zip)
        connect(emulatorProc, SIGNAL(finished(int)), this, SLOT(cleanTemp()));

    // GLideN64 workaround. Can be removed if workaround is no longer needed
    // See: https://github.com/gonetz/GLideN64/issues/454#issuecomment-126853972
    if (SETTINGS.value("Other/forcegl33", "").toString() == "true") {
        QProcessEnvironment emulatorEnv = QProcessEnvironment::systemEnvironment();
        emulatorEnv.insert("MESA_GL_VERSION_OVERRIDE", "3.3COMPAT");
        emulatorProc->setProcessEnvironment(emulatorEnv);
    }

    emulatorProc->setWorkingDirectory(QFileInfo(emulatorFile).dir().canonicalPath());
    emulatorProc->setProcessChannelMode(QProcess::MergedChannels);
    emulatorProc->start(emulatorPath, args);

    //Add command to log
    QString executable = emulatorPath;
    if (executable.contains(" "))
        executable = '"' + executable + '"';

    QString argString;
    foreach(QString arg, args)
    {
        if (arg.contains(" "))
            argString += " \"" + arg + "\"";
        else
            argString += " " + arg;
    }

    lastOutput = executable + argString + "\n\n";

    emit started();
}

void EmulatorHandler::stopEmulator()
{
    emulatorProc->terminate();
}
<|endoftext|>


<commit_before><commit_msg>P4 to Git Change 1578720 by chui@ocl-promo-incrementor on 2018/07/11 03:00:18<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: configregistry.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 15:19:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_configmgr.hxx"

#ifndef _CONFIGMGR_REGISTRY_CONFIGREGISTRY_HXX_
#include "configregistry.hxx"
#endif
#ifndef _CONFIGMGR_REGISTRY_CFGREGISTRYKEY_HXX_
#include "cfgregistrykey.hxx"
#endif
#ifndef CONFIGMGR_API_FACTORY_HXX_
#include "confapifactory.hxx"
#endif

#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _COM_SUN_STAR_LANG_SERVICENOTREGISTEREDEXCEPTION_HPP_
#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_WRAPPEDTARGETRUNTIMEEXCEPTION_HPP_
#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif

#define THISREF()       static_cast< ::cppu::OWeakObject* >(this)
#define UNISTRING(c)    makeUniString(c)

//..........................................................................
namespace configmgr
{
//..........................................................................

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::registry;
using namespace ::com::sun::star::container;
using namespace ::osl;
using namespace ::cppu;
using ::rtl::OUString;

namespace beans = ::com::sun::star::beans;

//==========================================================================
//= OConfigurationRegistry
//==========================================================================
    inline
    static
    OUString makeUniString(char const* c)
    {
        return OUString::createFromAscii(c);
    }

    // #99130# Don't export SimpleRegistry service
    static const AsciiServiceName aExportedConfigRegistryServices[] =
    {
        "com.sun.star.configuration.ConfigurationRegistry",
        NULL
    };
    static const AsciiServiceName aAdditionalConfigRegistryServices[] =
    {
        "com.sun.star.registry.SimpleRegistry",
        NULL
    };

    const AsciiServiceName aConfigRegistryImplementationName = "com.sun.star.comp.configuration.OConfigurationRegistry";

    const ServiceImplementationInfo OConfigurationRegistry::s_aServiceInfo =
    {
        aConfigRegistryImplementationName,
        aExportedConfigRegistryServices,
        aAdditionalConfigRegistryServices
    };

    Reference< XInterface > SAL_CALL instantiateConfigRegistry(CreationContext const& xContext )
    {
        OSL_ASSERT( xContext.is() );
        Reference< XMultiServiceFactory > xServiceManager( xContext->getServiceManager(), UNO_QUERY );
        ::cppu::OWeakObject * pNewInstance = new OConfigurationRegistry(xServiceManager);
        return pNewInstance;
    }

    const ServiceRegistrationInfo* getConfigurationRegistryServiceInfo()
    {
        return getRegistrationInfo(& OConfigurationRegistry::s_aServiceInfo);
    }

//--------------------------------------------------------------------------
OConfigurationRegistry::OConfigurationRegistry(const Reference< XMultiServiceFactory >& _rORB) throw(Exception, RuntimeException)
    :ServiceComponentImpl(&s_aServiceInfo)
    ,m_xORB(_rORB)
{
    // create the configuration provider used for accessing the configuration
    OSL_ENSURE(m_xORB.is(), "OConfigurationRegistry::OConfigurationRegistry : invalid service factory !");
    if (m_xORB.is())
    {
        m_xConfigurationProvider =
            m_xConfigurationProvider.query(
                m_xORB->createInstance(UNISTRING("com.sun.star.configuration.ConfigurationProvider"))
            );
    }

    if (!m_xConfigurationProvider.is())
    {
        // it's heavily needed ...
        throw ServiceNotRegisteredException(UNISTRING("Failed to instantiate the mandatory service com.sun.star.configuration.ConfigurationProvider."),
            THISREF());
    }
}

//--------------------------------------------------------------------------
Any SAL_CALL OConfigurationRegistry::queryInterface( const Type& _rType ) throw(RuntimeException)
{
    Any aReturn = ServiceComponentImpl::queryInterface(_rType);
    if (!aReturn.hasValue())
        aReturn = OConfigurationRegistry_Base::queryInterface(_rType);
    return aReturn;
}

//--------------------------------------------------------------------------
Sequence< Type > SAL_CALL OConfigurationRegistry::getTypes(  ) throw(RuntimeException)
{
    return ::comphelper::concatSequences(
        ServiceComponentImpl::getTypes(),
        OConfigurationRegistry_Base::getTypes());
}

//--------------------------------------------------------------------------
Sequence< sal_Int8 > SAL_CALL OConfigurationRegistry::getImplementationId(  ) throw(RuntimeException)
{
    static OImplementationId aId;
    return aId.getImplementationId();
}

//--------------------------------------------------------------------------
::rtl::OUString OConfigurationRegistry::getNodePathFromURL(const ::rtl::OUString& _rURL)
{
    // TODO
    return _rURL;
}

//--------------------------------------------------------------------------
::rtl::OUString SAL_CALL OConfigurationRegistry::getURL() throw(RuntimeException)
{
    MutexGuard aGuard(m_aMutex);
    return m_sLocation;
}

//--------------------------------------------------------------------------

// Not guarded !
void OConfigurationRegistry::implCheckOpen() throw(InvalidRegistryException, RuntimeException)
{
    if (!implIsOpen())
        throw InvalidRegistryException(UNISTRING("The registry is not bound to a configuration node."), THISREF());
}

//--------------------------------------------------------------------------
void SAL_CALL OConfigurationRegistry::open( const ::rtl::OUString& _rURL, sal_Bool _bReadOnly, sal_Bool /*_bCreate*/ ) throw(InvalidRegistryException, RuntimeException)
{
    MutexGuard aGuard(m_aMutex);

    if (implIsOpen())
        close();

    ::rtl::OUString sNodePath = getNodePathFromURL(_rURL);

    if (!m_xConfigurationProvider.is())
        throw DisposedException(UNISTRING("invalid object. configuration provider is already disposed."), THISREF());

    Reference< XInterface > xNodeAccess;
    try
    {
        char const * const sAccessType = _bReadOnly ?
            "com.sun.star.configuration.ConfigurationAccess" :
            "com.sun.star.configuration.ConfigurationUpdateAccess";

        // prepare parameters for creating the config access : the node path
        beans::PropertyValue aArgValue;
        aArgValue.Handle = -1;

        // currently theres is one parameter: the node path
        Sequence< Any > aArguments(1);

        // Argumenbt: NodePath
        aArgValue.Name = UNISTRING("nodepath");
        aArgValue.Value <<= sNodePath;

        aArguments[0] <<= aArgValue;

        xNodeAccess = m_xConfigurationProvider->createInstanceWithArguments(UNISTRING(sAccessType), aArguments);
    }
    catch (RuntimeException&)
    {   // allowed to leave this method
        throw;
    }
    catch (Exception& e)
    {   // not allowed to leave this method
        ::rtl::OUString sMessage = UNISTRING("The configuration provider does not supply a registry access for the requested Node.");
        sMessage += UNISTRING(" original error message of the provider : ");
        sMessage += e.Message;
        throw InvalidRegistryException(sMessage, THISREF());
    }

    Reference< XNameAccess > xReadRoot(xNodeAccess, UNO_QUERY);
    if (!_bReadOnly)
        m_xUpdateRoot = m_xUpdateRoot.query(xReadRoot);

    if (!xReadRoot.is() || (!_bReadOnly && !m_xUpdateRoot.is()))
        throw InvalidRegistryException(UNISTRING("The object supplied the by configuration provider is invalid."), THISREF());

    m_xRootKey = new OConfigurationRegistryKey(xReadRoot, !_bReadOnly, OConfigurationRegistryKey::SubtreeRoot());
    m_xSubtreeRoot = xNodeAccess;
}

//--------------------------------------------------------------------------
sal_Bool SAL_CALL OConfigurationRegistry::isValid(  ) throw(RuntimeException)
{
    MutexGuard aGuard(m_aMutex);
    return implIsOpen();
}

//--------------------------------------------------------------------------
sal_Bool OConfigurationRegistry::implIsOpen(  ) throw(RuntimeException)
{
    return m_xRootKey.is();
}

//--------------------------------------------------------------------------
void SAL_CALL  OConfigurationRegistry::close(  ) throw(InvalidRegistryException, RuntimeException)
{
    ClearableMutexGuard aGuard(m_aMutex);

    Reference< XRegistryKey > xRootKey(m_xRootKey);
    m_xRootKey = NULL;

    Reference< XComponent > xRootComponent(m_xSubtreeRoot, UNO_QUERY);
    m_xSubtreeRoot = NULL;
    m_xUpdateRoot = NULL;

    m_sLocation = ::rtl::OUString();

    aGuard.clear();

    if (xRootKey.is())
        xRootKey->closeKey();

    if (xRootComponent.is())
        xRootComponent->dispose();
}

//--------------------------------------------------------------------------
void SAL_CALL OConfigurationRegistry::disposing()
{
    close();

    {
        MutexGuard aGuard(m_aMutex);

        m_xConfigurationProvider.clear();
        m_xORB.clear();
    }

    ServiceComponentImpl::disposing();
}

//--------------------------------------------------------------------------
void SAL_CALL OConfigurationRegistry::destroy(  ) throw(InvalidRegistryException, RuntimeException)
{
    MutexGuard aGuard(m_aMutex);
    implCheckOpen();

    throw InvalidRegistryException(UNISTRING("This registry is a wrapper for a configuration access. It can not be destroyed."), THISREF());
}

//--------------------------------------------------------------------------
Reference< XRegistryKey > SAL_CALL OConfigurationRegistry::getRootKey(  ) throw(InvalidRegistryException, RuntimeException)
{
    MutexGuard aGuard(m_aMutex);
    implCheckOpen();

    return m_xRootKey;
}

//--------------------------------------------------------------------------
sal_Bool SAL_CALL OConfigurationRegistry::isReadOnly(  ) throw(InvalidRegistryException, RuntimeException)
{
    MutexGuard aGuard(m_aMutex);
    implCheckOpen();

    return !m_xUpdateRoot.is();
        // if we don't have the update root, we're readonly
}

//--------------------------------------------------------------------------
void SAL_CALL OConfigurationRegistry::mergeKey( const ::rtl::OUString& /*aKeyName*/, const ::rtl::OUString& /*aUrl*/ ) throw(InvalidRegistryException, MergeConflictException, RuntimeException)
{
    MutexGuard aGuard(m_aMutex);
    implCheckOpen();

    // not supported. but we can't throw an NoSupportException here ...
    throw InvalidRegistryException(UNISTRING("You can't merge into this registry. It's just a wrapper for a configuration node, which has a fixed structure which can not be modified"), THISREF());
}

//--------------------------------------------------------------------------
void SAL_CALL OConfigurationRegistry::flush(  ) throw(RuntimeException)
{
    {
        MutexGuard aGuard(m_aMutex);
        if (m_xUpdateRoot.is())
        {
            try
            {
                m_xUpdateRoot->commitChanges();
            }
            catch (WrappedTargetException& e)
            {   // not allowed to leave this method

                ::rtl::OUString sMessage;
                sMessage = UNISTRING("The changes made could not be committed. Orginal exception message : ");
                sMessage += e.Message;

                // TODO : the specification of XFlushable has to be changed !!!!!
                OSL_ENSURE(sal_False, "OConfigurationRegistry::flush : caught an exception, could not flush the data !");
    //          return;

                throw WrappedTargetRuntimeException(sMessage, THISREF(), e.TargetException);
            }
        }
    }

    Reference< XFlushListener > const * const pSelector = 0;
    if (OInterfaceContainerHelper* pContainer = this->rBHelper.getContainer(::getCppuType(pSelector)) )
    {
        ::cppu::OInterfaceIteratorHelper aIter( *pContainer );

        EventObject aFlushed(THISREF());
        while (aIter.hasMoreElements())
        try
        {
            static_cast< XFlushListener* >(aIter.next())->flushed(aFlushed);
        }
        catch (uno::Exception & )
        {}
    }
}

//--------------------------------------------------------------------------
void SAL_CALL OConfigurationRegistry::addFlushListener( const Reference< XFlushListener >& _rxListener ) throw(RuntimeException)
{
    this->rBHelper.addListener(::getCppuType(&_rxListener),_rxListener);
}

//--------------------------------------------------------------------------
void SAL_CALL OConfigurationRegistry::removeFlushListener( const Reference< XFlushListener >& _rxListener ) throw(RuntimeException)
{
    this->rBHelper.removeListener(::getCppuType(&_rxListener),_rxListener);
}

//..........................................................................
}   // namespace configmgr
//..........................................................................

<commit_msg>INTEGRATION: CWS configrefactor01 (1.11.24); FILE MERGED 2007/01/11 20:16:02 mmeeks 1.11.24.1: Submitted by: mmeeks More re-factoring, lots of locking rationalized, drastically reduced the mutex count, also removed ~300k interlocked increments with a non-interlocking SimpleReferencedObject base<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: configregistry.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: ihi $ $Date: 2007-11-23 14:29:56 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_configmgr.hxx"

#ifndef _CONFIGMGR_REGISTRY_CONFIGREGISTRY_HXX_
#include "configregistry.hxx"
#endif
#ifndef _CONFIGMGR_REGISTRY_CFGREGISTRYKEY_HXX_
#include "cfgregistrykey.hxx"
#endif
#ifndef CONFIGMGR_API_FACTORY_HXX_
#include "confapifactory.hxx"
#endif
#ifndef CONFIGMGR_UTILITY_HXX_
#include "utility.hxx"
#endif

#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _COM_SUN_STAR_LANG_SERVICENOTREGISTEREDEXCEPTION_HPP_
#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_WRAPPEDTARGETRUNTIMEEXCEPTION_HPP_
#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif

#define THISREF()       static_cast< ::cppu::OWeakObject* >(this)
#define UNISTRING(c)    makeUniString(c)

//..........................................................................
namespace configmgr
{
//..........................................................................

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::registry;
using namespace ::com::sun::star::container;
using namespace ::osl;
using namespace ::cppu;
using ::rtl::OUString;

namespace beans = ::com::sun::star::beans;

//==========================================================================
//= OConfigurationRegistry
//==========================================================================
    inline
    static
    OUString makeUniString(char const* c)
    {
        return OUString::createFromAscii(c);
    }

    // #99130# Don't export SimpleRegistry service
    static const AsciiServiceName aExportedConfigRegistryServices[] =
    {
        "com.sun.star.configuration.ConfigurationRegistry",
        NULL
    };
    static const AsciiServiceName aAdditionalConfigRegistryServices[] =
    {
        "com.sun.star.registry.SimpleRegistry",
        NULL
    };

    const AsciiServiceName aConfigRegistryImplementationName = "com.sun.star.comp.configuration.OConfigurationRegistry";

    const ServiceImplementationInfo OConfigurationRegistry::s_aServiceInfo =
    {
        aConfigRegistryImplementationName,
        aExportedConfigRegistryServices,
        aAdditionalConfigRegistryServices
    };

    Reference< XInterface > SAL_CALL instantiateConfigRegistry(CreationContext const& xContext )
    {
        OSL_ASSERT( xContext.is() );
        Reference< XMultiServiceFactory > xServiceManager( xContext->getServiceManager(), UNO_QUERY );
        ::cppu::OWeakObject * pNewInstance = new OConfigurationRegistry(xServiceManager);
        return pNewInstance;
    }

    const ServiceRegistrationInfo* getConfigurationRegistryServiceInfo()
    {
        return getRegistrationInfo(& OConfigurationRegistry::s_aServiceInfo);
    }

//--------------------------------------------------------------------------
OConfigurationRegistry::OConfigurationRegistry(const Reference< XMultiServiceFactory >& _rORB) throw(Exception, RuntimeException)
    :ServiceComponentImpl(&s_aServiceInfo)
    ,m_xORB(_rORB)
{
    // create the configuration provider used for accessing the configuration
    OSL_ENSURE(m_xORB.is(), "OConfigurationRegistry::OConfigurationRegistry : invalid service factory !");
    if (m_xORB.is())
    {
        m_xConfigurationProvider =
            m_xConfigurationProvider.query(
                m_xORB->createInstance(UNISTRING("com.sun.star.configuration.ConfigurationProvider"))
            );
    }

    if (!m_xConfigurationProvider.is())
    {
        // it's heavily needed ...
        throw ServiceNotRegisteredException(UNISTRING("Failed to instantiate the mandatory service com.sun.star.configuration.ConfigurationProvider."),
            THISREF());
    }
}

//--------------------------------------------------------------------------
Any SAL_CALL OConfigurationRegistry::queryInterface( const Type& _rType ) throw(RuntimeException)
{
    Any aReturn = ServiceComponentImpl::queryInterface(_rType);
    if (!aReturn.hasValue())
        aReturn = OConfigurationRegistry_Base::queryInterface(_rType);
    return aReturn;
}

//--------------------------------------------------------------------------
Sequence< Type > SAL_CALL OConfigurationRegistry::getTypes(  ) throw(RuntimeException)
{
    return ::comphelper::concatSequences(
        ServiceComponentImpl::getTypes(),
        OConfigurationRegistry_Base::getTypes());
}

//--------------------------------------------------------------------------
Sequence< sal_Int8 > SAL_CALL OConfigurationRegistry::getImplementationId(  ) throw(RuntimeException)
{
    static OImplementationId aId;
    return aId.getImplementationId();
}

//--------------------------------------------------------------------------
::rtl::OUString OConfigurationRegistry::getNodePathFromURL(const ::rtl::OUString& _rURL)
{
    // TODO
    return _rURL;
}

//--------------------------------------------------------------------------
::rtl::OUString SAL_CALL OConfigurationRegistry::getURL() throw(RuntimeException)
{
    UnoApiLock aLock;
    return m_sLocation;
}

//--------------------------------------------------------------------------

// Not guarded !
void OConfigurationRegistry::implCheckOpen() throw(InvalidRegistryException, RuntimeException)
{
    if (!implIsOpen())
        throw InvalidRegistryException(UNISTRING("The registry is not bound to a configuration node."), THISREF());
}

//--------------------------------------------------------------------------
void SAL_CALL OConfigurationRegistry::open( const ::rtl::OUString& _rURL, sal_Bool _bReadOnly, sal_Bool /*_bCreate*/ ) throw(InvalidRegistryException, RuntimeException)
{
    UnoApiLock aLock;

    if (implIsOpen())
        close();

    ::rtl::OUString sNodePath = getNodePathFromURL(_rURL);

    if (!m_xConfigurationProvider.is())
        throw DisposedException(UNISTRING("invalid object. configuration provider is already disposed."), THISREF());

    Reference< XInterface > xNodeAccess;
    try
    {
        char const * const sAccessType = _bReadOnly ?
            "com.sun.star.configuration.ConfigurationAccess" :
            "com.sun.star.configuration.ConfigurationUpdateAccess";

        // prepare parameters for creating the config access : the node path
        beans::PropertyValue aArgValue;
        aArgValue.Handle = -1;

        // currently theres is one parameter: the node path
        Sequence< Any > aArguments(1);

        // Argumenbt: NodePath
        aArgValue.Name = UNISTRING("nodepath");
        aArgValue.Value <<= sNodePath;

        aArguments[0] <<= aArgValue;

        xNodeAccess = m_xConfigurationProvider->createInstanceWithArguments(UNISTRING(sAccessType), aArguments);
    }
    catch (RuntimeException&)
    {   // allowed to leave this method
        throw;
    }
    catch (Exception& e)
    {   // not allowed to leave this method
        ::rtl::OUString sMessage = UNISTRING("The configuration provider does not supply a registry access for the requested Node.");
        sMessage += UNISTRING(" original error message of the provider : ");
        sMessage += e.Message;
        throw InvalidRegistryException(sMessage, THISREF());
    }

    Reference< XNameAccess > xReadRoot(xNodeAccess, UNO_QUERY);
    if (!_bReadOnly)
        m_xUpdateRoot = m_xUpdateRoot.query(xReadRoot);

    if (!xReadRoot.is() || (!_bReadOnly && !m_xUpdateRoot.is()))
        throw InvalidRegistryException(UNISTRING("The object supplied the by configuration provider is invalid."), THISREF());

    m_xRootKey = new OConfigurationRegistryKey(xReadRoot, !_bReadOnly, OConfigurationRegistryKey::SubtreeRoot());
    m_xSubtreeRoot = xNodeAccess;
}

//--------------------------------------------------------------------------
sal_Bool SAL_CALL OConfigurationRegistry::isValid(  ) throw(RuntimeException)
{
    UnoApiLock aLock;
    return implIsOpen();
}

//--------------------------------------------------------------------------
sal_Bool OConfigurationRegistry::implIsOpen(  ) throw(RuntimeException)
{
    return m_xRootKey.is();
}

//--------------------------------------------------------------------------
void SAL_CALL  OConfigurationRegistry::close(  ) throw(InvalidRegistryException, RuntimeException)
{
    UnoApiLock aLock;

    Reference< XRegistryKey > xRootKey(m_xRootKey);
    m_xRootKey = NULL;

    Reference< XComponent > xRootComponent(m_xSubtreeRoot, UNO_QUERY);
    m_xSubtreeRoot = NULL;
    m_xUpdateRoot = NULL;

    m_sLocation = ::rtl::OUString();

    if (xRootKey.is())
        xRootKey->closeKey();

    if (xRootComponent.is())
        xRootComponent->dispose();
}

//--------------------------------------------------------------------------
void SAL_CALL OConfigurationRegistry::disposing()
{
    close();

    {
        UnoApiLock aLock;

        m_xConfigurationProvider.clear();
        m_xORB.clear();
    }

    ServiceComponentImpl::disposing();
}

//--------------------------------------------------------------------------
void SAL_CALL OConfigurationRegistry::destroy(  ) throw(InvalidRegistryException, RuntimeException)
{
    UnoApiLock aLock;
    implCheckOpen();

    throw InvalidRegistryException(UNISTRING("This registry is a wrapper for a configuration access. It can not be destroyed."), THISREF());
}

//--------------------------------------------------------------------------
Reference< XRegistryKey > SAL_CALL OConfigurationRegistry::getRootKey(  ) throw(InvalidRegistryException, RuntimeException)
{
    UnoApiLock aLock;
    implCheckOpen();

    return m_xRootKey;
}

//--------------------------------------------------------------------------
sal_Bool SAL_CALL OConfigurationRegistry::isReadOnly(  ) throw(InvalidRegistryException, RuntimeException)
{
    UnoApiLock aLock;
    implCheckOpen();

    return !m_xUpdateRoot.is();
        // if we don't have the update root, we're readonly
}

//--------------------------------------------------------------------------
void SAL_CALL OConfigurationRegistry::mergeKey( const ::rtl::OUString& /*aKeyName*/, const ::rtl::OUString& /*aUrl*/ ) throw(InvalidRegistryException, MergeConflictException, RuntimeException)
{
    UnoApiLock aLock;
    implCheckOpen();

    // not supported. but we can't throw an NoSupportException here ...
    throw InvalidRegistryException(UNISTRING("You can't merge into this registry. It's just a wrapper for a configuration node, which has a fixed structure which can not be modified"), THISREF());
}

//--------------------------------------------------------------------------
void SAL_CALL OConfigurationRegistry::flush(  ) throw(RuntimeException)
{
    {
        UnoApiLock aLock;
        if (m_xUpdateRoot.is())
        {
            try
            {
                m_xUpdateRoot->commitChanges();
            }
            catch (WrappedTargetException& e)
            {   // not allowed to leave this method

                ::rtl::OUString sMessage;
                sMessage = UNISTRING("The changes made could not be committed. Orginal exception message : ");
                sMessage += e.Message;

                // TODO : the specification of XFlushable has to be changed !!!!!
                OSL_ENSURE(sal_False, "OConfigurationRegistry::flush : caught an exception, could not flush the data !");
    //          return;

                throw WrappedTargetRuntimeException(sMessage, THISREF(), e.TargetException);
            }
        }
    }

    Reference< XFlushListener > const * const pSelector = 0;
    if (OInterfaceContainerHelper* pContainer = this->rBHelper.getContainer(::getCppuType(pSelector)) )
    {
        ::cppu::OInterfaceIteratorHelper aIter( *pContainer );

        EventObject aFlushed(THISREF());
        while (aIter.hasMoreElements())
        try
        {
            static_cast< XFlushListener* >(aIter.next())->flushed(aFlushed);
        }
        catch (uno::Exception & )
        {}
    }
}

//--------------------------------------------------------------------------
void SAL_CALL OConfigurationRegistry::addFlushListener( const Reference< XFlushListener >& _rxListener ) throw(RuntimeException)
{
    this->rBHelper.addListener(::getCppuType(&_rxListener),_rxListener);
}

//--------------------------------------------------------------------------
void SAL_CALL OConfigurationRegistry::removeFlushListener( const Reference< XFlushListener >& _rxListener ) throw(RuntimeException)
{
    this->rBHelper.removeListener(::getCppuType(&_rxListener),_rxListener);
}

//..........................................................................
}   // namespace configmgr
//..........................................................................

<|endoftext|>


<commit_before>#include <boost/python.hpp>
#include "ModelInterface.h"
#include "pyToCppModelInterfaceCache.h"

#include <boost/python/stl_iterator.hpp>
#include <iostream>
#include <stdexcept>
#include <boost/python/numeric.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <numpy/noprefix.h>

namespace threeML {

template<typename T>
inline
std::vector<T> to_std_vector(const boost::python::object &iterable) {
  return std::vector<T>(boost::python::stl_input_iterator<T>(iterable),
                        boost::python::stl_input_iterator<T>());
}

void pyToCppModelInterfaceCache::setPtsSourceSpectrum(const int id, const numeric::array& spectrum)
{

  // These are both n_points in size

  PyArrayObject* spectrum__ = (PyArrayObject*) cube.ptr();

  unsigned int n_energies = (unsigned int) *(spectrum__->dimensions);

  double* spectrum_ = (double *) spectrum__->data;

  m_ptsSources[id].assign(spectrum_, spectrum_ + n_energies);

}

void pyToCppModelInterfaceCache::setPtsSourcePosition(const int id, const float lon, const float lat)
{

  m_ptsSourcesPos[id] = SkyCoord(lon, lat);

}

void pyToCppModelInterfaceCache::setExtSourceBoundaries(const int id, const float lon_min, const float lon_max,
                                                        const float lat_min, const float lat_max)
{

  BoundingBox this_boundingBox;

  this_boundingBox.lon_min = lon_min;
  this_boundingBox.lon_max = lon_max;
  this_boundingBox.lat_min = lat_min;
  this_boundingBox.lat_max = lat_max;

  m_boundingBoxes[id] = this_boundingBox;

}

void pyToCppModelInterfaceCache::setExtSourceCube(const int id, const numeric::array &cube,
                                                  const numeric::array &lon, const numeric::array &lat)
{

  // Add an extended source to the cache (a map)

  PyArrayObject* cube__ = (PyArrayObject*) cube.ptr();

  unsigned int n_points = (unsigned int) *(cube__->dimensions);
  unsigned int n_energies = (unsigned int) *(cube__->dimensions+1);

  // This is n_points * n_energies in size

  double* cube_ = (double *) cube__->data;

  // These are both n_points in size

  double* lon_ = (double *) ((PyArrayObject*) lon.ptr())->data;
  double* lat_ = (double *) ((PyArrayObject*) lat.ptr())->data;

  ExtSrcCube this_srcCube;

  for(unsigned int i=0; i < n_points; ++i)
  {

    float this_lon = (float) lon_[i];
    float this_lat = (float) lat_[i];

    SkyCoord this_coord(this_lon, this_lat);

    // A little of pointer algebra

    int this_data_start = i * n_energies;
    int this_data_stop = this_data_start + n_energies;

    // Note how this construct avoid the double copy which would
    // occur if we were to first create a vector and then
    // copy it into a standard map. Here instead the operator
    // [] creates an empty vector, which is then filled with
    // the assign method

    this_srcCube[this_coord].assign(cube_ + this_data_start, cube_ + this_data_stop);

  }

  // Finally add to the map

  m_extSources[id] = this_srcCube;

}

bool pyToCppModelInterfaceCache::isInsideAnyExtendedSource(double j2000_ra, double j2000_dec) const {
  return true;
}

int pyToCppModelInterfaceCache::getNumberOfPointSources() const {

  return m_ptsSourcesPos.size();

}

void pyToCppModelInterfaceCache::getPointSourcePosition(int srcid, double *j2000_ra, double *j2000_dec) const {

  SkyCoord this_position = m_ptsSourcesPos.at(srcid);

  *j2000_ra = this_position.first;
  *j2000_dec = this_position.second;

}

void pyToCppModelInterfaceCache::reset() {

  //Empty the cache

  m_extSources.clear();
  m_ptsSources.clear();
  /*
  m_boundingBoxes.clear();
  m_nExtSources = 0;
  m_nPtSources = 0;*/

}

std::vector<double>
pyToCppModelInterfaceCache::getPointSourceFluxes(int srcid, std::vector<double> energies) const {

  throw std::runtime_error("ModelInterfaceCache: point source not yet implemented");

}

int pyToCppModelInterfaceCache::getNumberOfExtendedSources() const {

  // We use the size of bounding boxes and not of m_extSources because the latter
  // could get filled in a second moment
  return m_boundingBoxes.size();

}

std::vector<double>
pyToCppModelInterfaceCache::getExtendedSourceFluxes(int srcid, double j2000_ra, double j2000_dec,
                                               std::vector<double> energies) const {

  SkyCoord sky_pos(j2000_ra, j2000_dec);

  return m_extSources.at(srcid).at(sky_pos);

}

std::vector<double>
pyToCppModelInterfaceCache::getExtendedSourceFluxes_test(int srcid, double j2000_ra, double j2000_dec) const {

  SkyCoord sky_pos(j2000_ra, j2000_dec);

  return m_extSources.at(srcid).at(sky_pos);

}

std::string pyToCppModelInterfaceCache::getPointSourceName(int srcid) const {

  //TODO: implement a mechanism to actually keep the true name

  std::stringstream name;

  name << "Point source " << srcid;

  return name.str();
}

std::string pyToCppModelInterfaceCache::getExtendedSourceName(int srcid) const {

  //TODO: implement a mechanism to actually keep the true name

  std::stringstream name;

  name << "Extended source " << srcid;

  return name.str();
}

void pyToCppModelInterfaceCache::getExtendedSourceBoundaries(int srcid, double *j2000_ra_min,
                                                        double *j2000_ra_max,
                                                        double *j2000_dec_min,
                                                        double *j2000_dec_max) const {

  const BoundingBox *this_boundingBox = &m_boundingBoxes.at(srcid);

  *j2000_ra_min = this_boundingBox->lon_min;
  *j2000_ra_max = this_boundingBox->lon_max;
  *j2000_dec_min = this_boundingBox->lat_min;
  *j2000_dec_max = this_boundingBox->lat_max;

}

}

using namespace threeML;
using namespace boost::python;

//This is needed to wrap the interface (i.e., all methods are virtual)
//contained in ModelInterface.h
struct ModelInterfaceCacheWrap: ModelInterface, wrapper<ModelInterface> {
  int getNumberOfPointSources() const { return this->get_override("getNumberOfPointSources")(); }

  void getPointSourcePosition(int srcid, double *j2000_ra, double *j2000_dec) const {
    this->get_override("getPointSourcePosition")();
  }

  std::vector<double> getPointSourceFluxes(int srcid, std::vector<double> energies) const {
    return this->get_override("getPointSourceFluxes")();
  }

  std::string getPointSourceName(int srcid) const { return this->get_override("getPointSourceName")(); }

  int getNumberOfExtendedSources() const { return this->get_override("getNumberOfExtendedSources")(); }

  std::vector<double> getExtendedSourceFluxes(int srcid, double j2000_ra, double j2000_dec,
                                              std::vector<double> energies) const {
    return this->get_override("getExtendedSourceFluxes")();
  }

  std::string getExtendedSourceName(int srcid) const { return this->get_override("getExtendedSourceName")(); }

  bool isInsideAnyExtendedSource(double j2000_ra, double j2000_dec) const {
    return this->get_override("isInsideAnyExtendedSource")();
  }

  void getExtendedSourceBoundaries(int srcid, double *j2000_ra_min,
                                   double *j2000_ra_max,
                                   double *j2000_dec_min,
                                   double *j2000_dec_max) const { this->get_override("getExtendedSourceBoundaries")(); }
};

template<class T>
struct VecToList {
  static PyObject *convert(const std::vector<T> &vec) {
    boost::python::list *l = new boost::python::list();

    for (size_t i = 0; i < vec.size(); i++)
      (*l).append(vec[i]);

    return l->ptr();
  }
};

BOOST_PYTHON_MODULE (pyModelInterfaceCache) {
  //hello
  to_python_converter<std::vector<double, std::allocator<double> >, VecToList<double> >();

  class_<ModelInterfaceCacheWrap, boost::noncopyable>("ModelInterface")
      .def("getNumberOfPointSources", pure_virtual(&ModelInterface::getNumberOfPointSources))
      .def("getPointSourcePosition", pure_virtual(&ModelInterface::getPointSourcePosition))
      .def("getPointSourceFluxes", pure_virtual(&ModelInterface::getPointSourceFluxes))
      .def("getPointSourceName", pure_virtual(&ModelInterface::getPointSourceName))
      .def("getNumberOfExtendedSources", pure_virtual(&ModelInterface::getNumberOfExtendedSources))
      .def("getExtendedSourceFluxes", pure_virtual(&ModelInterface::getExtendedSourceFluxes))
      .def("getExtendedSourceName", pure_virtual(&ModelInterface::getExtendedSourceName))
      .def("isInsideAnyExtendedSource", pure_virtual(&ModelInterface::isInsideAnyExtendedSource))
      .def("getExtendedSourceBoundaries", pure_virtual(&ModelInterface::getExtendedSourceBoundaries));

  numeric::array::set_module_and_type("numpy", "ndarray");

  class_<pyToCppModelInterfaceCache, bases<ModelInterface> >("pyToCppModelInterfaceCache", init< >())
      .def("getNumberOfPointSources", &pyToCppModelInterfaceCache::getNumberOfPointSources)
      .def("getPointSourcePosition", &pyToCppModelInterfaceCache::getPointSourcePosition)
      .def("getPointSourceFluxes", &pyToCppModelInterfaceCache::getPointSourceFluxes)
      .def("getPointSourceName", &pyToCppModelInterfaceCache::getPointSourceName)
      .def("getNumberOfExtendedSources", &pyToCppModelInterfaceCache::getNumberOfExtendedSources)
      .def("getExtendedSourceFluxes", &pyToCppModelInterfaceCache::getExtendedSourceFluxes)
      .def("getExtendedSourceName", &pyToCppModelInterfaceCache::getExtendedSourceName)
      .def("isInsideAnyExtendedSource", &pyToCppModelInterfaceCache::isInsideAnyExtendedSource)
      .def("getExtendedSourceBoundaries", &pyToCppModelInterfaceCache::getExtendedSourceBoundaries)
      .def("setExtSourceBoundaries", &pyToCppModelInterfaceCache::setExtSourceBoundaries)
      .def("setExtSourceCube",&pyToCppModelInterfaceCache::setExtSourceCube)
      .def("getExtendedSourceFluxes_test",&pyToCppModelInterfaceCache::getExtendedSourceFluxes_test)
      .def("reset",&pyToCppModelInterfaceCache::reset);
}
<commit_msg>Added point sources to the new interface<commit_after>#include <boost/python.hpp>
#include "ModelInterface.h"
#include "pyToCppModelInterfaceCache.h"

#include <boost/python/stl_iterator.hpp>
#include <iostream>
#include <stdexcept>
#include <boost/python/numeric.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <numpy/noprefix.h>

namespace threeML {

template<typename T>
inline
std::vector<T> to_std_vector(const boost::python::object &iterable) {
  return std::vector<T>(boost::python::stl_input_iterator<T>(iterable),
                        boost::python::stl_input_iterator<T>());
}

void pyToCppModelInterfaceCache::setPtsSourceSpectrum(const int id, const numeric::array& spectrum)
{

  // These are both n_points in size

  PyArrayObject* spectrum__ = (PyArrayObject*) spectrum.ptr();

  unsigned int n_energies = (unsigned int) *(spectrum__->dimensions);

  double* spectrum_ = (double *) spectrum__->data;

  m_ptsSources[id].assign(spectrum_, spectrum_ + n_energies);

}

void pyToCppModelInterfaceCache::setPtsSourcePosition(const int id, const float lon, const float lat)
{

  m_ptsSourcesPos[id] = SkyCoord(lon, lat);

}

void pyToCppModelInterfaceCache::setExtSourceBoundaries(const int id, const float lon_min, const float lon_max,
                                                        const float lat_min, const float lat_max)
{

  BoundingBox this_boundingBox;

  this_boundingBox.lon_min = lon_min;
  this_boundingBox.lon_max = lon_max;
  this_boundingBox.lat_min = lat_min;
  this_boundingBox.lat_max = lat_max;

  m_boundingBoxes[id] = this_boundingBox;

}

void pyToCppModelInterfaceCache::setExtSourceCube(const int id, const numeric::array &cube,
                                                  const numeric::array &lon, const numeric::array &lat)
{

  // Add an extended source to the cache (a map)

  PyArrayObject* cube__ = (PyArrayObject*) cube.ptr();

  unsigned int n_points = (unsigned int) *(cube__->dimensions);
  unsigned int n_energies = (unsigned int) *(cube__->dimensions+1);

  // This is n_points * n_energies in size

  double* cube_ = (double *) cube__->data;

  // These are both n_points in size

  double* lon_ = (double *) ((PyArrayObject*) lon.ptr())->data;
  double* lat_ = (double *) ((PyArrayObject*) lat.ptr())->data;

  ExtSrcCube this_srcCube;

  for(unsigned int i=0; i < n_points; ++i)
  {

    float this_lon = (float) lon_[i];
    float this_lat = (float) lat_[i];

    SkyCoord this_coord(this_lon, this_lat);

    // A little of pointer algebra

    int this_data_start = i * n_energies;
    int this_data_stop = this_data_start + n_energies;

    // Note how this construct avoid the double copy which would
    // occur if we were to first create a vector and then
    // copy it into a standard map. Here instead the operator
    // [] creates an empty vector, which is then filled with
    // the assign method

    this_srcCube[this_coord].assign(cube_ + this_data_start, cube_ + this_data_stop);

  }

  // Finally add to the map

  m_extSources[id] = this_srcCube;

}

bool pyToCppModelInterfaceCache::isInsideAnyExtendedSource(double j2000_ra, double j2000_dec) const {
  return true;
}

int pyToCppModelInterfaceCache::getNumberOfPointSources() const {

  return m_ptsSourcesPos.size();

}

void pyToCppModelInterfaceCache::getPointSourcePosition(int srcid, double *j2000_ra, double *j2000_dec) const {

  SkyCoord this_position = m_ptsSourcesPos.at(srcid);

  *j2000_ra = this_position.first;
  *j2000_dec = this_position.second;

}

void pyToCppModelInterfaceCache::reset() {

  //Empty the cache

  m_extSources.clear();
  m_ptsSources.clear();
  /*
  m_boundingBoxes.clear();
  m_nExtSources = 0;
  m_nPtSources = 0;*/

}

std::vector<double>
pyToCppModelInterfaceCache::getPointSourceFluxes(int srcid, std::vector<double> energies) const {

  throw std::runtime_error("ModelInterfaceCache: point source not yet implemented");

}

int pyToCppModelInterfaceCache::getNumberOfExtendedSources() const {

  // We use the size of bounding boxes and not of m_extSources because the latter
  // could get filled in a second moment
  return m_boundingBoxes.size();

}

std::vector<double>
pyToCppModelInterfaceCache::getExtendedSourceFluxes(int srcid, double j2000_ra, double j2000_dec,
                                               std::vector<double> energies) const {

  SkyCoord sky_pos(j2000_ra, j2000_dec);

  return m_extSources.at(srcid).at(sky_pos);

}

std::vector<double>
pyToCppModelInterfaceCache::getExtendedSourceFluxes_test(int srcid, double j2000_ra, double j2000_dec) const {

  SkyCoord sky_pos(j2000_ra, j2000_dec);

  return m_extSources.at(srcid).at(sky_pos);

}

std::string pyToCppModelInterfaceCache::getPointSourceName(int srcid) const {

  //TODO: implement a mechanism to actually keep the true name

  std::stringstream name;

  name << "Point source " << srcid;

  return name.str();
}

std::string pyToCppModelInterfaceCache::getExtendedSourceName(int srcid) const {

  //TODO: implement a mechanism to actually keep the true name

  std::stringstream name;

  name << "Extended source " << srcid;

  return name.str();
}

void pyToCppModelInterfaceCache::getExtendedSourceBoundaries(int srcid, double *j2000_ra_min,
                                                        double *j2000_ra_max,
                                                        double *j2000_dec_min,
                                                        double *j2000_dec_max) const {

  const BoundingBox *this_boundingBox = &m_boundingBoxes.at(srcid);

  *j2000_ra_min = this_boundingBox->lon_min;
  *j2000_ra_max = this_boundingBox->lon_max;
  *j2000_dec_min = this_boundingBox->lat_min;
  *j2000_dec_max = this_boundingBox->lat_max;

}

}

using namespace threeML;
using namespace boost::python;

//This is needed to wrap the interface (i.e., all methods are virtual)
//contained in ModelInterface.h
struct ModelInterfaceCacheWrap: ModelInterface, wrapper<ModelInterface> {
  int getNumberOfPointSources() const { return this->get_override("getNumberOfPointSources")(); }

  void getPointSourcePosition(int srcid, double *j2000_ra, double *j2000_dec) const {
    this->get_override("getPointSourcePosition")();
  }

  std::vector<double> getPointSourceFluxes(int srcid, std::vector<double> energies) const {
    return this->get_override("getPointSourceFluxes")();
  }

  std::string getPointSourceName(int srcid) const { return this->get_override("getPointSourceName")(); }

  int getNumberOfExtendedSources() const { return this->get_override("getNumberOfExtendedSources")(); }

  std::vector<double> getExtendedSourceFluxes(int srcid, double j2000_ra, double j2000_dec,
                                              std::vector<double> energies) const {
    return this->get_override("getExtendedSourceFluxes")();
  }

  std::string getExtendedSourceName(int srcid) const { return this->get_override("getExtendedSourceName")(); }

  bool isInsideAnyExtendedSource(double j2000_ra, double j2000_dec) const {
    return this->get_override("isInsideAnyExtendedSource")();
  }

  void getExtendedSourceBoundaries(int srcid, double *j2000_ra_min,
                                   double *j2000_ra_max,
                                   double *j2000_dec_min,
                                   double *j2000_dec_max) const { this->get_override("getExtendedSourceBoundaries")(); }
};

template<class T>
struct VecToList {
  static PyObject *convert(const std::vector<T> &vec) {
    boost::python::list *l = new boost::python::list();

    for (size_t i = 0; i < vec.size(); i++)
      (*l).append(vec[i]);

    return l->ptr();
  }
};

BOOST_PYTHON_MODULE (pyModelInterfaceCache) {
  //hello
  to_python_converter<std::vector<double, std::allocator<double> >, VecToList<double> >();

  class_<ModelInterfaceCacheWrap, boost::noncopyable>("ModelInterface")
      .def("getNumberOfPointSources", pure_virtual(&ModelInterface::getNumberOfPointSources))
      .def("getPointSourcePosition", pure_virtual(&ModelInterface::getPointSourcePosition))
      .def("getPointSourceFluxes", pure_virtual(&ModelInterface::getPointSourceFluxes))
      .def("getPointSourceName", pure_virtual(&ModelInterface::getPointSourceName))
      .def("getNumberOfExtendedSources", pure_virtual(&ModelInterface::getNumberOfExtendedSources))
      .def("getExtendedSourceFluxes", pure_virtual(&ModelInterface::getExtendedSourceFluxes))
      .def("getExtendedSourceName", pure_virtual(&ModelInterface::getExtendedSourceName))
      .def("isInsideAnyExtendedSource", pure_virtual(&ModelInterface::isInsideAnyExtendedSource))
      .def("getExtendedSourceBoundaries", pure_virtual(&ModelInterface::getExtendedSourceBoundaries));

  numeric::array::set_module_and_type("numpy", "ndarray");

  class_<pyToCppModelInterfaceCache, bases<ModelInterface> >("pyToCppModelInterfaceCache", init< >())
      .def("getNumberOfPointSources", &pyToCppModelInterfaceCache::getNumberOfPointSources)
      .def("getPointSourcePosition", &pyToCppModelInterfaceCache::getPointSourcePosition)
      .def("getPointSourceFluxes", &pyToCppModelInterfaceCache::getPointSourceFluxes)
      .def("getPointSourceName", &pyToCppModelInterfaceCache::getPointSourceName)
      .def("getNumberOfExtendedSources", &pyToCppModelInterfaceCache::getNumberOfExtendedSources)
      .def("getExtendedSourceFluxes", &pyToCppModelInterfaceCache::getExtendedSourceFluxes)
      .def("getExtendedSourceName", &pyToCppModelInterfaceCache::getExtendedSourceName)
      .def("isInsideAnyExtendedSource", &pyToCppModelInterfaceCache::isInsideAnyExtendedSource)
      .def("getExtendedSourceBoundaries", &pyToCppModelInterfaceCache::getExtendedSourceBoundaries)
      .def("setExtSourceBoundaries", &pyToCppModelInterfaceCache::setExtSourceBoundaries)
      .def("setExtSourceCube",&pyToCppModelInterfaceCache::setExtSourceCube)
      .def("getExtendedSourceFluxes_test",&pyToCppModelInterfaceCache::getExtendedSourceFluxes_test)
      .def("reset",&pyToCppModelInterfaceCache::reset);
}
<|endoftext|>