<commit_before>class Barrier {

private:
	uint N_THREADS;
	//uint waiting_threads;

	uint waiting_threads_counts[2];
	uint current_counter;

	ErlNifMutex* mtx;
	ErlNifCond* cond;

public:
	explicit Barrier(uint n_Threads) {
		N_THREADS = n_Threads;
		waiting_threads_counts[0] = waiting_threads_counts[1] = 0;
		current_counter = 0;

		mtx = enif_mutex_create((char*) "map_load_thread_cond_mtx");
		cond = enif_cond_create((char*) "map_load_thread_cond");

		//std::cerr << "Barrier("<< N_THREADS <<") CREATED"<<endl;
	}
	~Barrier() {
		enif_cond_destroy(cond);
		enif_mutex_destroy(mtx);
	}

	void await(){

		enif_mutex_lock(mtx);

		uint local_counter = current_counter;

		waiting_threads_counts[local_counter]++;
		//std::cerr << "await(): waiting_threads_counts[local_counter]++: "<< waiting_threads_counts[local_counter] <<endl;

		if(waiting_threads_counts[local_counter] < N_THREADS) {
			//std::cerr << "await(): Barrier NOT full" <<endl;

			while(waiting_threads_counts[local_counter] < N_THREADS) {
			//	std::cerr << "await(): cond_wait waiting_threads_counts[local_counter]: "<< waiting_threads_counts[local_counter] <<endl;
				enif_cond_wait(cond, mtx);
			}
		}
		else {
			//std::cerr << "await(): Barrier FULL. waiting_threads:" <<waiting_threads_counts[local_counter] << " broadcast!" <<endl;

			current_counter ^= 1;
			waiting_threads_counts[current_counter] = 0;

			enif_cond_broadcast(cond);
		}

	//	std::cerr << "await(): END" <<endl;
		enif_mutex_unlock(mtx);
	}

};

/*array must be big enough to contain list.length elements*/
uint list_to_double_arrayN(ErlNifEnv *env, ERL_NIF_TERM list, double* array, uint arrayLen, ERL_NIF_TERM* lastListCell) {

	if(array == NULL)
		return 0;

	uint len = 0;

	if(enif_is_list(env, list)) { //enif_get_list_length(env, list, &len) <---- O(n)!!!

		ERL_NIF_TERM curr_cell = list;

		uint i = 0;
		for(i = 0; enif_is_list(env, curr_cell) && i < arrayLen; i++) {

			ERL_NIF_TERM hd, tl;
			if(!enif_get_list_cell(env, curr_cell, &hd, &tl))
				break;//list is empty

			if(!(enif_get_double(env, hd, &(array[i]) ))) {
				std::cerr << "DEBUG: list_to_double_arrayN - Error: attempt to read float from something else!" << std::endl;
			}
			curr_cell = tl;

		}

		if(lastListCell != NULL) //user requested the term denoting the last cell
			*lastListCell = curr_cell;

		return i; //TODO check for off by one

	} else { //term "list" is not a list

		#ifdef DEBUG
		std::cerr << "DEBUG: list_to_double_arrayN - Error: trying to convert a non list as a list"<< std::endl ;
		#endif

		return 0;
	}
}

uint sync_list_to_double_arrayN(ErlNifEnv *env, ErlNifMutex *mtx, ERL_NIF_TERM list, double* array, uint arrayLen, ERL_NIF_TERM* lastListCell) {

	enif_mutex_lock(mtx);

//	char msg[256];
//	sprintf(msg, "DEBUG: sync_list_to_double_arrayN dentro. *lastListCell: %lu\n", *lastListCell);
//	cerr<< msg;
//
	uint result = list_to_double_arrayN(env, list, array,  arrayLen, lastListCell);
//
//	cerr << "[";
//	for(int i = 0; i< arrayLen; ++i)
//		cerr << array[i] << ", ";
//	cerr << "]"<< endl;
//
//	sprintf(msg, "DEBUG: sync_list_to_double_arrayN dentro. *lastListCell: %lu\n", *lastListCell);
//	cerr << msg;

	enif_mutex_unlock(mtx);

	return result;

}

void list_to_double_array(ErlNifEnv *env, ERL_NIF_TERM list, uint listLen, double* array) { //TODO scorre la lista 2 volte

	if(array == NULL)
		return;

	uint len = 0;

	if(enif_is_list(env, list)) {

		list_to_double_arrayN(env, list, array, listLen, NULL);
	}

}

ERL_NIF_TERM double_array_to_list(ErlNifEnv *env, double* array, size_t array_size) {

	if(array == NULL)
		return ATOM(error);

	ERL_NIF_TERM* floatTermArray =
			(ERL_NIF_TERM*) enif_alloc(sizeof(ERL_NIF_TERM) * array_size);

	for(uint i = 0; i < array_size; i++)
		floatTermArray[i] = enif_make_double(env, array[i]);

	ERL_NIF_TERM res = enif_make_list_from_array(env, floatTermArray, array_size);

	enif_free(floatTermArray);

	return res;
}

/*returns a string containing the content of the file at filePath
 * otherwise "NULL".*/
string readFromFileStr(char* filePath) {

	ifstream file(filePath, ios::in);
	if (!file.is_open()) {
		cerr << "Failed to open file for reading: " << filePath << endl;
		return "NULL";
	}

	ostringstream oss;
	oss << file.rdbuf();

	return oss.str();
}

/*returns a dinamically allocated string containing the content of the file at filePath
 * otherwise NULL.
 * The returned sting must be enif_free'd when not needed.
 * */

char* readFromFile(char* filePath) {

	string srcStdStr = readFromFileStr(filePath);

	char* toReturn = (char*) enif_alloc(srcStdStr.length()+1);

	return strcpy(toReturn, srcStdStr.c_str());

}

#define MIN(a, b) ((a < b) ? a : b)

int inline isPow2(unsigned int v) { return v && !(v & (v - 1));}

/*!
 * \brief A helper to return a value that is nearest value that is power of 2.
 *
 * \param x The input number for which we need to find the nearest value that is power of 2.
 * \return The nearest value that is power of 2.
 */
unsigned int nextPow2( unsigned int x )
{
    --x;
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    return x+1;
}

// Round Up Division function
size_t roundUp(uint group_size, uint global_size)
{
    uint r = global_size % group_size;
    if(r == 0)
        return global_size;
    else
        return global_size + group_size - r;
}

/*!
 * Compute the number of threads and blocks to use for the REDUCTION kernel.
 * We set threads / block to the minimum of maxThreads and n/2 where n is
 * problem size. We observe the maximum specified number of blocks, because
 * each kernel thread can process more than 1 elements.
 *
 * \param n Problem size.
 * \param maxBlocks Maximum number of blocks that can be used.
 * \param maxThreads Maximum number of threads that can be used.
 * \param blocks An output parameter passed by reference. Specify number of blocks to be used.
 * \param threads An output parameter passed by reference. Specify number of threads to be used.
 */
void getNumBlocksAndThreads(int n, int maxBlocks, int maxThreads, long unsigned int &blocks, long unsigned int &threads)
{
        threads = (n < maxThreads*2) ? nextPow2((n + 1)/ 2) : maxThreads;
        blocks = (n + (threads * 2 - 1)) / (threads * 2);

        if(maxBlocks > 0)
        	blocks = MIN(maxBlocks, blocks);
}

/*!
 *  It finds all instances of a string in another string and replaces it with
 *  a third string.
 *
 *  \param text A \p std::string which is searched.
 *  \param find The \p std::string which is searched for and replaced.
 *  \param replace The replacement \p std::string.
 */
void replaceTextInString(std::string& text, std::string find, std::string replace)
{
        std::string::size_type pos=0;
        while((pos = text.find(find, pos)) != std::string::npos)
        {
            text.erase(pos, find.length());
            text.insert(pos, replace);
            pos+=replace.length();
        }
}

<commit_msg>Cleanup<commit_after>/**
 * A thread synchronization barrier implemented using erl_nif synch facilities
 * /
class Barrier {

private:
	uint N_THREADS;

	uint waiting_threads_counts[2];
	uint current_counter;

	ErlNifMutex* mtx;
	ErlNifCond* cond;

public:
	explicit Barrier(uint n_Threads) {
		N_THREADS = n_Threads;
		waiting_threads_counts[0] = waiting_threads_counts[1] = 0;
		current_counter = 0;

		mtx = enif_mutex_create((char*) "map_load_thread_cond_mtx");
		cond = enif_cond_create((char*) "map_load_thread_cond");

		//std::cerr << "Barrier("<< N_THREADS <<") CREATED"<<endl;
	}
	~Barrier() {
		enif_cond_destroy(cond);
		enif_mutex_destroy(mtx);
	}

	void await(){

		enif_mutex_lock(mtx);

		uint local_counter = current_counter;

		waiting_threads_counts[local_counter]++;
		//std::cerr << "await(): waiting_threads_counts[local_counter]++: "<< waiting_threads_counts[local_counter] <<endl;

		if(waiting_threads_counts[local_counter] < N_THREADS) {
			//std::cerr << "await(): Barrier NOT full" <<endl;

			while(waiting_threads_counts[local_counter] < N_THREADS) {
			//	std::cerr << "await(): cond_wait waiting_threads_counts[local_counter]: "<< waiting_threads_counts[local_counter] <<endl;
				enif_cond_wait(cond, mtx);
			}
		}
		else {
			//std::cerr << "await(): Barrier FULL. waiting_threads:" <<waiting_threads_counts[local_counter] << " broadcast!" <<endl;

			current_counter ^= 1;
			waiting_threads_counts[current_counter] = 0;

			enif_cond_broadcast(cond);
		}

	//	std::cerr << "await(): END" <<endl;
		enif_mutex_unlock(mtx);
	}

};

/*array must be big enough to contain list.length elements*/
uint list_to_double_arrayN(ErlNifEnv *env, ERL_NIF_TERM list, double* array, uint arrayLen, ERL_NIF_TERM* lastListCell) {

	if(array == NULL)
		return 0;

	uint len = 0;

	if(enif_is_list(env, list)) {

		ERL_NIF_TERM curr_cell = list;

		uint i = 0;
		for(i = 0; enif_is_list(env, curr_cell) && i < arrayLen; i++) {

			ERL_NIF_TERM hd, tl;
			if(!enif_get_list_cell(env, curr_cell, &hd, &tl))
				break;//list is empty

			if(!(enif_get_double(env, hd, &(array[i]) ))) {
				std::cerr << "DEBUG: list_to_double_arrayN - Error: attempt to read float from something else!" << std::endl;
			}
			curr_cell = tl;

		}

		if(lastListCell != NULL) //user requested the term denoting the last cell
			*lastListCell = curr_cell;

		return i;

	} else { //term "list" is not a list

		#ifdef DEBUG
		std::cerr << "DEBUG: list_to_double_arrayN - Error: trying to convert a non list as a list"<< std::endl ;
		#endif

		return 0;
	}
}

uint sync_list_to_double_arrayN(ErlNifEnv *env, ErlNifMutex *mtx, ERL_NIF_TERM list, double* array, uint arrayLen, ERL_NIF_TERM* lastListCell) {

	enif_mutex_lock(mtx);

	uint result = list_to_double_arrayN(env, list, array,  arrayLen, lastListCell);

	enif_mutex_unlock(mtx);

	return result;

}

void list_to_double_array(ErlNifEnv *env, ERL_NIF_TERM list, uint listLen, double* array) { //TODO scorre la lista 2 volte

	if(array == NULL)
		return;

	uint len = 0;

	if(enif_is_list(env, list)) {

		list_to_double_arrayN(env, list, array, listLen, NULL);
	}

}

ERL_NIF_TERM double_array_to_list(ErlNifEnv *env, double* array, size_t array_size) {

	if(array == NULL)
		return ATOM(error);

	ERL_NIF_TERM* floatTermArray =
			(ERL_NIF_TERM*) enif_alloc(sizeof(ERL_NIF_TERM) * array_size);

	for(uint i = 0; i < array_size; i++)
		floatTermArray[i] = enif_make_double(env, array[i]);

	ERL_NIF_TERM res = enif_make_list_from_array(env, floatTermArray, array_size);

	enif_free(floatTermArray);

	return res;
}

/*returns a string containing the content of the file at filePath
 * otherwise "NULL".*/
string readFromFileStr(char* filePath) {

	ifstream file(filePath, ios::in);
	if (!file.is_open()) {
		cerr << "Failed to open file for reading: " << filePath << endl;
		return "NULL";
	}

	ostringstream oss;
	oss << file.rdbuf();

	return oss.str();
}

/*returns a dinamically allocated string containing the content of the file at filePath
 * otherwise NULL.
 * The returned sting must be enif_free'd when not needed.
 * */
char* readFromFile(char* filePath) {

	string srcStdStr = readFromFileStr(filePath);

	char* toReturn = (char*) enif_alloc(srcStdStr.length()+1);

	return strcpy(toReturn, srcStdStr.c_str());

}

#define MIN(a, b) ((a < b) ? a : b)

int inline isPow2(unsigned int v) { return v && !(v & (v - 1));}

/*
 * Return a value that is nearest value that is power of 2.
 */
unsigned int nextPow2( unsigned int x )
{
    --x;
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    return x+1;
}

// Round Up Division function
size_t roundUp(uint group_size, uint global_size)
{
    uint r = global_size % group_size;
    if(r == 0)
        return global_size;
    else
        return global_size + group_size - r;
}

/*!
 * Compute the number of threads and blocks to use for the REDUCTION kernel.
 * We set threads / block to the minimum of maxThreads and n/2 where n is
 * problem size. We observe the maximum specified number of blocks, because
 * each kernel thread can process more than 1 elements.
 *
 * \param n Problem size.
 * \param maxBlocks Maximum number of blocks that can be used.
 * \param maxThreads Maximum number of threads that can be used.
 * \param blocks An output parameter passed by reference. Specify number of blocks to be used.
 * \param threads An output parameter passed by reference. Specify number of threads to be used.
 */
void getNumBlocksAndThreads(int n, int maxBlocks, int maxThreads, long unsigned int &blocks, long unsigned int &threads)
{
        threads = (n < maxThreads*2) ? nextPow2((n + 1)/ 2) : maxThreads;
        blocks = (n + (threads * 2 - 1)) / (threads * 2);

        if(maxBlocks > 0)
        	blocks = MIN(maxBlocks, blocks);
}

/*
 *  It finds all instances of a string in another string and replaces it with
 *  a third string.
 *
 */
void replaceTextInString(std::string& text, std::string find, std::string replace)
{
        std::string::size_type pos=0;
        while((pos = text.find(find, pos)) != std::string::npos)
        {
            text.erase(pos, find.length());
            text.insert(pos, replace);
            pos+=replace.length();
        }
}

<|endoftext|>


<commit_before>#include "visgraph.hpp"
#include "../utils/utils.hpp"
#include <cstring>
#include <cstdio>
#include <cerrno>

static void randpolys(std::vector<Polygon>&);
static double rnddbl(double, double);
static void usage(void);

static unsigned int Npolys = 500;
static unsigned int Maxverts = 8;
static double Minrad = 0.05;
static double Maxrad = 0.075;
static const char *outfile;

int main(int argc, char *argv[]) {
	for (int i = 1; i < argc; i++) {
		if (strcmp(argv[i], "-h") == 0)
			usage();
		else if (i < argc - 1 && strcmp(argv[i], "-n") == 0)
			Npolys = strtoll(argv[++i], NULL, 10);
		else if (i < argc - 1 && strcmp(argv[i], "-v") == 0)
			Maxverts = strtoll(argv[++i], NULL, 10);
		else if (i < argc - 1 && strcmp(argv[i], "-o") == 0)
			outfile = argv[++i];
		else if (i < argc - 1 && strcmp(argv[i], "-m") == 0)
			Minrad = strtod(argv[++i], NULL);
		else if (i < argc - 1 && strcmp(argv[i], "-x") == 0)
			Maxrad = strtod(argv[++i], NULL);
	}

	std::vector<Polygon> polys;
	randpolys(polys);

	VisGraph graph(polys);
	if (outfile) {
		FILE *f = fopen(outfile, "w");
		if (!f)
			fatalx(errno, "Failed to open %s:", outfile);
		graph.output(stdout);
		fclose(f);
	} else {
		graph.output(stdout);
	}

	return 0;
}

static void randpolys(std::vector<Polygon> &polys) {
	for (unsigned int i = 0; i < Npolys; i++) {
redo:
		double r = rnddbl(Minrad, Maxrad);
		double x = rnddbl(r, 1 - r);
		double y = rnddbl(r, 1 - r);

		assert (x >= 0.0);
		assert (y >= 0.0);
		assert (r >= 0.0);

		Polygon p = Polygon::random(randgen.integer(3, Maxverts), x, y, r);

		for (unsigned int i = 0; i < polys.size(); i++) {
			if (polys[i].bbox.isect(p.bbox))
				goto redo;
		}

		polys.push_back(p);
	}
}

static double rnddbl(double min, double max) {
	assert (max > min);
	return randgen.real() * (max - min) + min;
}

static void usage(void) {
	puts("Usage: rand [options]");
	puts("\nPlaces random polygons in the unit square.  Computes the");
	puts("visibility graph and prints the instance to standard output");
	puts("\nOptions:");
	puts("	-h	prints this help message");
	puts("	-n <num>	specify the number of polygons (default: 500)");
	puts("	-v <num>	specify the max number of vertices (default: 8)");
	puts("	-o <file>	output to the specified file instead of standard output");
	puts("	-m <num>	minimum polygon radius (default: 0.05)");
	puts("	-x <num>	maximum polygon radius (default: 0.075)");
	exit(0);
}<commit_msg>visnav: better option names for rand and output statistics.<commit_after>#include "visgraph.hpp"
#include "../utils/utils.hpp"
#include <cstring>
#include <cstdio>
#include <cerrno>

static void randpolys(std::vector<Polygon>&);
static double rnddbl(double, double);
static void usage(void);

static unsigned int Npolys = 500;
static unsigned int Maxverts = 8;
static double Minrad = 0.05;
static double Maxrad = 0.075;
static const char *outfile;
static bool stats;

int main(int argc, char *argv[]) {
	for (int i = 1; i < argc; i++) {
		if (strcmp(argv[i], "-h") == 0)
			usage();
		else if (i < argc - 1 && strcmp(argv[i], "-o") == 0)
			outfile = argv[++i];
		else if (i < argc - 1 && strcmp(argv[i], "-npolys") == 0)
			Npolys = strtoll(argv[++i], NULL, 10);
		else if (i < argc - 1 && strcmp(argv[i], "-nverts") == 0)
			Maxverts = strtoll(argv[++i], NULL, 10);
		else if (i < argc - 1 && strcmp(argv[i], "-minrad") == 0)
			Minrad = strtod(argv[++i], NULL);
		else if (i < argc - 1 && strcmp(argv[i], "-maxrad") == 0)
			Maxrad = strtod(argv[++i], NULL);
		else if (strcmp(argv[i], "-stats") == 0)
			stats = true;
	}

	if (stats)
		fprintf(stderr, "seed: %lu\n", randgen.seed());

	std::vector<Polygon> polys;
	double start = walltime();
	randpolys(polys);
	if (stats)
		fprintf(stderr, "created %u polys in %gs\n", Npolys, walltime() - start);

	start = walltime();
	VisGraph graph(polys);
	if (stats)
		fprintf(stderr, "visability graph generated in %gs\n", walltime() - start);

	if (outfile) {
		FILE *f = fopen(outfile, "w");
		if (!f)
			fatalx(errno, "Failed to open %s:", outfile);
		graph.output(stdout);
		fclose(f);
	} else {
		graph.output(stdout);
	}

	return 0;
}

static void randpolys(std::vector<Polygon> &polys) {
	for (unsigned int i = 0; i < Npolys; i++) {
redo:
		double r = rnddbl(Minrad, Maxrad);
		double x = rnddbl(r, 1 - r);
		double y = rnddbl(r, 1 - r);

		assert (x >= 0.0);
		assert (y >= 0.0);
		assert (r >= 0.0);

		Polygon p = Polygon::random(randgen.integer(3, Maxverts), x, y, r);

		for (unsigned int i = 0; i < polys.size(); i++) {
			if (polys[i].bbox.isect(p.bbox))
				goto redo;
		}

		polys.push_back(p);
	}
}

static double rnddbl(double min, double max) {
	assert (max > min);
	return randgen.real() * (max - min) + min;
}

static void usage(void) {
	puts("Usage: rand [options]");
	puts("\nPlaces random polygons in the unit square.  Computes the");
	puts("visibility graph and prints the instance to standard output");
	puts("\nOptions:");
	puts("	-h	prints this help message");
	puts("	-o <file>	output to the specified file instead of standard output");
	puts("	-npolys <num>	specify the number of polygons (default: 500)");
	puts("	-nverts <num>	specify the max number of vertices (default: 8)");
	puts("	-minrad <num>	minimum polygon radius (default: 0.05)");
	puts("	-maxrad <num>	maximum polygon radius (default: 0.075)");
	puts("	-stats	print some stastics to standard error");
	exit(0);
}<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/x509_certificate.h"

#include <CommonCrypto/CommonDigest.h>
#include <time.h>

#include "base/logging.h"
#include "base/pickle.h"
#include "net/base/cert_status_flags.h"
#include "net/base/ev_root_ca_metadata.h"
#include "net/base/net_errors.h"

using base::Time;

namespace net {

namespace {

inline bool CSSMOIDEqual(const CSSM_OID* oid1, const CSSM_OID* oid2) {
  return oid1->Length == oid2->Length &&
      (memcmp(oid1->Data, oid2->Data, oid1->Length) == 0);
}

void ParsePrincipal(const CSSM_X509_NAME* name,
                    X509Certificate::Principal* principal) {
  std::vector<std::string> common_names, locality_names, state_names,
      country_names;

  // TODO(jcampan): add business_category and serial_number.
  const CSSM_OID* kOIDs[] = { &CSSMOID_CommonName,
                              &CSSMOID_LocalityName,
                              &CSSMOID_StateProvinceName,
                              &CSSMOID_CountryName,
                              &CSSMOID_StreetAddress,
                              &CSSMOID_OrganizationName,
                              &CSSMOID_OrganizationalUnitName,
                              &CSSMOID_DNQualifier };  // This should be "DC"
                                                       // but is undoubtedly
                                                       // wrong. TODO(avi):
                                                       // Find the right OID.

  std::vector<std::string>* values[] = {
      &common_names, &locality_names,
      &state_names, &country_names,
      &(principal->street_addresses),
      &(principal->organization_names),
      &(principal->organization_unit_names),
      &(principal->domain_components) };
  DCHECK(arraysize(kOIDs) == arraysize(values));

  for (size_t rdn = 0; rdn < name->numberOfRDNs; ++rdn) {
    CSSM_X509_RDN rdn_struct = name->RelativeDistinguishedName[rdn];
    for (size_t pair = 0; pair < rdn_struct.numberOfPairs; ++pair) {
      CSSM_X509_TYPE_VALUE_PAIR pair_struct =
          rdn_struct.AttributeTypeAndValue[pair];
      for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) {
        if (CSSMOIDEqual(&pair_struct.type, kOIDs[oid])) {
          std::string value =
              std::string(reinterpret_cast<std::string::value_type*>
                              (pair_struct.value.Data),
                          pair_struct.value.Length);
          values[oid]->push_back(value);
          break;
        }
      }
    }
  }

  // We don't expect to have more than one CN, L, S, and C.
  std::vector<std::string>* single_value_lists[4] = {
      &common_names, &locality_names, &state_names, &country_names };
  std::string* single_values[4] = {
      &principal->common_name, &principal->locality_name,
      &principal->state_or_province_name, &principal->country_name };
  for (size_t i = 0; i < arraysize(single_value_lists); ++i) {
    DCHECK(single_value_lists[i]->size() <= 1);
    if (single_value_lists[i]->size() > 0)
      *(single_values[i]) = (*(single_value_lists[i]))[0];
  }
}

OSStatus GetCertFieldsForOID(X509Certificate::OSCertHandle cert_handle,
                             CSSM_OID oid, uint32* num_of_fields,
                             CSSM_FIELD_PTR* fields) {
  *num_of_fields = 0;
  *fields = NULL;

  CSSM_DATA cert_data;
  OSStatus status = SecCertificateGetData(cert_handle, &cert_data);
  if (status)
    return status;

  CSSM_CL_HANDLE cl_handle;
  status = SecCertificateGetCLHandle(cert_handle, &cl_handle);
  if (status)
    return status;

  status = CSSM_CL_CertGetAllFields(cl_handle, &cert_data, num_of_fields,
                                    fields);
  return status;
}

void GetCertGeneralNamesForOID(X509Certificate::OSCertHandle cert_handle,
                               CSSM_OID oid, CE_GeneralNameType name_type,
                               std::vector<std::string>* result) {
  uint32 num_of_fields;
  CSSM_FIELD_PTR fields;
  OSStatus status = GetCertFieldsForOID(cert_handle, oid, &num_of_fields,
                                        &fields);
  if (status)
    return;

  for (size_t field = 0; field < num_of_fields; ++field) {
    if (CSSMOIDEqual(&fields[field].FieldOid, &oid)) {
      CSSM_X509_EXTENSION_PTR cssm_ext =
          (CSSM_X509_EXTENSION_PTR)fields[field].FieldValue.Data;
      CE_GeneralNames* alt_name =
          (CE_GeneralNames*) cssm_ext->value.parsedValue;

      for (size_t name = 0; name < alt_name->numNames; ++name) {
        const CE_GeneralName& name_struct = alt_name->generalName[name];
        // For future extension: We're assuming that these values are of types
        // GNT_RFC822Name, GNT_DNSName or GNT_URI, all of which are encoded as
        // IA5String. In general, we should be switching off
        // |name_struct.nameType| and doing type-appropriate conversions. See
        // certextensions.h and the comment immediately preceding
        // CE_GeneralNameType for more information.
        DCHECK(name_struct.nameType == GNT_RFC822Name ||
               name_struct.nameType == GNT_DNSName ||
               name_struct.nameType == GNT_URI);
        if (name_struct.nameType == name_type) {
          const CSSM_DATA& name_data = name_struct.name;
          std::string value =
          std::string(reinterpret_cast<std::string::value_type*>
                      (name_data.Data),
                      name_data.Length);
          result->push_back(value);
        }
      }
    }
  }
}

void GetCertDateForOID(X509Certificate::OSCertHandle cert_handle,
                       CSSM_OID oid, Time* result) {
  *result = Time::Time();

  uint32 num_of_fields;
  CSSM_FIELD_PTR fields;
  OSStatus status = GetCertFieldsForOID(cert_handle, oid, &num_of_fields,
                                        &fields);
  if (status)
    return;

  for (size_t field = 0; field < num_of_fields; ++field) {
    if (CSSMOIDEqual(&fields[field].FieldOid, &oid)) {
      CSSM_X509_TIME* x509_time =
          reinterpret_cast<CSSM_X509_TIME *>(fields[field].FieldValue.Data);
      std::string time_string =
          std::string(reinterpret_cast<std::string::value_type*>
                      (x509_time->time.Data),
                      x509_time->time.Length);

      DCHECK(x509_time->timeType == BER_TAG_UTC_TIME ||
             x509_time->timeType == BER_TAG_GENERALIZED_TIME);

      struct tm time;
      const char* parse_string;
      if (x509_time->timeType == BER_TAG_UTC_TIME)
        parse_string = "%y%m%d%H%M%SZ";
      else if (x509_time->timeType == BER_TAG_GENERALIZED_TIME)
        parse_string = "%y%m%d%H%M%SZ";
      else {
        // Those are the only two BER tags for time; if neither are used then
        // this is a rather broken cert.
        return;
      }

      strptime(time_string.c_str(), parse_string, &time);

      Time::Exploded exploded;
      exploded.year         = time.tm_year + 1900;
      exploded.month        = time.tm_mon + 1;
      exploded.day_of_week  = time.tm_wday;
      exploded.day_of_month = time.tm_mday;
      exploded.hour         = time.tm_hour;
      exploded.minute       = time.tm_min;
      exploded.second       = time.tm_sec;
      exploded.millisecond  = 0;

      *result = Time::FromUTCExploded(exploded);
      break;
    }
  }
}

}  // namespace

void X509Certificate::Initialize() {
  const CSSM_X509_NAME* name;
  OSStatus status = SecCertificateGetSubject(cert_handle_, &name);
  if (!status) {
    ParsePrincipal(name, &subject_);
  }
  status = SecCertificateGetIssuer(cert_handle_, &name);
  if (!status) {
    ParsePrincipal(name, &issuer_);
  }

  GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotBefore,
                    &valid_start_);
  GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotAfter,
                    &valid_expiry_);

  fingerprint_ = CalculateFingerprint(cert_handle_);

  // Store the certificate in the cache in case we need it later.
  X509Certificate::Cache::GetInstance()->Insert(this);
}

// static
X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle,
                                                   void** pickle_iter) {
  const char* data;
  int length;
  if (!pickle.ReadData(pickle_iter, &data, &length))
    return NULL;

  return CreateFromBytes(data, length);
}

void X509Certificate::Persist(Pickle* pickle) {
  CSSM_DATA cert_data;
  OSStatus status = SecCertificateGetData(cert_handle_, &cert_data);
  if (status) {
    NOTREACHED();
    return;
  }

  pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), cert_data.Length);
}

bool X509Certificate::HasExpired() const {
  NOTIMPLEMENTED();
  return false;
}

void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
  dns_names->clear();

  GetCertGeneralNamesForOID(cert_handle_, CSSMOID_SubjectAltName, GNT_DNSName,
                            dns_names);

  if (dns_names->empty())
    dns_names->push_back(subject_.common_name);
}

int X509Certificate::Verify(const std::string& hostname,
                            bool rev_checking_enabled,
                            CertVerifyResult* verify_result) const {
  NOTIMPLEMENTED();
  return ERR_NOT_IMPLEMENTED;
}

// Returns true if the certificate is an extended-validation certificate.
//
// The certificate has already been verified by the HTTP library.  cert_status
// represents the result of that verification.  This function performs
// additional checks of the certificatePolicies extensions of the certificates
// in the certificate chain according to Section 7 (pp. 11-12) of the EV
// Certificate Guidelines Version 1.0 at
// http://cabforum.org/EV_Certificate_Guidelines.pdf.
bool X509Certificate::IsEV(int cert_status) const {
  // TODO(avi): implement this
  NOTIMPLEMENTED();
  return false;
}

// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
    const char* data, int length) {
  CSSM_DATA cert_data;
  cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data));
  cert_data.Length = length;

  OSCertHandle cert_handle = NULL;
  OSStatus status = SecCertificateCreateFromData(&cert_data,
                                                 CSSM_CERT_X_509v3,
                                                 CSSM_CERT_ENCODING_BER,
                                                 &cert_handle);
  if (status)
    return NULL;

  return cert_handle;
}

// static
void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
  CFRelease(cert_handle);
}

// static
X509Certificate::Fingerprint X509Certificate::CalculateFingerprint(
    OSCertHandle cert) {
  Fingerprint sha1;
  memset(sha1.data, 0, sizeof(sha1.data));

  CSSM_DATA cert_data;
  OSStatus status = SecCertificateGetData(cert, &cert_data);
  if (status)
    return sha1;

  DCHECK(NULL != cert_data.Data);
  DCHECK(0 != cert_data.Length);

  CC_SHA1(cert_data.Data, cert_data.Length, sha1.data);

  return sha1;
}

}  // namespace net
<commit_msg>Fix leak in cert code that Valgrind found.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/x509_certificate.h"

#include <CommonCrypto/CommonDigest.h>
#include <time.h>

#include "base/logging.h"
#include "base/pickle.h"
#include "net/base/cert_status_flags.h"
#include "net/base/ev_root_ca_metadata.h"
#include "net/base/net_errors.h"

using base::Time;

namespace net {

namespace {

inline bool CSSMOIDEqual(const CSSM_OID* oid1, const CSSM_OID* oid2) {
  return oid1->Length == oid2->Length &&
      (memcmp(oid1->Data, oid2->Data, oid1->Length) == 0);
}

void ParsePrincipal(const CSSM_X509_NAME* name,
                    X509Certificate::Principal* principal) {
  std::vector<std::string> common_names, locality_names, state_names,
      country_names;

  // TODO(jcampan): add business_category and serial_number.
  const CSSM_OID* kOIDs[] = { &CSSMOID_CommonName,
                              &CSSMOID_LocalityName,
                              &CSSMOID_StateProvinceName,
                              &CSSMOID_CountryName,
                              &CSSMOID_StreetAddress,
                              &CSSMOID_OrganizationName,
                              &CSSMOID_OrganizationalUnitName,
                              &CSSMOID_DNQualifier };  // This should be "DC"
                                                       // but is undoubtedly
                                                       // wrong. TODO(avi):
                                                       // Find the right OID.

  std::vector<std::string>* values[] = {
      &common_names, &locality_names,
      &state_names, &country_names,
      &(principal->street_addresses),
      &(principal->organization_names),
      &(principal->organization_unit_names),
      &(principal->domain_components) };
  DCHECK(arraysize(kOIDs) == arraysize(values));

  for (size_t rdn = 0; rdn < name->numberOfRDNs; ++rdn) {
    CSSM_X509_RDN rdn_struct = name->RelativeDistinguishedName[rdn];
    for (size_t pair = 0; pair < rdn_struct.numberOfPairs; ++pair) {
      CSSM_X509_TYPE_VALUE_PAIR pair_struct =
          rdn_struct.AttributeTypeAndValue[pair];
      for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) {
        if (CSSMOIDEqual(&pair_struct.type, kOIDs[oid])) {
          std::string value =
              std::string(reinterpret_cast<std::string::value_type*>
                              (pair_struct.value.Data),
                          pair_struct.value.Length);
          values[oid]->push_back(value);
          break;
        }
      }
    }
  }

  // We don't expect to have more than one CN, L, S, and C.
  std::vector<std::string>* single_value_lists[4] = {
      &common_names, &locality_names, &state_names, &country_names };
  std::string* single_values[4] = {
      &principal->common_name, &principal->locality_name,
      &principal->state_or_province_name, &principal->country_name };
  for (size_t i = 0; i < arraysize(single_value_lists); ++i) {
    DCHECK(single_value_lists[i]->size() <= 1);
    if (single_value_lists[i]->size() > 0)
      *(single_values[i]) = (*(single_value_lists[i]))[0];
  }
}

struct CSSMFields {
  CSSMFields() : cl_handle(NULL), num_of_fields(0), fields(NULL) {}
  ~CSSMFields() {
    if (cl_handle)
      CSSM_CL_FreeFields(cl_handle, num_of_fields, &fields);
  }

  CSSM_CL_HANDLE cl_handle;
  uint32 num_of_fields;
  CSSM_FIELD_PTR fields;
};

OSStatus GetCertFields(X509Certificate::OSCertHandle cert_handle,
                       CSSMFields* fields) {
  DCHECK(cert_handle);
  DCHECK(fields);

  CSSM_DATA cert_data;
  OSStatus status = SecCertificateGetData(cert_handle, &cert_data);
  if (status)
    return status;

  status = SecCertificateGetCLHandle(cert_handle, &fields->cl_handle);
  if (status) {
    DCHECK(!fields->cl_handle);
    return status;
  }

  status = CSSM_CL_CertGetAllFields(fields->cl_handle, &cert_data,
                                    &fields->num_of_fields, &fields->fields);
  return status;
}

void GetCertGeneralNamesForOID(X509Certificate::OSCertHandle cert_handle,
                               CSSM_OID oid, CE_GeneralNameType name_type,
                               std::vector<std::string>* result) {
  CSSMFields fields;
  OSStatus status = GetCertFields(cert_handle, &fields);
  if (status)
    return;

  for (size_t field = 0; field < fields.num_of_fields; ++field) {
    if (CSSMOIDEqual(&fields.fields[field].FieldOid, &oid)) {
      CSSM_X509_EXTENSION_PTR cssm_ext =
          (CSSM_X509_EXTENSION_PTR)fields.fields[field].FieldValue.Data;
      CE_GeneralNames* alt_name =
          (CE_GeneralNames*) cssm_ext->value.parsedValue;

      for (size_t name = 0; name < alt_name->numNames; ++name) {
        const CE_GeneralName& name_struct = alt_name->generalName[name];
        // For future extension: We're assuming that these values are of types
        // GNT_RFC822Name, GNT_DNSName or GNT_URI, all of which are encoded as
        // IA5String. In general, we should be switching off
        // |name_struct.nameType| and doing type-appropriate conversions. See
        // certextensions.h and the comment immediately preceding
        // CE_GeneralNameType for more information.
        DCHECK(name_struct.nameType == GNT_RFC822Name ||
               name_struct.nameType == GNT_DNSName ||
               name_struct.nameType == GNT_URI);
        if (name_struct.nameType == name_type) {
          const CSSM_DATA& name_data = name_struct.name;
          std::string value =
          std::string(reinterpret_cast<std::string::value_type*>
                      (name_data.Data),
                      name_data.Length);
          result->push_back(value);
        }
      }
    }
  }
}

void GetCertDateForOID(X509Certificate::OSCertHandle cert_handle,
                       CSSM_OID oid, Time* result) {
  *result = Time::Time();

  CSSMFields fields;
  OSStatus status = GetCertFields(cert_handle, &fields);
  if (status)
    return;

  for (size_t field = 0; field < fields.num_of_fields; ++field) {
    if (CSSMOIDEqual(&fields.fields[field].FieldOid, &oid)) {
      CSSM_X509_TIME* x509_time =
          reinterpret_cast<CSSM_X509_TIME *>
            (fields.fields[field].FieldValue.Data);
      std::string time_string =
          std::string(reinterpret_cast<std::string::value_type*>
                      (x509_time->time.Data),
                      x509_time->time.Length);

      DCHECK(x509_time->timeType == BER_TAG_UTC_TIME ||
             x509_time->timeType == BER_TAG_GENERALIZED_TIME);

      struct tm time;
      const char* parse_string;
      if (x509_time->timeType == BER_TAG_UTC_TIME)
        parse_string = "%y%m%d%H%M%SZ";
      else if (x509_time->timeType == BER_TAG_GENERALIZED_TIME)
        parse_string = "%y%m%d%H%M%SZ";
      else {
        // Those are the only two BER tags for time; if neither are used then
        // this is a rather broken cert.
        return;
      }

      strptime(time_string.c_str(), parse_string, &time);

      Time::Exploded exploded;
      exploded.year         = time.tm_year + 1900;
      exploded.month        = time.tm_mon + 1;
      exploded.day_of_week  = time.tm_wday;
      exploded.day_of_month = time.tm_mday;
      exploded.hour         = time.tm_hour;
      exploded.minute       = time.tm_min;
      exploded.second       = time.tm_sec;
      exploded.millisecond  = 0;

      *result = Time::FromUTCExploded(exploded);
      break;
    }
  }
}

}  // namespace

void X509Certificate::Initialize() {
  const CSSM_X509_NAME* name;
  OSStatus status = SecCertificateGetSubject(cert_handle_, &name);
  if (!status) {
    ParsePrincipal(name, &subject_);
  }
  status = SecCertificateGetIssuer(cert_handle_, &name);
  if (!status) {
    ParsePrincipal(name, &issuer_);
  }

  GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotBefore,
                    &valid_start_);
  GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotAfter,
                    &valid_expiry_);

  fingerprint_ = CalculateFingerprint(cert_handle_);

  // Store the certificate in the cache in case we need it later.
  X509Certificate::Cache::GetInstance()->Insert(this);
}

// static
X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle,
                                                   void** pickle_iter) {
  const char* data;
  int length;
  if (!pickle.ReadData(pickle_iter, &data, &length))
    return NULL;

  return CreateFromBytes(data, length);
}

void X509Certificate::Persist(Pickle* pickle) {
  CSSM_DATA cert_data;
  OSStatus status = SecCertificateGetData(cert_handle_, &cert_data);
  if (status) {
    NOTREACHED();
    return;
  }

  pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), cert_data.Length);
}

bool X509Certificate::HasExpired() const {
  NOTIMPLEMENTED();
  return false;
}

void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
  dns_names->clear();

  GetCertGeneralNamesForOID(cert_handle_, CSSMOID_SubjectAltName, GNT_DNSName,
                            dns_names);

  if (dns_names->empty())
    dns_names->push_back(subject_.common_name);
}

int X509Certificate::Verify(const std::string& hostname,
                            bool rev_checking_enabled,
                            CertVerifyResult* verify_result) const {
  NOTIMPLEMENTED();
  return ERR_NOT_IMPLEMENTED;
}

// Returns true if the certificate is an extended-validation certificate.
//
// The certificate has already been verified by the HTTP library.  cert_status
// represents the result of that verification.  This function performs
// additional checks of the certificatePolicies extensions of the certificates
// in the certificate chain according to Section 7 (pp. 11-12) of the EV
// Certificate Guidelines Version 1.0 at
// http://cabforum.org/EV_Certificate_Guidelines.pdf.
bool X509Certificate::IsEV(int cert_status) const {
  // TODO(avi): implement this
  NOTIMPLEMENTED();
  return false;
}

// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
    const char* data, int length) {
  CSSM_DATA cert_data;
  cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data));
  cert_data.Length = length;

  OSCertHandle cert_handle = NULL;
  OSStatus status = SecCertificateCreateFromData(&cert_data,
                                                 CSSM_CERT_X_509v3,
                                                 CSSM_CERT_ENCODING_BER,
                                                 &cert_handle);
  if (status)
    return NULL;

  return cert_handle;
}

// static
void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
  CFRelease(cert_handle);
}

// static
X509Certificate::Fingerprint X509Certificate::CalculateFingerprint(
    OSCertHandle cert) {
  Fingerprint sha1;
  memset(sha1.data, 0, sizeof(sha1.data));

  CSSM_DATA cert_data;
  OSStatus status = SecCertificateGetData(cert, &cert_data);
  if (status)
    return sha1;

  DCHECK(NULL != cert_data.Data);
  DCHECK(0 != cert_data.Length);

  CC_SHA1(cert_data.Data, cert_data.Length, sha1.data);

  return sha1;
}

}  // namespace net
<|endoftext|>


<commit_before>/*
 * C Runtime startup for isolated programs loaded by the system.  The program
 * loader is responsible for much of what a conventional C startup routine
 * might do: filling in the GOT, initializing our data segment, setting the
 * stack pointer.  We just need to run any functions specified during
 * initialization.
 */

#include "etl/attribute_macros.h"

using InitFnPtr = void (*)();

extern "C" {
  void _start();

  extern InitFnPtr _preinit_array_start, _preinit_array_end;
  extern InitFnPtr _init_array_start, _init_array_end;

  void _init();
  void _init_epilogue();

  int main();
}

void _start() {
  for (auto * f = &_preinit_array_start; f != &_preinit_array_end; ++f) {
    (*f)();
  }

  _init();

  for (auto * f = &_init_array_start; f != &_init_array_end; ++f) {
    (*f)();
  }

  (void) main();
  while (true);
}

ETL_SECTION(".init_prologue")
ETL_NAKED
void _init() {
  asm volatile ("push {r4-r11, lr}");
}

ETL_SECTION(".init_epilogue")
ETL_NAKED
void _init_epilogue() {
  asm volatile ("pop {r4-r11, pc}");
}

<commit_msg>a/rt/crt0: mark init_epilogue USED.<commit_after>/*
 * C Runtime startup for isolated programs loaded by the system.  The program
 * loader is responsible for much of what a conventional C startup routine
 * might do: filling in the GOT, initializing our data segment, setting the
 * stack pointer.  We just need to run any functions specified during
 * initialization.
 */

#include "etl/attribute_macros.h"

using InitFnPtr = void (*)();

extern "C" {
  void _start();

  extern InitFnPtr _preinit_array_start, _preinit_array_end;
  extern InitFnPtr _init_array_start, _init_array_end;

  void _init();
  void _init_epilogue();

  int main();
}

void _start() {
  for (auto * f = &_preinit_array_start; f != &_preinit_array_end; ++f) {
    (*f)();
  }

  _init();

  for (auto * f = &_init_array_start; f != &_init_array_end; ++f) {
    (*f)();
  }

  (void) main();
  while (true);
}

ETL_SECTION(".init_prologue")
ETL_NAKED
void _init() {
  asm volatile ("push {r4-r11, lr}");
}

ETL_SECTION(".init_epilogue")
ETL_NAKED
ETL_USED
void _init_epilogue() {
  asm volatile ("pop {r4-r11, pc}");
}

<|endoftext|>


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

#ifndef CONFIGMGR_API_APITYPES_HXX_
#define CONFIGMGR_API_APITYPES_HXX_

#ifndef _COM_SUN_STAR_UNO_TYPE_HXX_
#include <com/sun/star/uno/Type.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_XINTERFACE_HPP_
#include <com/sun/star/uno/XInterface.hpp>
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifndef INCLUDED_VECTOR
#include <vector>
#define INCLUDED_VECTOR
#endif  //  INCLUDED_VECTOR

namespace configmgr
{
    namespace configapi
    {
        namespace uno = ::com::sun::star::uno;

        inline
        uno::Type getAnyType( )
        {
            return ::getCppuType( static_cast< uno::Any const * >(0) );
        }

        inline
        uno::Type getUnoInterfaceType( )
        {
            return ::getCppuType( static_cast< uno::Reference< uno::XInterface > const * >(0) );
        }

        template <typename Interface>
        inline
        uno::Type getReferenceType( Interface const* )
        {
            return ::getCppuType( static_cast< uno::Reference<Interface> const * >(0) );
        }

        template <typename Type>
        inline
        uno::Type getSequenceType( Type const* )
        {
            return ::getCppuType( static_cast< uno::Sequence<Type> const * >(0) );
        }

        template <typename T>
        inline
        uno::Sequence<T> makeSequence(::std::vector<T> const& aVector)
        {
            if (aVector.empty())
                return uno::Sequence<T>();
            return uno::Sequence<T>(&aVector[0],aVector.size());
        }
    }

}

#endif // CONFIGMGR_API_APITYPES_HXX_

<commit_msg>INTEGRATION: CWS changefileheader (1.8.130); FILE MERGED 2008/04/01 15:06:41 thb 1.8.130.3: #i85898# Stripping all external header guards 2008/04/01 12:27:21 thb 1.8.130.2: #i85898# Stripping all external header guards 2008/03/31 12:22:43 rt 1.8.130.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: apitypes.hxx,v $
 * $Revision: 1.9 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef CONFIGMGR_API_APITYPES_HXX_
#define CONFIGMGR_API_APITYPES_HXX_

#include <com/sun/star/uno/Type.hxx>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/uno/XInterface.hpp>
#include <rtl/ustring.hxx>

#ifndef INCLUDED_VECTOR
#include <vector>
#define INCLUDED_VECTOR
#endif  //  INCLUDED_VECTOR

namespace configmgr
{
    namespace configapi
    {
        namespace uno = ::com::sun::star::uno;

        inline
        uno::Type getAnyType( )
        {
            return ::getCppuType( static_cast< uno::Any const * >(0) );
        }

        inline
        uno::Type getUnoInterfaceType( )
        {
            return ::getCppuType( static_cast< uno::Reference< uno::XInterface > const * >(0) );
        }

        template <typename Interface>
        inline
        uno::Type getReferenceType( Interface const* )
        {
            return ::getCppuType( static_cast< uno::Reference<Interface> const * >(0) );
        }

        template <typename Type>
        inline
        uno::Type getSequenceType( Type const* )
        {
            return ::getCppuType( static_cast< uno::Sequence<Type> const * >(0) );
        }

        template <typename T>
        inline
        uno::Sequence<T> makeSequence(::std::vector<T> const& aVector)
        {
            if (aVector.empty())
                return uno::Sequence<T>();
            return uno::Sequence<T>(&aVector[0],aVector.size());
        }
    }

}

#endif // CONFIGMGR_API_APITYPES_HXX_

<|endoftext|>


<commit_before>/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * 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.
 */

#include "MsgFileOutputStream.hpp"

#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>

#include <cassert>
#include <cerrno>
#include <cstdio>

static  XalanFileOutputStream::HandleType
openFile(const char*	theFileName)
{
	typedef XalanFileOutputStream::HandleType	HandleType;

#if defined(WIN32)

			return CreateFile(
					theFileName,
					GENERIC_WRITE,
					0,
					0,
					CREATE_ALWAYS,
					FILE_ATTRIBUTE_NORMAL,
					0);

#else

			return fopen(theFileName, "wb");

#endif
}

XalanFileOutputStream::XalanFileOutputStream(
			const char*	theFileName) :
			m_fileName(theFileName),
			m_handle(openFile(theFileName))
{
#if defined(WIN32)
    if (m_handle == INVALID_HANDLE_VALUE)
#else
    if (m_handle == 0)
#endif
	{
		throw XalanFileOutputStreamOpenException(
					theFileName,
					errno);
	}
}

XalanFileOutputStream::~XalanFileOutputStream()
{
#if defined(WIN32)
    if (m_handle != INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_handle);
	}
#else
    if (m_handle != 0)
	{
		fclose(m_handle);
	}
#endif
}

void
XalanFileOutputStream::doFlush()
{
#if !defined(WIN32)
	if (fflush(m_handle) != 0)
	{
		throw XalanFileOutputStreamWriteException(
			m_fileName,
			errno);
	}
#endif
}

void
XalanFileOutputStream::writeData(
			const char*		theBuffer,
			unsigned int		theBufferLength)
{
#if defined(WIN32)
	DWORD			theBytesWritten;

	assert(size_t(DWORD(theBufferLength)) == theBufferLength);

	if (WriteFile(m_handle, theBuffer, DWORD(theBufferLength), &theBytesWritten, 0) == false ||
	    theBytesWritten != theBufferLength)
	{
		throw XalanFileOutputStreamWriteException(
			m_fileName,
			GetLastError());
	}
#else
	const size_t	theBytesWritten =
		fwrite(theBuffer,
			   1,
			   theBufferLength,
			   m_handle);

	if (theBytesWritten != theBufferLength)
	{
		throw XalanFileOutputStreamWriteException(
			m_fileName,
			errno);
	}
#endif
}

static char*
FormatMessageLocal(
			const char*				theMessage,
			const char*				theFileName,
			int						theErrorCode)
{
	assert( theMessage != 0 );

	assert( theFileName != 0);

	char*		strtoBuild = new char[256];
	strtoBuild[0] = '\0';

	strncat(strtoBuild,theMessage, 100);
	strtoBuild[100] = 0; // in case that lenght(theMessage) > 100

	strcat(strtoBuild,".  The C++ run-time error code (errno) is ");

	char szNumb[20];
	szNumb[0] = 0;
	sprintf(szNumb,"%d",theErrorCode);

	strncat(strtoBuild,szNumb,18);

	strcat(strtoBuild,".");

	return strtoBuild;
}

XalanFileOutputStream::XalanFileOutputStreamOpenException::XalanFileOutputStreamOpenException(
		const char*		theFileName,
		int					theErrorCode) :
		m_pMessage( FormatMessageLocal(
				"Error opening file: ",
				theFileName,
				theErrorCode))

{
}

XalanFileOutputStream::XalanFileOutputStreamOpenException::~XalanFileOutputStreamOpenException()
{
	delete [] m_pMessage;
}

XalanFileOutputStream::XalanFileOutputStreamWriteException::XalanFileOutputStreamWriteException(
		const char*		theFileName,
		int				theErrorCode) :
		m_pMessage(FormatMessageLocal(
					"Error writing file: ",
					theFileName,
					theErrorCode))
{
}

XalanFileOutputStream::XalanFileOutputStreamWriteException::~XalanFileOutputStreamWriteException()
{
	delete [] m_pMessage;
}

void 	XalanFileOutputStream::write(const UTF16Ch*	theString, unsigned int		theLength)
{
	assert ( theString != 0 );
	writeData((const char*)theString,theLength * sizeof(UTF16Ch) );
}

void 	XalanFileOutputStream::write(const char*	theString, unsigned int		theLength)
{
	assert ( theString != 0 );

	UTF16Ch* theUTFString = XMLString::transcode(theString);

	write(theUTFString,theLength);

	XMLString::release(&theUTFString);
}

void XalanFileOutputStream::writeAsASCII(const UTF16Ch*	theString, unsigned int		theLengts)
{
	char* szString = XMLString::transcode(theString);
	writeData( szString, theLengts );
	XMLString::release(&szString);

}

void XalanFileOutputStream::writeAsASCII(const char*	theString, unsigned int		theLengts)
{
	writeData( theString, theLengts );
}

const UTF16Ch	s_UTF16ByteOrderMark[] =
{
	UTF16Ch(0xFEFF),
	UTF16Ch(0)
};

void 	XalanFileOutputStream::writeUTFprefix()
{
	write(s_UTF16ByteOrderMark,1);
}
<commit_msg>Removing an assert preventing debug build for cygwin/gcc/Win32 configuration<commit_after>/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * 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.
 */

#include "MsgFileOutputStream.hpp"

#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>

#include <cassert>
#include <cerrno>
#include <cstdio>

static  XalanFileOutputStream::HandleType
openFile(const char*	theFileName)
{
	typedef XalanFileOutputStream::HandleType	HandleType;

#if defined(WIN32)

			return CreateFile(
					theFileName,
					GENERIC_WRITE,
					0,
					0,
					CREATE_ALWAYS,
					FILE_ATTRIBUTE_NORMAL,
					0);

#else

			return fopen(theFileName, "wb");

#endif
}

XalanFileOutputStream::XalanFileOutputStream(
			const char*	theFileName) :
			m_fileName(theFileName),
			m_handle(openFile(theFileName))
{
#if defined(WIN32)
    if (m_handle == INVALID_HANDLE_VALUE)
#else
    if (m_handle == 0)
#endif
	{
		throw XalanFileOutputStreamOpenException(
					theFileName,
					errno);
	}
}

XalanFileOutputStream::~XalanFileOutputStream()
{
#if defined(WIN32)
    if (m_handle != INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_handle);
	}
#else
    if (m_handle != 0)
	{
		fclose(m_handle);
	}
#endif
}

void
XalanFileOutputStream::doFlush()
{
#if !defined(WIN32)
	if (fflush(m_handle) != 0)
	{
		throw XalanFileOutputStreamWriteException(
			m_fileName,
			errno);
	}
#endif
}

void
XalanFileOutputStream::writeData(
			const char*		theBuffer,
			unsigned int		theBufferLength)
{
#if defined(WIN32)
	DWORD			theBytesWritten;

	if (WriteFile(m_handle, theBuffer, DWORD(theBufferLength), &theBytesWritten, 0) == false ||
	    theBytesWritten != theBufferLength)
	{
		throw XalanFileOutputStreamWriteException(
			m_fileName,
			GetLastError());
	}
#else
	const size_t	theBytesWritten =
		fwrite(theBuffer,
			   1,
			   theBufferLength,
			   m_handle);

	if (theBytesWritten != theBufferLength)
	{
		throw XalanFileOutputStreamWriteException(
			m_fileName,
			errno);
	}
#endif
}

static char*
FormatMessageLocal(
			const char*				theMessage,
			const char*				theFileName,
			int						theErrorCode)
{
	assert( theMessage != 0 );

	assert( theFileName != 0);

	char*		strtoBuild = new char[256];
	strtoBuild[0] = '\0';

	strncat(strtoBuild,theMessage, 100);
	strtoBuild[100] = 0; // in case that lenght(theMessage) > 100

	strcat(strtoBuild,".  The C++ run-time error code (errno) is ");

	char szNumb[20];
	szNumb[0] = 0;
	sprintf(szNumb,"%d",theErrorCode);

	strncat(strtoBuild,szNumb,18);

	strcat(strtoBuild,".");

	return strtoBuild;
}

XalanFileOutputStream::XalanFileOutputStreamOpenException::XalanFileOutputStreamOpenException(
		const char*		theFileName,
		int					theErrorCode) :
		m_pMessage( FormatMessageLocal(
				"Error opening file: ",
				theFileName,
				theErrorCode))

{
}

XalanFileOutputStream::XalanFileOutputStreamOpenException::~XalanFileOutputStreamOpenException()
{
	delete [] m_pMessage;
}

XalanFileOutputStream::XalanFileOutputStreamWriteException::XalanFileOutputStreamWriteException(
		const char*		theFileName,
		int				theErrorCode) :
		m_pMessage(FormatMessageLocal(
					"Error writing file: ",
					theFileName,
					theErrorCode))
{
}

XalanFileOutputStream::XalanFileOutputStreamWriteException::~XalanFileOutputStreamWriteException()
{
	delete [] m_pMessage;
}

void 	XalanFileOutputStream::write(const UTF16Ch*	theString, unsigned int		theLength)
{
	assert ( theString != 0 );
	writeData((const char*)theString,theLength * sizeof(UTF16Ch) );
}

void 	XalanFileOutputStream::write(const char*	theString, unsigned int		theLength)
{
	assert ( theString != 0 );

	UTF16Ch* theUTFString = XMLString::transcode(theString);

	write(theUTFString,theLength);

	XMLString::release(&theUTFString);
}

void XalanFileOutputStream::writeAsASCII(const UTF16Ch*	theString, unsigned int		theLengts)
{
	char* szString = XMLString::transcode(theString);
	writeData( szString, theLengts );
	XMLString::release(&szString);

}

void XalanFileOutputStream::writeAsASCII(const char*	theString, unsigned int		theLengts)
{
	writeData( theString, theLengts );
}

const UTF16Ch	s_UTF16ByteOrderMark[] =
{
	UTF16Ch(0xFEFF),
	UTF16Ch(0)
};

void 	XalanFileOutputStream::writeUTFprefix()
{
	write(s_UTF16ByteOrderMark,1);
}
<|endoftext|>


<commit_before>// @(#)root/netx:$Id$
/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// TNetXNGSystem                                                              //
//                                                                            //
// Authors: Justin Salmon, Lukasz Janyst                                      //
//          CERN, 2013                                                        //
//                                                                            //
// Enables access to XRootD filesystem interface using the new client.        //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

#include "TNetXNGSystem.h"
#include "TFileStager.h"
#include "Rtypes.h"
#include "TList.h"
#include "TUrl.h"
#include "TVirtualMutex.h"
#include <XrdCl/XrdClFileSystem.hh>
#include <XrdCl/XrdClXRootDResponses.hh>
#include <XrdSys/XrdSysDNS.hh>

////////////////////////////////////////////////////////////////////////////////
/// PluginManager creation function

TSystem* ROOT_Plugin_TNetXNGSystem(const char *url, Bool_t owner) {
   return new TNetXNGSystem(url, owner);
}

ClassImp(TNetXNGSystem);

THashList TNetXNGSystem::fgAddrFQDN;
TMutex TNetXNGSystem::fgAddrMutex;

namespace
{
   struct DirectoryInfo {
      XrdCl::URL                     *fUrl;         // Path of this directory
      XrdCl::DirectoryList           *fDirList;     // Directory listing
      XrdCl::DirectoryList::Iterator *fDirListIter; // Iterator for this listing

   public:
      DirectoryInfo(const char *dir) : fUrl(new XrdCl::URL(dir)), fDirList(0), fDirListIter(0) {}

      ~DirectoryInfo() {
        delete fUrl;
        delete fDirList;
      }
   };
}

////////////////////////////////////////////////////////////////////////////////
/// Constructor: Create system class without connecting to server
///
/// param owner: (unused)

TNetXNGSystem::TNetXNGSystem(Bool_t /*owner*/) :
   TSystem("-root", "Net file Helper System"), fUrl(0), fFileSystem(0)
{
   // Name must start with '-' to bypass the TSystem singleton check, then
   // be changed to "root"
   SetName("root");
}

////////////////////////////////////////////////////////////////////////////////
/// Constructor: Create system class and connect to server
///
/// param url:   URL of the entry-point server to be contacted
/// param owner: (unused)

TNetXNGSystem::TNetXNGSystem(const char *url, Bool_t /*owner*/) :
   TSystem("-root", "Net file Helper System")
{
   using namespace XrdCl;

   // Name must start with '-' to bypass the TSystem singleton check
   SetName("root");
   fUrl        = new URL(std::string(url));
   fFileSystem = new FileSystem(fUrl->GetURL());
}

////////////////////////////////////////////////////////////////////////////////
/// Destructor

TNetXNGSystem::~TNetXNGSystem()
{
   delete fFileSystem;
   delete fUrl;
}

////////////////////////////////////////////////////////////////////////////////
/// Open a directory
///
/// param dir: the name of the directory to open
/// returns:   a non-zero pointer (with no special purpose) in case of
///            success, 0 in case of error

void* TNetXNGSystem::OpenDirectory(const char *dir)
{
   using namespace XrdCl;

   DirectoryInfo *dirInfo = new DirectoryInfo(dir);
   fDirPtrs.insert( (void*)dirInfo );
   return (void *) dirInfo;
}

////////////////////////////////////////////////////////////////////////////////
/// Create a directory
///
/// param dir: the directory name
/// returns:   0 on success, -1 otherwise

Int_t TNetXNGSystem::MakeDirectory(const char *dir)
{
   using namespace XrdCl;
   URL url(dir);
   XRootDStatus st = fFileSystem->MkDir(url.GetPath(), MkDirFlags::MakePath,
                                        Access::None);
   if (!st.IsOK()) {
      Error("MakeDirectory", "%s", st.GetErrorMessage().c_str());
      return -1;
   }

   return 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Free a directory
///
/// param dirp: the pointer to the directory to be freed

void TNetXNGSystem::FreeDirectory(void *dirp)
{
   fDirPtrs.erase( dirp );
   delete (DirectoryInfo *) dirp;
}

////////////////////////////////////////////////////////////////////////////////
/// Get a directory entry.
///
/// param dirp: the directory pointer
/// returns:    0 in case there are no more entries

const char* TNetXNGSystem::GetDirEntry(void *dirp)
{
   using namespace XrdCl;
   DirectoryInfo *dirInfo = (DirectoryInfo *) dirp;

   if (!dirInfo->fDirList) {
      XRootDStatus st = fFileSystem->DirList(dirInfo->fUrl->GetPath(),
                                             DirListFlags::Locate,
                                             dirInfo->fDirList);
      if (!st.IsOK()) {
         Error("GetDirEntry", "%s", st.GetErrorMessage().c_str());
         return 0;
      }
      dirInfo->fDirListIter = new DirectoryList::Iterator(dirInfo->fDirList->Begin());
   }

   if (*(dirInfo->fDirListIter) != dirInfo->fDirList->End()) {
      const char *filename = (**(dirInfo->fDirListIter))->GetName().c_str();
      (*(dirInfo->fDirListIter))++;
      return filename;

   } else {
      return 0;
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Get info about a file (stat)
///
/// param path: the path of the file to stat (in)
/// param buf:  structure that will hold the stat info (out)
/// returns:    0 if success, 1 if the file could not be stat'ed

Int_t TNetXNGSystem::GetPathInfo(const char *path, FileStat_t &buf)
{
   using namespace XrdCl;
   StatInfo *info = 0;
   URL target(path);
   XRootDStatus st = fFileSystem->Stat(target.GetPath(), info);

   if (!st.IsOK()) {

      if (gDebug > 1) {
         Info("GetPathInfo", "Stat error: %s", st.GetErrorMessage().c_str());
      }
      delete info;
      return 1;

   } else {

      // Flag offline files
      if (info->TestFlags(StatInfo::Offline)) {
         buf.fMode = kS_IFOFF;
      } else {
         std::stringstream sstr(info->GetId());
         Long64_t id;
         sstr >> id;

         buf.fDev    = (id >> 32);
         buf.fIno    = (id & 0x00000000FFFFFFFF);
         buf.fUid    = -1;  // not available
         buf.fGid    = -1;  // not available
         buf.fIsLink = 0;   // not available
         buf.fSize   = info->GetSize();
         buf.fMtime  = info->GetModTime();

         if (info->TestFlags(StatInfo::XBitSet))
            buf.fMode = (kS_IFREG | kS_IXUSR | kS_IXGRP | kS_IXOTH);
         if (info->GetFlags() == 0)                 buf.fMode = kS_IFREG;
         if (info->TestFlags(StatInfo::IsDir))      buf.fMode = kS_IFDIR;
         if (info->TestFlags(StatInfo::Other))      buf.fMode = kS_IFSOCK;
         if (info->TestFlags(StatInfo::IsReadable)) buf.fMode |= kS_IRUSR;
         if (info->TestFlags(StatInfo::IsWritable)) buf.fMode |= kS_IWUSR;
      }
   }

   delete info;
   return 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Check consistency of this helper with the one required by 'path' or
/// 'dirptr'
///
/// param path:   the path to check
/// param dirptr: the directory pointer to check

Bool_t TNetXNGSystem::ConsistentWith(const char *path, void *dirptr)
{
   using namespace XrdCl;

   if( path )
   {
      URL url(path);

      if( gDebug > 1 )
         Info("ConsistentWith", "Protocol: '%s' (%s), Username: '%s' (%s), "
              "Password: '%s' (%s), Hostname: '%s' (%s), Port: %d (%d)",
               fUrl->GetProtocol().c_str(), url.GetProtocol().c_str(),
               fUrl->GetUserName().c_str(), url.GetUserName().c_str(),
               fUrl->GetPassword().c_str(), url.GetPassword().c_str(),
               fUrl->GetHostName().c_str(), url.GetHostName().c_str(),
               fUrl->GetPort(), url.GetPort());

      // Require match of protocol, user, password, host and port
      if( fUrl->GetProtocol() == url.GetProtocol() &&
          fUrl->GetUserName() == url.GetUserName() &&
          fUrl->GetPassword() == url.GetPassword() &&
          fUrl->GetHostName() == url.GetHostName() &&
          fUrl->GetPort() == url.GetPort())
         return kTRUE;
   }

   if( dirptr )
      return fDirPtrs.find( dirptr ) != fDirPtrs.end();

   return kFALSE;
}

////////////////////////////////////////////////////////////////////////////////
/// Unlink a file on the remote server
///
/// param path: the path of the file to unlink
/// returns:    0 on success, -1 otherwise

int TNetXNGSystem::Unlink(const char *path)
{
   using namespace XrdCl;
   StatInfo *info;
   URL url(path);

   // Stat the path to find out if it's a file or a directory
   XRootDStatus st = fFileSystem->Stat(url.GetPath(), info);
   if (!st.IsOK()) {
      Error("Unlink", "%s", st.GetErrorMessage().c_str());
      delete info;
      return -1;
   }

   if (info->TestFlags(StatInfo::IsDir))
      st = fFileSystem->RmDir(url.GetPath());
   else
      st = fFileSystem->Rm(url.GetPath());
   delete info;

   if (!st.IsOK()) {
      Error("Unlink", "%s", st.GetErrorMessage().c_str());
      return -1;
   }

   return 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Is this path a local path?
///
/// param path: the URL of the path to check
/// returns:    kTRUE if the path is local, kFALSE otherwise

Bool_t TNetXNGSystem::IsPathLocal(const char *path)
{
   return TSystem::IsPathLocal(path);
}

////////////////////////////////////////////////////////////////////////////////
/// Get the endpoint URL of a file.
///
/// param path:   the entry-point URL of the file (in)
/// param endurl: the endpoint URL of the file (out)
/// returns:      0 in case of success and 1 if the file could not be
///               stat'ed.

Int_t TNetXNGSystem::Locate(const char *path, TString &endurl)
{
   using namespace XrdCl;
   LocationInfo *info = 0;
   URL pathUrl(path);

   // Locate the file
   XRootDStatus st = fFileSystem->Locate(pathUrl.GetPath(), OpenFlags::None,
                                         info);
   if (!st.IsOK()) {
      Error("Locate", "%s", st.GetErrorMessage().c_str());
      delete info;
      return 1;
   }

   // Use the first endpoint address returned by the client
   URL locUrl(info->Begin()->GetAddress());
   TString loc = locUrl.GetHostName();
   delete info;
   info = 0;

   R__LOCKGUARD(&fgAddrMutex);

   // The location returned by the client library is the numeric host address
   // without path. Try to lookup a hostname and replace the path portion of
   // the url before returning the result.
   TNamed *hn = 0;
   if (fgAddrFQDN.GetSize() <= 0 ||
       !(hn = dynamic_cast<TNamed *>(fgAddrFQDN.FindObject(loc)))) {
      char *addr[1] = {0}, *name[1] = {0};
      int naddr = XrdSysDNS::getAddrName(loc.Data(), 1, addr, name);
      if (naddr == 1) {
         hn = new TNamed(loc.Data(), name[0]);
      } else {
         hn = new TNamed(loc, loc);
      }
      fgAddrFQDN.Add(hn);
      free(addr[0]);
      free(name[0]);
      if (gDebug > 0)
         Info("Locate","caching host name: %s", hn->GetTitle());
   }

   TUrl res(path);
   res.SetHost(hn->GetTitle());
   res.SetPort(locUrl.GetPort());
   endurl = res.GetUrl();

   return 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Issue a stage request for a single file
///
/// param path: the path of the file to stage
/// param opt:  defines 'option' and 'priority' for 'Prepare': the format is
///             opt = "option=o priority=p"
/// returns:    0 for success, -1 for error

Int_t TNetXNGSystem::Stage(const char* path, UChar_t priority)
{
   TList *files = new TList();
   files->Add((TObject *) new TUrl(path));
   return Stage((TCollection *) files, priority);
}

////////////////////////////////////////////////////////////////////////////////
/// Issue stage requests for multiple files
///
/// param pathlist: list of paths of files to stage
/// param opt:      defines 'option' and 'priority' for 'Prepare': the
///                 format is opt = "option=o priority=p"
/// returns:        0 for success, -1 for error

Int_t TNetXNGSystem::Stage(TCollection *files, UChar_t priority)
{
   using namespace XrdCl;
   std::vector<std::string> fileList;
   TIter it(files);
   TObject *object = 0;

   while ((object = (TObject *) it.Next())) {

      TString path = TFileStager::GetPathName(object);
      if (path == "") {
         Warning("Stage", "object is of unexpected type %s - ignoring",
               object->ClassName());
         continue;
      }

      fileList.push_back(std::string(URL(path.Data()).GetPath()));
   }

   Buffer *response;
   XRootDStatus st = fFileSystem->Prepare(fileList, PrepareFlags::Stage,
                                          (uint8_t) priority, response);
   if (!st.IsOK()) {
      Error("Stage", "%s", st.GetErrorMessage().c_str());
      return -1;
   }

   return 0;
}

<commit_msg>netxng: remove deletion of invalid object after failed Stat call<commit_after>// @(#)root/netx:$Id$
/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// TNetXNGSystem                                                              //
//                                                                            //
// Authors: Justin Salmon, Lukasz Janyst                                      //
//          CERN, 2013                                                        //
//                                                                            //
// Enables access to XRootD filesystem interface using the new client.        //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

#include "TNetXNGSystem.h"
#include "TFileStager.h"
#include "Rtypes.h"
#include "TList.h"
#include "TUrl.h"
#include "TVirtualMutex.h"
#include <XrdCl/XrdClFileSystem.hh>
#include <XrdCl/XrdClXRootDResponses.hh>
#include <XrdSys/XrdSysDNS.hh>

////////////////////////////////////////////////////////////////////////////////
/// PluginManager creation function

TSystem* ROOT_Plugin_TNetXNGSystem(const char *url, Bool_t owner) {
   return new TNetXNGSystem(url, owner);
}

ClassImp(TNetXNGSystem);

THashList TNetXNGSystem::fgAddrFQDN;
TMutex TNetXNGSystem::fgAddrMutex;

namespace
{
   struct DirectoryInfo {
      XrdCl::URL                     *fUrl;         // Path of this directory
      XrdCl::DirectoryList           *fDirList;     // Directory listing
      XrdCl::DirectoryList::Iterator *fDirListIter; // Iterator for this listing

   public:
      DirectoryInfo(const char *dir) : fUrl(new XrdCl::URL(dir)), fDirList(0), fDirListIter(0) {}

      ~DirectoryInfo() {
        delete fUrl;
        delete fDirList;
      }
   };
}

////////////////////////////////////////////////////////////////////////////////
/// Constructor: Create system class without connecting to server
///
/// param owner: (unused)

TNetXNGSystem::TNetXNGSystem(Bool_t /*owner*/) :
   TSystem("-root", "Net file Helper System"), fUrl(0), fFileSystem(0)
{
   // Name must start with '-' to bypass the TSystem singleton check, then
   // be changed to "root"
   SetName("root");
}

////////////////////////////////////////////////////////////////////////////////
/// Constructor: Create system class and connect to server
///
/// param url:   URL of the entry-point server to be contacted
/// param owner: (unused)

TNetXNGSystem::TNetXNGSystem(const char *url, Bool_t /*owner*/) :
   TSystem("-root", "Net file Helper System")
{
   using namespace XrdCl;

   // Name must start with '-' to bypass the TSystem singleton check
   SetName("root");
   fUrl        = new URL(std::string(url));
   fFileSystem = new FileSystem(fUrl->GetURL());
}

////////////////////////////////////////////////////////////////////////////////
/// Destructor

TNetXNGSystem::~TNetXNGSystem()
{
   delete fFileSystem;
   delete fUrl;
}

////////////////////////////////////////////////////////////////////////////////
/// Open a directory
///
/// param dir: the name of the directory to open
/// returns:   a non-zero pointer (with no special purpose) in case of
///            success, 0 in case of error

void* TNetXNGSystem::OpenDirectory(const char *dir)
{
   using namespace XrdCl;

   DirectoryInfo *dirInfo = new DirectoryInfo(dir);
   fDirPtrs.insert( (void*)dirInfo );
   return (void *) dirInfo;
}

////////////////////////////////////////////////////////////////////////////////
/// Create a directory
///
/// param dir: the directory name
/// returns:   0 on success, -1 otherwise

Int_t TNetXNGSystem::MakeDirectory(const char *dir)
{
   using namespace XrdCl;
   URL url(dir);
   XRootDStatus st = fFileSystem->MkDir(url.GetPath(), MkDirFlags::MakePath,
                                        Access::None);
   if (!st.IsOK()) {
      Error("MakeDirectory", "%s", st.GetErrorMessage().c_str());
      return -1;
   }

   return 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Free a directory
///
/// param dirp: the pointer to the directory to be freed

void TNetXNGSystem::FreeDirectory(void *dirp)
{
   fDirPtrs.erase( dirp );
   delete (DirectoryInfo *) dirp;
}

////////////////////////////////////////////////////////////////////////////////
/// Get a directory entry.
///
/// param dirp: the directory pointer
/// returns:    0 in case there are no more entries

const char* TNetXNGSystem::GetDirEntry(void *dirp)
{
   using namespace XrdCl;
   DirectoryInfo *dirInfo = (DirectoryInfo *) dirp;

   if (!dirInfo->fDirList) {
      XRootDStatus st = fFileSystem->DirList(dirInfo->fUrl->GetPath(),
                                             DirListFlags::Locate,
                                             dirInfo->fDirList);
      if (!st.IsOK()) {
         Error("GetDirEntry", "%s", st.GetErrorMessage().c_str());
         return 0;
      }
      dirInfo->fDirListIter = new DirectoryList::Iterator(dirInfo->fDirList->Begin());
   }

   if (*(dirInfo->fDirListIter) != dirInfo->fDirList->End()) {
      const char *filename = (**(dirInfo->fDirListIter))->GetName().c_str();
      (*(dirInfo->fDirListIter))++;
      return filename;

   } else {
      return 0;
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Get info about a file (stat)
///
/// param path: the path of the file to stat (in)
/// param buf:  structure that will hold the stat info (out)
/// returns:    0 if success, 1 if the file could not be stat'ed

Int_t TNetXNGSystem::GetPathInfo(const char *path, FileStat_t &buf)
{
   using namespace XrdCl;
   StatInfo *info = 0;
   URL target(path);
   XRootDStatus st = fFileSystem->Stat(target.GetPath(), info);

   if (!st.IsOK()) {

      if (gDebug > 1) {
         Info("GetPathInfo", "Stat error: %s", st.GetErrorMessage().c_str());
      }
      delete info;
      return 1;

   } else {

      // Flag offline files
      if (info->TestFlags(StatInfo::Offline)) {
         buf.fMode = kS_IFOFF;
      } else {
         std::stringstream sstr(info->GetId());
         Long64_t id;
         sstr >> id;

         buf.fDev    = (id >> 32);
         buf.fIno    = (id & 0x00000000FFFFFFFF);
         buf.fUid    = -1;  // not available
         buf.fGid    = -1;  // not available
         buf.fIsLink = 0;   // not available
         buf.fSize   = info->GetSize();
         buf.fMtime  = info->GetModTime();

         if (info->TestFlags(StatInfo::XBitSet))
            buf.fMode = (kS_IFREG | kS_IXUSR | kS_IXGRP | kS_IXOTH);
         if (info->GetFlags() == 0)                 buf.fMode = kS_IFREG;
         if (info->TestFlags(StatInfo::IsDir))      buf.fMode = kS_IFDIR;
         if (info->TestFlags(StatInfo::Other))      buf.fMode = kS_IFSOCK;
         if (info->TestFlags(StatInfo::IsReadable)) buf.fMode |= kS_IRUSR;
         if (info->TestFlags(StatInfo::IsWritable)) buf.fMode |= kS_IWUSR;
      }
   }

   delete info;
   return 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Check consistency of this helper with the one required by 'path' or
/// 'dirptr'
///
/// param path:   the path to check
/// param dirptr: the directory pointer to check

Bool_t TNetXNGSystem::ConsistentWith(const char *path, void *dirptr)
{
   using namespace XrdCl;

   if( path )
   {
      URL url(path);

      if( gDebug > 1 )
         Info("ConsistentWith", "Protocol: '%s' (%s), Username: '%s' (%s), "
              "Password: '%s' (%s), Hostname: '%s' (%s), Port: %d (%d)",
               fUrl->GetProtocol().c_str(), url.GetProtocol().c_str(),
               fUrl->GetUserName().c_str(), url.GetUserName().c_str(),
               fUrl->GetPassword().c_str(), url.GetPassword().c_str(),
               fUrl->GetHostName().c_str(), url.GetHostName().c_str(),
               fUrl->GetPort(), url.GetPort());

      // Require match of protocol, user, password, host and port
      if( fUrl->GetProtocol() == url.GetProtocol() &&
          fUrl->GetUserName() == url.GetUserName() &&
          fUrl->GetPassword() == url.GetPassword() &&
          fUrl->GetHostName() == url.GetHostName() &&
          fUrl->GetPort() == url.GetPort())
         return kTRUE;
   }

   if( dirptr )
      return fDirPtrs.find( dirptr ) != fDirPtrs.end();

   return kFALSE;
}

////////////////////////////////////////////////////////////////////////////////
/// Unlink a file on the remote server
///
/// param path: the path of the file to unlink
/// returns:    0 on success, -1 otherwise

int TNetXNGSystem::Unlink(const char *path)
{
   using namespace XrdCl;
   StatInfo *info;
   URL url(path);

   // Stat the path to find out if it's a file or a directory
   XRootDStatus st = fFileSystem->Stat(url.GetPath(), info);
   if (!st.IsOK()) {
      Error("Unlink", "%s", st.GetErrorMessage().c_str());
      return -1;
   }

   if (info->TestFlags(StatInfo::IsDir))
      st = fFileSystem->RmDir(url.GetPath());
   else
      st = fFileSystem->Rm(url.GetPath());
   delete info;

   if (!st.IsOK()) {
      Error("Unlink", "%s", st.GetErrorMessage().c_str());
      return -1;
   }

   return 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Is this path a local path?
///
/// param path: the URL of the path to check
/// returns:    kTRUE if the path is local, kFALSE otherwise

Bool_t TNetXNGSystem::IsPathLocal(const char *path)
{
   return TSystem::IsPathLocal(path);
}

////////////////////////////////////////////////////////////////////////////////
/// Get the endpoint URL of a file.
///
/// param path:   the entry-point URL of the file (in)
/// param endurl: the endpoint URL of the file (out)
/// returns:      0 in case of success and 1 if the file could not be
///               stat'ed.

Int_t TNetXNGSystem::Locate(const char *path, TString &endurl)
{
   using namespace XrdCl;
   LocationInfo *info = 0;
   URL pathUrl(path);

   // Locate the file
   XRootDStatus st = fFileSystem->Locate(pathUrl.GetPath(), OpenFlags::None,
                                         info);
   if (!st.IsOK()) {
      Error("Locate", "%s", st.GetErrorMessage().c_str());
      delete info;
      return 1;
   }

   // Use the first endpoint address returned by the client
   URL locUrl(info->Begin()->GetAddress());
   TString loc = locUrl.GetHostName();
   delete info;
   info = 0;

   R__LOCKGUARD(&fgAddrMutex);

   // The location returned by the client library is the numeric host address
   // without path. Try to lookup a hostname and replace the path portion of
   // the url before returning the result.
   TNamed *hn = 0;
   if (fgAddrFQDN.GetSize() <= 0 ||
       !(hn = dynamic_cast<TNamed *>(fgAddrFQDN.FindObject(loc)))) {
      char *addr[1] = {0}, *name[1] = {0};
      int naddr = XrdSysDNS::getAddrName(loc.Data(), 1, addr, name);
      if (naddr == 1) {
         hn = new TNamed(loc.Data(), name[0]);
      } else {
         hn = new TNamed(loc, loc);
      }
      fgAddrFQDN.Add(hn);
      free(addr[0]);
      free(name[0]);
      if (gDebug > 0)
         Info("Locate","caching host name: %s", hn->GetTitle());
   }

   TUrl res(path);
   res.SetHost(hn->GetTitle());
   res.SetPort(locUrl.GetPort());
   endurl = res.GetUrl();

   return 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Issue a stage request for a single file
///
/// param path: the path of the file to stage
/// param opt:  defines 'option' and 'priority' for 'Prepare': the format is
///             opt = "option=o priority=p"
/// returns:    0 for success, -1 for error

Int_t TNetXNGSystem::Stage(const char* path, UChar_t priority)
{
   TList *files = new TList();
   files->Add((TObject *) new TUrl(path));
   return Stage((TCollection *) files, priority);
}

////////////////////////////////////////////////////////////////////////////////
/// Issue stage requests for multiple files
///
/// param pathlist: list of paths of files to stage
/// param opt:      defines 'option' and 'priority' for 'Prepare': the
///                 format is opt = "option=o priority=p"
/// returns:        0 for success, -1 for error

Int_t TNetXNGSystem::Stage(TCollection *files, UChar_t priority)
{
   using namespace XrdCl;
   std::vector<std::string> fileList;
   TIter it(files);
   TObject *object = 0;

   while ((object = (TObject *) it.Next())) {

      TString path = TFileStager::GetPathName(object);
      if (path == "") {
         Warning("Stage", "object is of unexpected type %s - ignoring",
               object->ClassName());
         continue;
      }

      fileList.push_back(std::string(URL(path.Data()).GetPath()));
   }

   Buffer *response;
   XRootDStatus st = fFileSystem->Prepare(fileList, PrepareFlags::Stage,
                                          (uint8_t) priority, response);
   if (!st.IsOK()) {
      Error("Stage", "%s", st.GetErrorMessage().c_str());
      return -1;
   }

   return 0;
}

<|endoftext|>