<commit_before>/*
 *  Copyright 2008-2012 NVIDIA Corporation
 *
 *  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 <thrust/detail/config.h>
#include <thrust/detail/allocator/allocator_traits.h>
#include <thrust/detail/type_traits/pointer_traits.h>
#include <thrust/iterator/iterator_traits.h>
#include <thrust/detail/copy.h>
#include <thrust/tuple.h>
#include <thrust/advance.h>
#include <thrust/distance.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/for_each.h>
#include <memory>

namespace thrust
{
namespace detail
{
namespace allocator_traits_detail
{

template<typename Allocator, typename InputType, typename OutputType>
  struct copy_construct_with_allocator
{
  Allocator &a;

  __host__ __device__
  copy_construct_with_allocator(Allocator &a)
    : a(a)
  {}

  template<typename Tuple>
  inline __host__ __device__
  void operator()(Tuple t)
  {
    const InputType &in = thrust::get<0>(t);
    OutputType &out = thrust::get<1>(t);

    allocator_traits<Allocator>::construct(a, &out, in);
  }
};

template<typename Allocator, typename T>
  struct needs_copy_construct_via_allocator
    : has_member_construct2<
        Allocator,
        T,
        T
      >
{};

// we know that std::allocator::construct's only effect is to call T's
// copy constructor, so we needn't use it for copy construction
template<typename U, typename T>
  struct needs_copy_construct_via_allocator<std::allocator<U>, T>
    : thrust::detail::false_type
{};

// XXX it's regrettable that this implementation is copied almost
//     exactly from system::detail::generic::uninitialized_copy
//     perhaps generic::uninitialized_copy could call this routine
//     with a default allocator
template<typename Allocator, typename FromSystem, typename ToSystem, typename InputIterator, typename Pointer>
__host__ __device__
  typename enable_if_convertible<
    FromSystem,
    ToSystem,
    Pointer
  >::type
    uninitialized_copy_with_allocator(Allocator &a,
                                      thrust::execution_policy<FromSystem> &from_system,
                                      thrust::execution_policy<ToSystem> &to_system,
                                      InputIterator first,
                                      InputIterator last,
                                      Pointer result)
{
  // zip up the iterators
  typedef thrust::tuple<InputIterator,Pointer> IteratorTuple;
  typedef thrust::zip_iterator<IteratorTuple>  ZipIterator;

  ZipIterator begin = thrust::make_zip_iterator(thrust::make_tuple(first,result));
  ZipIterator end = begin;

  // get a zip_iterator pointing to the end
  const typename thrust::iterator_difference<InputIterator>::type n = thrust::distance(first,last);
  thrust::advance(end,n);

  // create a functor
  typedef typename iterator_traits<InputIterator>::value_type InputType;
  typedef typename iterator_traits<Pointer>::value_type       OutputType;

  // do the for_each
  // note we use to_system to dispatch the for_each
  thrust::for_each(to_system, begin, end, copy_construct_with_allocator<Allocator,InputType,OutputType>(a));

  // return the end of the output range
  return thrust::get<1>(end.get_iterator_tuple());
}

// XXX it's regrettable that this implementation is copied almost
//     exactly from system::detail::generic::uninitialized_copy_n
//     perhaps generic::uninitialized_copy_n could call this routine
//     with a default allocator
template<typename Allocator, typename FromSystem, typename ToSystem, typename InputIterator, typename Size, typename Pointer>
__host__ __device__
  typename enable_if_convertible<
    FromSystem,
    ToSystem,
    Pointer
  >::type
    uninitialized_copy_with_allocator_n(Allocator &a,
                                        thrust::execution_policy<FromSystem> &from_system,
                                        thrust::execution_policy<ToSystem> &to_system,
                                        InputIterator first,
                                        Size n,
                                        Pointer result)
{
  // zip up the iterators
  typedef thrust::tuple<InputIterator,Pointer> IteratorTuple;
  typedef thrust::zip_iterator<IteratorTuple>  ZipIterator;

  ZipIterator begin = thrust::make_zip_iterator(thrust::make_tuple(first,result));

  // create a functor
  typedef typename iterator_traits<InputIterator>::value_type InputType;
  typedef typename iterator_traits<Pointer>::value_type       OutputType;

  // do the for_each_n
  // note we use to_system to dispatch the for_each_n
  ZipIterator end = thrust::for_each_n(to_system, begin, n, copy_construct_with_allocator<Allocator,InputType,OutputType>(a));

  // return the end of the output range
  return thrust::get<1>(end.get_iterator_tuple());
}

template<typename Allocator, typename FromSystem, typename ToSystem, typename InputIterator, typename Pointer>
__host__ __device__
  typename disable_if_convertible<
    FromSystem,
    ToSystem,
    Pointer
  >::type
    uninitialized_copy_with_allocator(Allocator &,
                                      thrust::execution_policy<FromSystem> &from_system,
                                      thrust::execution_policy<ToSystem> &to_system,
                                      InputIterator first,
                                      InputIterator last,
                                      Pointer result)
{
  // the systems aren't trivially interoperable
  // just call two_system_copy and hope for the best
  return thrust::detail::two_system_copy(from_system, to_system, first, last, result);
} // end uninitialized_copy_with_allocator()

template<typename Allocator, typename FromSystem, typename ToSystem, typename InputIterator, typename Size, typename Pointer>
__host__ __device__
  typename disable_if_convertible<
    FromSystem,
    ToSystem,
    Pointer
  >::type
    uninitialized_copy_with_allocator_n(Allocator &,
                                        thrust::execution_policy<FromSystem> &from_system,
                                        thrust::execution_policy<ToSystem> &to_system,
                                        InputIterator first,
                                        Size n,
                                        Pointer result)
{
  // the systems aren't trivially interoperable
  // just call two_system_copy_n and hope for the best
  return thrust::detail::two_system_copy_n(from_system, to_system, first, n, result);
} // end uninitialized_copy_with_allocator_n()

template<typename FromSystem, typename Allocator, typename InputIterator, typename Pointer>
__host__ __device__
  typename disable_if<
    needs_copy_construct_via_allocator<
      Allocator,
      typename pointer_element<Pointer>::type
    >::value,
    Pointer
  >::type
    copy_construct_range(thrust::execution_policy<FromSystem> &from_system,
                         Allocator &a,
                         InputIterator first,
                         InputIterator last,
                         Pointer result)
{
  // just call two_system_copy
  return thrust::detail::two_system_copy(from_system, allocator_system<Allocator>::get(a), first, last, result);
}

template<typename FromSystem, typename Allocator, typename InputIterator, typename Size, typename Pointer>
__host__ __device__
  typename disable_if<
    needs_copy_construct_via_allocator<
      Allocator,
      typename pointer_element<Pointer>::type
    >::value,
    Pointer
  >::type
    copy_construct_range_n(thrust::execution_policy<FromSystem> &from_system,
                           Allocator &a,
                           InputIterator first,
                           Size n,
                           Pointer result)
{
  // just call two_system_copy_n
  return thrust::detail::two_system_copy_n(from_system, allocator_system<Allocator>::get(a), first, n, result);
}

template<typename FromSystem, typename Allocator, typename InputIterator, typename Pointer>
__host__ __device__
  typename enable_if<
    needs_copy_construct_via_allocator<
      Allocator,
      typename pointer_element<Pointer>::type
    >::value,
    Pointer
  >::type
    copy_construct_range(thrust::execution_policy<FromSystem> &from_system,
                         Allocator &a,
                         InputIterator first,
                         InputIterator last,
                         Pointer result)
{
  return uninitialized_copy_with_allocator(a, from_system, allocator_system<Allocator>::get(a), first, last, result);
}

template<typename FromSystem, typename Allocator, typename InputIterator, typename Size, typename Pointer>
__host__ __device__
  typename enable_if<
    needs_copy_construct_via_allocator<
      Allocator,
      typename pointer_element<Pointer>::type
    >::value,
    Pointer
  >::type
    copy_construct_range_n(thrust::execution_policy<FromSystem> &from_system,
                           Allocator &a,
                           InputIterator first,
                           Size n,
                           Pointer result)
{
  return uninitialized_copy_with_allocator_n(a, from_system, allocator_system<Allocator>::get(a), first, n, result);
}

} // end allocator_traits_detail

template<typename System, typename Allocator, typename InputIterator, typename Pointer>
__host__ __device__
  Pointer copy_construct_range(thrust::execution_policy<System> &from_system,
                               Allocator &a,
                               InputIterator first,
                               InputIterator last,
                               Pointer result)
{
  return allocator_traits_detail::copy_construct_range(from_system, a, first, last, result);
}

template<typename System, typename Allocator, typename InputIterator, typename Size, typename Pointer>
__host__ __device__
  Pointer copy_construct_range_n(thrust::execution_policy<System> &from_system,
                                 Allocator &a,
                                 InputIterator first,
                                 Size n,
                                 Pointer result)
{
  return allocator_traits_detail::copy_construct_range_n(from_system, a, first, n, result);
}

} // end detail
} // end thrust

<commit_msg>Add const to the policy arguments of uninitialized_copy_with_allocator like all the other similar algorithms.<commit_after>/*
 *  Copyright 2008-2012 NVIDIA Corporation
 *
 *  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 <thrust/detail/config.h>
#include <thrust/detail/allocator/allocator_traits.h>
#include <thrust/detail/type_traits/pointer_traits.h>
#include <thrust/iterator/iterator_traits.h>
#include <thrust/detail/copy.h>
#include <thrust/tuple.h>
#include <thrust/advance.h>
#include <thrust/distance.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/for_each.h>
#include <memory>

namespace thrust
{
namespace detail
{
namespace allocator_traits_detail
{

template<typename Allocator, typename InputType, typename OutputType>
  struct copy_construct_with_allocator
{
  Allocator &a;

  __host__ __device__
  copy_construct_with_allocator(Allocator &a)
    : a(a)
  {}

  template<typename Tuple>
  inline __host__ __device__
  void operator()(Tuple t)
  {
    const InputType &in = thrust::get<0>(t);
    OutputType &out = thrust::get<1>(t);

    allocator_traits<Allocator>::construct(a, &out, in);
  }
};

template<typename Allocator, typename T>
  struct needs_copy_construct_via_allocator
    : has_member_construct2<
        Allocator,
        T,
        T
      >
{};

// we know that std::allocator::construct's only effect is to call T's
// copy constructor, so we needn't use it for copy construction
template<typename U, typename T>
  struct needs_copy_construct_via_allocator<std::allocator<U>, T>
    : thrust::detail::false_type
{};

// XXX it's regrettable that this implementation is copied almost
//     exactly from system::detail::generic::uninitialized_copy
//     perhaps generic::uninitialized_copy could call this routine
//     with a default allocator
template<typename Allocator, typename FromSystem, typename ToSystem, typename InputIterator, typename Pointer>
__host__ __device__
  typename enable_if_convertible<
    FromSystem,
    ToSystem,
    Pointer
  >::type
    uninitialized_copy_with_allocator(Allocator &a,
                                      const thrust::execution_policy<FromSystem> &from_system,
                                      const thrust::execution_policy<ToSystem> &to_system,
                                      InputIterator first,
                                      InputIterator last,
                                      Pointer result)
{
  // zip up the iterators
  typedef thrust::tuple<InputIterator,Pointer> IteratorTuple;
  typedef thrust::zip_iterator<IteratorTuple>  ZipIterator;

  ZipIterator begin = thrust::make_zip_iterator(thrust::make_tuple(first,result));
  ZipIterator end = begin;

  // get a zip_iterator pointing to the end
  const typename thrust::iterator_difference<InputIterator>::type n = thrust::distance(first,last);
  thrust::advance(end,n);

  // create a functor
  typedef typename iterator_traits<InputIterator>::value_type InputType;
  typedef typename iterator_traits<Pointer>::value_type       OutputType;

  // do the for_each
  // note we use to_system to dispatch the for_each
  thrust::for_each(to_system, begin, end, copy_construct_with_allocator<Allocator,InputType,OutputType>(a));

  // return the end of the output range
  return thrust::get<1>(end.get_iterator_tuple());
}

// XXX it's regrettable that this implementation is copied almost
//     exactly from system::detail::generic::uninitialized_copy_n
//     perhaps generic::uninitialized_copy_n could call this routine
//     with a default allocator
template<typename Allocator, typename FromSystem, typename ToSystem, typename InputIterator, typename Size, typename Pointer>
__host__ __device__
  typename enable_if_convertible<
    FromSystem,
    ToSystem,
    Pointer
  >::type
    uninitialized_copy_with_allocator_n(Allocator &a,
                                        const thrust::execution_policy<FromSystem> &from_system,
                                        const thrust::execution_policy<ToSystem> &to_system,
                                        InputIterator first,
                                        Size n,
                                        Pointer result)
{
  // zip up the iterators
  typedef thrust::tuple<InputIterator,Pointer> IteratorTuple;
  typedef thrust::zip_iterator<IteratorTuple>  ZipIterator;

  ZipIterator begin = thrust::make_zip_iterator(thrust::make_tuple(first,result));

  // create a functor
  typedef typename iterator_traits<InputIterator>::value_type InputType;
  typedef typename iterator_traits<Pointer>::value_type       OutputType;

  // do the for_each_n
  // note we use to_system to dispatch the for_each_n
  ZipIterator end = thrust::for_each_n(to_system, begin, n, copy_construct_with_allocator<Allocator,InputType,OutputType>(a));

  // return the end of the output range
  return thrust::get<1>(end.get_iterator_tuple());
}

template<typename Allocator, typename FromSystem, typename ToSystem, typename InputIterator, typename Pointer>
__host__ __device__
  typename disable_if_convertible<
    FromSystem,
    ToSystem,
    Pointer
  >::type
    uninitialized_copy_with_allocator(Allocator &,
                                      const thrust::execution_policy<FromSystem> &from_system,
                                      const thrust::execution_policy<ToSystem> &to_system,
                                      InputIterator first,
                                      InputIterator last,
                                      Pointer result)
{
  // the systems aren't trivially interoperable
  // just call two_system_copy and hope for the best
  return thrust::detail::two_system_copy(from_system, to_system, first, last, result);
} // end uninitialized_copy_with_allocator()

template<typename Allocator, typename FromSystem, typename ToSystem, typename InputIterator, typename Size, typename Pointer>
__host__ __device__
  typename disable_if_convertible<
    FromSystem,
    ToSystem,
    Pointer
  >::type
    uninitialized_copy_with_allocator_n(Allocator &,
                                        const thrust::execution_policy<FromSystem> &from_system,
                                        const thrust::execution_policy<ToSystem> &to_system,
                                        InputIterator first,
                                        Size n,
                                        Pointer result)
{
  // the systems aren't trivially interoperable
  // just call two_system_copy_n and hope for the best
  return thrust::detail::two_system_copy_n(from_system, to_system, first, n, result);
} // end uninitialized_copy_with_allocator_n()

template<typename FromSystem, typename Allocator, typename InputIterator, typename Pointer>
__host__ __device__
  typename disable_if<
    needs_copy_construct_via_allocator<
      Allocator,
      typename pointer_element<Pointer>::type
    >::value,
    Pointer
  >::type
    copy_construct_range(thrust::execution_policy<FromSystem> &from_system,
                         Allocator &a,
                         InputIterator first,
                         InputIterator last,
                         Pointer result)
{
  // just call two_system_copy
  return thrust::detail::two_system_copy(from_system, allocator_system<Allocator>::get(a), first, last, result);
}

template<typename FromSystem, typename Allocator, typename InputIterator, typename Size, typename Pointer>
__host__ __device__
  typename disable_if<
    needs_copy_construct_via_allocator<
      Allocator,
      typename pointer_element<Pointer>::type
    >::value,
    Pointer
  >::type
    copy_construct_range_n(thrust::execution_policy<FromSystem> &from_system,
                           Allocator &a,
                           InputIterator first,
                           Size n,
                           Pointer result)
{
  // just call two_system_copy_n
  return thrust::detail::two_system_copy_n(from_system, allocator_system<Allocator>::get(a), first, n, result);
}

template<typename FromSystem, typename Allocator, typename InputIterator, typename Pointer>
__host__ __device__
  typename enable_if<
    needs_copy_construct_via_allocator<
      Allocator,
      typename pointer_element<Pointer>::type
    >::value,
    Pointer
  >::type
    copy_construct_range(thrust::execution_policy<FromSystem> &from_system,
                         Allocator &a,
                         InputIterator first,
                         InputIterator last,
                         Pointer result)
{
  return uninitialized_copy_with_allocator(a, from_system, allocator_system<Allocator>::get(a), first, last, result);
}

template<typename FromSystem, typename Allocator, typename InputIterator, typename Size, typename Pointer>
__host__ __device__
  typename enable_if<
    needs_copy_construct_via_allocator<
      Allocator,
      typename pointer_element<Pointer>::type
    >::value,
    Pointer
  >::type
    copy_construct_range_n(thrust::execution_policy<FromSystem> &from_system,
                           Allocator &a,
                           InputIterator first,
                           Size n,
                           Pointer result)
{
  return uninitialized_copy_with_allocator_n(a, from_system, allocator_system<Allocator>::get(a), first, n, result);
}

} // end allocator_traits_detail

template<typename System, typename Allocator, typename InputIterator, typename Pointer>
__host__ __device__
  Pointer copy_construct_range(thrust::execution_policy<System> &from_system,
                               Allocator &a,
                               InputIterator first,
                               InputIterator last,
                               Pointer result)
{
  return allocator_traits_detail::copy_construct_range(from_system, a, first, last, result);
}

template<typename System, typename Allocator, typename InputIterator, typename Size, typename Pointer>
__host__ __device__
  Pointer copy_construct_range_n(thrust::execution_policy<System> &from_system,
                                 Allocator &a,
                                 InputIterator first,
                                 Size n,
                                 Pointer result)
{
  return allocator_traits_detail::copy_construct_range_n(from_system, a, first, n, result);
}

} // end detail
} // end thrust

<|endoftext|>


<commit_before>/* ------------------------------------------------
Copyright 2014 AT&T Intellectual Property
   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 <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netdb.h>
#include <unistd.h>

#include "simple_http.h"

#define MAX_HTTP_REQUEST 64 * 1024

// perform HTTP GET and retrieve the json response
int http_get_request(endpoint addr, gs_csp_t url, gs_uint32_t* http_code, gs_sp_t json_response) {

	int sockfd;
	struct sockaddr_in servaddr;
	char request_buf[MAX_HTTP_REQUEST];
	char response_buf[MAX_HTTP_REQUEST];
	char temp_buf[MAX_HTTP_REQUEST];
	char content_type[MAX_HTTP_REQUEST];
	int n;

	char ipstr[16];
	inet_ntop(AF_INET, &addr.ip, ipstr, INET_ADDRSTRLEN);

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (!sockfd) {
		fprintf(stderr, "Unable to create socket for HTTP connection\n");
		return -1;
	}

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = addr.port;
	servaddr.sin_addr.s_addr = addr.ip;

	if (connect(sockfd, (sockaddr*)&servaddr, sizeof(servaddr))) {
		fprintf(stderr, "Unable to connect to HTTP server\n");
		return -1;
	}

	// construct HTTP request
	sprintf(request_buf, "GET %s HTTP/1.0\r\n"
			"Host: %s\r\n"
			"Accept: application/json\r\n"
			"Connection: close\r\n\r\n",
			url, ipstr);

	write(sockfd, request_buf, strlen(request_buf));

	// retrive HTTP response
	char* write_pos = response_buf;
	while ((n = read(sockfd, write_pos, MAX_HTTP_REQUEST)) > 0)
		write_pos += n;
	*write_pos = '\0';
	close(sockfd);

	// split HTTP response into header and the main body
	char* header_end = strstr(response_buf, "\r\n\r\n");
	*header_end = 0;
	strcpy(json_response, header_end + 4);

	// parse HTTP header
	char* header_line = strtok(response_buf, "\r\n");
	int ver1, ver2;

	// extract http response code
	sscanf (header_line, "HTTP/%d.%d %d %s", &ver1, &ver2, http_code, temp_buf);

	// extract content-type
	*content_type = 0;
	while ((header_line = strtok(NULL, "\r\n"))) {
		if (!strncmp(header_line, "Content-Type: ", strlen("Content-Type: "))) {
			strcpy(content_type, header_line + strlen("Content-Type: "));
			if (strcmp(content_type, "application/json")) {
				printf("Invalid Content-Type %s, application/json expected\n", content_type);
				return -1;
			}
			break;		// we only care about Content-Type headers
		}
	}

	if ((*http_code == 200) && (*content_type == 0)) {
		printf("Missing Content-Type in server response, application/json expected\n");
		return -1;
	}

	return 0;
}

// perform HTTP POST request ignoring the response
int http_post_request(endpoint addr, gs_csp_t url, gs_sp_t json_request, gs_uint32_t* http_code) {
	int sockfd;
	struct sockaddr_in servaddr;
	char request_buf[MAX_HTTP_REQUEST];
	char response_buf[MAX_HTTP_REQUEST];
	char temp_buf[MAX_HTTP_REQUEST];
	int n;

	char ipstr[16];
	inet_ntop(AF_INET, &addr.ip, ipstr, INET_ADDRSTRLEN);

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (!sockfd) {
		fprintf(stderr, "Unable to create socket for HTTP connection\n");
		return -1;
	}

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = addr.port;
	servaddr.sin_addr.s_addr = addr.ip;

	if (connect(sockfd, (sockaddr*)&servaddr, sizeof(servaddr))) {
		fprintf(stderr, "Unable to connect to HTTP server\n");
		return -1;
	}

	// construct HTTP request
	sprintf(request_buf, "POST %s HTTP/1.0\r\n"
			"Host: %s\r\n"
			"Content-Type: application/json\r\n"
			"Content-Length: %lu\r\n"
			"Connection: close\r\n\r\n"
			"%s",
			url, ipstr, strlen(json_request), json_request);

	write(sockfd, request_buf, strlen(request_buf));

	// retrive HTTP response
	char* write_pos = response_buf;
	while ((n = read(sockfd, write_pos, MAX_HTTP_REQUEST)) > 0)
		write_pos += n;
	*write_pos = '\0';
	close(sockfd);

	// parse HTTP header
	char* header_line = strtok(response_buf, "\r\n");
	int ver1, ver2;

	// extract http response code
	sscanf (header_line, "HTTP/%d.%d %d %s", &ver1, &ver2, http_code, temp_buf);

	return 0;
}
<commit_msg>Direct all the error messages to stderr<commit_after>/* ------------------------------------------------
Copyright 2014 AT&T Intellectual Property
   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 <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netdb.h>
#include <unistd.h>

#include "simple_http.h"

#define MAX_HTTP_REQUEST 64 * 1024

// perform HTTP GET and retrieve the json response
int http_get_request(endpoint addr, gs_csp_t url, gs_uint32_t* http_code, gs_sp_t json_response) {

	int sockfd;
	struct sockaddr_in servaddr;
	char request_buf[MAX_HTTP_REQUEST];
	char response_buf[MAX_HTTP_REQUEST];
	char temp_buf[MAX_HTTP_REQUEST];
	char content_type[MAX_HTTP_REQUEST];
	int n;

	char ipstr[16];
	inet_ntop(AF_INET, &addr.ip, ipstr, INET_ADDRSTRLEN);

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (!sockfd) {
		fprintf(stderr, "Unable to create socket for HTTP connection\n");
		return -1;
	}

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = addr.port;
	servaddr.sin_addr.s_addr = addr.ip;

	if (connect(sockfd, (sockaddr*)&servaddr, sizeof(servaddr))) {
		fprintf(stderr, "Unable to connect to HTTP server\n");
		return -1;
	}

	// construct HTTP request
	sprintf(request_buf, "GET %s HTTP/1.0\r\n"
			"Host: %s\r\n"
			"Accept: application/json\r\n"
			"Connection: close\r\n\r\n",
			url, ipstr);

	write(sockfd, request_buf, strlen(request_buf));

	// retrive HTTP response
	char* write_pos = response_buf;
	while ((n = read(sockfd, write_pos, MAX_HTTP_REQUEST)) > 0)
		write_pos += n;
	*write_pos = '\0';
	close(sockfd);

	// split HTTP response into header and the main body
	char* header_end = strstr(response_buf, "\r\n\r\n");
	*header_end = 0;
	strcpy(json_response, header_end + 4);

	// parse HTTP header
	char* header_line = strtok(response_buf, "\r\n");
	int ver1, ver2;

	// extract http response code
	sscanf (header_line, "HTTP/%d.%d %d %s", &ver1, &ver2, http_code, temp_buf);

	// extract content-type
	*content_type = 0;
	while ((header_line = strtok(NULL, "\r\n"))) {
		if (!strncmp(header_line, "Content-Type: ", strlen("Content-Type: "))) {
			strcpy(content_type, header_line + strlen("Content-Type: "));
			if (strcmp(content_type, "application/json")) {
				fprintf(stderr, "Invalid Content-Type %s, application/json expected\n", content_type);
				return -1;
			}
			break;		// we only care about Content-Type headers
		}
	}

	if ((*http_code == 200) && (*content_type == 0)) {
		fprintf(stderr, "Missing Content-Type in server response, application/json expected\n");
		return -1;
	}

	return 0;
}

// perform HTTP POST request ignoring the response
int http_post_request(endpoint addr, gs_csp_t url, gs_sp_t json_request, gs_uint32_t* http_code) {
	int sockfd;
	struct sockaddr_in servaddr;
	char request_buf[MAX_HTTP_REQUEST];
	char response_buf[MAX_HTTP_REQUEST];
	char temp_buf[MAX_HTTP_REQUEST];
	int n;

	char ipstr[16];
	inet_ntop(AF_INET, &addr.ip, ipstr, INET_ADDRSTRLEN);

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (!sockfd) {
		fprintf(stderr, "Unable to create socket for HTTP connection\n");
		return -1;
	}

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = addr.port;
	servaddr.sin_addr.s_addr = addr.ip;

	if (connect(sockfd, (sockaddr*)&servaddr, sizeof(servaddr))) {
		fprintf(stderr, "Unable to connect to HTTP server\n");
		return -1;
	}

	// construct HTTP request
	sprintf(request_buf, "POST %s HTTP/1.0\r\n"
			"Host: %s\r\n"
			"Content-Type: application/json\r\n"
			"Content-Length: %lu\r\n"
			"Connection: close\r\n\r\n"
			"%s",
			url, ipstr, strlen(json_request), json_request);

	write(sockfd, request_buf, strlen(request_buf));

	// retrive HTTP response
	char* write_pos = response_buf;
	while ((n = read(sockfd, write_pos, MAX_HTTP_REQUEST)) > 0)
		write_pos += n;
	*write_pos = '\0';
	close(sockfd);

	// parse HTTP header
	char* header_line = strtok(response_buf, "\r\n");
	int ver1, ver2;

	// extract http response code
	sscanf (header_line, "HTTP/%d.%d %d %s", &ver1, &ver2, http_code, temp_buf);

	return 0;
}
<|endoftext|>


<commit_before>#include "yaml.h"
#include "tests.h"
#include <fstream>
#include <iostream>

void run()
{
	std::ifstream fin("tests/test.yaml");

	try {
		YAML::Parser parser(fin);
		YAML::Node doc;
		parser.GetNextDocument(doc);

		std::cout << "name: " << doc["name"] << "\n";
		std::cout << "age: " << doc["age"] << "\n";
	} catch(YAML::TypedKeyNotFound <std::string>& e) {
		std::cout << "Key '" << e.key << "' not found at line " << e.line+1 << ", col " << e.column+1 << "\n";
	} catch(YAML::KeyNotFound& e) {
		std::cout << "Key not found at line " << e.line+1 << ", col " << e.column+1 << "\n";
	} catch(YAML::Exception& e) {
		std::cout << "Error at line " << e.line+1 << ", col " << e.column+1 << ": " << e.msg << "\n";
	}
}

int main(int argc, char **argv)
{
	bool verbose = false;
	for(int i=1;i<argc;i++) {
		if(strcmp(argv[i], "-v") == 0)
			verbose = true;
	}

#ifdef WINDOWS
	_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_CRTDBG_ALLOC_MEM_DF);
#endif // WINDOWS
	Test::RunAll(verbose);
	run();

	return 0;
}
<commit_msg>Included <cstring> for strcmp<commit_after>#include "yaml.h"
#include "tests.h"
#include <fstream>
#include <iostream>
#include <cstring>

void run()
{
	std::ifstream fin("tests/test.yaml");

	try {
		YAML::Parser parser(fin);
		YAML::Node doc;
		parser.GetNextDocument(doc);

		std::cout << "name: " << doc["name"] << "\n";
		std::cout << "age: " << doc["age"] << "\n";
	} catch(YAML::TypedKeyNotFound <std::string>& e) {
		std::cout << "Key '" << e.key << "' not found at line " << e.line+1 << ", col " << e.column+1 << "\n";
	} catch(YAML::KeyNotFound& e) {
		std::cout << "Key not found at line " << e.line+1 << ", col " << e.column+1 << "\n";
	} catch(YAML::Exception& e) {
		std::cout << "Error at line " << e.line+1 << ", col " << e.column+1 << ": " << e.msg << "\n";
	}
}

int main(int argc, char **argv)
{
	bool verbose = false;
	for(int i=1;i<argc;i++) {
		if(std::strcmp(argv[i], "-v") == 0)
			verbose = true;
	}

#ifdef WINDOWS
	_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_CRTDBG_ALLOC_MEM_DF);
#endif // WINDOWS
	Test::RunAll(verbose);
	run();

	return 0;
}
<|endoftext|>


<commit_before>#include "yaml.h"
#include "tests.h"
#include <fstream>
#include <iostream>

void run()
{
	std::ifstream fin("tests/test.yaml");

	try {
		YAML::Parser parser(fin);
		YAML::Node doc;
		parser.GetNextDocument(doc);
		for(unsigned i=0;i<doc.size();i++) {
			bool value;
			doc[i] >> value;
			std::cout << (value ? "true" : "false") << "\n";
		}
	} catch(YAML::Exception&) {
		std::cout << "Error parsing the yaml!\n";
	}
}

int main(int argc, char **argv)
{
	bool verbose = false;
	for(int i=1;i<argc;i++) {
		if(strcmp(argv[i], "-v") == 0)
			verbose = true;
	}

#ifdef WINDOWS
	_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_CRTDBG_ALLOC_MEM_DF);
#endif // WINDOWS
	Test::RunAll(verbose);
	run();

	return 0;
}
<commit_msg>Added line/column data for nodes so they can give better invalid scalar exceptions.<commit_after>#include "yaml.h"
#include "tests.h"
#include <fstream>
#include <iostream>

void run()
{
	std::ifstream fin("tests/test.yaml");

	try {
		YAML::Parser parser(fin);
		YAML::Node doc;
		parser.GetNextDocument(doc);
		for(unsigned i=0;i<doc.size();i++) {
			bool value;
			doc[i] >> value;
			std::cout << (value ? "true" : "false") << "\n";
		}
	} catch(YAML::Exception& e) {
		std::cout << "Error at line " << e.line+1 << ", col " << e.column+1 << ": " << e.msg << "\n";
	}
}

int main(int argc, char **argv)
{
	bool verbose = false;
	for(int i=1;i<argc;i++) {
		if(strcmp(argv[i], "-v") == 0)
			verbose = true;
	}

#ifdef WINDOWS
	_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_CRTDBG_ALLOC_MEM_DF);
#endif // WINDOWS
	Test::RunAll(verbose);
	run();

	return 0;
}
<|endoftext|>


<commit_before>//=============================================================================
// ■ global.hpp
//-----------------------------------------------------------------------------
//   VMDE通用C++头文件。
//=============================================================================

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <ctime>
#include <thread>

#include <ruby.h>

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#define GLM_FORCE_SSE41
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include <portaudio.h>
#include <vorbis/vorbisfile.h>

#include <SOIL.h>

#ifndef _INCLUDE_GLOBAL_H
	#define _INCLUDE_GLOBAL_H
	using namespace std;
	//-------------------------------------------------------------------------
	// ● 定义类型
	//-------------------------------------------------------------------------
	typedef VALUE (*type_ruby_function)(ANYARGS);
	typedef void (*type_free_function)(void*);
	//-------------------------------------------------------------------------
	// ● 定义宏魔法
	//-------------------------------------------------------------------------
	// UNUSED - 标记无用函数参数
	//     int random(int n UNUSED) { return 4; }
	#define UNUSED __attribute__((unused))
	// ARRAY_SIZE - 获取定义的数组大小
	//     int a[56]; → ARRAY_SIZE(a) == 56
	#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
	// MLVN - Macro-Local Variable Name
	// 这是为了不让明文变量名被莫名其妙使用而设计的。
	//     #define TEST do { int MLVN() = 0, MLVN(another) = 0; } while(0)
	#define MLVN(name) My_Lovely_##name##___
	// NTIMES - 执行多次
	//     NTIMES(3) puts("Three or more, use a for");
	#define NTIMES(n) \
		for (unsigned short MLVN(index) = 0; MLVN(index) < (n); MLVN(index)++)
	// TWICE - 执行两次
	//     TWICE a++;
	//     TWICE { a++; b++; }
	#define TWICE NTIMES(2)
	// EXPLOSION!
	// 可以安全地在用户级代码中调用并获得SIGSEGV。
	// 在退出程序时装逼。
	#define EXPLOSION EXP_ASSIGNMENT
	// EXP_ASSIGNMENT - EXPLOSION的赋值实现
	#define EXP_ASSIGNMENT ((void) (*((float*) NULL) = INFINITY))
	// EXP_MEMORY - EXPLOSION的标准C库内存操作实现
	#define EXP_MEMORY ((void) memset(NULL, 233, 1))
	// EXP_SIGNAL - EXPLOSION的标准C库信号实现
	// * 需要#include <csignal>，但本项目没有包含。
	#define EXP_SIGNAL ((void) ((raise(SIGSEGV) == 0) || abort()))
	// EXP_CONSTSTR - EXPLOSION的只读字符串实现
	#define EXP_CONSTSTR ((void) *"" = 0;)
	// EXP_ASM - EXPLOSION的Pentium Pro指令实现
	// * 这个实现不会导致SIGSEGV。
	#define EXP_ASM (__asm__("UD2"))
	// xeFree - 释放内存黑魔法
	#define xefree(pointer) if (pointer) free(pointer)
	//-------------------------------------------------------------------------
	// ● PY Deal For ＭICR0$○F┬ Ｗindoges (ᴚ)
	//Becuase it;s Windoges,I jsut dno't want to use CORERCT ENGRISh &忠闻吔屎炉此
	//-------------------------------------------------------------------------
	#ifdef __CYGWIN__
		#warning This wont work in Cygwin. Try at your own risk.
	#endif
	#ifdef __MINGW32__
		#define EXPORTED extern "C" __declspec(dllexport)
	#else
		#define EXPORTED extern "C"
	#endif

	//-------------------------------------------------------------------------
	// ● Global
	//-------------------------------------------------------------------------
	#define GAME_NAME "VM / 76"

	//-------------------------------------------------------------------------
	// ● shaders.cpp
	//-------------------------------------------------------------------------
	class Shaders {
	public:
		GLuint basic_2D_vsh;
		GLuint basic_2D_fsh;
		GLuint shaderProgram;

	public:
		void init_shaders(const GLchar* vsh_src_ptr, const GLchar* fsh_src_ptr);
		void link_program();
	};

	extern const GLchar* temp_vertexShaderSource;
	extern const GLchar* temp_fragmentShaderSource;

	extern Shaders* main_shader;
	//-------------------------------------------------------------------------
	// ● ruby_connection.cpp
	//-------------------------------------------------------------------------
	void init_ruby_classes();
	void init_ruby_modules();
	//-------------------------------------------------------------------------
	// ● init.cpp
	//-------------------------------------------------------------------------
	void init_engine(int w, int h);
	void setup_viewport();
	void init_vmde(int w, int h);
	void reload_shaders();
	//-------------------------------------------------------------------------
	// ● main.cpp
	//-------------------------------------------------------------------------
	void glfw_error_callback(int error, const char* description);
	void main_draw_start();
	void main_draw_end();
	void main_set_brightness(float b);
	void matrix2D();

	extern glm::mat4 projection, view;
	//-------------------------------------------------------------------------
	// ● resources.cpp
	//-------------------------------------------------------------------------
	namespace Res {
		class Texture {
		public:
			GLuint texture;
			int width, height;
			Texture(char* file, GLuint index, GLuint sh);
		};

		extern Texture* tex_unit[16];
	}
	//-------------------------------------------------------------------------
	// ● util.cpp
	//-------------------------------------------------------------------------
	#define DEBUG_ENVIRONMENT "VMDrawEngine"
	// log - Util::log_internal的方便缩写，可以直接得到当前函数名
	//     log("%p", log);
	#define log(...) Util::log_internal(__func__, __VA_ARGS__)
	namespace Util {
		extern const float PIf;
		extern const double PI;
		#define PId PI
		void log_internal(const char* function_name, const char* format, ...);
	}
#endif
<commit_msg>强化xefree<commit_after>//=============================================================================
// ■ global.hpp
//-----------------------------------------------------------------------------
//   VMDE通用C++头文件。
//=============================================================================

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <ctime>
#include <thread>

#include <ruby.h>

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#define GLM_FORCE_SSE41
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include <portaudio.h>
#include <vorbis/vorbisfile.h>

#include <SOIL.h>

#ifndef _INCLUDE_GLOBAL_H
	#define _INCLUDE_GLOBAL_H
	using namespace std;
	//-------------------------------------------------------------------------
	// ● 定义类型
	//-------------------------------------------------------------------------
	typedef VALUE (*type_ruby_function)(ANYARGS);
	typedef void (*type_free_function)(void*);
	//-------------------------------------------------------------------------
	// ● 定义宏魔法
	//-------------------------------------------------------------------------
	// UNUSED - 标记无用函数参数
	//     int random(int n UNUSED) { return 4; }
	#define UNUSED __attribute__((unused))
	// ARRAY_SIZE - 获取定义的数组大小
	//     int a[56]; → ARRAY_SIZE(a) == 56
	#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
	// MLVN - Macro-Local Variable Name
	// 这是为了不让明文变量名被莫名其妙使用而设计的。
	//     #define TEST do { int MLVN() = 0, MLVN(another) = 0; } while(0)
	#define MLVN(name) My_Lovely_##name##___
	// NTIMES - 执行多次
	//     NTIMES(3) puts("Three or more, use a for");
	#define NTIMES(n) \
		for (unsigned short MLVN(index) = 0; MLVN(index) < (n); MLVN(index)++)
	// TWICE - 执行两次
	//     TWICE a++;
	//     TWICE { a++; b++; }
	#define TWICE NTIMES(2)
	// EXPLOSION!
	// 可以安全地在用户级代码中调用并获得SIGSEGV。
	// 在退出程序时装逼。
	#define EXPLOSION EXP_ASSIGNMENT
	// EXP_ASSIGNMENT - EXPLOSION的赋值实现
	#define EXP_ASSIGNMENT ((void) (*((float*) NULL) = INFINITY))
	// EXP_MEMORY - EXPLOSION的标准C库内存操作实现
	#define EXP_MEMORY ((void) memset(NULL, 233, 1))
	// EXP_SIGNAL - EXPLOSION的标准C库信号实现
	// * 需要#include <csignal>，但本项目没有包含。
	#define EXP_SIGNAL ((void) ((raise(SIGSEGV) == 0) || abort()))
	// EXP_CONSTSTR - EXPLOSION的只读字符串实现
	#define EXP_CONSTSTR ((void) *"" = 0;)
	// EXP_ASM - EXPLOSION的Pentium Pro指令实现
	// * 这个实现不会导致SIGSEGV。
	#define EXP_ASM (__asm__("UD2"))
	// xeFree - 释放内存黑魔法
	#define xefree(pointer) do { if (pointer) free(pointer); } while (false)
	//-------------------------------------------------------------------------
	// ● PY Deal For ＭICR0$○F┬ Ｗindoges (ᴚ)
	//Becuase it;s Windoges,I jsut dno't want to use CORERCT ENGRISh &忠闻吔屎炉此
	//-------------------------------------------------------------------------
	#ifdef __CYGWIN__
		#warning This wont work in Cygwin. Try at your own risk.
	#endif
	#ifdef __MINGW32__
		#define EXPORTED extern "C" __declspec(dllexport)
	#else
		#define EXPORTED extern "C"
	#endif

	//-------------------------------------------------------------------------
	// ● Global
	//-------------------------------------------------------------------------
	#define GAME_NAME "VM / 76"

	//-------------------------------------------------------------------------
	// ● shaders.cpp
	//-------------------------------------------------------------------------
	class Shaders {
	public:
		GLuint basic_2D_vsh;
		GLuint basic_2D_fsh;
		GLuint shaderProgram;

	public:
		void init_shaders(const GLchar* vsh_src_ptr, const GLchar* fsh_src_ptr);
		void link_program();
	};

	extern const GLchar* temp_vertexShaderSource;
	extern const GLchar* temp_fragmentShaderSource;

	extern Shaders* main_shader;
	//-------------------------------------------------------------------------
	// ● ruby_connection.cpp
	//-------------------------------------------------------------------------
	void init_ruby_classes();
	void init_ruby_modules();
	//-------------------------------------------------------------------------
	// ● init.cpp
	//-------------------------------------------------------------------------
	void init_engine(int w, int h);
	void setup_viewport();
	void init_vmde(int w, int h);
	void reload_shaders();
	//-------------------------------------------------------------------------
	// ● main.cpp
	//-------------------------------------------------------------------------
	void glfw_error_callback(int error, const char* description);
	void main_draw_start();
	void main_draw_end();
	void main_set_brightness(float b);
	void matrix2D();

	extern glm::mat4 projection, view;
	//-------------------------------------------------------------------------
	// ● resources.cpp
	//-------------------------------------------------------------------------
	namespace Res {
		class Texture {
		public:
			GLuint texture;
			int width, height;
			Texture(char* file, GLuint index, GLuint sh);
		};

		extern Texture* tex_unit[16];
	}
	//-------------------------------------------------------------------------
	// ● util.cpp
	//-------------------------------------------------------------------------
	#define DEBUG_ENVIRONMENT "VMDrawEngine"
	// log - Util::log_internal的方便缩写，可以直接得到当前函数名
	//     log("%p", log);
	#define log(...) Util::log_internal(__func__, __VA_ARGS__)
	namespace Util {
		extern const float PIf;
		extern const double PI;
		#define PId PI
		void log_internal(const char* function_name, const char* format, ...);
	}
#endif
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/**
 * \file lower_named_interface_blocks.cpp
 *
 * This lowering pass converts all interface blocks with instance names
 * into interface blocks without an instance name.
 *
 * For example, the following shader:
 *
 *   out block {
 *     float block_var;
 *   } inst_name;
 *
 *   main()
 *   {
 *     inst_name.block_var = 0.0;
 *   }
 *
 * Is rewritten to:
 *
 *   out block {
 *     float block_var;
 *   };
 *
 *   main()
 *   {
 *     block_var = 0.0;
 *   }
 *
 * This takes place after the shader code has already been verified with
 * the interface name in place.
 *
 * The linking phase will use the interface block name rather than the
 * interface's instance name when linking interfaces.
 *
 * This modification to the ir allows our currently existing dead code
 * elimination to work with interface blocks without changes.
 */

#include "glsl_symbol_table.h"
#include "ir.h"
#include "ir_optimization.h"
#include "ir_rvalue_visitor.h"
#include "program/hash_table.h"

namespace {

class flatten_named_interface_blocks_declarations : public ir_rvalue_visitor
{
public:
   void * const mem_ctx;
   hash_table *interface_namespace;

   flatten_named_interface_blocks_declarations(void *mem_ctx)
      : mem_ctx(mem_ctx),
        interface_namespace(NULL)
   {
   }

   void run(exec_list *instructions);

   virtual ir_visitor_status visit_leave(ir_assignment *);
   virtual void handle_rvalue(ir_rvalue **rvalue);
};

} /* anonymous namespace */

void
flatten_named_interface_blocks_declarations::run(exec_list *instructions)
{
   interface_namespace = hash_table_ctor(0, hash_table_string_hash,
                                         hash_table_string_compare);

   /* First pass: adjust instance block variables with an instance name
    * to not have an instance name.
    *
    * The interface block variables are stored in the interface_namespace
    * hash table so they can be used in the second pass.
    */
   foreach_list_safe(node, instructions) {
      ir_variable *var = ((ir_instruction *) node)->as_variable();
      if (!var || !var->is_interface_instance())
         continue;

      /* It should be possible to handle uniforms during this pass,
       * but, this will require changes to the other uniform block
       * support code.
       */
      if (var->mode == ir_var_uniform)
         continue;

      const glsl_type * iface_t = var->type;
      const glsl_type * array_t = NULL;
      exec_node *insert_pos = var;

      if (iface_t->is_array()) {
         array_t = iface_t;
         iface_t = array_t->fields.array;
      }

      assert (iface_t->is_interface());

      for (unsigned i = 0; i < iface_t->length; i++) {
         const char * field_name = iface_t->fields.structure[i].name;
         char *iface_field_name =
            ralloc_asprintf(mem_ctx, "%s.%s",
                            iface_t->name, field_name);

         ir_variable *found_var =
            (ir_variable *) hash_table_find(interface_namespace,
                                            iface_field_name);
         if (!found_var) {
            ir_variable *new_var;
            char *var_name =
               ralloc_strdup(mem_ctx, iface_t->fields.structure[i].name);
            if (array_t == NULL) {
               new_var =
                  new(mem_ctx) ir_variable(iface_t->fields.structure[i].type,
                                           var_name,
                                           (ir_variable_mode) var->mode);
            } else {
               const glsl_type *new_array_type =
                  glsl_type::get_array_instance(
                     iface_t->fields.structure[i].type,
                     array_t->length);
               new_var =
                  new(mem_ctx) ir_variable(new_array_type,
                                           var_name,
                                           (ir_variable_mode) var->mode);
            }
            new_var->location = iface_t->fields.structure[i].location;

            new_var->init_interface_type(iface_t);
            hash_table_insert(interface_namespace, new_var,
                              iface_field_name);
            insert_pos->insert_after(new_var);
            insert_pos = new_var;
         }
      }
      var->remove();
   }

   /* Second pass: visit all ir_dereference_record instances, and if they
    * reference an interface block, then flatten the refererence out.
    */
   visit_list_elements(this, instructions);
   hash_table_dtor(interface_namespace);
   interface_namespace = NULL;
}

ir_visitor_status
flatten_named_interface_blocks_declarations::visit_leave(ir_assignment *ir)
{
   ir_dereference_record *lhs_rec = ir->lhs->as_dereference_record();
   if (lhs_rec) {
      ir_rvalue *lhs_rec_tmp = lhs_rec;
      handle_rvalue(&lhs_rec_tmp);
      if (lhs_rec_tmp != lhs_rec) {
         ir->set_lhs(lhs_rec_tmp);
      }
   }
   return rvalue_visit(ir);
}

void
flatten_named_interface_blocks_declarations::handle_rvalue(ir_rvalue **rvalue)
{
   if (*rvalue == NULL)
      return;

   ir_dereference_record *ir = (*rvalue)->as_dereference_record();
   if (ir == NULL)
      return;

   ir_variable *var = ir->variable_referenced();
   if (var == NULL)
      return;

   if (!var->is_interface_instance())
      return;

   /* It should be possible to handle uniforms during this pass,
    * but, this will require changes to the other uniform block
    * support code.
    */
   if (var->mode == ir_var_uniform)
      return;

   if (var->get_interface_type() != NULL) {
      char *iface_field_name =
         ralloc_asprintf(mem_ctx, "%s.%s", var->get_interface_type()->name,
                         ir->field);
      /* Find the variable in the set of flattened interface blocks */
      ir_variable *found_var =
         (ir_variable *) hash_table_find(interface_namespace,
                                         iface_field_name);
      assert(found_var);

      ir_dereference_variable *deref_var =
         new(mem_ctx) ir_dereference_variable(found_var);

      ir_dereference_array *deref_array =
         ir->record->as_dereference_array();
      if (deref_array != NULL) {
         *rvalue =
            new(mem_ctx) ir_dereference_array(deref_var,
                                              deref_array->array_index);
      } else {
         *rvalue = deref_var;
      }
   }
}

void
lower_named_interface_blocks(void *mem_ctx, gl_shader *shader)
{
   flatten_named_interface_blocks_declarations v_decl(mem_ctx);
   v_decl.run(shader->ir);
}

<commit_msg>glsl: set explicit_location correctly in lower_named_interface_blocks.<commit_after>/*
 * Copyright (c) 2013 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/**
 * \file lower_named_interface_blocks.cpp
 *
 * This lowering pass converts all interface blocks with instance names
 * into interface blocks without an instance name.
 *
 * For example, the following shader:
 *
 *   out block {
 *     float block_var;
 *   } inst_name;
 *
 *   main()
 *   {
 *     inst_name.block_var = 0.0;
 *   }
 *
 * Is rewritten to:
 *
 *   out block {
 *     float block_var;
 *   };
 *
 *   main()
 *   {
 *     block_var = 0.0;
 *   }
 *
 * This takes place after the shader code has already been verified with
 * the interface name in place.
 *
 * The linking phase will use the interface block name rather than the
 * interface's instance name when linking interfaces.
 *
 * This modification to the ir allows our currently existing dead code
 * elimination to work with interface blocks without changes.
 */

#include "glsl_symbol_table.h"
#include "ir.h"
#include "ir_optimization.h"
#include "ir_rvalue_visitor.h"
#include "program/hash_table.h"

namespace {

class flatten_named_interface_blocks_declarations : public ir_rvalue_visitor
{
public:
   void * const mem_ctx;
   hash_table *interface_namespace;

   flatten_named_interface_blocks_declarations(void *mem_ctx)
      : mem_ctx(mem_ctx),
        interface_namespace(NULL)
   {
   }

   void run(exec_list *instructions);

   virtual ir_visitor_status visit_leave(ir_assignment *);
   virtual void handle_rvalue(ir_rvalue **rvalue);
};

} /* anonymous namespace */

void
flatten_named_interface_blocks_declarations::run(exec_list *instructions)
{
   interface_namespace = hash_table_ctor(0, hash_table_string_hash,
                                         hash_table_string_compare);

   /* First pass: adjust instance block variables with an instance name
    * to not have an instance name.
    *
    * The interface block variables are stored in the interface_namespace
    * hash table so they can be used in the second pass.
    */
   foreach_list_safe(node, instructions) {
      ir_variable *var = ((ir_instruction *) node)->as_variable();
      if (!var || !var->is_interface_instance())
         continue;

      /* It should be possible to handle uniforms during this pass,
       * but, this will require changes to the other uniform block
       * support code.
       */
      if (var->mode == ir_var_uniform)
         continue;

      const glsl_type * iface_t = var->type;
      const glsl_type * array_t = NULL;
      exec_node *insert_pos = var;

      if (iface_t->is_array()) {
         array_t = iface_t;
         iface_t = array_t->fields.array;
      }

      assert (iface_t->is_interface());

      for (unsigned i = 0; i < iface_t->length; i++) {
         const char * field_name = iface_t->fields.structure[i].name;
         char *iface_field_name =
            ralloc_asprintf(mem_ctx, "%s.%s",
                            iface_t->name, field_name);

         ir_variable *found_var =
            (ir_variable *) hash_table_find(interface_namespace,
                                            iface_field_name);
         if (!found_var) {
            ir_variable *new_var;
            char *var_name =
               ralloc_strdup(mem_ctx, iface_t->fields.structure[i].name);
            if (array_t == NULL) {
               new_var =
                  new(mem_ctx) ir_variable(iface_t->fields.structure[i].type,
                                           var_name,
                                           (ir_variable_mode) var->mode);
            } else {
               const glsl_type *new_array_type =
                  glsl_type::get_array_instance(
                     iface_t->fields.structure[i].type,
                     array_t->length);
               new_var =
                  new(mem_ctx) ir_variable(new_array_type,
                                           var_name,
                                           (ir_variable_mode) var->mode);
            }
            new_var->location = iface_t->fields.structure[i].location;
            new_var->explicit_location = (new_var->location >= 0);

            new_var->init_interface_type(iface_t);
            hash_table_insert(interface_namespace, new_var,
                              iface_field_name);
            insert_pos->insert_after(new_var);
            insert_pos = new_var;
         }
      }
      var->remove();
   }

   /* Second pass: visit all ir_dereference_record instances, and if they
    * reference an interface block, then flatten the refererence out.
    */
   visit_list_elements(this, instructions);
   hash_table_dtor(interface_namespace);
   interface_namespace = NULL;
}

ir_visitor_status
flatten_named_interface_blocks_declarations::visit_leave(ir_assignment *ir)
{
   ir_dereference_record *lhs_rec = ir->lhs->as_dereference_record();
   if (lhs_rec) {
      ir_rvalue *lhs_rec_tmp = lhs_rec;
      handle_rvalue(&lhs_rec_tmp);
      if (lhs_rec_tmp != lhs_rec) {
         ir->set_lhs(lhs_rec_tmp);
      }
   }
   return rvalue_visit(ir);
}

void
flatten_named_interface_blocks_declarations::handle_rvalue(ir_rvalue **rvalue)
{
   if (*rvalue == NULL)
      return;

   ir_dereference_record *ir = (*rvalue)->as_dereference_record();
   if (ir == NULL)
      return;

   ir_variable *var = ir->variable_referenced();
   if (var == NULL)
      return;

   if (!var->is_interface_instance())
      return;

   /* It should be possible to handle uniforms during this pass,
    * but, this will require changes to the other uniform block
    * support code.
    */
   if (var->mode == ir_var_uniform)
      return;

   if (var->get_interface_type() != NULL) {
      char *iface_field_name =
         ralloc_asprintf(mem_ctx, "%s.%s", var->get_interface_type()->name,
                         ir->field);
      /* Find the variable in the set of flattened interface blocks */
      ir_variable *found_var =
         (ir_variable *) hash_table_find(interface_namespace,
                                         iface_field_name);
      assert(found_var);

      ir_dereference_variable *deref_var =
         new(mem_ctx) ir_dereference_variable(found_var);

      ir_dereference_array *deref_array =
         ir->record->as_dereference_array();
      if (deref_array != NULL) {
         *rvalue =
            new(mem_ctx) ir_dereference_array(deref_var,
                                              deref_array->array_index);
      } else {
         *rvalue = deref_var;
      }
   }
}

void
lower_named_interface_blocks(void *mem_ctx, gl_shader *shader)
{
   flatten_named_interface_blocks_declarations v_decl(mem_ctx);
   v_decl.run(shader->ir);
}

<|endoftext|>


<commit_before>#include <iostream>
#include <map>
#include <regex>
#include <string>
#include <vector>

#include "persistenceDiagrams/IO.hh"
#include "persistenceDiagrams/PersistenceDiagram.hh"
#include "persistenceDiagrams/PersistenceIndicatorFunction.hh"

#include "utilities/Filesystem.hh"

using DataType                     = double;
using PersistenceDiagram           = aleph::PersistenceDiagram<DataType>;
using PersistenceIndicatorFunction = aleph::math::StepFunction<DataType>;

/*
  Auxiliary structure for describing a data set. I need this in order to
  figure out the corresponding dimension of the persistence diagram.
*/

struct DataSet
{
  std::string filename;
  unsigned dimension;

  PersistenceDiagram persistenceDiagram;
  PersistenceIndicatorFunction persistenceIndicatorFunction;
};

int main( int argc, char** argv )
{
  if( argc <= 1 )
  {
    // TODO: Show usage
    return -1;
  }

  // Maps data sets to file names. Whether a new filename constitutes
  // a new data set is decided by taking a look at the prefix of the
  // filename.
  std::map<std::string, std::vector<DataSet> > dataSets;

  // TODO: Make this regular expression more, well, 'expressive' and
  // support more methods of specifying a dimension.
  std::regex reDataSetPrefix( "(.*)_k([[:digit:]]+)\\.txt" );
  std::smatch matches;

  // Get filenames & prefixes ------------------------------------------

  {
    std::vector<std::string> filenames;
    filenames.reserve( argc - 1 );

    for( int i = 1; i < argc; i++ )
      filenames.push_back( argv[i] );

    for( auto&& filename : filenames )
    {
      if( std::regex_match( filename, matches, reDataSetPrefix ) )
      {
        auto name      = matches[1];
        auto dimension = unsigned( std::stoul( matches[2] ) );

        dataSets[name].push_back( { filename, dimension, {}, {} } );
      }
    }
  }

  // Load persistence diagrams -----------------------------------------

  std::vector<PersistenceDiagram> persistenceDiagrams;

  for( auto&& pair : dataSets )
  {
    for( auto&& dataSet : pair.second )
    {
      std::cerr << "* Processing '" << dataSet.filename << "'...";

      dataSet.persistenceDiagram = aleph::load<DataType>( dataSet.filename );

      // FIXME: This is only required in order to ensure that the
      // persistence indicator function has a finite integral; it
      // can be solved more elegantly by using a special value to
      // indicate infinite intervals.
      dataSet.persistenceDiagram.removeUnpaired();

      dataSet.persistenceIndicatorFunction
         = aleph::persistenceIndicatorFunction( dataSet.persistenceDiagram );

      std::cerr << "finished\n";
    }
  }
}
<commit_msg>Implemented distance calculations between matching indicator functions<commit_after>#include <algorithm>
#include <iostream>
#include <limits>
#include <map>
#include <regex>
#include <string>
#include <vector>

#include "persistenceDiagrams/IO.hh"
#include "persistenceDiagrams/PersistenceDiagram.hh"
#include "persistenceDiagrams/PersistenceIndicatorFunction.hh"

#include "utilities/Filesystem.hh"

using DataType                     = double;
using PersistenceDiagram           = aleph::PersistenceDiagram<DataType>;
using PersistenceIndicatorFunction = aleph::math::StepFunction<DataType>;

/*
  Auxiliary structure for describing a data set. I need this in order to
  figure out the corresponding dimension of the persistence diagram.
*/

struct DataSet
{
  std::string filename;
  unsigned dimension;

  PersistenceDiagram persistenceDiagram;
  PersistenceIndicatorFunction persistenceIndicatorFunction;
};

// Calculates the distance between two data sets. This requires enumerating all
// dimensions, and finding the corresponding persistence indicator function. If
// no such function exists, the function uses the norm of the function.
double distance( const std::vector<DataSet>& dataSet1, const std::vector<DataSet>& dataSet2, unsigned minDimension, unsigned maxDimension )
{
  auto getPersistenceIndicatorFunction = [] ( const std::vector<DataSet>& dataSet, unsigned dimension )
  {
    auto it = std::find_if( dataSet.begin(), dataSet.end(),
                            [&dimension] ( const DataSet& dataSet )
                            {
                              return dataSet.dimension == dimension;
                            } );

    if( it != dataSet.end() )
      return it->persistenceIndicatorFunction;
    else
      return PersistenceIndicatorFunction();
  };

  double d = 0.0;

  for( unsigned dimension = minDimension; dimension <= maxDimension; dimension++ )
  {
    auto f = getPersistenceIndicatorFunction( dataSet1, dimension );
    auto g = getPersistenceIndicatorFunction( dataSet2, dimension );

    g = g * (-1.0);
    d = d + (f+g).integral();
  }

  return d;
}

int main( int argc, char** argv )
{
  if( argc <= 1 )
  {
    // TODO: Show usage
    return -1;
  }

  // Maps data sets to file names. Whether a new filename constitutes
  // a new data set is decided by taking a look at the prefix of the
  // filename.
  std::map<std::string, std::vector<DataSet> > dataSets;

  // TODO: Make this regular expression more, well, 'expressive' and
  // support more methods of specifying a dimension.
  std::regex reDataSetPrefix( "(.*)_k([[:digit:]]+)\\.txt" );
  std::smatch matches;

  // Get filenames & prefixes ------------------------------------------

  unsigned minDimension = std::numeric_limits<unsigned>::max();
  unsigned maxDimension = 0;

  {
    std::vector<std::string> filenames;
    filenames.reserve( argc - 1 );

    for( int i = 1; i < argc; i++ )
      filenames.push_back( argv[i] );

    for( auto&& filename : filenames )
    {
      if( std::regex_match( filename, matches, reDataSetPrefix ) )
      {
        auto name      = matches[1];
        auto dimension = unsigned( std::stoul( matches[2] ) );

        dataSets[name].push_back( { filename, dimension, {}, {} } );

        minDimension = std::min( minDimension, dimension );
        maxDimension = std::max( maxDimension, dimension );
      }
    }
  }

  // Load persistence diagrams & calculate indicator functions ---------

  std::vector<PersistenceDiagram> persistenceDiagrams;

  for( auto&& pair : dataSets )
  {
    for( auto&& dataSet : pair.second )
    {
      std::cerr << "* Processing '" << dataSet.filename << "'...";

      dataSet.persistenceDiagram = aleph::load<DataType>( dataSet.filename );

      // FIXME: This is only required in order to ensure that the
      // persistence indicator function has a finite integral; it
      // can be solved more elegantly by using a special value to
      // indicate infinite intervals.
      dataSet.persistenceDiagram.removeUnpaired();

      dataSet.persistenceIndicatorFunction
         = aleph::persistenceIndicatorFunction( dataSet.persistenceDiagram );

      std::cerr << "finished\n";
    }
  }

  // Calculate all distances -------------------------------------------

  std::vector< std::vector<double> > distances;
  distances.resize( dataSets.size(), std::vector<double>( dataSets.size() ) );

  std::size_t row = 0;

  for( auto it1 = dataSets.begin(); it1 != dataSets.end(); ++it1, ++row )
  {
    std::size_t col = 0;
    for( auto it2 = std::next( it1 ); it2 != dataSets.end(); ++it2, ++col )
    {
      auto d = distance( it1->second, it2->second, minDimension, maxDimension );

      distances[row][col] = d;
      distances[col][row] = d;

      std::cerr << "D[" << row << "][" << col << "]: " << d << "\n";
    }
  }
}
<|endoftext|>


<commit_before>#include <event/event_callback.h>

#include <io/pipe/pipe.h>

#include <zlib/inflate_pipe.h>

#define	INFLATE_CHUNK_SIZE	65536

InflatePipe::InflatePipe(void)
: PipeProducer("/zlib/inflate_pipe"),
  stream_()
{
	stream_.zalloc = Z_NULL;
	stream_.zfree = Z_NULL;
	stream_.opaque = Z_NULL;

	stream_.avail_in = 0;
	stream_.next_in = Z_NULL;

	int error = inflateInit(&stream_);
	if (error != Z_OK)
		HALT(log_) << "Could not initialize inflate stream.";
}

InflatePipe::~InflatePipe()
{
	int error = inflateEnd(&stream_);
	if (error != Z_OK)
		ERROR(log_) << "Inflate stream did not end cleanly.";
}

void
InflatePipe::consume(Buffer *in)
{
	Buffer out;
	uint8_t outbuf[INFLATE_CHUNK_SIZE];
	bool first = true;

	stream_.avail_out = sizeof outbuf;
	stream_.next_out = outbuf;

	for (;;) {
		Buffer::SegmentIterator iter = in->segments();
		const BufferSegment *seg;
		int flush;

		if (iter.end()) {
			seg = NULL;
			flush = first ? Z_FINISH : Z_SYNC_FLUSH;

			stream_.avail_in = 0;
			stream_.next_in = Z_NULL;
		} else {
			seg = *iter;
			flush = Z_NO_FLUSH;
			first = false;

			stream_.avail_in = seg->length();
			stream_.next_in = (Bytef *)(uintptr_t)seg->data();
		}

		for (;;) {
			int error = inflate(&stream_, flush);
			if (error == Z_OK && stream_.avail_out > 0 &&
			    flush == Z_NO_FLUSH)
				break;
			if (error == Z_NEED_DICT || error == Z_DATA_ERROR ||
			    error == Z_MEM_ERROR) {
				produce_error();
				return;
			}

			if (flush != Z_NO_FLUSH && error == Z_BUF_ERROR &&
			    stream_.avail_out == sizeof outbuf)
				error = Z_OK;

			if (stream_.avail_out != sizeof outbuf)
				out.append(outbuf, sizeof outbuf - stream_.avail_out);
			stream_.avail_out = sizeof outbuf;
			stream_.next_out = outbuf;

			if (flush == Z_NO_FLUSH)
				break;
			if (error == Z_OK || error == Z_STREAM_END) {
				if (!out.empty())
					produce(&out);

				if (flush == Z_FINISH && error == Z_STREAM_END) {
					Buffer eos;
					produce(&eos);
				}
				return;
			}
			/* More data to output.  */
		}

		if (seg != NULL)
			in->skip(seg->length() - stream_.avail_in);
	}
	NOTREACHED();
}
<commit_msg>o) Error out if we get EOS but more data follows. o) Give error information.<commit_after>#include <event/event_callback.h>

#include <io/pipe/pipe.h>

#include <zlib/inflate_pipe.h>

#define	INFLATE_CHUNK_SIZE	65536

InflatePipe::InflatePipe(void)
: PipeProducer("/zlib/inflate_pipe"),
  stream_()
{
	stream_.zalloc = Z_NULL;
	stream_.zfree = Z_NULL;
	stream_.opaque = Z_NULL;

	stream_.avail_in = 0;
	stream_.next_in = Z_NULL;

	int error = inflateInit(&stream_);
	if (error != Z_OK)
		HALT(log_) << "Could not initialize inflate stream.";
}

InflatePipe::~InflatePipe()
{
	int error = inflateEnd(&stream_);
	if (error != Z_OK)
		ERROR(log_) << "Inflate stream did not end cleanly.";
}

void
InflatePipe::consume(Buffer *in)
{
	Buffer out;
	uint8_t outbuf[INFLATE_CHUNK_SIZE];
	bool first = true;

	stream_.avail_out = sizeof outbuf;
	stream_.next_out = outbuf;

	for (;;) {
		Buffer::SegmentIterator iter = in->segments();
		const BufferSegment *seg;
		int flush;

		if (iter.end()) {
			seg = NULL;
			flush = first ? Z_FINISH : Z_SYNC_FLUSH;

			stream_.avail_in = 0;
			stream_.next_in = Z_NULL;
		} else {
			seg = *iter;
			flush = Z_NO_FLUSH;
			first = false;

			stream_.avail_in = seg->length();
			stream_.next_in = (Bytef *)(uintptr_t)seg->data();
		}

		for (;;) {
			int error = inflate(&stream_, flush);
			if (error == Z_OK && stream_.avail_out > 0 &&
			    flush == Z_NO_FLUSH)
				break;
			if (error == Z_NEED_DICT || error == Z_DATA_ERROR ||
			    error == Z_MEM_ERROR) {
				ERROR(log_) << "inflate(): " << zError(error);
				produce_error();
				return;
			}

			if (flush != Z_NO_FLUSH && error == Z_BUF_ERROR &&
			    stream_.avail_out == sizeof outbuf)
				error = Z_OK;

			if (stream_.avail_out != sizeof outbuf)
				out.append(outbuf, sizeof outbuf - stream_.avail_out);
			stream_.avail_out = sizeof outbuf;
			stream_.next_out = outbuf;

			if (flush == Z_NO_FLUSH)
				break;
			if (error == Z_OK || error == Z_STREAM_END) {
				if (!out.empty())
					produce(&out);

				if (flush == Z_FINISH && error == Z_STREAM_END) {
					Buffer eos;
					produce(&eos);
				}

				if (!in->empty()) {
					ERROR(log_) << "Stream ended but more data follows.";
					produce_error();
				}
				return;
			}
			/* More data to output.  */
		}

		if (seg != NULL)
			in->skip(seg->length() - stream_.avail_in);
	}
	NOTREACHED();
}
<|endoftext|>


<commit_before>/**
 * \file CameraUniCap_Source.hpp
 * \brief Unicap-based camera source implementation
 * \date 2010-06-11
 * \author Konrad Banachowicz
 */

#include "CameraUniCap_Source.hpp"

#include "Logger.hpp"

#include <opencv/highgui.h>

namespace Sources {
namespace CameraUniCap {

#define MAX_DEVICES 64
#define MAX_FORMATS 64
#define MAX_PROPERTIES 64

CameraUniCap_Source::CameraUniCap_Source(const std::string & name) : Base::Component(name) {

}

CameraUniCap_Source::~CameraUniCap_Source() {

}

bool CameraUniCap_Source::onInit() {

	unicap_device_t devices[MAX_DEVICES];
	unicap_format_t formats[MAX_FORMATS];
	unicap_property_t properties[MAX_PROPERTIES];

	int dev_count;
	int format_count;
	int property_count;

	bool device_found = false;

	unicap_status_t status = STATUS_SUCCESS;

	LOG(LINFO) << "CameraUniCap_Source::initialize()\n";
	newImage = registerEvent("newImage");

	registerStream("out_img", &out_img);

	/*
	 Get the all device found by the unicap library
	 */
	for (dev_count = 0; SUCCESS(status) && (dev_count < MAX_DEVICES); dev_count++) {
		status = unicap_enumerate_devices(NULL, &devices[dev_count], dev_count); // (1)
		if (SUCCESS(status))
			LOG(LINFO) << dev_count << " : "
					<< devices[dev_count].identifier << '\n';
		else
			break;
	}

	for (int i = 0; i < dev_count; i++) {
		if (props.device == devices[i].device) {
			device = devices[i];
			LOG(LINFO) << "device found\n";
			device_found = true;
			break;
		}
	}

	if (!device_found) {
		LOG(LERROR) << "Device not found: " << props.device << '\n';
		throw(Common::DisCODeException("Failed to open device"));
	}

	/*
	 Acquire a handle to this device
	 */
	if (!SUCCESS(unicap_open(&handle, &device))) {
		LOG(LERROR) << "Failed to open device: " << device.identifier
				<< '\n';
		throw(Common::DisCODeException("Failed to open device"));
	}

	/*
	 Get the video formats supported by the device
	 */
	status = STATUS_SUCCESS;

	for (format_count = 0; SUCCESS(status) && (format_count < MAX_FORMATS); format_count++) {
		status = unicap_enumerate_formats(handle, NULL, &formats[format_count],
				format_count);
		if (SUCCESS(status)) {
			LOG(LINFO) << format_count << ": "
					<< formats[format_count].identifier << '\n';
		} else {
			break;
		}
	}

	for (int i = 0; i < format_count; i++) {
		if (props.format == (char*) &formats[i].fourcc) {
			format = formats[i];
			LOG(LINFO) << "format found\n";
			break;
		}
	}

	for (int i = 0; i < format.size_count; i++) {
		if ((props.width == format.sizes[i].width) && (props.height
				== format.sizes[i].height)) {
			format.size = format.sizes[i];
			LOG(LINFO) << "size found\n";
			break;
		}
	}

	format.buffer_type = UNICAP_BUFFER_TYPE_SYSTEM;

	/*
	 Set this video format
	 */
	if (!SUCCESS(unicap_set_format(handle, &format))) {
		LOG(LERROR) << "Failed to set video format\n";

	}

	status = STATUS_SUCCESS;

	for (property_count = 0; SUCCESS(status) && (property_count
			< MAX_PROPERTIES); property_count++) {
		status = unicap_enumerate_properties(handle, NULL,
				&properties[property_count], property_count);
		if (SUCCESS(status)) {
			unicap_get_property(handle, &properties[property_count]);
			if (properties[property_count].type == UNICAP_PROPERTY_TYPE_RANGE)
				LOG(LINFO) << "Property "
						<< properties[property_count].identifier
						<< ": Current = " << properties[property_count].value
						<< ", Range = ["
						<< properties[property_count].range.min << ".."
						<< properties[property_count].range.max << "]\n";

			if (std::string("Brightness")
					== properties[property_count].identifier) {
				if ((props.brightness <= 1.0) && (props.brightness >= 0.0)) {
					properties[property_count].value = props.brightness
							* properties[property_count].range.max;
					unicap_set_property(handle, &properties[property_count]);
				} else {
					LOG(LWARNING) << "Property "
							<< properties[property_count].identifier
							<< " out of range \n";
				}
			} else if (std::string("Contrast")
					== properties[property_count].identifier) {
				if ((props.contrast <= 1.0) && (props.contrast >= 0.0)) {
					properties[property_count].value = props.contrast
							* properties[property_count].range.max;
					unicap_set_property(handle, &properties[property_count]);
				} else {
					LOG(LWARNING) << "Property "
							<< properties[property_count].identifier
							<< " out of range \n";
				}
			} else if (std::string("Saturation")
					== properties[property_count].identifier) {
				if ((props.saturation <= 1.0) && (props.saturation >= 0.0)) {
					properties[property_count].value = props.saturation
							* properties[property_count].range.max;
					unicap_set_property(handle, &properties[property_count]);
				} else {
					LOG(LWARNING) << "Property "
							<< properties[property_count].identifier
							<< " out of range \n";
				}
			} else if (std::string("Hue")
					== properties[property_count].identifier) {
				if ((props.hue <= 1.0) && (props.hue >= 0.0)) {
					properties[property_count].value = props.hue
							* properties[property_count].range.max;
					unicap_set_property(handle, &properties[property_count]);
				} else {
					LOG(LWARNING) << "Property "
							<< properties[property_count].identifier
							<< " out of range \n";
				}
			} else

			if (std::string("video source")
					== properties[property_count].identifier) {
				LOG(LINFO) << "video sources : \n";
				for (int i = 0; i
						< properties[property_count].menu.menu_item_count; i++) {
					LOG(LINFO) << i << " : "
							<< properties[property_count].menu.menu_items[i]
							<< '\n';
					if (props.input
							== properties[property_count].menu.menu_items[i]) {
						strcpy(properties[property_count].menu_item,
								properties[property_count].menu.menu_items[i]);
						unicap_set_property(handle, &properties[property_count]);
					}
				}
			} else if (std::string("video norm")
					== properties[property_count].identifier) {
				LOG(LINFO) << "video norms : \n";
				for (int i = 0; i
						< properties[property_count].menu.menu_item_count; i++) {
					LOG(LINFO) << i << " : "
							<< properties[property_count].menu.menu_items[i]
							<< '\n';
					if (props.norm
							== properties[property_count].menu.menu_items[i]) {
						strcpy(properties[property_count].menu_item,
								properties[property_count].menu.menu_items[i]);
						unicap_set_property(handle, &properties[property_count]);
					}
				}
			}
		} else {
			break;
		}
	}

	unicap_register_callback(handle, UNICAP_EVENT_NEW_FRAME,
			(unicap_callback_t) new_frame_cb, this);

	return true;
}

bool CameraUniCap_Source::onFinish() {
	LOG(LINFO) << "CameraUniCap_Source::finish()\n";

	/*
	 Close the device

	 This invalidates the handle
	 */
	if (!SUCCESS(unicap_close(handle))) {
		LOG(LERROR) << "Failed to close the device: " << device.identifier
				<< '\n';
	}

	return true;

}

bool CameraUniCap_Source::onStep() {
	return true;
}

bool CameraUniCap_Source::onStart() {
	LOG(LINFO) << "CameraUniCap_Source::start()\n";
	/*
	 Start the capture process on the device
	 */
	if (!SUCCESS(unicap_start_capture(handle))) {
		LOG(LERROR) << "Failed to start capture on device: "	<< device.identifier << '\n';
		return false;
	}
	return true;
}

bool CameraUniCap_Source::onStop() {
	LOG(LINFO) << "CameraUniCap_Source::stop()\n";
	/*
	 Stop the device
	 */
	if (!SUCCESS(unicap_stop_capture(handle))) {
		LOG(LERROR) << "Failed to stop capture on device: " << device.identifier << "\n";
		return false;
	}

	return true;
}

void CameraUniCap_Source::new_frame_cb(unicap_event_t event,
		unicap_handle_t handle, unicap_data_buffer_t *buffer, void *usr_data) {

	Mat
			frame =
					Mat(
							((CameraUniCap_Source*) (usr_data))->format.size.height,
							((CameraUniCap_Source*) (usr_data))->format.size.width,
							(std::string("GREY")
									== (char*) &((CameraUniCap_Source*) (usr_data))->format.fourcc) ? CV_8UC1
									: CV_8UC3, (void *) buffer->data).clone();

	LOG(LTRACE) << "Got new frame\n";

	((CameraUniCap_Source*) (usr_data))->out_img.write(frame);
	((CameraUniCap_Source*) (usr_data))->newImage->raise();

}

}

}
<commit_msg>CameraUniCap operation changed (frames on demand)<commit_after>/**
 * \file CameraUniCap_Source.hpp
 * \brief Unicap-based camera source implementation
 * \date 2010-06-11
 * \author Konrad Banachowicz
 */

#include "CameraUniCap_Source.hpp"

#include "Logger.hpp"

#include <opencv/highgui.h>

namespace Sources {
namespace CameraUniCap {

#define MAX_DEVICES 64
#define MAX_FORMATS 64
#define MAX_PROPERTIES 64

CameraUniCap_Source::CameraUniCap_Source(const std::string & name) : Base::Component(name) {

}

CameraUniCap_Source::~CameraUniCap_Source() {

}

bool CameraUniCap_Source::onInit() {

	unicap_device_t devices[MAX_DEVICES];
	unicap_format_t formats[MAX_FORMATS];
	unicap_property_t properties[MAX_PROPERTIES];

	int dev_count;
	int format_count;
	int property_count;

	bool device_found = false;

	unicap_status_t status = STATUS_SUCCESS;

	LOG(LINFO) << "CameraUniCap_Source::initialize()\n";
	newImage = registerEvent("newImage");

	registerStream("out_img", &out_img);

	/*
	 Get the all device found by the unicap library
	 */
	for (dev_count = 0; SUCCESS(status) && (dev_count < MAX_DEVICES); dev_count++) {
		status = unicap_enumerate_devices(NULL, &devices[dev_count], dev_count); // (1)
		if (SUCCESS(status))
			LOG(LINFO) << dev_count << " : "
					<< devices[dev_count].identifier << '\n';
		else
			break;
	}

	for (int i = 0; i < dev_count; i++) {
		if (props.device == devices[i].device) {
			device = devices[i];
			LOG(LINFO) << "device found\n";
			device_found = true;
			break;
		}
	}

	if (!device_found) {
		LOG(LERROR) << "Device not found: " << props.device << '\n';
		throw(Common::DisCODeException("Failed to open device"));
	}

	/*
	 Acquire a handle to this device
	 */
	if (!SUCCESS(unicap_open(&handle, &device))) {
		LOG(LERROR) << "Failed to open device: " << device.identifier
				<< '\n';
		throw(Common::DisCODeException("Failed to open device"));
	}

	/*
	 Get the video formats supported by the device
	 */
	status = STATUS_SUCCESS;

	for (format_count = 0; SUCCESS(status) && (format_count < MAX_FORMATS); format_count++) {
		status = unicap_enumerate_formats(handle, NULL, &formats[format_count],
				format_count);
		if (SUCCESS(status)) {
			LOG(LINFO) << format_count << ": "
					<< formats[format_count].identifier << '\n';
		} else {
			break;
		}
	}

	for (int i = 0; i < format_count; i++) {
		if (props.format == (char*) &formats[i].fourcc) {
			format = formats[i];
			LOG(LINFO) << "format found\n";
			break;
		}
	}

	for (int i = 0; i < format.size_count; i++) {
		if ((props.width == format.sizes[i].width) && (props.height
				== format.sizes[i].height)) {
			format.size = format.sizes[i];
			LOG(LINFO) << "size found\n";
			break;
		}
	}

	//format.buffer_type = UNICAP_BUFFER_TYPE_SYSTEM;
	format.buffer_type = UNICAP_BUFFER_TYPE_USER; // (1)

	/*
	 Set this video format
	 */
	if (!SUCCESS(unicap_set_format(handle, &format))) {
		LOG(LERROR) << "Failed to set video format\n";

	}

	buffer.data = new unsigned char[format.buffer_size]; // (2)
	buffer.buffer_size = format.buffer_size;

	status = STATUS_SUCCESS;

	for (property_count = 0; SUCCESS(status) && (property_count
			< MAX_PROPERTIES); property_count++) {
		status = unicap_enumerate_properties(handle, NULL,
				&properties[property_count], property_count);
		if (SUCCESS(status)) {
			unicap_get_property(handle, &properties[property_count]);
			if (properties[property_count].type == UNICAP_PROPERTY_TYPE_RANGE)
				LOG(LINFO) << "Property "
						<< properties[property_count].identifier
						<< ": Current = " << properties[property_count].value
						<< ", Range = ["
						<< properties[property_count].range.min << ".."
						<< properties[property_count].range.max << "]\n";

			if (std::string("Brightness")
					== properties[property_count].identifier) {
				if ((props.brightness <= 1.0) && (props.brightness >= 0.0)) {
					properties[property_count].value = props.brightness
							* properties[property_count].range.max;
					unicap_set_property(handle, &properties[property_count]);
				} else {
					LOG(LWARNING) << "Property "
							<< properties[property_count].identifier
							<< " out of range \n";
				}
			} else if (std::string("Contrast")
					== properties[property_count].identifier) {
				if ((props.contrast <= 1.0) && (props.contrast >= 0.0)) {
					properties[property_count].value = props.contrast
							* properties[property_count].range.max;
					unicap_set_property(handle, &properties[property_count]);
				} else {
					LOG(LWARNING) << "Property "
							<< properties[property_count].identifier
							<< " out of range \n";
				}
			} else if (std::string("Saturation")
					== properties[property_count].identifier) {
				if ((props.saturation <= 1.0) && (props.saturation >= 0.0)) {
					properties[property_count].value = props.saturation
							* properties[property_count].range.max;
					unicap_set_property(handle, &properties[property_count]);
				} else {
					LOG(LWARNING) << "Property "
							<< properties[property_count].identifier
							<< " out of range \n";
				}
			} else if (std::string("Hue")
					== properties[property_count].identifier) {
				if ((props.hue <= 1.0) && (props.hue >= 0.0)) {
					properties[property_count].value = props.hue
							* properties[property_count].range.max;
					unicap_set_property(handle, &properties[property_count]);
				} else {
					LOG(LWARNING) << "Property "
							<< properties[property_count].identifier
							<< " out of range \n";
				}
			} else

			if (std::string("video source")
					== properties[property_count].identifier) {
				LOG(LINFO) << "video sources : \n";
				for (int i = 0; i
						< properties[property_count].menu.menu_item_count; i++) {
					LOG(LINFO) << i << " : "
							<< properties[property_count].menu.menu_items[i]
							<< '\n';
					if (props.input
							== properties[property_count].menu.menu_items[i]) {
						strcpy(properties[property_count].menu_item,
								properties[property_count].menu.menu_items[i]);
						unicap_set_property(handle, &properties[property_count]);
					}
				}
			} else if (std::string("video norm")
					== properties[property_count].identifier) {
				LOG(LINFO) << "video norms : \n";
				for (int i = 0; i
						< properties[property_count].menu.menu_item_count; i++) {
					LOG(LINFO) << i << " : "
							<< properties[property_count].menu.menu_items[i]
							<< '\n';
					if (props.norm
							== properties[property_count].menu.menu_items[i]) {
						strcpy(properties[property_count].menu_item,
								properties[property_count].menu.menu_items[i]);
						unicap_set_property(handle, &properties[property_count]);
					}
				}
			}
		} else {
			break;
		}
	}

	//unicap_register_callback(handle, UNICAP_EVENT_NEW_FRAME, (unicap_callback_t) new_frame_cb, this);

	return true;
}

bool CameraUniCap_Source::onFinish() {
	LOG(LINFO) << "CameraUniCap_Source::finish()\n";

	/*
	 Close the device

	 This invalidates the handle
	 */
	if (!SUCCESS(unicap_close(handle))) {
		LOG(LERROR) << "Failed to close the device: " << device.identifier
				<< '\n';
	}

	return true;

}

bool CameraUniCap_Source::onStep() {
	unicap_queue_buffer(handle, &buffer); // (4)

	unicap_data_buffer_t * returned_buffer;

	//LOG(LNOTICE) << "1";

	if (!SUCCESS(unicap_wait_buffer(handle, &returned_buffer))) {
		LOG(LERROR) << "Failed to wait for buffer!";
		return false;
	}

	//LOG(LNOTICE) << "2";

	cv::Mat frame = Mat(
				format.size.height,
				format.size.width,
				CV_8UC3,
				(void *) buffer.data
			).clone();

	//LOG(LNOTICE) << "3";

	out_img.write(frame);
	newImage->raise();

	//LOG(LNOTICE) << "4";

	if (!SUCCESS(unicap_queue_buffer(handle, returned_buffer))) {
		LOG(LERROR) << "Failed to queue buffer!";
		return false;
	}

	//LOG(LNOTICE) << "5";

	return true;
}

bool CameraUniCap_Source::onStart() {
	LOG(LINFO) << "CameraUniCap_Source::start()\n";
	/*
	 Start the capture process on the device
	 */
	if (!SUCCESS(unicap_start_capture(handle))) {
		LOG(LERROR) << "Failed to start capture on device: "	<< device.identifier << '\n';
		return false;
	}
	return true;
}

bool CameraUniCap_Source::onStop() {
	LOG(LINFO) << "CameraUniCap_Source::stop()\n";
	/*
	 Stop the device
	 */
	if (!SUCCESS(unicap_stop_capture(handle))) {
		LOG(LERROR) << "Failed to stop capture on device: " << device.identifier << "\n";
		return false;
	}

	return true;
}

void CameraUniCap_Source::new_frame_cb(unicap_event_t event,
		unicap_handle_t handle, unicap_data_buffer_t *buffer, void *usr_data) {

	Mat
			frame =
					Mat(
							((CameraUniCap_Source*) (usr_data))->format.size.height,
							((CameraUniCap_Source*) (usr_data))->format.size.width,
							(std::string("GREY")
									== (char*) &((CameraUniCap_Source*) (usr_data))->format.fourcc) ? CV_8UC1
									: CV_8UC3, (void *) buffer->data).clone();

	LOG(LTRACE) << "Got new frame\n";

	((CameraUniCap_Source*) (usr_data))->out_img.write(frame);
	((CameraUniCap_Source*) (usr_data))->newImage->raise();

}

}

}
<|endoftext|>