text:
/*
 *
 * (C) 2005-14 - ntop.org
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lessed General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 *
 */

#define __USE_XOPEN2K
#include <sys/types.h>
#include <pthread.h>

#ifdef ENABLE_BPF
#include <pcap/pcap.h>
#include <pcap/bpf.h>
#include <linux/types.h>
#include <linux/filter.h>
#endif

#include "pfring.h"
#include "pfring_utils.h"
#include "pfring_hw_filtering.h"
#include "pfring_mod.h"

// #define RING_DEBUG

#define MAX_NUM_LOOPS         1000
#define YIELD_MULTIPLIER        10

#define USE_MB

#define gcc_mb() __asm__ __volatile__("": : :"memory")

#if defined(__i386__) || defined(__x86_64__)
#define rmb()   asm volatile("lfence":::"memory")
#define wmb()   asm volatile("sfence" ::: "memory")
#else /* other architectures (e.g. ARM) */
#define rmb() gcc_mb()
#define wmb() gcc_mb()
#endif

#define ALIGN(a,b) (((a) + ((b)-1) ) & ~((b)-1))

#if 0
unsigned long long rdtsc() {
  unsigned long long a;
  asm volatile("rdtsc":"=A" (a));
  return(a);
}
#endif

/* **************************************************** */

inline int pfring_there_is_pkt_available(pfring *ring) {
#if 1
  return(ring->slots_info->tot_insert != ring->slots_info->tot_read);
#else
  /* stronger check: */
  return ((ring->slots_info->remove_off != ring->slots_info->insert_off &&
          (ring->slots_info->tot_insert != ring->slots_info->tot_read)) ||
         ((ring->slots_info->remove_off == ring->slots_info->insert_off) &&
	 ((ring->slots_info->tot_insert - ring->slots_info->tot_read) >= ring->slots_info->min_num_slots)));
#endif
}

/* **************************************************** */

int pfring_mod_open_setup(pfring *ring) {
  int rc;
  u_int memSlotsLen;

  ring->fd = socket(PF_RING, SOCK_RAW, htons(ETH_P_ALL));

  if(ring->fd < 0)
    return -1;

#ifdef RING_DEBUG
  printf("[PF_RING] Open RING [fd=%d]\n", ring->fd);
#endif

  if(ring->caplen > MAX_CAPLEN) ring->caplen = MAX_CAPLEN;
  rc = setsockopt(ring->fd, 0, SO_RING_BUCKET_LEN, &ring->caplen, sizeof(ring->caplen));

  if(rc < 0) {
    close(ring->fd);
    return -1;
  }

  if(!ring->long_header) {
    rc = setsockopt(ring->fd, 0, SO_USE_SHORT_PKT_HEADER, &ring->long_header, sizeof(ring->long_header));

    if(rc < 0) {
      close(ring->fd);
      return -1;
    }
  }

  if(!strcmp(ring->device_name, "none")) {
    /* No binding yet */
    rc = 0;
  } else /* "any" or "<interface name>" */
    rc = pfring_bind(ring, ring->device_name);

  if(rc < 0) {
    close(ring->fd);
    return -1;
  }

  ring->kernel_packet_consumer = 0;

  ring->buffer = (char *)mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE,
			      MAP_SHARED, ring->fd, 0);

  if(ring->buffer == MAP_FAILED) {
    fprintf(stderr, "[PF_RING] mmap() failed: try with a smaller snaplen\n");
    close(ring->fd);
    return -1;
  }

  ring->slots_info = (FlowSlotInfo *)ring->buffer;
  if(ring->slots_info->version != RING_FLOWSLOT_VERSION) {
    fprintf(stderr, "[PF_RING] Wrong RING version: "
	   "kernel is %i, libpfring was compiled with %i\n",
	   ring->slots_info->version, RING_FLOWSLOT_VERSION);
    close(ring->fd);
    return -1;
  }
  memSlotsLen = ring->slots_info->tot_mem;

  if(munmap(ring->buffer, PAGE_SIZE) == -1) {
    fprintf(stderr, "[PF_RING] Warning: unable to unmap ring buffer memory [address=%p][size=%u]\n",
            ring->buffer, PAGE_SIZE);
  }

  ring->buffer = (char *)mmap(NULL, memSlotsLen,
			      PROT_READ|PROT_WRITE,
			      MAP_SHARED, ring->fd, 0);

  if(ring->buffer == MAP_FAILED) {
    fprintf(stderr, "[PF_RING] mmap() failed");
    close(ring->fd);
    return -1;
   }

   ring->slots_info = (FlowSlotInfo *)ring->buffer;
   ring->slots = (char *)(ring->buffer+sizeof(FlowSlotInfo));

#ifdef RING_DEBUG
  printf("RING (%s): tot_mem=%u/max_slot_len=%u/"
	 "insert_off=%llu/remove_off=%llu/dropped=%lu\n",
	 ring->device_name, ring->slots_info->tot_mem,
	 ring->slots_info->slot_len,   ring->slots_info->insert_off,
	 ring->slots_info->remove_off, ring->slots_info->tot_lost);
#endif

  if(ring->promisc) {
    if(pfring_set_if_promisc(ring->device_name, 1) == 0)
      ring->clear_promisc = 1;
  }

  ring->slot_header_len = pfring_get_slot_header_len(ring);
  if(ring->slot_header_len == (u_int16_t)-1) {
    fprintf(stderr, "[PF_RING] ring failure (pfring_get_slot_header_len)\n");
    close(ring->fd);
    return -1;
  }

  pfring_hw_ft_init(ring);

  if(ring->tx.enabled_rx_packet_send) {
    int dummy = 0;
    if(setsockopt(ring->fd, 0, SO_ENABLE_RX_PACKET_BOUNCE, &dummy, sizeof(dummy)) < 0) {
      fprintf(stderr, "[PF_RING] failure enabling rx packet bounce support\n");
      close(ring->fd);
      return -1;
    }
  }

  return(0);
}

/* **************************************************** */

int pfring_mod_open(pfring *ring) {
  /* Setting pointers, we need these functions soon */
  ring->close = pfring_mod_close;
  ring->stats = pfring_mod_stats;
  ring->recv  = pfring_mod_recv;
  ring->set_poll_watermark = pfring_mod_set_poll_watermark;
  ring->set_poll_duration = pfring_mod_set_poll_duration;
  ring->set_channel_id = pfring_mod_set_channel_id;
  ring->set_channel_mask = pfring_mod_set_channel_mask;
  ring->set_application_name  = pfring_mod_set_application_name;
  ring->set_application_stats = pfring_mod_set_application_stats;
  ring->get_appl_stats_file_name = pfring_mod_get_appl_stats_file_name;
  ring->bind = pfring_mod_bind;
  ring->send = pfring_mod_send;
  ring->get_num_rx_channels = pfring_mod_get_num_rx_channels;
  ring->set_sampling_rate = pfring_mod_set_sampling_rate;
  ring->get_selectable_fd = pfring_mod_get_selectable_fd;
  ring->set_direction = pfring_mod_set_direction;
  ring->set_socket_mode = pfring_mod_set_socket_mode;
  ring->set_cluster = pfring_mod_set_cluster;
  ring->remove_from_cluster = pfring_mod_remove_from_cluster;
  ring->set_master_id = pfring_mod_set_master_id;
  ring->set_master = pfring_mod_set_master;
  ring->get_ring_id = pfring_mod_get_ring_id;
  ring->get_num_queued_pkts = pfring_mod_get_num_queued_pkts;
  ring->get_packet_consumer_mode = pfring_mod_get_packet_consumer_mode;
  ring->set_packet_consumer_mode = pfring_mod_set_packet_consumer_mode;
  ring->get_hash_filtering_rule_stats = pfring_mod_get_hash_filtering_rule_stats;
  ring->handle_hash_filtering_rule = pfring_mod_handle_hash_filtering_rule;
  ring->purge_idle_hash_rules = pfring_mod_purge_idle_hash_rules;
  ring->add_filtering_rule = pfring_mod_add_filtering_rule;
  ring->remove_filtering_rule = pfring_mod_remove_filtering_rule;
  ring->purge_idle_rules = pfring_mod_purge_idle_rules;
  ring->get_filtering_rule_stats = pfring_mod_get_filtering_rule_stats;
  ring->toggle_filtering_policy = pfring_mod_toggle_filtering_policy;
  ring->enable_rss_rehash = pfring_mod_enable_rss_rehash;
  ring->poll = pfring_mod_poll;
  ring->version = pfring_mod_version;
  ring->get_bound_device_address = pfring_mod_get_bound_device_address;
  ring->get_bound_device_ifindex = pfring_mod_get_bound_device_ifindex;
  ring->get_device_ifindex = pfring_mod_get_device_ifindex;
  ring->get_slot_header_len = pfring_mod_get_slot_header_len;
  ring->set_virtual_device = pfring_mod_set_virtual_device;
  ring->add_hw_rule = pfring_hw_ft_add_hw_rule;
  ring->remove_hw_rule = pfring_hw_ft_remove_hw_rule;
  ring->loopback_test = pfring_mod_loopback_test;
  ring->enable_ring = pfring_mod_enable_ring;
  ring->disable_ring = pfring_mod_disable_ring;
  ring->is_pkt_available = pfring_mod_is_pkt_available;
  ring->set_bpf_filter = pfring_mod_set_bpf_filter;
  ring->remove_bpf_filter = pfring_mod_remove_bpf_filter;
  ring->shutdown = pfring_mod_shutdown;
  ring->send_last_rx_packet = pfring_mod_send_last_rx_packet;
  ring->set_bound_dev_name = pfring_mod_set_bound_dev_name;

  ring->poll_duration = DEFAULT_POLL_DURATION;

  return(pfring_mod_open_setup(ring));
}

/* ******************************* */

int pfring_mod_set_channel_mask(pfring *ring, u_int64_t channel_mask64) {
  return(setsockopt(ring->fd, 0, SO_SET_CHANNEL_ID, &channel_mask64, sizeof(channel_mask64)));
}

/* ******************************* */

int pfring_mod_set_channel_id(pfring *ring, u_int32_t channel_id) {
  return pfring_set_channel_mask(ring, 1 << channel_id);
}

/* ******************************* */

int pfring_mod_set_application_name(pfring *ring, char *name) {
#if !defined(SO_SET_APPL_NAME)
  return(-1);
#else
  return(setsockopt(ring->fd, 0, SO_SET_APPL_NAME, name, strlen(name)));
#endif
}

/* ******************************* */

int pfring_mod_set_application_stats(pfring *ring, char *stats) {
#if !defined(SO_SET_APPL_STATS)
  return(-1);
#else
  return(setsockopt(ring->fd, 0, SO_SET_APPL_STATS, stats, strlen(stats)));
#endif
}

/* **************************************************** */

char* pfring_mod_get_appl_stats_file_name(pfring *ring, char *path, u_int path_len) {
  socklen_t len = (socklen_t)path_len;
  int rc = getsockopt(ring->fd, 0, SO_GET_APPL_STATS_FILE_NAME, path, &len);

  return((rc == 0) ? path : NULL);
}

/* **************************************************** */

int pfring_mod_bind(pfring *ring, char *device_name) {
  struct sockaddr sa;
  char *at, *elem, *pos, name_copy[256];
  u_int64_t channel_mask = RING_ANY_CHANNEL;
  int rc = 0;

  if((device_name == NULL) || (strcmp(device_name, "none") == 0))
    return(-1);

  /* FIX: in case of multiple interfaces the channel ID must be the same */
  at = strchr(device_name, '@');
  if(at != NULL) {
    char *tok;

    at[0] = '\0';

    /* Syntax
       ethX@1,5       channel 1 and 5
       ethX@1-5       channel 1,2...5
       ethX@1-3,5-7   channel 1,2,3,5,6,7
    */

    pos = NULL;
    tok = strtok_r(&at[1], ",", &pos);
    channel_mask = 0;

    while(tok != NULL) {
      char *dash = strchr(tok, '-');
      int32_t min_val, max_val, i;

      if(dash) {
	dash[0] = '\0';
	min_val = atoi(tok);
	max_val = atoi(&dash[1]);

      } else
	min_val = max_val = atoi(tok);

      for(i = min_val; i <= max_val; i++)
	channel_mask |= 1 << i;

      tok = strtok_r(NULL, ",", &pos);
    }
  }

  /* Setup TX */
  ring->sock_tx.sll_family = PF_PACKET;
  ring->sock_tx.sll_protocol = htons(ETH_P_ALL);

  snprintf(name_copy, sizeof(name_copy), "%s", device_name);

  pos = NULL;
  elem = strtok_r(name_copy, ";,", &pos);

  while(elem != NULL) {
    memset(&sa, 0, sizeof(sa));
    sa.sa_family = PF_RING;
    snprintf(sa.sa_data, sizeof(sa.sa_data), "%s", elem);

    rc = bind(ring->fd, (struct sockaddr *)&sa, sizeof(sa));

    if(rc == 0) {
      /* if(channel_mask != RING_ANY_CHANNEL) */ {
	rc = pfring_set_channel_mask(ring, channel_mask);

	//if(rc != 0)
	//  printf("pfring_set_channel_id() failed: %d\n", rc);
      }
    }

    pfring_enable_hw_timestamp(ring, elem, ring->hw_ts.enable_hw_timestamp ? 1 : 0, 0 /* TX timestamp disabled by default */);

    elem = strtok_r(NULL, ";,", &pos);
  }

  return(rc);
}

/* **************************************************** */

void pfring_mod_close(pfring *ring) {
  if(ring->buffer != NULL) {
    if(munmap(ring->buffer, ring->slots_info->tot_mem) == -1) {
      fprintf(stderr, "[PF_RING] Warning: unable to unmap ring buffer memory [address=%p][size=%u]\n",
     	      ring->buffer, (unsigned int)ring->slots_info->tot_mem);
    }
  }

  if(ring->clear_promisc)
    pfring_set_if_promisc(ring->device_name, 0);

  close(ring->fd);
}

/* **************************************************** */

int  pfring_mod_send(pfring *ring, char *pkt, u_int pkt_len, u_int8_t flush_packet) {
  return(sendto(ring->fd, pkt, pkt_len, 0, (struct sockaddr *)&ring->sock_tx, sizeof(ring->sock_tx)));
}

/* **************************************************** */

int pfring_mod_set_poll_watermark(pfring *ring, u_int16_t watermark) {
  return(setsockopt(ring->fd, 0, SO_SET_POLL_WATERMARK, &watermark, sizeof(watermark)));
}

/* **************************************************** */

int pfring_mod_set_poll_duration(pfring *ring, u_int duration) {
  ring->poll_duration = duration;

  return 0;
}

/* **************************************************** */

u_int8_t pfring_mod_get_num_rx_channels(pfring *ring) {
  socklen_t len = sizeof(u_int32_t);
  u_int8_t num_rx_channels;
  int rc = getsockopt(ring->fd, 0, SO_GET_NUM_RX_CHANNELS, &num_rx_channels, &len);

  return((rc == 0) ? num_rx_channels : 1);
}

/* **************************************************** */

int pfring_mod_set_sampling_rate(pfring *ring, u_int32_t rate /* 1 = no sampling */) {
  return(setsockopt(ring->fd, 0, SO_SET_SAMPLING_RATE, &rate, sizeof(rate)));
}

/* ******************************* */

int pfring_mod_stats(pfring *ring, pfring_stat *stats) {

  if((ring->slots_info != NULL) && (stats != NULL)) {
    rmb();
    stats->recv = ring->slots_info->tot_read;
    stats->drop = ring->slots_info->tot_lost;
    return(0);
  }

  return(-1);
}

/* **************************************************** */

int pfring_mod_is_pkt_available(pfring *ring) {
  return(pfring_there_is_pkt_available(ring));
}

/* **************************************************** */

int pfring_mod_next_pkt_time(pfring *ring, struct timespec *ts) {
  struct pfring_pkthdr *header = (struct pfring_pkthdr*) &ring->slots[ring->slots_info->remove_off];

  if(!pfring_there_is_pkt_available(ring))
    return PF_RING_ERROR_NO_PKT_AVAILABLE;

  if(!header->ts.tv_sec)
    return PF_RING_ERROR_WRONG_CONFIGURATION;

  ts->tv_sec = header->ts.tv_sec;
  ts->tv_nsec = header->ts.tv_usec * 1000;

  /* TODO In order to use ns from hw ts we should make sure that
   * hw ts is in sync with sys time. */
  //if(header->extended_hdr.timestamp_ns)
  //  ts->tv_nsec = header->extended_hdr.timestamp_ns % 1000000000;

  return 0;
}

/* **************************************************** */

int pfring_mod_recv(pfring *ring, u_char** buffer, u_int buffer_len,
		    struct pfring_pkthdr *hdr,
		    u_int8_t wait_for_incoming_packet) {
  int rc = 0;

  if(ring->is_shutting_down || (ring->buffer == NULL))
    return(-1);

  ring->break_recv_loop = 0;

  do_pfring_recv:
    if(ring->break_recv_loop)
      return(0);

    if(unlikely(ring->reentrant))
      pthread_rwlock_wrlock(&ring->rx_lock);

    //rmb();

    if(pfring_there_is_pkt_available(ring)) {
      char *bucket = &ring->slots[ring->slots_info->remove_off];
      u_int64_t next_off;
      u_int32_t real_slot_len, bktLen;

      /* Keep it for packet sending */
      ring->tx.last_received_hdr = (struct pfring_pkthdr*)bucket;

      memcpy(hdr, bucket, ring->slot_header_len);

#if 0
      if((hdr->caplen > 1518) || (hdr->len > 1518))
        fprintf(stderr, "%s:%d-----> Invalid packet length [caplen: %u][len: %u]"
                        "[hdr len: %u][slot len: %u][real slot len: %u]"
                        "[insert_off: %u][remove_off: %u][tot_insert: %lu][tot_read: %lu]\n",
                __FUNCTION__, __LINE__, hdr->caplen, hdr->len, ring->slot_header_len,
                ring->slots_info->slot_len, ring->slot_header_len+hdr->caplen,
                ring->slots_info->insert_off, ring->slots_info->remove_off,
                ring->slots_info->tot_insert, ring->slots_info->tot_read);
#endif

      bktLen = hdr->caplen;

      if(ring->slot_header_len == sizeof(struct pfring_pkthdr)) /* using long pkt header, parsed_header_len is available */
        bktLen += hdr->extended_hdr.parsed_header_len;

      real_slot_len = ring->slot_header_len + bktLen;

      /* padding at the end of the packet (it should contain the magic number) */
      real_slot_len += sizeof(u_int16_t);
      real_slot_len = ALIGN(real_slot_len, sizeof(u_int64_t));

#if 0
      printf("Real slot len adjusted to %u (MAGIC=%02X)\n", real_slot_len, bucket[ring->slot_header_len + bktLen]);
#endif

      if(bktLen > buffer_len) bktLen = buffer_len;

      if(buffer_len == 0)
	*buffer = (u_char*)&bucket[ring->slot_header_len];
      else
	memcpy(*buffer, &bucket[ring->slot_header_len], bktLen);

      next_off = ring->slots_info->remove_off + real_slot_len;
      if((next_off + ring->slots_info->slot_len) > (ring->slots_info->tot_mem - sizeof(FlowSlotInfo)))
        next_off = 0;

#ifdef USE_MB
      /* This prevents the compiler from reordering instructions.
       * http://en.wikipedia.org/wiki/Memory_ordering#Compiler_memory_barrier */
      gcc_mb();
#endif

      ring->slots_info->tot_read++, ring->slots_info->remove_off = next_off;

#if 0 /* this safety check is not so safe as could fail due to concurrent update */
      if(unlikely((ring->slots_info->tot_insert == ring->slots_info->tot_read)
	 && (ring->slots_info->remove_off > ring->slots_info->insert_off
	 && ring->slots_info->insert_off != 0))) {
        fprintf(stderr, " *** corrupted ring buffer indexes (recovered) ***\n",
	ring->slots_info->remove_off = ring->slots_info->insert_off;
	ring->slots_info->tot_read = ring->slots_info->tot_insert;
      }
#endif

      if(unlikely(ring->reentrant)) pthread_rwlock_unlock(&ring->rx_lock);
      return(1);
    }

    /* Nothing to do: we need to wait */
    if(unlikely(ring->reentrant)) pthread_rwlock_unlock(&ring->rx_lock);

    if(wait_for_incoming_packet) {
      rc = pfring_poll(ring, ring->poll_duration);

      if((rc == -1) && (errno != EINTR))
	return(-1);
      else
	goto do_pfring_recv;
    }

  return(0); /* non-blocking, no packet */
}

/* ******************************* */

int pfring_mod_get_selectable_fd(pfring *ring) {
  return(ring->fd);
}

/* ******************************* */

int pfring_mod_set_direction(pfring *ring, packet_direction direction) {
  return(setsockopt(ring->fd, 0, SO_SET_PACKET_DIRECTION, &direction, sizeof(direction)));
}

/* ******************************* */

int pfring_mod_set_socket_mode(pfring *ring, socket_mode mode) {
  return(setsockopt(ring->fd, 0, SO_SET_SOCKET_MODE, &mode, sizeof(mode)));
}

/* ******************************* */

int pfring_mod_set_master_id(pfring *ring, u_int32_t master_id) {
  return(setsockopt(ring->fd, 0, SO_SET_MASTER_RING, &master_id, sizeof(master_id)));
}

/* ******************************* */

int pfring_mod_set_master(pfring *ring, pfring *master) {
  int id = pfring_get_ring_id(master);

  if(id != -1)
    return(pfring_set_master_id(ring, id));
  else
    return(id);
}

/* ******************************* */

int pfring_mod_set_cluster(pfring *ring, u_int clusterId, cluster_type the_type) {
  struct add_to_cluster cluster;
  cluster.clusterId = clusterId, cluster.the_type = the_type;

  return(setsockopt(ring->fd, 0, SO_ADD_TO_CLUSTER, &cluster, sizeof(cluster)));
}

/* ******************************* */

int pfring_mod_remove_from_cluster(pfring *ring) {
  return(setsockopt(ring->fd, 0, SO_REMOVE_FROM_CLUSTER, NULL, 0));
}

/* ******************************* */

int pfring_mod_purge_idle_hash_rules(pfring *ring, u_int16_t inactivity_sec) {
  return(setsockopt(ring->fd, 0, SO_PURGE_IDLE_HASH_RULES, &inactivity_sec, sizeof(inactivity_sec)));
}

/* ******************************* */

int pfring_mod_purge_idle_rules(pfring *ring, u_int16_t inactivity_sec) {
  return(setsockopt(ring->fd, 0, SO_PURGE_IDLE_RULES, &inactivity_sec, sizeof(inactivity_sec)));
}

/* **************************************************** */

int pfring_mod_toggle_filtering_policy(pfring *ring, u_int8_t rules_default_accept_policy) {

  int rc = setsockopt(ring->fd, 0, SO_TOGGLE_FILTER_POLICY,
		      &rules_default_accept_policy,
		      sizeof(rules_default_accept_policy));

  if(rc == 0)
    ring->socket_default_accept_policy = rules_default_accept_policy;

  if(rc < 0)
    return rc;

  if(ring->ft_mode != software_only)
    rc = pfring_hw_ft_set_traffic_policy(ring, rules_default_accept_policy);

  return rc;
}

/* **************************************************** */

int pfring_mod_enable_rss_rehash(pfring *ring) {
  char dummy;

  return(setsockopt(ring->fd, 0, SO_REHASH_RSS_PACKET, &dummy, sizeof(dummy)));
}

/* **************************************************** */

int pfring_mod_poll(pfring *ring, u_int wait_duration) {
  if(wait_duration == 0)
    return(ring->is_pkt_available(ring));
  else {
    struct pollfd pfd;
    int rc;

    /* Sleep when nothing is happening */
    pfd.fd      = ring->fd;
    pfd.events  = POLLIN /* | POLLERR */;
    pfd.revents = 0;
    errno       = 0;

    rc = poll(&pfd, 1, wait_duration);
    ring->num_poll_calls++;

    return(rc);
  }
}

/* **************************************************** */

int pfring_mod_version(pfring *ring, u_int32_t *version) {
  socklen_t len = sizeof(u_int32_t);
  return(getsockopt(ring->fd, 0, SO_GET_RING_VERSION, version, &len));
}

/* **************************************************** */

u_int32_t pfring_mod_get_num_queued_pkts(pfring *ring) {
  socklen_t len = sizeof(u_int32_t);
  u_int32_t num_queued_pkts;

  int rc = getsockopt(ring->fd, 0, SO_GET_NUM_QUEUED_PKTS, &num_queued_pkts, &len);

  return((rc == 0) ? num_queued_pkts : 0);
}

/* **************************************************** */

u_int16_t pfring_mod_get_ring_id(pfring *ring) {
  u_int32_t id;
  socklen_t len = sizeof(id);

  int rc = getsockopt(ring->fd, 0, SO_GET_RING_ID, &id, &len);

  return((rc == 0) ? id : -1);
}

/* **************************************************** */

int pfring_mod_get_filtering_rule_stats(pfring *ring, u_int16_t rule_id,
				        char* stats, u_int *stats_len) {
  if(*stats_len < sizeof(u_int16_t))
    return(-1);

  memcpy(stats, &rule_id, sizeof(u_int16_t));
  return(getsockopt(ring->fd, 0,
		    SO_GET_FILTERING_RULE_STATS,
		    stats, stats_len));
}

/* **************************************************** */

int pfring_mod_get_hash_filtering_rule_stats(pfring *ring,
					     hash_filtering_rule* rule,
					     char* stats, u_int *stats_len) {
  char buffer[2048];
  int rc;
  u_int len;

  memcpy(buffer, rule, sizeof(hash_filtering_rule));
  len = sizeof(buffer);
  rc = getsockopt(ring->fd, 0,
		  SO_GET_HASH_FILTERING_RULE_STATS,
		  buffer, &len);
  if(rc < 0)
    return(rc);

  *stats_len = min_val(*stats_len, rc);
  memcpy(stats, buffer, *stats_len);
  return(0);
}

/* **************************************************** */

int pfring_mod_add_filtering_rule(pfring *ring, filtering_rule* rule_to_add) {
  int rc = -1;

  if(!rule_to_add)
    return -1;

  /* Sanitize entry (add IPv6 check) */
  rule_to_add->core_fields.shost.v4 &= rule_to_add->core_fields.shost_mask.v4;
  rule_to_add->core_fields.dhost.v4 &= rule_to_add->core_fields.dhost_mask.v4;

  if(rule_to_add->balance_id > rule_to_add->balance_pool)
    rule_to_add->balance_id = 0;

  if(ring->ft_mode != hardware_only) {
    rc = setsockopt(ring->fd, 0, SO_ADD_FILTERING_RULE,
		    rule_to_add, sizeof(filtering_rule));

    if(rc < 0)
      return rc;
  }

  if(ring->ft_mode != software_only)
    rc = pfring_hw_ft_add_filtering_rule(ring, rule_to_add);

  return rc;
}

/* **************************************************** */

int pfring_mod_enable_ring(pfring *ring) {
  char dummy = 0;

  return(setsockopt(ring->fd, 0, SO_ACTIVATE_RING, &dummy, sizeof(dummy)));
}

/* **************************************************** */

int pfring_mod_disable_ring(pfring *ring) {
  char dummy;

  return(setsockopt(ring->fd, 0, SO_DEACTIVATE_RING, &dummy, sizeof(dummy)));
}

/* **************************************************** */

int pfring_mod_remove_filtering_rule(pfring *ring, u_int16_t rule_id) {
  int rc = -1;

  if(ring->ft_mode != hardware_only) {
    rc = setsockopt(ring->fd, 0, SO_REMOVE_FILTERING_RULE,
		    &rule_id, sizeof(rule_id));

    if(rc < 0)
      return rc;
  }

  if(ring->ft_mode != software_only)
    rc = pfring_hw_ft_remove_filtering_rule(ring, rule_id);

  return rc;
}

/* **************************************************** */

int pfring_mod_handle_hash_filtering_rule(pfring *ring,
				 	  hash_filtering_rule* rule_to_add,
					  u_char add_rule) {
  int rc = -1;

  if(!rule_to_add)
    return -1;

  if(ring->ft_mode != hardware_only) {
    rc = setsockopt(ring->fd, 0, add_rule ? SO_ADD_FILTERING_RULE : SO_REMOVE_FILTERING_RULE,
		    rule_to_add, sizeof(hash_filtering_rule));

    if(rc < 0)
      return rc;
  }

  if(ring->ft_mode != software_only)
    rc = pfring_hw_ft_handle_hash_filtering_rule(ring, rule_to_add, add_rule);

  return rc;
}

/* ******************************* */

u_int8_t pfring_mod_get_packet_consumer_mode(pfring *ring) {
  u_int8_t id;
  socklen_t len = sizeof(id);
  int rc = getsockopt(ring->fd, 0, SO_GET_PACKET_CONSUMER_MODE, &id, &len);

  return((rc == 0) ? id : -1);
}

/* **************************************************** */

int pfring_mod_set_packet_consumer_mode(pfring *ring, u_int8_t plugin_id,
				  	char *plugin_data, u_int plugin_data_len) {
  char buffer[4096];

  if(plugin_data_len > (sizeof(buffer)-1)) return(-2);

  memcpy(buffer, &plugin_id, 1);

  if(plugin_data_len > 0)
    memcpy(&buffer[1], plugin_data, plugin_data_len);

  return(setsockopt(ring->fd, 0, SO_SET_PACKET_CONSUMER_MODE,
		    buffer, plugin_data_len+1));
}

/* **************************************************** */

int pfring_mod_set_virtual_device(pfring *ring, virtual_filtering_device_info *info) {
  return(setsockopt(ring->fd, 0, SO_SET_VIRTUAL_FILTERING_DEVICE,
		    (char*)info, sizeof(virtual_filtering_device_info)));
}

/* **************************************************** */

int pfring_mod_loopback_test(pfring *ring, char *buffer, u_int buffer_len, u_int test_len) {
  socklen_t len;

  if(test_len > buffer_len) test_len = buffer_len;
  len = test_len;

  return(getsockopt(ring->fd, 0, SO_GET_LOOPBACK_TEST, (char*)buffer, &len));
}

/* **************************************************** */

int pfring_mod_get_bound_device_address(pfring *ring, u_char mac_address[6]) {
  socklen_t len = 6;

  return(getsockopt(ring->fd, 0, SO_GET_BOUND_DEVICE_ADDRESS, mac_address, &len));
}

/* **************************************************** */

int pfring_mod_get_bound_device_ifindex(pfring *ring, int *if_index) {
  socklen_t len = sizeof(int);

  return(getsockopt(ring->fd, 0, SO_GET_BOUND_DEVICE_IFINDEX, if_index, &len));
}

/* **************************************************** */

int pfring_mod_get_device_ifindex(pfring *ring, char *device_name, int *if_index) {
  char buffer[32];
  socklen_t len = sizeof(buffer);
  int rc;

  memset(buffer, 0, sizeof(buffer));
  strncpy(buffer, device_name, sizeof(buffer) - 1);

  rc = getsockopt(ring->fd, 0, SO_GET_DEVICE_IFINDEX, buffer, &len);

  if (rc < 0)
    return rc;

  memcpy(if_index, buffer, sizeof(*if_index));
  return 0;
}

/* **************************************************** */

int pfring_mod_get_link_status(pfring *ring) {
  int link_up = 1;
  socklen_t len = sizeof(link_up);
  getsockopt(ring->fd, 0, SO_GET_LINK_STATUS, &link_up, &len);
  return link_up;
}

/* **************************************************** */

u_int16_t pfring_mod_get_slot_header_len(pfring *ring) {
  u_int16_t hlen;
  socklen_t len = sizeof(hlen);
  int rc = getsockopt(ring->fd, 0, SO_GET_PKT_HEADER_LEN, &hlen, &len);

  return((rc == 0) ? hlen : -1);
}

/* **************************************************** */

int pfring_mod_set_bpf_filter(pfring *ring, char *filter_buffer) {
  int                rc = -1;
#ifdef ENABLE_BPF
  struct bpf_program filter;
  struct sock_fprog  fcode;

  if(!filter_buffer)
    return -1;

  if(unlikely(ring->reentrant))
    pthread_rwlock_wrlock(&ring->rx_lock);

  if(pcap_compile_nopcap(ring->caplen,  /* snaplen_arg */
                         DLT_EN10MB,    /* linktype_arg */
                         &filter,       /* program */
                         filter_buffer, /* const char *buf */
                         0,             /* optimize */
                         0              /* mask */
                         ) == -1) {
    rc = -1;
    goto pfring_mod_set_bpf_filter_exit;
  }

  if(filter.bf_insns == NULL) {
    rc = -1;
    goto pfring_mod_set_bpf_filter_exit;
  }

  fcode.len    = filter.bf_len;
  fcode.filter = (struct sock_filter *) filter.bf_insns;

  rc = setsockopt(ring->fd, 0, SO_ATTACH_FILTER, &fcode, sizeof(fcode));

  pcap_freecode(&filter);

  if(rc == -1)
    pfring_mod_remove_bpf_filter(ring);

 pfring_mod_set_bpf_filter_exit:
  if(unlikely(ring->reentrant))
    pthread_rwlock_unlock(&ring->rx_lock);

#endif

  return rc;
}

/* **************************************************** */

int pfring_mod_remove_bpf_filter(pfring *ring) {
  int rc = -1;
#ifdef ENABLE_BPF
  int dummy = 0;

  if(unlikely(ring->reentrant))
    pthread_rwlock_wrlock(&ring->rx_lock);

  rc = setsockopt(ring->fd, 0, SO_DETACH_FILTER, &dummy, sizeof(dummy));

  if(rc == -1)
    rc = setsockopt(ring->fd, SOL_SOCKET, SO_DETACH_FILTER, &dummy, sizeof(dummy));

  if(unlikely(ring->reentrant))
    pthread_rwlock_unlock(&ring->rx_lock);
#endif

  return rc;
}

/* **************************************************** */

int pfring_mod_send_last_rx_packet(pfring *ring, int tx_interface_id) {
  if(!ring->tx.enabled_rx_packet_send)
    return(PF_RING_ERROR_WRONG_CONFIGURATION);

  if(ring->tx.last_received_hdr == NULL)
    return(PF_RING_ERROR_NO_PKT_AVAILABLE); /* We have not yet read a single packet */

  ring->tx.last_received_hdr->extended_hdr.tx.bounce_interface = tx_interface_id;
  return(0);
}

/* **************************************************** */

void pfring_mod_shutdown(pfring *ring) {
  int dummy = 0;

  setsockopt(ring->fd, 0, SO_SHUTDOWN_RING, &dummy, sizeof(dummy));
}

/* **************************************************** */

int pfring_mod_set_bound_dev_name(pfring *ring, char *custom_dev_name) {
   return(setsockopt(ring->fd, 0, SO_SET_CUSTOM_BOUND_DEV_NAME,
		     custom_dev_name, strlen(custom_dev_name)));
}


text:
#include <aws/es/model/CognitoOptions.h>
#include <aws/core/utils/json/JsonSerializer.h>

#include <utility>

using namespace Aws::Utils::Json;
using namespace Aws::Utils;

namespace Aws
{
namespace ElasticsearchService
{
namespace Model
{

CognitoOptions::CognitoOptions() :
    m_enabled(false),
    m_enabledHasBeenSet(false),
    m_userPoolIdHasBeenSet(false),
    m_identityPoolIdHasBeenSet(false),
    m_roleArnHasBeenSet(false)
{
}

CognitoOptions::CognitoOptions(JsonView jsonValue) :
    m_enabled(false),
    m_enabledHasBeenSet(false),
    m_userPoolIdHasBeenSet(false),
    m_identityPoolIdHasBeenSet(false),
    m_roleArnHasBeenSet(false)
{
  *this = jsonValue;
}

CognitoOptions& CognitoOptions::operator =(JsonView jsonValue)
{
  if(jsonValue.ValueExists("Enabled"))
  {
    m_enabled = jsonValue.GetBool("Enabled");

    m_enabledHasBeenSet = true;
  }

  if(jsonValue.ValueExists("UserPoolId"))
  {
    m_userPoolId = jsonValue.GetString("UserPoolId");

    m_userPoolIdHasBeenSet = true;
  }

  if(jsonValue.ValueExists("IdentityPoolId"))
  {
    m_identityPoolId = jsonValue.GetString("IdentityPoolId");

    m_identityPoolIdHasBeenSet = true;
  }

  if(jsonValue.ValueExists("RoleArn"))
  {
    m_roleArn = jsonValue.GetString("RoleArn");

    m_roleArnHasBeenSet = true;
  }

  return *this;
}

JsonValue CognitoOptions::Jsonize() const
{
  JsonValue payload;

  if(m_enabledHasBeenSet)
  {
   payload.WithBool("Enabled", m_enabled);

  }

  if(m_userPoolIdHasBeenSet)
  {
   payload.WithString("UserPoolId", m_userPoolId);

  }

  if(m_identityPoolIdHasBeenSet)
  {
   payload.WithString("IdentityPoolId", m_identityPoolId);

  }

  if(m_roleArnHasBeenSet)
  {
   payload.WithString("RoleArn", m_roleArn);

  }

  return payload;
}

} // namespace Model
} // namespace ElasticsearchService
} // namespace Aws

redpajama_set_name: RedPajamaGithub


text:
.rteindent1 {
  margin-left: 40px;
}
.rteindent2 {
  margin-left: 80px;
}
.rteindent3 {
  margin-left: 120px;
}
.rteindent4 {
  margin-left: 160px;
}
.rteleft {
  text-align: left;
}
.rteright {
  text-align: right;
}
.rtecenter {
  text-align: center;
}
.rtejustify {
  text-align: justify;
}
.image_assist{
  background-color: #eeeeee;
  background-repeat: no-repeat;
  background-image: url(plugins/imgassist/imgassist.gif);
  background-position: 50% 50%;
  border: 1px dashed #dddddd;
}
.ibimage_left {
  float: left;
}
.ibimage_right {
  float: right;
}


text:
$('#symfony_websitebundle_update_save').on('click', function(e) {
        e.preventDefault();

        var $form = $(this).closest('form');
        var $href = $form.attr('action');
        var $post = $form.attr('method');
        var $data = $form.serialize();
        var loc = window.location.href;
        $.ajax({
            dataType: "json",
            type: $post,
            url: loc,
            data: $data,
            success: function (data, textStatus, jqXHR) {
                if (data.success) {
                   $('#message').html(data.message);
                   $('.update').addClass('hidden');
                } else {
                   $('#message').html(data.message);
                }
            },
            error: function (jqXHR, textStatus, errorThrown) {
                console.log( errorThrown );
            }

        });
});

$('#buttonEdit').on('click', function() {
    $('.update').removeClass('hidden');
});

$('#cancel').on('click', function() {
    $('.update').addClass('hidden');
});


text:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:key="@string/security_preferences_key"
        android:title="Security Preferences">
        <CheckBoxPreference
            android:key="@string/fingerprint_preference_key"
            android:summary="@string/fingerprint_preference_summary"
            android:title="@string/fingerprint_preference_title" />

        <CheckBoxPreference
            android:key="@string/pin_preference_key"
            android:summary="@string/pin_preference_summary"
            android:title="@string/pin_preference_title" />
    </PreferenceCategory>
</PreferenceScreen>


text:
import os from 'os';
import path from 'path';

import { CommandExists } from '../lib/command-exists';
import Editor from './editor';
import logger from '../utils/logger';

export default class Xcode extends Editor {
  private commandExists = new CommandExists();

  public static getName(): string {
    return 'Xcode';
  }

  public get name(): string {
    return 'Xcode';
  }

  public get icon(): string {
    return '';
  }

  public get binaries(): string[] {
    return ['xed'];
  }

  public async isEditorInstalled(): Promise<boolean> {
    try {
      let exists = false;
      await Promise.all(
        Object.keys(this.binaries).map(async (binary) => {
          if (await this.isBinary(binary)) {
            exists = true;
          }
        }),
      );
      if (exists) return true;
      return await this.isDirectory(this.appDirectory());
    } catch (err) {
      logger.error(err);
      return false;
    }
  }

  public async isPluginInstalled(): Promise<boolean> {
    const pluginPath = path.join(this.pluginsDirectory(), 'WakaTime.xcplugin/Contents');
    return this.isDirectory(pluginPath);
  }

  public async installPlugin(): Promise<void> {
    throw new Error('Method not implemented.');
  }

  public async uninstallPlugin(): Promise<void> {
    throw new Error('Method not implemented.');
  }

  public async isBinary(binary: string): Promise<boolean> {
    return this.commandExists.exists(binary);
  }

  public pluginsDirectory(): string {
    switch (os.platform()) {
      case 'win32': {
        const is64bit = process.arch === 'x64' || process.env.PROCESSOR_ARCHITEW6432;
        if (is64bit) return '';
        return '';
      }
      case 'darwin':
        return path.join(
          os.homedir(),
          'Library/Application Support/Developer/Shared/Xcode/Plug-ins',
        );
      case 'linux':
        return '';
      default:
        return null;
    }
  }

  private appDirectory(): string {
    switch (os.platform()) {
      case 'win32':
        return '';
      case 'darwin':
        return '/Applications/Xcode.app/Contents';
      default:
        return null;
    }
  }
}


text:
module Whiff
  module ArpScan

    IP_ADDRESS_REGEX = /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/

    MAC_ADDRESS_REGEX = /([0-9A-F]{2}[:]){5}([0-9A-F]{2})/i

    def self.fetch(ip_address, interface, options={})
      raise 'Must run as root' unless options[:test] == true || Process.uid == 0
      raise 'arp-scan not installed' unless arp_scan_installed?
      raise 'invalid IP address' unless ip_address =~ IP_ADDRESS_REGEX
      cmd = "#{options[:env]} arp-scan -l -s #{ip_address} -I #{interface} -q"
      puts cmd
      addresses = []
      stdout = `#{cmd}`
      stdout.each_line do |line|
        addresses << extract_mac_address(line)
      end
      addresses.delete_if{|a| a.nil?}.uniq!
      puts addresses if options[:verbose]
      addresses
    end

    def self.extract_mac_address(str)
      str.match(MAC_ADDRESS_REGEX) { |m| m }
    end

    def self.arp_scan_installed?
      `which arp-scan`
      $?.success?
    end
  end
end


text:
package org.antlr4;

import org.antlr.v4.runtime.RecognitionException;

/**
 *
 * @author junichi11
 */
public class SyntaxError {

    private final String message;
    private final int line;
    private final int charPositionInLine;
    private final RecognitionException recognitionException;

    public SyntaxError(String message, int line, int charPositionInLine, RecognitionException recognitionException) {
        this.message = message;
        this.line = line;
        this.charPositionInLine = charPositionInLine;
        this.recognitionException = recognitionException;
    }

    public String getMessage() {
        return message;
    }

    public int getLine() {
        return line;
    }

    public int getCharPositionInLine() {
        return charPositionInLine;
    }

    public RecognitionException getRecognitionException() {
        return recognitionException;
    }

}


text:
package com.adapter;

import com.manniu.manniu.R;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.Display;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;

/**
 * 自定义dialog
 *
 * @author zhousheng
 *
 */
public class UpdateDialog extends Dialog implements
		android.view.View.OnClickListener {
	private DialogClickListener listener;
	Context context;
	private TextView tv_restinfo_pop_tel_content;
	private TextView dialog_textViewID;
	private TextView dialog_textViewID1;
	private String leftBtnText;
	private String rightBtnText;
	private String content;

	public UpdateDialog(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		this.context = context;
	}

	/**
	 * 自定义dialog
	 *
	 * @param context
	 * @param theme
	 *            主题
	 * @param content
	 *            主体文字
	 * @param leftBtnText
	 *            左按钮文字,若为""则隐藏
	 * @param rightBtnText
	 *            右按钮文字,若为""则隐藏
	 * @param listener
	 *            回调接口
	 */
	public UpdateDialog(Context context, int theme, String content,
			String leftBtnText, String rightBtnText,
			DialogClickListener listener) {
		super(context, theme);
		this.context = context;
		this.content = content;
		this.leftBtnText = leftBtnText;
		this.rightBtnText = rightBtnText;
		this.listener = listener;
	}

	public void setTextSize(int size) {
		dialog_textViewID.setTextSize(size);
		dialog_textViewID1.setTextSize(size);
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.dlg_update);
		tv_restinfo_pop_tel_content = (TextView) findViewById(R.id.tv_restinfo_pop_tel_content);
		dialog_textViewID1 = (TextView) findViewById(R.id.dialog_textViewID1);
		dialog_textViewID = (TextView) findViewById(R.id.dialog_textViewID);
		dialog_textViewID.setOnClickListener(this);
		dialog_textViewID1.setOnClickListener(this);
		initView();
		initDialog(context);
	}

	/**
	 * 设置dialog的宽为屏幕的3分之1
	 *
	 * @param context
	 */
	private void initDialog(Context context) {
		setCanceledOnTouchOutside(false);
		setOnKeyListener(new OnKeyListener() {

			@Override
			public boolean onKey(DialogInterface dialog, int keyCode,
					KeyEvent event) {
				if (keyCode == KeyEvent.KEYCODE_BACK
						&& event.getRepeatCount() == 0) {
					return true;
				} else {
					return false;
				}
			}
		});
		WindowManager windowManager = this.getWindow().getWindowManager();
		Display display = windowManager.getDefaultDisplay();
		WindowManager.LayoutParams lp = this.getWindow().getAttributes();
		lp.width = (int) (display.getWidth() / 6 * 5); //// 设置宽度
		this.getWindow().setAttributes(lp);
	}

	private void initView() {
		tv_restinfo_pop_tel_content.setText(content);
		if (leftBtnText.equals(""))
			dialog_textViewID.setVisibility(View.GONE);
		else
			dialog_textViewID.setText(leftBtnText);
		if (rightBtnText.equals(""))
			dialog_textViewID1.setVisibility(View.GONE);
		else
			dialog_textViewID1.setText(rightBtnText);
	}

	public interface DialogClickListener {
		void onLeftBtnClick(Dialog dialog);

		void onRightBtnClick(Dialog dialog);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.dialog_textViewID:
			listener.onLeftBtnClick(this);
			break;
		case R.id.dialog_textViewID1:
			listener.onRightBtnClick(this);
			break;
		default:
			break;
		}
	}
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Problem_03___Fallen_In_Love
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = int.Parse(Console.ReadLine());
            int dotsOut = n * 2;
            int dotsIn = 0;
            int leave = 0;

            for (int i = 0; i < n; i++)
            {
                Console.Write(new string('#',1));
                Console.Write(new string('~', leave));
                Console.Write(new string('#', 1));
                Console.Write(new string('.', dotsOut));
                Console.Write(new string('#', 1));
                Console.Write(new string('.', dotsIn));
                Console.Write(new string('#', 1));
                Console.Write(new string('.', dotsOut));
                Console.Write(new string('#', 1));
                Console.Write(new string('~', leave));
                Console.Write(new string('#', 1));

                leave++;
                dotsOut -= 2;
                dotsIn += 2;
                Console.WriteLine();
            }

            dotsOut = 1;
            dotsIn = n*2;
            leave = n;
            for (int i = 0; i < n; i++)
            {
                Console.Write(new string('.', dotsOut));
                Console.Write(new string('#', 1));
                Console.Write(new string('~', leave));
                Console.Write(new string('#', 1));
                Console.Write(new string('.', dotsIn));
                Console.Write(new string('#', 1));
                Console.Write(new string('~', leave));
                Console.Write(new string('#', 1));
                Console.Write(new string('.', dotsOut));

                leave--;
                dotsOut += 2;
                dotsIn -= 2;
                Console.WriteLine();
            }

            Console.Write(new string('.', ((4 * n + 6)-4)/2));
            Console.Write(new string('#', 4));
            Console.Write(new string('.', ((4 * n + 6) - 4) / 2));
            Console.WriteLine();

            for (int i = 1; i <= n; i++)
            {
                Console.Write(new string('.', ((4 * n + 6) - 2) / 2));
                Console.Write(new string('#', 2));
                Console.Write(new string('.', ((4 * n + 6) - 2) / 2));
                Console.WriteLine();
            }
        }
    }
}


text:
@import UIKit;
#import "ORKDefaultFont.h"
#import "ORKDefines.h"

NS_ASSUME_NONNULL_BEGIN

/**
 This is a base class, not being used directly.
 */
ORK_CLASS_AVAILABLE
@interface ORKLabel : UILabel <ORKDefaultFont>

@end

@interface ORKLabel ()

- (void)init_ORKLabel;

- (void)updateAppearance;

@end

NS_ASSUME_NONNULL_END


text:
package com.glaf.oa.assessresult.model;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.glaf.oa.assessresult.util.AssessresultJsonFactory;
import com.glaf.core.base.JSONable;

@Entity
@Table(name = "oa_assessresult")
public class Assessresult implements Serializable, JSONable {

	private static final long serialVersionUID = 1L;

	@Id
	@Column(name = "resultid", nullable = false)
	protected Long resultid;

	@Column(name = "qustionid")
	protected Long qustionid;

	@Column(name = "area")
	protected String area;

	@Column(name = "company", length = 100)
	protected String company;

	@Column(name = "dept", length = 100)
	protected String dept;

	@Column(name = "post", length = 100)
	protected String post;

	@Column(name = "year")
	protected Integer year;

	@Column(name = "season")
	protected Integer season;

	@Column(name = "month")
	protected Integer month;

	@Column(name = "beevaluation", length = 20)
	protected String beevaluation;

	@Column(name = "evaluation", length = 20)
	protected String evaluation;

	@Column(name = "comment")
	protected String comment;

	@Column(name = "rewardsum")
	protected Double rewardsum;

	@Column(name = "score")
	protected Double score;

	@Column(name = "createBy", length = 50)
	protected String createBy;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "createDate")
	protected Date createDate;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "updateDate")
	protected Date updateDate;

	@Column(name = "updateBy", length = 50)
	protected String updateBy;

	protected String title;

	public Assessresult() {

	}

	public String getTitle() {

		return title;
	}

	public void setTitle(String title) {

		this.title = title;
	}

	public Long getResultid() {

		return this.resultid;
	}

	public void setResultid(Long resultid) {

		this.resultid = resultid;
	}

	public Long getQustionid() {

		return this.qustionid;
	}

	public String getArea() {

		return this.area;
	}

	public String getCompany() {

		return this.company;
	}

	public String getDept() {

		return this.dept;
	}

	public String getPost() {

		return this.post;
	}

	public Integer getYear() {

		return this.year;
	}

	public Integer getSeason() {

		return this.season;
	}

	public Integer getMonth() {

		return this.month;
	}

	public String getBeevaluation() {

		return this.beevaluation;
	}

	public String getEvaluation() {

		return this.evaluation;
	}

	public Double getRewardsum() {

		return this.rewardsum;
	}

	public Double getScore() {

		return this.score;
	}

	public String getCreateBy() {

		return this.createBy;
	}

	public Date getCreateDate() {

		return this.createDate;
	}

	public Date getUpdateDate() {

		return this.updateDate;
	}

	public String getUpdateBy() {

		return this.updateBy;
	}

	public void setQustionid(Long qustionid) {

		this.qustionid = qustionid;
	}

	public void setArea(String area) {

		this.area = area;
	}

	public void setCompany(String company) {

		this.company = company;
	}

	public void setDept(String dept) {

		this.dept = dept;
	}

	public void setPost(String post) {

		this.post = post;
	}

	public void setYear(Integer year) {

		this.year = year;
	}

	public void setSeason(Integer season) {

		this.season = season;
	}

	public void setMonth(Integer month) {

		this.month = month;
	}

	public void setBeevaluation(String beevaluation) {

		this.beevaluation = beevaluation;
	}

	public void setEvaluation(String evaluation) {

		this.evaluation = evaluation;
	}

	public void setRewardsum(Double rewardsum) {

		this.rewardsum = rewardsum;
	}

	public void setScore(Double score) {

		this.score = score;
	}

	public void setCreateBy(String createBy) {

		this.createBy = createBy;
	}

	public void setCreateDate(Date createDate) {

		this.createDate = createDate;
	}

	public void setUpdateDate(Date updateDate) {

		this.updateDate = updateDate;
	}

	public void setUpdateBy(String updateBy) {

		this.updateBy = updateBy;
	}

	@Override
	public boolean equals(Object obj) {

		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Assessresult other = (Assessresult) obj;
		if (resultid == null) {
			if (other.resultid != null)
				return false;
		} else if (!resultid.equals(other.resultid))
			return false;
		return true;
	}

	@Override
	public int hashCode() {

		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((resultid == null) ? 0 : resultid.hashCode());
		return result;
	}

	public Assessresult jsonToObject(JSONObject jsonObject) {

		return AssessresultJsonFactory.jsonToObject(jsonObject);
	}

	public JSONObject toJsonObject() {

		return AssessresultJsonFactory.toJsonObject(this);
	}

	public ObjectNode toObjectNode() {

		return AssessresultJsonFactory.toObjectNode(this);
	}

	public String getComment() {

		return comment;
	}

	public void setComment(String comment) {

		this.comment = comment;
	}

	@Override
	public String toString() {

		return ToStringBuilder.reflectionToString(this,
				ToStringStyle.MULTI_LINE_STYLE);
	}

}


text:
package test;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 *
 *
 */
@WebServlet(name = "ChatWindow", urlPatterns = {"/ChatWindow"})
public class ChatWindow extends HttpServlet {

String username,tempName;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        response.setContentType("text/html;charset=UTF-8");

        try (PrintWriter out = response.getWriter())
        {
            /* TODO output your page here. You may use following sample code. */

         String message = request.getParameter("txtMsg");  //Extract Message
         String username = session.getAttribute("username").toString(); //Extract Username

         //Display Chat Room
         out.println("    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"> <title>Chat Room</title>  ");
         out.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"> ");
         out.println("
Hi ");
         out.println(username);
         out.println("
 Welcome to Hello Chat ");
         out.println("

");
         out.println("  ");
         out.println("      <form name=\"ChatWindow\" action=\"ChatWindow\">");
         out.println("Message: <input type=\"text\" name=\"txtMsg\" value=\"\" /><input type=\"submit\" value=\"Send\" name=\"cmdSend\"/>");
         out.println("

 Refresh Chat Room");
         out.println("

");
         out.println("Messages in Chat Box:");
         out.println("

");
         out.println("<textarea  readonly=\"readonly\"   name=\"txtMessage\" rows=\"20\" cols=\"60\">");

         //If eneterd message != null then insert into database
        if(request.getParameter("txtMsg")!=null)
         {

           try
           {
                Class.forName("com.mysql.jdbc.Driver");
                java.sql.Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/hello_chat","root","Shikh@r696");

                Statement st=con.createStatement();

                String sql = "insert into hello_message values ('"+username+"','"+message+"')";
                st.executeUpdate(sql);

                st.execute("commit");

           }
           catch(Exception ex1)
           {
                        System.err.println(ex1.getMessage());
                        String messages = "No";
                        out.println(messages);
           }
         }
         // Retrieve all messages from database

         try
         {
            Class.forName("com.mysql.jdbc.Driver");
            java.sql.Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/hello_chat","root","Shikh@r696");

            Statement st=con.createStatement();

            ResultSet rs=st.executeQuery("select * from hello_message");

            // Print all retrieved messages
            while(rs.next())
            {
                String messages =rs.getString(1)+ " >> " + rs.getString(2);

                out.println(messages);
            }

            con.close();
         }
         catch(Exception ex1)
         {
            System.err.println(ex1.getMessage());
         }

         out.println("</textarea>");
         out.println("
");
         out.println("</form>");
         out.println("");
         out.println("");
        }

    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        //Session

        session = request.getSession();

        if(username!=null)
        {
            tempName=username;
        }

        processRequest(request, response);

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
 HttpSession session;
}


text:
package json

import (
	"encoding/json"
	"errors"
	"net"

	jsonconfig "github.com/v2ray/v2ray-core/proxy/common/config/json"
)

const (
	AuthMethodNoAuth   = "noauth"
	AuthMethodUserPass = "password"
)

type SocksAccount struct {
	Username string `json:"user"`
	Password string `json:"pass"`
}

type SocksAccountMap map[string]string

func (this *SocksAccountMap) UnmarshalJSON(data []byte) error {
	var accounts []SocksAccount
	err := json.Unmarshal(data, &accounts)
	if err != nil {
		return err
	}
	*this = make(map[string]string)
	for _, account := range accounts {
		(*this)[account.Username] = account.Password
	}
	return nil
}

func (this *SocksAccountMap) HasAccount(user, pass string) bool {
	if actualPass, found := (*this)[user]; found {
		return actualPass == pass
	}
	return false
}

type IPAddress net.IP

func (this *IPAddress) UnmarshalJSON(data []byte) error {
	var ipStr string
	err := json.Unmarshal(data, &ipStr)
	if err != nil {
		return err
	}
	ip := net.ParseIP(ipStr)
	if ip == nil {
		return errors.New("Unknown IP format: " + ipStr)
	}
	*this = IPAddress(ip)
	return nil
}

type SocksConfig struct {
	AuthMethod string          `json:"auth"`
	Accounts   SocksAccountMap `json:"accounts"`
	UDP        bool            `json:"udp"`
	HostIP     IPAddress       `json:"ip"`
}

func (sc *SocksConfig) IsNoAuth() bool {
	return sc.AuthMethod == AuthMethodNoAuth
}

func (sc *SocksConfig) IsPassword() bool {
	return sc.AuthMethod == AuthMethodUserPass
}

func (sc *SocksConfig) HasAccount(user, pass string) bool {
	return sc.Accounts.HasAccount(user, pass)
}

func (sc *SocksConfig) IP() net.IP {
	return net.IP(sc.HostIP)
}

func (this *SocksConfig) UDPEnabled() bool {
	return this.UDP
}

func init() {
	jsonconfig.RegisterInboundConnectionConfig("socks", func() interface{} {
		return &SocksConfig{
			HostIP: IPAddress(net.IPv4(127, 0, 0, 1)),
		}
	})
}


text:
<!--

    Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com)

    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.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>org.jboss.pnc.causeway</groupId>
    <artifactId>causeway</artifactId>
    <version>2.4.2-SNAPSHOT</version>
  </parent>

  <artifactId>causeway-web</artifactId>
  <packaging>war</packaging>
  <name>Causeway :: Web</name>

  <dependencies>
    <dependency>
      <groupId>org.jboss.pnc.causeway</groupId>
      <artifactId>causeway-core</artifactId>
      <scope>provided</scope>
      <type>ejb</type>
    </dependency>
    <dependency>
      <groupId>org.jboss.pnc.causeway</groupId>
      <artifactId>causeway-rest</artifactId>
      <scope>provided</scope>
      <type>ejb</type>
    </dependency>
    <dependency>
      <groupId>org.jboss.spec.javax.ws.rs</groupId>
      <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.keycloak</groupId>
      <artifactId>keycloak-core</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jboss.spec.javax.servlet</groupId>
      <artifactId>jboss-servlet-api_4.0_spec</artifactId>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
    </dependency>
  </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
                    <webResources>
                        <resource>
                            <directory>src/main/webapp</directory>
                            <filtering>true</filtering>
                            <includes>
                                <include>**/*.html</include>
                            </includes>
                        </resource>
                    </webResources>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>


text:
package org.avirtuos.teslog.config;

import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RunWith(MockitoJUnitRunner.class)
public class PropertyConfigServiceTest extends TestCase {
    private static final Logger LOGGER = LoggerFactory.getLogger(PropertyConfigServiceTest.class);

    private String testConfigFile = "unit-test.properties";

    @Test
    public void testGet() throws Exception {
        LOGGER.info("testGet: enter");
        ConfigServiceFactory.loadConfig(testConfigFile);

        String actualString = ConfigServiceFactory.get().get(stringConfigKey);
        assertEquals("my string value", actualString);

        double actualDouble = ConfigServiceFactory.get().get(doubleConfigKey);
        assertEquals(2.4, actualDouble);

        int actualInt = ConfigServiceFactory.get().get(integerConfigKey);
        assertEquals(100, actualInt);

        boolean actualBool = ConfigServiceFactory.get().get(boolConfigKey);
        assertEquals(false, actualBool);

        LOGGER.info("testGet: exit");
    }

    private ConfigKey<Integer> integerConfigKey = new ConfigKey<Integer>() {
        @Override
        public String getName() {
            return "intValue";
        }

        @Override
        public Integer getDefaultValue() {
            return -1;
        }

        @Override
        public Class<Integer> getType() {
            return Integer.class;
        }
    };

    private ConfigKey<String> stringConfigKey = new ConfigKey<String>() {
        @Override
        public String getName() {
            return "stringValue";
        }

        @Override
        public String getDefaultValue() {
            return "default";
        }

        @Override
        public Class<String> getType() {
            return String.class;
        }
    };

    private ConfigKey<Double> doubleConfigKey = new ConfigKey<Double>() {
        @Override
        public String getName() {
            return "doubleValue";
        }

        @Override
        public Double getDefaultValue() {
            return 1.1;
        }

        @Override
        public Class<Double> getType() {
            return Double.class;
        }
    };

    private ConfigKey<Boolean> boolConfigKey = new ConfigKey<Boolean>() {
        @Override
        public String getName() {
            return "boolValue";
        }

        @Override
        public Boolean getDefaultValue() {
            return true;
        }

        @Override
        public Class<Boolean> getType() {
            return Boolean.class;
        }
    };
}


text:
layout: post
title: TEDx Avignon
type: talk
category: news
---

I did [my best](https://www.youtube.com/watch?v=WwqRIFXJCMo&feature=youtu.be) to
explain what a physicist has to say about cities at TEDx Avignon.


text:
package displayers

import (
	"io"

	"github.com/digitalocean/doctl/do"
)

// Key is used to display the SSH Key results from a `list` operation.
type Key struct {
	Keys do.SSHKeys
}

var _ Displayable = &Key{}

func (ke *Key) JSON(out io.Writer) error {
	return writeJSON(ke.Keys, out)
}

func (ke *Key) Cols() []string {
	return []string{
		"ID", "Name", "FingerPrint",
	}
}

func (ke *Key) ColMap() map[string]string {
	return map[string]string{
		"ID": "ID", "Name": "Name", "FingerPrint": "FingerPrint",
	}
}

func (ke *Key) KV() []map[string]interface{} {
	out := make([]map[string]interface{}, 0, len(ke.Keys))

	for _, k := range ke.Keys {
		o := map[string]interface{}{
			"ID": k.ID, "Name": k.Name, "FingerPrint": k.Fingerprint,
		}

		out = append(out, o)
	}

	return out
}

// KeyGet is used to display the SSH Key results from a `get` operation. This
// separate displayer is required in order to include the public key in this
// operation.
type KeyGet struct {
	Keys do.SSHKeys
}

var _ Displayable = &KeyGet{}

func (ke *KeyGet) JSON(out io.Writer) error {
	return writeJSON(ke.Keys, out)
}

func (ke *KeyGet) Cols() []string {
	return []string{
		"ID", "Name", "FingerPrint", "PublicKey",
	}
}

func (ke *KeyGet) ColMap() map[string]string {
	return map[string]string{
		"ID": "ID", "Name": "Name", "FingerPrint": "FingerPrint", "PublicKey": "Public Key",
	}
}

func (ke *KeyGet) KV() []map[string]interface{} {
	out := make([]map[string]interface{}, 0, len(ke.Keys))

	for _, k := range ke.Keys {
		o := map[string]interface{}{
			"ID": k.ID, "Name": k.Name, "FingerPrint": k.Fingerprint, "PublicKey": k.PublicKey,
		}

		out = append(out, o)
	}

	return out
}


text:
<?php

require_once('../header.php');

$survey = getSurvey($_GET['id']);
$modules = getModules($survey['id']);

?>

<?php echo htmlspecialchars($survey['title_en']); ?>
<?php echo htmlspecialchars($survey['subtitle_en']); ?>

<?php echo htmlspecialchars($survey['title_cy']); ?>
<?php echo htmlspecialchars($survey['subtitle_cy']); ?>

<?php echo htmlspecialchars($survey['datetime']); ?>

    <?php if (!$survey['locked']) { ?>
      <a href="send.php?id=<?php echo $survey['id']; ?>" class="btn btn-danger">Lock & Send Survey
    <?php } else { ?>
      <a class="btn btn-primary" href="send.php?id=<?php echo $survey['id'] ?>&resend=1"> Resend
    <?php } ?>

<?php
  $completed = count(getParticipants($survey['id'], 1));
  $incomplete = count(getParticipants($survey['id'], 0));
  if (($completed + $incomplete) > 0) { ?>

  <div class="progress-bar progress-bar-success" style="width: <?php echo ($completed/($completed+$incomplete))*100 ?>%" data-toggle="tooltip" data-placement="top" title="<?php echo ($completed/($completed+$incomplete))*100 ?>%">
    <?php echo $completed; ?> Answered

  <div class="progress-bar progress-bar-danger" style="width: <?php echo ($incomplete/($completed+$incomplete))*100 ?>%" data-toggle="tooltip" data-placement="top" title="<?php echo ($incomplete/($completed+$incomplete))*100 ?>%">
    <?php echo $incomplete; ?> Unanswered

<?php } ?>

Questions

Participants

Modules

<a href="results.php?id=<?php echo $survey['id'] ?>">Results

Questions

      <?php include('tpl_questions.php'); ?>

Participants

      <?php if ($survey['locked']) { ?>

To send out a reminder-email for incomplete surveys, hit the <a class="btn btn-primary btn-xs" href="send.php?id=<?php echo $survey['id'] ?>&resend=1"> Resend button above.

      <?php } ?>

            Student ID
            Completed?
            Token

        <?php
        $students = getStudents($survey['id'], 1);
        foreach ($students as $student) { ?>
            <tr<?php echo htmlspecialchars($student['completed']) ? ' class="success"' : ' class="danger"'; ?>>
              <?php echo htmlspecialchars($student['aber_id']); ?>
              <?php echo htmlspecialchars($student['completed']) ? 'Yes' : 'No'; ?>
              <?php echo htmlspecialchars($student['token']); ?>

        <?php } ?>
        <?php
        $students = getStudents($survey['id'], 0);
        foreach ($students as $student) { ?>
            <tr<?php echo htmlspecialchars($student['completed']) ? ' class="success"' : ' class="danger"'; ?>>
              <?php echo htmlspecialchars($student['aber_id']); ?>
              <?php echo htmlspecialchars($student['completed']) ? 'Yes' : 'No'; ?>
              <?php echo htmlspecialchars($student['token']); ?>

        <?php } ?>

Modules

            Module Code
            Title
            Staff

          <?php
          foreach ($modules as $module) { ?>

              <?php echo htmlspecialchars($module['module_code']); ?>
              <?php echo htmlspecialchars($module['title']); ?>

                <?php
                  $staff = getModuleStaff($survey['id'], $module['module_code']);
                  $result = array();
                  foreach ($staff as $staff_member) {
                    $result[] = $staff_member['aber_id'];
                  }
                  echo implode(', ', $result);
                ?>

          <?php } ?>

<?php require_once('../footer.php'); ?>


text:
isslocation = new Mongo.Collection('isslocation');
issairwater = new Mongo.Collection('issairwater');
isscomputer = new Mongo.Collection('isscomputer');
isssolar = new Mongo.Collection('isssolar');


text:
package enums // import "google.golang.org/genproto/googleapis/ads/googleads/v0/enums"

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package

// Possible values for Custom placeholder fields.
type CustomPlaceholderFieldEnum_CustomPlaceholderField int32

const (
	// Not specified.
	CustomPlaceholderFieldEnum_UNSPECIFIED CustomPlaceholderFieldEnum_CustomPlaceholderField = 0
	// Used for return value only. Represents value unknown in this version.
	CustomPlaceholderFieldEnum_UNKNOWN CustomPlaceholderFieldEnum_CustomPlaceholderField = 1
	// Data Type: STRING. Required. Combination ID and ID2 must be unique per
	// offer.
	CustomPlaceholderFieldEnum_ID CustomPlaceholderFieldEnum_CustomPlaceholderField = 2
	// Data Type: STRING. Combination ID and ID2 must be unique per offer.
	CustomPlaceholderFieldEnum_ID2 CustomPlaceholderFieldEnum_CustomPlaceholderField = 3
	// Data Type: STRING. Required. Main headline with product name to be shown
	// in dynamic ad.
	CustomPlaceholderFieldEnum_ITEM_TITLE CustomPlaceholderFieldEnum_CustomPlaceholderField = 4
	// Data Type: STRING. Optional text to be shown in the image ad.
	CustomPlaceholderFieldEnum_ITEM_SUBTITLE CustomPlaceholderFieldEnum_CustomPlaceholderField = 5
	// Data Type: STRING. Optional description of the product to be shown in the
	// ad.
	CustomPlaceholderFieldEnum_ITEM_DESCRIPTION CustomPlaceholderFieldEnum_CustomPlaceholderField = 6
	// Data Type: STRING. Full address of your offer or service, including
	// postal code. This will be used to identify the closest product to the
	// user when there are multiple offers in the feed that are relevant to the
	// user.
	CustomPlaceholderFieldEnum_ITEM_ADDRESS CustomPlaceholderFieldEnum_CustomPlaceholderField = 7
	// Data Type: STRING. Price to be shown in the ad.
	// Example: "100.00 USD"
	CustomPlaceholderFieldEnum_PRICE CustomPlaceholderFieldEnum_CustomPlaceholderField = 8
	// Data Type: STRING. Formatted price to be shown in the ad.
	// Example: "Starting at $100.00 USD", "$80 - $100"
	CustomPlaceholderFieldEnum_FORMATTED_PRICE CustomPlaceholderFieldEnum_CustomPlaceholderField = 9
	// Data Type: STRING. Sale price to be shown in the ad.
	// Example: "80.00 USD"
	CustomPlaceholderFieldEnum_SALE_PRICE CustomPlaceholderFieldEnum_CustomPlaceholderField = 10
	// Data Type: STRING. Formatted sale price to be shown in the ad.
	// Example: "On sale for $80.00", "$60 - $80"
	CustomPlaceholderFieldEnum_FORMATTED_SALE_PRICE CustomPlaceholderFieldEnum_CustomPlaceholderField = 11
	// Data Type: URL. Image to be displayed in the ad. Highly recommended for
	// image ads.
	CustomPlaceholderFieldEnum_IMAGE_URL CustomPlaceholderFieldEnum_CustomPlaceholderField = 12
	// Data Type: STRING. Used as a recommendation engine signal to serve items
	// in the same category.
	CustomPlaceholderFieldEnum_ITEM_CATEGORY CustomPlaceholderFieldEnum_CustomPlaceholderField = 13
	// Data Type: URL_LIST. Final URLs for the ad when using Upgraded
	// URLs. User will be redirected to these URLs when they click on an ad, or
	// when they click on a specific product for ads that have multiple
	// products.
	CustomPlaceholderFieldEnum_FINAL_URLS CustomPlaceholderFieldEnum_CustomPlaceholderField = 14
	// Data Type: URL_LIST. Final mobile URLs for the ad when using Upgraded
	// URLs.
	CustomPlaceholderFieldEnum_FINAL_MOBILE_URLS CustomPlaceholderFieldEnum_CustomPlaceholderField = 15
	// Data Type: URL. Tracking template for the ad when using Upgraded URLs.
	CustomPlaceholderFieldEnum_TRACKING_URL CustomPlaceholderFieldEnum_CustomPlaceholderField = 16
	// Data Type: STRING_LIST. Keywords used for product retrieval.
	CustomPlaceholderFieldEnum_CONTEXTUAL_KEYWORDS CustomPlaceholderFieldEnum_CustomPlaceholderField = 17
	// Data Type: STRING. Android app link. Must be formatted as:
	// android-app://{package_id}/{scheme}/{host_path}.
	// The components are defined as follows:
	// package_id: app ID as specified in Google Play.
	// scheme: the scheme to pass to the application. Can be HTTP, or a custom
	//   scheme.
	// host_path: identifies the specific content within your application.
	CustomPlaceholderFieldEnum_ANDROID_APP_LINK CustomPlaceholderFieldEnum_CustomPlaceholderField = 18
	// Data Type: STRING_LIST. List of recommended IDs to show together with
	// this item.
	CustomPlaceholderFieldEnum_SIMILAR_IDS CustomPlaceholderFieldEnum_CustomPlaceholderField = 19
	// Data Type: STRING. iOS app link.
	CustomPlaceholderFieldEnum_IOS_APP_LINK CustomPlaceholderFieldEnum_CustomPlaceholderField = 20
	// Data Type: INT64. iOS app store ID.
	CustomPlaceholderFieldEnum_IOS_APP_STORE_ID CustomPlaceholderFieldEnum_CustomPlaceholderField = 21
)

var CustomPlaceholderFieldEnum_CustomPlaceholderField_name = map[int32]string{
	0:  "UNSPECIFIED",
	1:  "UNKNOWN",
	2:  "ID",
	3:  "ID2",
	4:  "ITEM_TITLE",
	5:  "ITEM_SUBTITLE",
	6:  "ITEM_DESCRIPTION",
	7:  "ITEM_ADDRESS",
	8:  "PRICE",
	9:  "FORMATTED_PRICE",
	10: "SALE_PRICE",
	11: "FORMATTED_SALE_PRICE",
	12: "IMAGE_URL",
	13: "ITEM_CATEGORY",
	14: "FINAL_URLS",
	15: "FINAL_MOBILE_URLS",
	16: "TRACKING_URL",
	17: "CONTEXTUAL_KEYWORDS",
	18: "ANDROID_APP_LINK",
	19: "SIMILAR_IDS",
	20: "IOS_APP_LINK",
	21: "IOS_APP_STORE_ID",
}
var CustomPlaceholderFieldEnum_CustomPlaceholderField_value = map[string]int32{
	"UNSPECIFIED":          0,
	"UNKNOWN":              1,
	"ID":                   2,
	"ID2":                  3,
	"ITEM_TITLE":           4,
	"ITEM_SUBTITLE":        5,
	"ITEM_DESCRIPTION":     6,
	"ITEM_ADDRESS":         7,
	"PRICE":                8,
	"FORMATTED_PRICE":      9,
	"SALE_PRICE":           10,
	"FORMATTED_SALE_PRICE": 11,
	"IMAGE_URL":            12,
	"ITEM_CATEGORY":        13,
	"FINAL_URLS":           14,
	"FINAL_MOBILE_URLS":    15,
	"TRACKING_URL":         16,
	"CONTEXTUAL_KEYWORDS":  17,
	"ANDROID_APP_LINK":     18,
	"SIMILAR_IDS":          19,
	"IOS_APP_LINK":         20,
	"IOS_APP_STORE_ID":     21,
}

func (x CustomPlaceholderFieldEnum_CustomPlaceholderField) String() string {
	return proto.EnumName(CustomPlaceholderFieldEnum_CustomPlaceholderField_name, int32(x))
}
func (CustomPlaceholderFieldEnum_CustomPlaceholderField) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_custom_placeholder_field_da1fc5fdf27a9f46, []int{0, 0}
}

// Values for Custom placeholder fields.
// For more information about dynamic remarketing feeds, see
// https://support.google.com/google-ads/answer/6053288.
type CustomPlaceholderFieldEnum struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *CustomPlaceholderFieldEnum) Reset()         { *m = CustomPlaceholderFieldEnum{} }
func (m *CustomPlaceholderFieldEnum) String() string { return proto.CompactTextString(m) }
func (*CustomPlaceholderFieldEnum) ProtoMessage()    {}
func (*CustomPlaceholderFieldEnum) Descriptor() ([]byte, []int) {
	return fileDescriptor_custom_placeholder_field_da1fc5fdf27a9f46, []int{0}
}
func (m *CustomPlaceholderFieldEnum) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_CustomPlaceholderFieldEnum.Unmarshal(m, b)
}
func (m *CustomPlaceholderFieldEnum) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_CustomPlaceholderFieldEnum.Marshal(b, m, deterministic)
}
func (dst *CustomPlaceholderFieldEnum) XXX_Merge(src proto.Message) {
	xxx_messageInfo_CustomPlaceholderFieldEnum.Merge(dst, src)
}
func (m *CustomPlaceholderFieldEnum) XXX_Size() int {
	return xxx_messageInfo_CustomPlaceholderFieldEnum.Size(m)
}
func (m *CustomPlaceholderFieldEnum) XXX_DiscardUnknown() {
	xxx_messageInfo_CustomPlaceholderFieldEnum.DiscardUnknown(m)
}

var xxx_messageInfo_CustomPlaceholderFieldEnum proto.InternalMessageInfo

func init() {
	proto.RegisterType((*CustomPlaceholderFieldEnum)(nil), "google.ads.googleads.v0.enums.CustomPlaceholderFieldEnum")
	proto.RegisterEnum("google.ads.googleads.v0.enums.CustomPlaceholderFieldEnum_CustomPlaceholderField", CustomPlaceholderFieldEnum_CustomPlaceholderField_name, CustomPlaceholderFieldEnum_CustomPlaceholderField_value)
}

func init() {
	proto.RegisterFile("google/ads/googleads/v0/enums/custom_placeholder_field.proto", fileDescriptor_custom_placeholder_field_da1fc5fdf27a9f46)
}

var fileDescriptor_custom_placeholder_field_da1fc5fdf27a9f46 = []byte{
	// 484 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x52, 0xdd, 0x8e, 0x12, 0x31,
	0x18, 0x15, 0x70, 0x41, 0x3e, 0x96, 0xa5, 0x14, 0x56, 0x8d, 0x66, 0x2f, 0xdc, 0x07, 0x18, 0x88,
	0x5e, 0xea, 0x4d, 0x99, 0x16, 0xd2, 0x30, 0x4c, 0x27, 0x6d, 0xd9, 0x75, 0x0d, 0x49, 0x83, 0xcc,
	0x38, 0x6e, 0x02, 0x0c, 0x61, 0x96, 0x7d, 0x1d, 0x13, 0x2f, 0x7d, 0x08, 0x1f, 0xc0, 0xf8, 0x50,
	0xa6, 0x1d, 0x16, 0xbc, 0x58, 0xbd, 0x69, 0xbe, 0xef, 0x9c, 0xef, 0x9c, 0xfe, 0x1d, 0xf8, 0x90,
	0x66, 0x59, 0xba, 0x4c, 0x7a, 0xf3, 0x38, 0xef, 0x15, 0xa5, 0xad, 0xee, 0xfb, 0xbd, 0x64, 0xbd,
	0x5b, 0xe5, 0xbd, 0xc5, 0x2e, 0xbf, 0xcb, 0x56, 0x66, 0xb3, 0x9c, 0x2f, 0x92, 0xaf, 0xd9, 0x32,
	0x4e, 0xb6, 0xe6, 0xcb, 0x6d, 0xb2, 0x8c, 0xbd, 0xcd, 0x36, 0xbb, 0xcb, 0xf0, 0x45, 0x21, 0xf1,
	0xe6, 0x71, 0xee, 0x1d, 0xd4, 0xde, 0x7d, 0xdf, 0x73, 0xea, 0xcb, 0x9f, 0x15, 0x78, 0xe5, 0x3b,
	0x87, 0xe8, 0x68, 0x30, 0xb4, 0x7a, 0xb6, 0xde, 0xad, 0x2e, 0xbf, 0x55, 0xe0, 0xf9, 0xe3, 0x34,
	0x6e, 0x41, 0x63, 0x1a, 0xaa, 0x88, 0xf9, 0x7c, 0xc8, 0x19, 0x45, 0x4f, 0x70, 0x03, 0x6a, 0xd3,
	0x70, 0x1c, 0x8a, 0xeb, 0x10, 0x95, 0x70, 0x15, 0xca, 0x9c, 0xa2, 0x32, 0xae, 0x41, 0x85, 0xd3,
	0xb7, 0xa8, 0x82, 0xcf, 0x00, 0xb8, 0x66, 0x13, 0xa3, 0xb9, 0x0e, 0x18, 0x7a, 0x8a, 0xdb, 0xd0,
	0x74, 0xbd, 0x9a, 0x0e, 0x0a, 0xe8, 0x04, 0x77, 0x01, 0x39, 0x88, 0x32, 0xe5, 0x4b, 0x1e, 0x69,
	0x2e, 0x42, 0x54, 0xc5, 0x08, 0x4e, 0x1d, 0x4a, 0x28, 0x95, 0x4c, 0x29, 0x54, 0xc3, 0x75, 0x38,
	0x89, 0x24, 0xf7, 0x19, 0x7a, 0x86, 0x3b, 0xd0, 0x1a, 0x0a, 0x39, 0x21, 0x5a, 0x33, 0x6a, 0x0a,
	0xb0, 0x6e, 0xb7, 0x52, 0x24, 0x60, 0xfb, 0x1e, 0xf0, 0x4b, 0xe8, 0x1e, 0x87, 0xfe, 0x62, 0x1a,
	0xb8, 0x09, 0x75, 0x3e, 0x21, 0x23, 0x66, 0xa6, 0x32, 0x40, 0xa7, 0x87, 0x33, 0xf9, 0x44, 0xb3,
	0x91, 0x90, 0x37, 0xa8, 0x69, 0xbd, 0x86, 0x3c, 0x24, 0x81, 0x9d, 0x50, 0xe8, 0x0c, 0x9f, 0x43,
	0xbb, 0xe8, 0x27, 0x62, 0xc0, 0x03, 0x56, 0xc0, 0x2d, 0x7b, 0x48, 0x2d, 0x89, 0x3f, 0xe6, 0xe1,
	0xc8, 0x79, 0x21, 0xfc, 0x02, 0x3a, 0xbe, 0x08, 0x35, 0xfb, 0xa8, 0xa7, 0x24, 0x30, 0x63, 0x76,
	0x73, 0x2d, 0x24, 0x55, 0xa8, 0x6d, 0x6f, 0x49, 0x42, 0x2a, 0x05, 0xa7, 0x86, 0x44, 0x91, 0x09,
	0x78, 0x38, 0x46, 0xd8, 0xbe, 0xa6, 0xe2, 0x13, 0x1e, 0x10, 0x69, 0x38, 0x55, 0xa8, 0xe3, 0xae,
	0x2d, 0xd4, 0x71, 0xa4, 0xeb, 0x9e, 0x67, 0x8f, 0x28, 0x2d, 0x24, 0x33, 0x9c, 0xa2, 0xf3, 0xc1,
	0xef, 0x12, 0xbc, 0x59, 0x64, 0x2b, 0xef, 0xbf, 0xdf, 0x3c, 0x78, 0xfd, 0xf8, 0x27, 0x46, 0x36,
	0x22, 0x51, 0xe9, 0xd3, 0x60, 0xaf, 0x4e, 0xb3, 0xe5, 0x7c, 0x9d, 0x7a, 0xd9, 0x36, 0xed, 0xa5,
	0xc9, 0xda, 0x05, 0xe8, 0x21, 0x72, 0x9b, 0xdb, 0xfc, 0x1f, 0x09, 0x7c, 0xef, 0xd6, 0xef, 0xe5,
	0xca, 0x88, 0x90, 0x1f, 0xe5, 0x8b, 0x51, 0x61, 0x45, 0xe2, 0xdc, 0x2b, 0x4a, 0x5b, 0x5d, 0xf5,
	0x3d, 0x9b, 0xa7, 0xfc, 0xd7, 0x03, 0x3f, 0x23, 0x71, 0x3e, 0x3b, 0xf0, 0xb3, 0xab, 0xfe, 0xcc,
	0xf1, 0x9f, 0xab, 0x6e, 0xd3, 0x77, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x58, 0x53, 0x00, 0x84,
	0xf5, 0x02, 0x00, 0x00,
}


text:
XML parsers for GIS metadata that are designed to read in, validate, update and output a core set of properties that have been mapped between the most common standards, currently:

* FGDC
* ISO-19139 (and ISO-19115)
* ArcGIS (tested with ArcGIS format 1.0).

This library is compatible with Python versions 2.7 and 3.4 through 3.6.

[![Build Status](https://api.travis-ci.com/consbio/gis-metadata-parser.png?branch=main)](https://app.travis-ci.com/github/consbio/gis-metadata-parser)
[![Coverage Status](https://coveralls.io/repos/github/consbio/gis-metadata-parser/badge.svg?branch=main)](https://coveralls.io/github/consbio/gis-metadata-parser?branch=main)

## Installation
Install with `pip install gis-metadata-parser`.

## Usage

Parsers can be instantiated from files, XML strings or URLs. They can be converted from one standard to another as well.
```python
from gis_metadata.arcgis_metadata_parser import ArcGISParser
from gis_metadata.fgdc_metadata_parser import FgdcParser
from gis_metadata.iso_metadata_parser import IsoParser
from gis_metadata.metadata_parser import get_metadata_parser

# From file objects
with open(r'/path/to/metadata.xml') as metadata:
    fgdc_from_file = FgdcParser(metadata)

with open(r'/path/to/metadata.xml') as metadata:
    iso_from_file = IsoParser(metadata)

# Detect standard based on root element, metadata
fgdc_from_string = get_metadata_parser(
    """
    <?xml version='1.0' encoding='UTF-8'?>
    <metadata>
        <idinfo>
        </idinfo>
    </metadata>
    """
)

# Detect ArcGIS standard based on root element and its nodes
iso_from_string = get_metadata_parser(
    """
    <?xml version='1.0' encoding='UTF-8'?>
    <metadata>
        <dataIdInfo/></dataIdInfo>
        <distInfo/></distInfo>
        <dqInfo/></dqInfo>
    </metadata>
    """
)

# Detect ISO standard based on root element, MD_Metadata or MI_Metadata
iso_from_string = get_metadata_parser(
    """
    <?xml version='1.0' encoding='UTF-8'?>
    <MD_Metadata>
        <identificationInfo>
        </identificationInfo>
    </MD_Metadata>
    """
)

# Convert from one standard to another
fgdc_converted = iso_from_file.convert_to(FgdcParser)
iso_converted = fgdc_from_file.convert_to(IsoParser)
arcgis_converted = iso_converted.convert_to(ArcGISParser)

# Output supported properties as key value pairs (dict)
fgdc_key_vals = fgdc_from_file.convert_to(dict)
iso_key_vals = iso_from_file.convert_to(dict)
```

Finally, the properties of the parser can be updated, validated, applied and output:
```python
with open(r'/path/to/metadata.xml') as metadata:
    fgdc_from_file = FgdcParser(metadata)

# Example simple properties
fgdc_from_file.title
fgdc_from_file.abstract
fgdc_from_file.place_keywords
fgdc_from_file.thematic_keywords

# :see: gis_metadata.utils.SUPPORTED_PROPS for list of all supported properties

# Complex properties
fgdc_from_file.attributes
fgdc_from_file.bounding_box
fgdc_from_file.contacts
fgdc_from_file.dates
fgdc_from_file.digital_forms
fgdc_from_file.larger_works
fgdc_from_file.process_steps
fgdc_from_file.raster_info

# :see: gis_metadata.utils.COMPLEX_DEFINITIONS for structure of all complex properties

# Update properties
fgdc_from_file.title = 'New Title'
fgdc_from_file.dates = {'type': 'single' 'values': '1/1/2016'}

# Apply updates
fgdc_from_file.validate()                                      # Ensure updated properties are valid
fgdc_from_file.serialize()                                     # Output updated XML as a string
fgdc_from_file.write()                                         # Output updated XML to existing file
fgdc_from_file.write(out_file_or_path='/path/to/updated.xml')  # Output updated XML to new file
```

## Extending and Customizing

### Tips

There are a few unwritten (until now) rules about the way the metadata parsers are wired to work:

1. Properties are generally defined by XPATH in each `parser._data_map`
2. Simple parser properties accept only values of `string` and `list`'s of `string`'s
3. XPATH's configured in the data map support references to element attributes: `'path/to/element/@attr'`
4. Complex parser properties are defined by custom parser/updater functions instead of by XPATH
5. Complex parser properties accept values of type `dict` containing simple properties, or a list of said `dict`'s
6. XPATH keys in the data map with leading underscores are parsed, but not validated or written out
7. XPATH keys in the data map that "shadow" other properties but with a leading underscore serve as secondary values
8. Secondary values are used in the absence of a primary value if primary location (element or attribute) is missing
9. Additional underscores indicate further locations to check for missing values, i.e. `title`, `_title`, `__title`

Some examples of existing secondary properties are as follows:
```python
# In the ArcGIS parser for distribution contact phone:

ARCGIS_TAG_FORMATS = frozendict({
     ...
    'dist_phone': 'distInfo/distributor/distorCont/rpCntInfo/cntPhone/voiceNum',
    '_dist_phone': 'distInfo/distributor/distorCont/rpCntInfo/voiceNum',  # If not in cntPhone
    ...
})

# In the FGDC parser for sub-properties in the contacts definition:

FGDC_DEFINITIONS = dict({k: dict(v) for k, v in iteritems(COMPLEX_DEFINITIONS)})
FGDC_DEFINITIONS[CONTACTS].update({
    '_name': '{_name}',
    '_organization': '{_organization}'
})
...
class FgdcParser(MetadataParser):
    ...
    def _init_data_map(self):
        ...
        ct_format = FGDC_TAG_FORMATS[CONTACTS]
        fgdc_data_structures[CONTACTS] = format_xpaths(
            ...
            name=ct_format.format(ct_path='cntperp/cntper'),
            _name=ct_format.format(ct_path='cntorgp/cntper'),  # If not in cntperp
            organization=ct_format.format(ct_path='cntperp/cntorg'),
            _organization=ct_format.format(ct_path='cntorgp/cntorg'),  # If not in cntperp
        )

# Also see the ISO parser for secondary and tertiary sub-properties in the attributes definition:

ISO_DEFINITIONS = dict({k: dict(v) for k, v in iteritems(COMPLEX_DEFINITIONS)})
ISO_DEFINITIONS[ATTRIBUTES].update({
    '_definition_source': '{_definition_src}',
    '__definition_source': '{__definition_src}',
    '___definition_source': '{___definition_src}'
})
```

### Examples

Any of the supported parsers can be extended to include more of a standard's supported data. In this example we'll add two new properties to the `IsoParser`:

* `metadata_language`: a simple string field describing the language of the metadata file itself (not the dataset)
* `metadata_contacts`: a complex structure with contact info leveraging and enhancing the existing contact structure

This example will cover:

1. Adding a new simple property
2. Configuring a secondary location for a property value
3. Referencing an element attribute in an XPATH
4. Adding a new complex property
5. Customizing the complex property to include a new sub-property

Also, this example is specifically covered by unit tests.

```python
from gis_metadata.iso_metadata_parser import IsoParser
from gis_metadata.utils import COMPLEX_DEFINITIONS, CONTACTS, format_xpaths, ParserProperty

class CustomIsoParser(IsoParser):

    def _init_data_map(self):
        super(CustomIsoParser, self)._init_data_map()

        # 1. Basic property: text or list (with secondary location referencing `codeListValue` attribute)

        lang_prop = 'metadata_language'
        self._data_map[lang_prop] = 'language/CharacterString'                    # Parse from here if present
        self._data_map['_' + lang_prop] = 'language/LanguageCode/@codeListValue'  # Otherwise, try from here

        # 2. Complex structure (reuse of contacts structure plus phone)

        # 2.1 Define some basic variables
        ct_prop = 'metadata_contacts'
        ct_xpath = 'contact/CI_ResponsibleParty/{ct_path}'
        ct_defintion = COMPLEX_DEFINITIONS[CONTACTS]
        ct_defintion['phone'] = '{phone}'

        # 2.2 Reuse CONTACT structure to specify locations per prop (adapted from parent to add `phone`)
        self._data_structures[ct_prop] = format_xpaths(
            ct_defintion,
            name=ct_xpath.format(ct_path='individualName/CharacterString'),
            organization=ct_xpath.format(ct_path='organisationName/CharacterString'),
            position=ct_xpath.format(ct_path='positionName/CharacterString'),
            phone=ct_xpath.format(
                ct_path='contactInfo/CI_Contact/phone/CI_Telephone/voice/CharacterString'
            ),
            email=ct_xpath.format(
                ct_path='contactInfo/CI_Contact/address/CI_Address/electronicMailAddress/CharacterString'
            )
        )

        # 2.3 Set the contact root to insert new elements at "contact" level given the defined path:
        #   'contact/CI_ResponsibleParty/...'
        # By default we would get multiple "CI_ResponsibleParty" elements under a single "contact"
        # This way we get multiple "contact" elements, each with its own single "CI_ResponsibleParty"
        self._data_map['_{prop}_root'.format(prop=ct_prop)] = 'contact'

        # 2.4 Leverage the default methods for parsing complex properties (or write your own parser/updater)
        self._data_map[ct_prop] = ParserProperty(self._parse_complex_list, self._update_complex_list)

        # 3. And finally, let the parent validation logic know about the two new custom properties

        self._metadata_props.add(lang_prop)
        self._metadata_props.add(ct_prop)

with open(r'/path/to/metadata.xml') as metadata:
    iso_from_file = CustomIsoParser(metadata)

iso_from_file.metadata_language
iso_from_file.metadata_contacts
```


text:
export interface Model {
}


text:
var config = require("config");

var _ = require("underscore");

var util = require("utilities");

var timeout = 1e4;

var http = {
    resourcePath: false,
    lastHTTPClient: null,
    _isOnline: function(showAlert) {
        showAlert = showAlert || true;
        var online = Ti.Network.getOnline();
        if (!online && showAlert) {
            alert("This feature requires an internet connection and no active internet connection was found. Please check your settings to make sure your wifi or cellular data is turned on.");
            return false;
        }
        return true;
    },
    __getResourcePath: function() {
        if (false === this.resourcePath) throw "Query resource is not defined";
        var url = config.getValue("pp_url") + this.resourcePath;
        return url;
    },
    __request: function(method, urlAppend, sendData, callback) {
        if (this._isOnline(true)) {
            if (!_.isFunction(callback)) throw "Callback provided to HTTP request is not a function";
            var url = this.__getResourcePath();
            urlAppend && (url += urlAppend);
            console.log(url);
            var client = Ti.Network.createHTTPClient({
                onload: function() {
                    if (this.handled) {
                        Ti.API.debug("Service response already handled, abandoning onload callback.");
                        return;
                    }
                    this.handled = true;
                    var response = null;
                    this.responseText && (response = JSON.parse(this.responseText));
                    callback(response);
                },
                onerror: function(e) {
                    if (this.handled) {
                        Ti.API.debug("Service response already handled, abandoning onerror callback.");
                        return;
                    }
                    this.handled = true;
                    if (this.status) alert(this.statusText); else {
                        var error = "";
                        switch (util.OS) {
                          case "iphone":
                            var re = /ASIHTTPRequestErrorDomain Code=\d+ "(.+?)"/;
                            var matches = e.error.match(re);
                            error = matches ? matches.length > 0 ? matches[1] : matches[0] : e.error;
                            break;

                          case "android":
                            error = e.error.match(/timeout|timed out/i) ? "The request timed out" : e.error;
                            break;

                          default:
                            error = e.error;
                        }
                    }
                    if ("The request timed out" == error) {
                        var dialog = Ti.UI.createAlertDialog({
                            title: "Request timeout",
                            message: "Would you like to retry?",
                            buttonNames: [ "Retry", "Cancel" ],
                            cancel: 1
                        });
                        dialog.addEventListener("click", function(e) {
                            switch (e.index) {
                              case 0:
                                Ti.API.debug("The retry button was clicked");
                                ParentModel._httpAttempt(client, method, url, sendData);
                                break;

                              case e.source.cancel:
                                Ti.API.debug("The cancel button was clicked");
                            }
                        });
                        dialog.show();
                    } else {
                        Ti.API.debug("ERROR ALERT");
                        error && alert(error);
                    }
                },
                handled: false
            });
            client.setTimeout(timeout);
            this.lastHTTPClient = client;
            Ti.API.debug("URL : " + url);
            Ti.API.debug("METHOD : " + method);
            this._httpAttempt(client, method, url, sendData);
        }
    },
    _httpAttempt: function(client, method, url, sendData) {
        client.open(method, url);
        this._addAppAuthHeaders(client);
        this._addUserAuthHeaders(client);
        setTimeout(function() {
            if (4 !== client.readyState && !client.handled) {
                Ti.API.error("HTTPClient trap triggered! This might be caused by an uncatchable native exception or a connection error.");
                client.onerror({
                    error: "An unknown error occurred"
                });
            }
        }, timeout + 1e3);
        client.setRequestHeader("accept", "application/json");
        client.send(sendData);
    },
    _addAppAuthHeaders: function(client) {
        var now = new Date();
        var hash_time = Math.floor(now.getTime() / 1e3);
        var hash_str = config.getValue("sha256_secret_key") + "___" + hash_time + "___" + client.getLocation();
        var hash_val = Ti.Utils.sha256(hash_str);
        var header_time = now.toUTCString();
        client.setRequestHeader("Date", header_time);
        client.setRequestHeader("PP-Security", hash_val);
    },
    _addUserAuthHeaders: function(client) {
        var username = Ti.App.Properties.getString("username");
        var password = Ti.App.Properties.getString("password");
        if (username && password) {
            authstr = "Basic " + Titanium.Utils.base64encode(username + ":" + password);
            client.setRequestHeader("Authorization", authstr);
        }
    },
    getLastHttpClient: function() {
        return this.lastHTTPClient;
    },
    getAcessToken: function() {}
};

http = _.extend(http, {
    keyField: null,
    get: function(urlAppend, callback) {
        this.__request("GET", urlAppend, null, callback);
    },
    post: function(postData, callback) {
        if (null == postData) {
            Ti.API.error("No data has been set for post");
            return;
        }
        this.__request("POST", null, postData, function(data) {
            data = data.d.results[0];
            data.success && null != this.keyField && (this[this.keyField] = data.id);
            callback(data);
        });
    },
    put: function(putData, callback) {
        if (null == putData) {
            Ti.API.error("No data has been set for put");
            return;
        }
        if (null == this.keyField) {
            Ti.API.error("You must specify a keyField before using the 'PUT' request. The keyField is the primary key field for an object.");
            return;
        }
        var querystring = "?" + this.keyField + "=" + putData[this.keyField];
        this.__request("PUT", querystring, putData, function(data) {
            callback(data.d.results[0]);
        });
    },
    remove: function(deleteData, callback) {
        if (null == deleteData) {
            Ti.API.error("No data has been set for put");
            return;
        }
        var queryString = "";
        var index = 0;
        for (var _data in deleteData) {
            queryString += (0 === index ? "?" : "&") + _data + "=" + deleteData[_data];
            index++;
        }
        this.__request("DELETE", queryString, {}, function(data) {
            callback(data.d.results[0]);
        });
    }
});

module.exports = http;