⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loadmsgcat.c

📁 经典的C语言MP3编码解码实现,可以在linux/unix平台下编译运行.
💻 C
📖 第 1 页 / 共 3 页
字号:
      __builtin_expect (fstat (fd, &st) != 0, 0)#endif      || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0)      || __builtin_expect (size < sizeof (struct mo_file_header), 0))    {      /* Something went wrong.  */      close (fd);      return;    }#ifdef HAVE_MMAP  /* Now we are ready to load the file.  If mmap() is available we try     this first.  If not available or it failed we try to load it.  */  data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,					 MAP_PRIVATE, fd, 0);  if (__builtin_expect (data != (struct mo_file_header *) -1, 1))    {      /* mmap() call was successful.  */      close (fd);      use_mmap = 1;    }#endif  /* If the data is not yet available (i.e. mmap'ed) we try to load     it manually.  */  if (data == (struct mo_file_header *) -1)    {      size_t to_read;      char *read_ptr;      data = (struct mo_file_header *) malloc (size);      if (data == NULL)	return;      to_read = size;      read_ptr = (char *) data;      do	{	  long int nb = (long int) read (fd, read_ptr, to_read);	  if (nb <= 0)	    {#ifdef EINTR	      if (nb == -1 && errno == EINTR)		continue;#endif	      close (fd);	      return;	    }	  read_ptr += nb;	  to_read -= nb;	}      while (to_read > 0);      close (fd);    }  /* Using the magic number we can test whether it really is a message     catalog file.  */  if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED,			0))    {      /* The magic number is wrong: not a message catalog file.  */#ifdef HAVE_MMAP      if (use_mmap)	munmap ((caddr_t) data, size);      else#endif	free (data);      return;    }  domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));  if (domain == NULL)    return;  domain_file->data = domain;  domain->data = (char *) data;  domain->use_mmap = use_mmap;  domain->mmap_size = size;  domain->must_swap = data->magic != _MAGIC;  domain->malloced = NULL;  /* Fill in the information about the available tables.  */  revision = W (domain->must_swap, data->revision);  /* We support only the major revisions 0 and 1.  */  switch (revision >> 16)    {    case 0:    case 1:      domain->nstrings = W (domain->must_swap, data->nstrings);      domain->orig_tab = (const struct string_desc *)	((char *) data + W (domain->must_swap, data->orig_tab_offset));      domain->trans_tab = (const struct string_desc *)	((char *) data + W (domain->must_swap, data->trans_tab_offset));      domain->hash_size = W (domain->must_swap, data->hash_tab_size);      domain->hash_tab =	(domain->hash_size > 2	 ? (const nls_uint32 *)	   ((char *) data + W (domain->must_swap, data->hash_tab_offset))	 : NULL);      domain->must_swap_hash_tab = domain->must_swap;      /* Now dispatch on the minor revision.  */      switch (revision & 0xffff)	{	case 0:	  domain->n_sysdep_strings = 0;	  domain->orig_sysdep_tab = NULL;	  domain->trans_sysdep_tab = NULL;	  break;	case 1:	default:	  {	    nls_uint32 n_sysdep_strings;	    if (domain->hash_tab == NULL)	      /* This is invalid.  These minor revisions need a hash table.  */	      goto invalid;	    n_sysdep_strings =	      W (domain->must_swap, data->n_sysdep_strings);	    if (n_sysdep_strings > 0)	      {		nls_uint32 n_sysdep_segments;		const struct sysdep_segment *sysdep_segments;		const char **sysdep_segment_values;		const nls_uint32 *orig_sysdep_tab;		const nls_uint32 *trans_sysdep_tab;		nls_uint32 n_inmem_sysdep_strings;		size_t memneed;		char *mem;		struct sysdep_string_desc *inmem_orig_sysdep_tab;		struct sysdep_string_desc *inmem_trans_sysdep_tab;		nls_uint32 *inmem_hash_tab;		unsigned int i, j;		/* Get the values of the system dependent segments.  */		n_sysdep_segments =		  W (domain->must_swap, data->n_sysdep_segments);		sysdep_segments = (const struct sysdep_segment *)		  ((char *) data		   + W (domain->must_swap, data->sysdep_segments_offset));		sysdep_segment_values =		  alloca (n_sysdep_segments * sizeof (const char *));		for (i = 0; i < n_sysdep_segments; i++)		  {		    const char *name =		      (char *) data		      + W (domain->must_swap, sysdep_segments[i].offset);		    nls_uint32 namelen =		      W (domain->must_swap, sysdep_segments[i].length);		    if (!(namelen > 0 && name[namelen - 1] == '\0'))		      {			freea (sysdep_segment_values);			goto invalid;		      }		    sysdep_segment_values[i] = get_sysdep_segment_value (name);		  }		orig_sysdep_tab = (const nls_uint32 *)		  ((char *) data		   + W (domain->must_swap, data->orig_sysdep_tab_offset));		trans_sysdep_tab = (const nls_uint32 *)		  ((char *) data		   + W (domain->must_swap, data->trans_sysdep_tab_offset));		/* Compute the amount of additional memory needed for the		   system dependent strings and the augmented hash table.		   At the same time, also drop string pairs which refer to		   an undefined system dependent segment.  */		n_inmem_sysdep_strings = 0;		memneed = domain->hash_size * sizeof (nls_uint32);		for (i = 0; i < n_sysdep_strings; i++)		  {		    int valid = 1;		    size_t needs[2];		    for (j = 0; j < 2; j++)		      {			const struct sysdep_string *sysdep_string =			  (const struct sysdep_string *)			  ((char *) data			   + W (domain->must_swap,				j == 0				? orig_sysdep_tab[i]				: trans_sysdep_tab[i]));			size_t need = 0;			const struct segment_pair *p = sysdep_string->segments;			if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END)			  for (p = sysdep_string->segments;; p++)			    {			      nls_uint32 sysdepref;			      need += W (domain->must_swap, p->segsize);			      sysdepref = W (domain->must_swap, p->sysdepref);			      if (sysdepref == SEGMENTS_END)				break;			      if (sysdepref >= n_sysdep_segments)				{				  /* Invalid.  */				  freea (sysdep_segment_values);				  goto invalid;				}			      if (sysdep_segment_values[sysdepref] == NULL)				{				  /* This particular string pair is invalid.  */				  valid = 0;				  break;				}			      need += strlen (sysdep_segment_values[sysdepref]);			    }			needs[j] = need;			if (!valid)			  break;		      }		    if (valid)		      {			n_inmem_sysdep_strings++;			memneed += needs[0] + needs[1];		      }		  }		memneed += 2 * n_inmem_sysdep_strings			   * sizeof (struct sysdep_string_desc);		if (n_inmem_sysdep_strings > 0)		  {		    unsigned int k;		    /* Allocate additional memory.  */		    mem = (char *) malloc (memneed);		    if (mem == NULL)		      goto invalid;		    domain->malloced = mem;		    inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem;		    mem += n_inmem_sysdep_strings			   * sizeof (struct sysdep_string_desc);		    inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem;		    mem += n_inmem_sysdep_strings			   * sizeof (struct sysdep_string_desc);		    inmem_hash_tab = (nls_uint32 *) mem;		    mem += domain->hash_size * sizeof (nls_uint32);		    /* Compute the system dependent strings.  */		    k = 0;		    for (i = 0; i < n_sysdep_strings; i++)		      {			int valid = 1;			for (j = 0; j < 2; j++)			  {			    const struct sysdep_string *sysdep_string =			      (const struct sysdep_string *)			      ((char *) data			       + W (domain->must_swap,				    j == 0				    ? orig_sysdep_tab[i]				    : trans_sysdep_tab[i]));			    const struct segment_pair *p =			      sysdep_string->segments;			    if (W (domain->must_swap, p->sysdepref)				!= SEGMENTS_END)			      for (p = sysdep_string->segments;; p++)				{				  nls_uint32 sysdepref;				  sysdepref =				    W (domain->must_swap, p->sysdepref);				  if (sysdepref == SEGMENTS_END)				    break;				  if (sysdep_segment_values[sysdepref] == NULL)				    {				      /* This particular string pair is					 invalid.  */				      valid = 0;				      break;				    }				}			    if (!valid)			      break;			  }			if (valid)			  {			    for (j = 0; j < 2; j++)			      {				const struct sysdep_string *sysdep_string =				  (const struct sysdep_string *)				  ((char *) data				   + W (domain->must_swap,					j == 0					? orig_sysdep_tab[i]					: trans_sysdep_tab[i]));				const char *static_segments =				  (char *) data				  + W (domain->must_swap, sysdep_string->offset);				const struct segment_pair *p =				  sysdep_string->segments;				/* Concatenate the segments, and fill				   inmem_orig_sysdep_tab[k] (for j == 0) and				   inmem_trans_sysdep_tab[k] (for j == 1).  */				struct sysdep_string_desc *inmem_tab_entry =				  (j == 0				   ? inmem_orig_sysdep_tab				   : inmem_trans_sysdep_tab)				  + k;				if (W (domain->must_swap, p->sysdepref)				    == SEGMENTS_END)				  {				    /* Only one static segment.  */				    inmem_tab_entry->length =				      W (domain->must_swap, p->segsize);				    inmem_tab_entry->pointer = static_segments;				  }				else				  {				    inmem_tab_entry->pointer = mem;				    for (p = sysdep_string->segments;; p++)				      {					nls_uint32 segsize =					  W (domain->must_swap, p->segsize);					nls_uint32 sysdepref =					  W (domain->must_swap, p->sysdepref);					size_t n;					if (segsize > 0)					  {					    memcpy (mem, static_segments, segsize);					    mem += segsize;					    static_segments += segsize;					  }					if (sysdepref == SEGMENTS_END)					  break;					n = strlen (sysdep_segment_values[sysdepref]);					memcpy (mem, sysdep_segment_values[sysdepref], n);					mem += n;				      }				    inmem_tab_entry->length =				      mem - inmem_tab_entry->pointer;				  }			      }			    k++;			  }		      }		    if (k != n_inmem_sysdep_strings)		      abort ();		    /* Compute the augmented hash table.  */		    for (i = 0; i < domain->hash_size; i++)		      inmem_hash_tab[i] =			W (domain->must_swap_hash_tab, domain->hash_tab[i]);		    for (i = 0; i < n_inmem_sysdep_strings; i++)		      {			const char *msgid = inmem_orig_sysdep_tab[i].pointer;			nls_uint32 hash_val = hash_string (msgid);			nls_uint32 idx = hash_val % domain->hash_size;			nls_uint32 incr =			  1 + (hash_val % (domain->hash_size - 2));			for (;;)			  {			    if (inmem_hash_tab[idx] == 0)			      {				/* Hash table entry is empty.  Use it.  */				inmem_hash_tab[idx] = 1 + domain->nstrings + i;				break;			      }			    if (idx >= domain->hash_size - incr)			      idx -= domain->hash_size - incr;			    else			      idx += incr;			  }		      }		    domain->n_sysdep_strings = n_inmem_sysdep_strings;		    domain->orig_sysdep_tab = inmem_orig_sysdep_tab;		    domain->trans_sysdep_tab = inmem_trans_sysdep_tab;		    domain->hash_tab = inmem_hash_tab;		    domain->must_swap_hash_tab = 0;		  }		else		  {		    domain->n_sysdep_strings = 0;		    domain->orig_sysdep_tab = NULL;		    domain->trans_sysdep_tab = NULL;		  }		freea (sysdep_segment_values);	      }	    else	      {		domain->n_sysdep_strings = 0;		domain->orig_sysdep_tab = NULL;		domain->trans_sysdep_tab = NULL;	      }	  }	  break;	}      break;    default:      /* This is an invalid revision.  */    invalid:      /* This is an invalid .mo file.  */      if (domain->malloced)	free (domain->malloced);#ifdef HAVE_MMAP      if (use_mmap)	munmap ((caddr_t) data, size);      else#endif	free (data);      free (domain);      domain_file->data = NULL;      return;    }  /* Now initialize the character set converter from the character set     the file is encoded with (found in the header entry) to the domain's     specified character set or the locale's character set.  */  nullentry = _nl_init_domain_conv (domain_file, domain, domainbinding);  /* Also look for a plural specification.  */  EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);}#ifdef _LIBCvoidinternal_function_nl_unload_domain (struct loaded_domain *domain){  if (domain->plural != &__gettext_germanic_plural)    __gettext_free_exp (domain->plural);  _nl_free_domain_conv (domain);  if (domain->malloced)    free (domain->malloced);# ifdef _POSIX_MAPPED_FILES  if (domain->use_mmap)    munmap ((caddr_t) domain->data, domain->mmap_size);  else# endif	/* _POSIX_MAPPED_FILES */    free ((void *) domain->data);  free (domain);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -