utils.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:7k
源码类别:

Windows CE

开发平台:

C/C++

  1. /* metaflac - Command-line FLAC metadata editor
  2.  * Copyright (C) 2001,2002,2003,2004,2005  Josh Coalson
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  */
  18. #include "utils.h"
  19. #include "FLAC/assert.h"
  20. #include "share/utf8.h"
  21. #include <ctype.h>
  22. #include <stdarg.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. void die(const char *message)
  27. {
  28. FLAC__ASSERT(0 != message);
  29. fprintf(stderr, "ERROR: %sn", message);
  30. exit(1);
  31. }
  32. #ifdef FLAC__VALGRIND_TESTING
  33. size_t local_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
  34. {
  35. size_t ret = fwrite(ptr, size, nmemb, stream);
  36. if(!ferror(stream))
  37. fflush(stream);
  38. return ret;
  39. }
  40. #endif
  41. char *local_strdup(const char *source)
  42. {
  43. char *ret;
  44. FLAC__ASSERT(0 != source);
  45. if(0 == (ret = strdup(source)))
  46. die("out of memory during strdup()");
  47. return ret;
  48. }
  49. void local_strcat(char **dest, const char *source)
  50. {
  51. unsigned ndest, nsource;
  52. FLAC__ASSERT(0 != dest);
  53. FLAC__ASSERT(0 != source);
  54. ndest = *dest? strlen(*dest) : 0;
  55. nsource = strlen(source);
  56. if(nsource == 0)
  57. return;
  58. *dest = (char*)realloc(*dest, ndest + nsource + 1);
  59. if(0 == *dest)
  60. die("out of memory growing string");
  61. strcpy((*dest)+ndest, source);
  62. }
  63. void hexdump(const char *filename, const FLAC__byte *buf, unsigned bytes, const char *indent)
  64. {
  65. unsigned i, left = bytes;
  66. const FLAC__byte *b = buf;
  67. for(i = 0; i < bytes; i += 16) {
  68. printf("%s%s%s%08X: "
  69. "%02X %02X %02X %02X %02X %02X %02X %02X "
  70. "%02X %02X %02X %02X %02X %02X %02X %02X "
  71. "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%cn",
  72. filename? filename:"", filename? ":":"",
  73. indent, i,
  74. left >  0? (unsigned char)b[ 0] : 0,
  75. left >  1? (unsigned char)b[ 1] : 0,
  76. left >  2? (unsigned char)b[ 2] : 0,
  77. left >  3? (unsigned char)b[ 3] : 0,
  78. left >  4? (unsigned char)b[ 4] : 0,
  79. left >  5? (unsigned char)b[ 5] : 0,
  80. left >  6? (unsigned char)b[ 6] : 0,
  81. left >  7? (unsigned char)b[ 7] : 0,
  82. left >  8? (unsigned char)b[ 8] : 0,
  83. left >  9? (unsigned char)b[ 9] : 0,
  84. left > 10? (unsigned char)b[10] : 0,
  85. left > 11? (unsigned char)b[11] : 0,
  86. left > 12? (unsigned char)b[12] : 0,
  87. left > 13? (unsigned char)b[13] : 0,
  88. left > 14? (unsigned char)b[14] : 0,
  89. left > 15? (unsigned char)b[15] : 0,
  90. (left >  0) ? (isprint(b[ 0]) ? b[ 0] : '.') : ' ',
  91. (left >  1) ? (isprint(b[ 1]) ? b[ 1] : '.') : ' ',
  92. (left >  2) ? (isprint(b[ 2]) ? b[ 2] : '.') : ' ',
  93. (left >  3) ? (isprint(b[ 3]) ? b[ 3] : '.') : ' ',
  94. (left >  4) ? (isprint(b[ 4]) ? b[ 4] : '.') : ' ',
  95. (left >  5) ? (isprint(b[ 5]) ? b[ 5] : '.') : ' ',
  96. (left >  6) ? (isprint(b[ 6]) ? b[ 6] : '.') : ' ',
  97. (left >  7) ? (isprint(b[ 7]) ? b[ 7] : '.') : ' ',
  98. (left >  8) ? (isprint(b[ 8]) ? b[ 8] : '.') : ' ',
  99. (left >  9) ? (isprint(b[ 9]) ? b[ 9] : '.') : ' ',
  100. (left > 10) ? (isprint(b[10]) ? b[10] : '.') : ' ',
  101. (left > 11) ? (isprint(b[11]) ? b[11] : '.') : ' ',
  102. (left > 12) ? (isprint(b[12]) ? b[12] : '.') : ' ',
  103. (left > 13) ? (isprint(b[13]) ? b[13] : '.') : ' ',
  104. (left > 14) ? (isprint(b[14]) ? b[14] : '.') : ' ',
  105. (left > 15) ? (isprint(b[15]) ? b[15] : '.') : ' '
  106. );
  107. left -= 16;
  108. b += 16;
  109.    }
  110. }
  111. void print_error_with_chain_status(FLAC__Metadata_Chain *chain, const char *format, ...)
  112. {
  113. const FLAC__Metadata_ChainStatus status = FLAC__metadata_chain_status(chain);
  114. va_list args;
  115. FLAC__ASSERT(0 != format);
  116. va_start(args, format);
  117. (void) vfprintf(stderr, format, args);
  118. va_end(args);
  119. fprintf(stderr, ", status = "%s"n", FLAC__Metadata_ChainStatusString[status]);
  120. if(status == FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE) {
  121. fprintf(stderr, "n"
  122. "The FLAC file could not be opened.  Most likely the file does not existn"
  123. "or is not readable.n"
  124. );
  125. }
  126. else if(status == FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE) {
  127. fprintf(stderr, "n"
  128. "The file does not appear to be a FLAC file.n"
  129. );
  130. }
  131. else if(status == FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE) {
  132. fprintf(stderr, "n"
  133. "The FLAC file does not have write permissions.n"
  134. );
  135. }
  136. else if(status == FLAC__METADATA_CHAIN_STATUS_BAD_METADATA) {
  137. fprintf(stderr, "n"
  138. "The metadata to be writted does not conform to the FLAC metadatan"
  139. "specifications.n"
  140. );
  141. }
  142. else if(status == FLAC__METADATA_CHAIN_STATUS_READ_ERROR) {
  143. fprintf(stderr, "n"
  144. "There was an error while reading the FLAC file.n"
  145. );
  146. }
  147. else if(status == FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR) {
  148. fprintf(stderr, "n"
  149. "There was an error while writing FLAC file; most probably the disk isn"
  150. "full.n"
  151. );
  152. }
  153. else if(status == FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR) {
  154. fprintf(stderr, "n"
  155. "There was an error removing the temporary FLAC file.n"
  156. );
  157. }
  158. }
  159. FLAC__bool parse_vorbis_comment_field(const char *field_ref, char **field, char **name, char **value, unsigned *length, const char **violation)
  160. {
  161. static const char * const violations[] = {
  162. "field name contains invalid character",
  163. "field contains no '=' character"
  164. };
  165. char *p, *q, *s;
  166. if(0 != field)
  167. *field = local_strdup(field_ref);
  168. s = local_strdup(field_ref);
  169. if(0 == (p = strchr(s, '='))) {
  170. free(s);
  171. *violation = violations[1];
  172. return false;
  173. }
  174. *p++ = '';
  175. for(q = s; *q; q++) {
  176. if(*q < 0x20 || *q > 0x7d || *q == 0x3d) {
  177. free(s);
  178. *violation = violations[0];
  179. return false;
  180. }
  181. }
  182. *name = local_strdup(s);
  183. *value = local_strdup(p);
  184. *length = strlen(p);
  185. free(s);
  186. return true;
  187. }
  188. void write_vc_field(const char *filename, const FLAC__StreamMetadata_VorbisComment_Entry *entry, FLAC__bool raw, FILE *f)
  189. {
  190. if(0 != entry->entry) {
  191. if(filename)
  192. fprintf(f, "%s:", filename);
  193. if(!raw) {
  194. /*
  195.  * WATCHOUT: comments that contain an embedded null will
  196.  * be truncated by utf_decode().
  197.  */
  198. char *converted;
  199. if(utf8_decode(entry->entry, &converted) >= 0) {
  200. (void) local_fwrite(converted, 1, strlen(converted), f);
  201. free(converted);
  202. }
  203. else {
  204. (void) local_fwrite(entry->entry, 1, entry->length, f);
  205. }
  206. }
  207. else {
  208. (void) local_fwrite(entry->entry, 1, entry->length, f);
  209. }
  210. }
  211. putc('n', f);
  212. }
  213. void write_vc_fields(const char *filename, const char *field_name, const FLAC__StreamMetadata_VorbisComment_Entry entry[], unsigned num_entries, FLAC__bool raw, FILE *f)
  214. {
  215. unsigned i;
  216. const unsigned field_name_length = (0 != field_name)? strlen(field_name) : 0;
  217. for(i = 0; i < num_entries; i++) {
  218. if(0 == field_name || FLAC__metadata_object_vorbiscomment_entry_matches(entry[i], field_name, field_name_length))
  219. write_vc_field(filename, entry + i, raw, f);
  220. }
  221. }