[linux-dvb] basic NLS support for scan util

ldvb at ns.bog.msu.ru ldvb at ns.bog.msu.ru
Thu May 8 13:13:52 CEST 2008


So, new option appears, -E encoding.
If not given, use no recoding (default, old behaviour).
Affects provider's name and services name, thus output is encoded in 
encoding (I see some progs using UTF or so in input channels.conf, and, 
also, there is no other way for progs to know which encoding was used by 
provider).
-------------- next part --------------
*** scan.c.orig	2008-05-03 16:26:59.000000000 +0400
--- scan.c	2008-05-08 15:49:23.000000000 +0400
***************
*** 33,38 ****
--- 33,39 ----
  #include <assert.h>
  #include <glob.h>
  #include <ctype.h>
+ #include <iconv.h>
  
  #include <linux/dvb/frontend.h>
  #include <linux/dvb/dmx.h>
***************
*** 43,48 ****
--- 44,50 ----
  #include "dump-vdr.h"
  #include "scan.h"
  #include "lnb.h"
+ #include "../../lib/libucsi/dvb/types.h"
  
  #include "atsc_psip_section.h"
  
***************
*** 84,89 ****
--- 86,93 ----
  static enum format output_format = OUTPUT_ZAP;
  static int output_format_set = 0;
  
+ #define ICONV_ENC_LENGTH	32
+ static char output_encoding[ICONV_ENC_LENGTH]="";
  
  enum polarisation {
  	POLARISATION_HORIZONTAL     = 0x00,
***************
*** 107,113 ****
--- 111,119 ----
  	int transport_stream_id;
  	int service_id;
  	char *provider_name;
+ 	char *provider_name_enc;
  	char *service_name;
+ 	char *service_name_enc;	// recoded to the charset given
  	uint16_t pmt_pid;
  	uint16_t pcr_pid;
  	uint16_t video_pid;
***************
*** 126,131 ****
--- 132,138 ----
  	int channel_num;
  };
  
+ 
  struct transponder {
  	struct list_head list;
  	struct list_head services;
***************
*** 536,544 ****
  {
  	unsigned char len;
  	unsigned char *src, *dest;
  
  	s->type = buf[2];
! 
  	buf += 3;
  	len = *buf;
  	buf++;
--- 543,557 ----
  {
  	unsigned char len;
  	unsigned char *src, *dest;
+ 	int consumed=0;
+ 	iconv_t conv_;
+ 	char buv[1024], *buv_, *srv;
+ 	const char *chs;
+ 	
+ 	size_t inbytesleft=0, outbytesleft=0;
  
  	s->type = buf[2];
! 	
  	buf += 3;
  	len = *buf;
  	buf++;
***************
*** 550,566 ****
  	memcpy (s->provider_name, buf, len);
  	s->provider_name[len] = '\0';
  
  	/* remove control characters (FIXME: handle short/long name) */
  	/* FIXME: handle character set correctly (e.g. via iconv)
  	 * c.f. EN 300 468 annex A */
  	for (src = dest = (unsigned char *) s->provider_name; *src; src++)
! 		if (*src >= 0x20 && (*src < 0x80 || *src > 0x9f))
  			*dest++ = *src;
  	*dest = '\0';
  	if (!s->provider_name[0]) {
  		/* zap zero length names */
  		free (s->provider_name);
  		s->provider_name = 0;
  	}
  
  	if (s->service_name)
--- 563,598 ----
  	memcpy (s->provider_name, buf, len);
  	s->provider_name[len] = '\0';
  
+ 	// I do not know, if a provider would like to use NLS....
+ 	chs=dvb_charset(s->provider_name, len+1, &consumed);
  	/* remove control characters (FIXME: handle short/long name) */
  	/* FIXME: handle character set correctly (e.g. via iconv)
  	 * c.f. EN 300 468 annex A */
  	for (src = dest = (unsigned char *) s->provider_name; *src; src++)
! 		if (*src >= 0x20 && (*src < 0x80 || *src > 0x9f)) {
  			*dest++ = *src;
+ 			inbytesleft++;
+ 			}
  	*dest = '\0';
  	if (!s->provider_name[0]) {
  		/* zap zero length names */
  		free (s->provider_name);
  		s->provider_name = 0;
+ 	} 	else {
+ 	if(strlen(output_encoding) > 1) {
+ 	bzero(buv,1024);
+ 	if(s->provider_name_enc) free(s->provider_name_enc);
+ 	if(consumed > 0) {
+ 		conv_=iconv_open(output_encoding, chs);
+ 		inbytesleft++; // for '\0'
+ 		buv_=(char*)buv;
+ 		srv=s->provider_name;
+ 		outbytesleft=inbytesleft*4;
+ 		iconv(conv_,&srv, &inbytesleft,&buv_, &outbytesleft);
+ 		iconv_close(conv_);
+ 		s->provider_name_enc=strdup(buv);
+ 		}
+ 		}
  	}
  
  	if (s->service_name)
***************
*** 574,597 ****
  	memcpy (s->service_name, buf, len);
  	s->service_name[len] = '\0';
  
  	/* remove control characters (FIXME: handle short/long name) */
  	/* FIXME: handle character set correctly (e.g. via iconv)
  	 * c.f. EN 300 468 annex A */
  	for (src = dest = (unsigned char *) s->service_name; *src; src++)
! 		if (*src >= 0x20 && (*src < 0x80 || *src > 0x9f))
  			*dest++ = *src;
  	*dest = '\0';
  	if (!s->service_name[0]) {
  		/* zap zero length names */
  		free (s->service_name);
  		s->service_name = 0;
  	}
- 
  	info("0x%04x 0x%04x: pmt_pid 0x%04x %s -- %s (%s%s)\n",
  	    s->transport_stream_id,
  	    s->service_id,
  	    s->pmt_pid,
! 	    s->provider_name, s->service_name,
  	    s->running == RM_NOT_RUNNING ? "not running" :
  	    s->running == RM_STARTS_SOON ? "starts soon" :
  	    s->running == RM_PAUSING     ? "pausing" :
--- 606,648 ----
  	memcpy (s->service_name, buf, len);
  	s->service_name[len] = '\0';
  
+ 	chs=dvb_charset(s->service_name, len+1, &consumed);
+ 	inbytesleft=0;
  	/* remove control characters (FIXME: handle short/long name) */
  	/* FIXME: handle character set correctly (e.g. via iconv)
  	 * c.f. EN 300 468 annex A */
  	for (src = dest = (unsigned char *) s->service_name; *src; src++)
! 		if (*src >= 0x20 && (*src < 0x80 || *src > 0x9f)) {
  			*dest++ = *src;
+ 			inbytesleft++;
+ 			}
  	*dest = '\0';
  	if (!s->service_name[0]) {
  		/* zap zero length names */
  		free (s->service_name);
  		s->service_name = 0;
+ 	} else {
+ 	if(strlen(output_encoding) > 1) {
+ 	bzero(buv,1024);
+ 	if(s->service_name_enc) free(s->service_name_enc);
+ 	if(consumed > 0) {
+ 		conv_=iconv_open(output_encoding, chs);
+ 		inbytesleft++; // for '\0'
+ 		buv_=(char*)buv;
+ 		srv=s->service_name;
+ 		outbytesleft=inbytesleft*4;
+ 		iconv(conv_,&srv, &inbytesleft,&buv_, &outbytesleft);
+ 		iconv_close(conv_);
+ 		s->service_name_enc=strdup(buv);
+ 		}
+ 		}
  	}
  	info("0x%04x 0x%04x: pmt_pid 0x%04x %s -- %s (%s%s)\n",
  	    s->transport_stream_id,
  	    s->service_id,
  	    s->pmt_pid,
! 	    (s->provider_name_enc)?s->provider_name_enc:s->provider_name,
! 	    (s->service_name_enc)? s->service_name_enc: s->service_name,
  	    s->running == RM_NOT_RUNNING ? "not running" :
  	    s->running == RM_STARTS_SOON ? "starts soon" :
  	    s->running == RM_PAUSING     ? "pausing" :
***************
*** 829,835 ****
          debug("0x%04x 0x%04x: %s -- %s, pmt_pid 0x%04x, vpid 0x%04x, apid %s\n",
  	    s->transport_stream_id,
  	    s->service_id,
! 	    s->provider_name, s->service_name,
  	    s->pmt_pid, s->video_pid, msg_buf);
  }
  
--- 880,887 ----
          debug("0x%04x 0x%04x: %s -- %s, pmt_pid 0x%04x, vpid 0x%04x, apid %s\n",
  	    s->transport_stream_id,
  	    s->service_id,
! 	    (s->provider_name_enc)?s->provider_name_enc:s->provider_name,
! 	    (s->service_name_enc)?s->service_name_enc:s->service_name,
  	    s->pmt_pid, s->video_pid, msg_buf);
  }
  
***************
*** 1897,1903 ****
  {
          int i;
  
! 	fprintf(f, "%-24.24s (0x%04x) %02x: ", s->service_name, s->service_id, s->type);
  	if (!s->pcr_pid || (s->type > 2))
  		fprintf(f, "           ");
  	else if (s->pcr_pid == s->video_pid)
--- 1949,1955 ----
  {
          int i;
  
! 	fprintf(f, "%-24.24s (0x%04x) %02x: ", (s->service_name_enc)?s->service_name_enc:s->service_name, s->service_id, s->type);
  	if (!s->pcr_pid || (s->type > 2))
  		fprintf(f, "           ");
  	else if (s->pcr_pid == s->video_pid)
***************
*** 2001,2008 ****
  				break;
  			  case OUTPUT_VDR:
  				vdr_dump_service_parameter_set (stdout,
! 						    s->service_name,
! 						    s->provider_name,
  						    t->type,
  						    &t->param,
  						    sat_polarisation(t),
--- 2053,2060 ----
  				break;
  			  case OUTPUT_VDR:
  				vdr_dump_service_parameter_set (stdout,
! 						    (s->service_name_enc)?s->service_name_enc : s->service_name,
! 						    (s->provider_name_enc)?s->provider_name_enc:s->provider_name,
  						    t->type,
  						    &t->param,
  						    sat_polarisation(t),
***************
*** 2028,2034 ****
  				break;
  			  case OUTPUT_ZAP:
  				zap_dump_service_parameter_set (stdout,
! 						    s->service_name,
  						    t->type,
  						    &t->param,
  						    sat_polarisation(t),
--- 2080,2086 ----
  				break;
  			  case OUTPUT_ZAP:
  				zap_dump_service_parameter_set (stdout,
! 						    (s->service_name_enc)?s->service_name_enc : s->service_name,
  						    t->type,
  						    &t->param,
  						    sat_polarisation(t),
***************
*** 2107,2113 ****
  	"	-P do not use ATSC PSIP tables for scanning\n"
  	"	    (but only PAT and PMT) (applies for ATSC only)\n"
  	"	-A N	check for ATSC 1=Terrestrial [default], 2=Cable or 3=both\n"
! 	"	-U	Uniquely name unknown services\n";
  
  void
  bad_usage(char *pname, int problem)
--- 2159,2166 ----
  	"	-P do not use ATSC PSIP tables for scanning\n"
  	"	    (but only PAT and PMT) (applies for ATSC only)\n"
  	"	-A N	check for ATSC 1=Terrestrial [default], 2=Cable or 3=both\n"
! 	"	-U	Uniquely name unknown services\n"
! 	"	-E enc	Output encoding for iconv. Look at iconv -l.\n";
  
  void
  bad_usage(char *pname, int problem)
***************
*** 2155,2161 ****
  
  	/* start with default lnb type */
  	lnb_type = *lnb_enum(0);
! 	while ((opt = getopt(argc, argv, "5cnpa:f:d:s:o:x:e:t:i:l:vquPA:U")) != -1) {
  		switch (opt) {
  		case 'a':
  			adapter = strtoul(optarg, NULL, 0);
--- 2208,2214 ----
  
  	/* start with default lnb type */
  	lnb_type = *lnb_enum(0);
! 	while ((opt = getopt(argc, argv, "5cnpa:f:d:s:o:x:e:t:E:i:l:vquPA:U")) != -1) {
  		switch (opt) {
  		case 'a':
  			adapter = strtoul(optarg, NULL, 0);
***************
*** 2235,2240 ****
--- 2288,2296 ----
  		case 'U':
  			unique_anon_services = 1;
  			break;
+ 		case 'E':
+ 			strncpy(output_encoding,optarg,ICONV_ENC_LENGTH);
+ 			break;
  		default:
  			bad_usage(argv[0], 0);
  			return -1;
-------------- next part --------------
*** Makefile.orig	2008-05-03 16:26:59.000000000 +0400
--- Makefile	2008-05-06 17:46:24.000000000 +0400
***************
*** 15,20 ****
--- 15,21 ----
  removing = atsc_psip_section.c atsc_psip_section.h
  
  CPPFLAGS += -DDATADIR=\"$(prefix)/share\"
+ LOADLIBES +=  -L../../lib/libucsi -lucsi
  
  .PHONY: all
  


More information about the linux-dvb mailing list