Changeset 384 for libmpc/trunk/common
- Timestamp:
- 03/25/08 16:31:41 (17 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
libmpc/trunk/common/tags.c
r383 r384 22 22 */ 23 23 24 #include "mpcenc.h" 24 // #include "mpcenc.h" 25 #include <stdio.h> 26 #include <mpc/mpc_types.h> 27 28 // Path separator 29 #if defined __unix__ || defined __bsdi__ || defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __APPLE__ 30 # define PATH_SEP '/' 31 # define DRIVE_SEP '\0' 32 #elif defined _WIN32 || defined __TURBOC__ || defined __ZTC__ || defined _MSC_VER 33 # define PATH_SEP '\\' 34 # define DRIVE_SEP ':' 35 #else 36 # define PATH_SEP '/' // Amiga: C:/ 37 # define DRIVE_SEP ':' 38 #endif 25 39 26 40 #ifdef USE_WIDECHAR … … 805 819 } 806 820 807 /* 808 * Writes collect tag items and write it to a file. 809 * Items are destroyed, so tags can only be written once. 821 #define TAG_NO_HEADER 1 822 #define TAG_NO_FOOTER 2 823 #define TAG_NO_PREAMBLE 4 824 825 826 /** 827 * Writes collect tag items and write it to a file. 828 * Items are destroyed, so tags can only be written once. 829 * @param fp 830 * @param Version 831 * @param flags options for writing header / footer : 832 * 1 : do not write header 833 * 2 : do not write footer 834 * 4 : do not write "APETAGEX" 835 * @return 810 836 */ 811 812 837 int 813 FinalizeTags ( FILE* fp, unsigned int Version )838 FinalizeTags ( FILE* fp, unsigned int Version, unsigned int flags ) 814 839 { 815 840 static unsigned char H [32] = "APETAGEX"; … … 821 846 if ( TagCount == 0 ) 822 847 return 0; 848 849 if (flags & TAG_NO_PREAMBLE) { 850 estimatedbytes -= 8; 851 writtenbytes += 8; 852 } 853 if (flags & TAG_NO_FOOTER) 854 estimatedbytes = 0; 855 if (flags & TAG_NO_HEADER) 856 writtenbytes = 0; 823 857 824 858 qsort ( T, TagCount, sizeof (*T), cmpfn2 ); … … 828 862 829 863 if ( estimatedbytes >= 8192 + 103 ) 830 stderr_printf ("\nTag is %.1f Kbyte long. This is longer than the maximum recommended 8 KByte.\n\a", estimatedbytes/1024. );864 fprintf (stderr, "\nTag is %.1f Kbyte long. This is longer than the maximum recommended 8 KByte.\n\a", estimatedbytes/1024. ); 831 865 832 866 H [ 8] = Version >> 0; … … 844 878 845 879 H [23] = 0x80 | 0x20; 846 writtenbytes += fwrite ( H, 1, 32, fp ); 880 if (!(flags & TAG_NO_HEADER)) { 881 if (flags & TAG_NO_PREAMBLE) 882 writtenbytes += fwrite ( H + 8, 1, 24, fp ); 883 else 884 writtenbytes += fwrite ( H, 1, 32, fp ); 885 } 847 886 848 887 for ( i = 0; i < TagCount; i++ ) { … … 863 902 864 903 H [23] = 0x80; 865 writtenbytes += fwrite ( H, 1, 32, fp ); 904 if (!(flags & TAG_NO_FOOTER)) { 905 if (flags & TAG_NO_PREAMBLE) 906 writtenbytes += fwrite ( H + 8, 1, 24, fp ); 907 else 908 writtenbytes += fwrite ( H, 1, 32, fp ); 909 } 866 910 867 911 if ( estimatedbytes != writtenbytes ) 868 stderr_printf ("\nError writing APE tag.\n" );912 fprintf (stderr, "\nError writing APE tag.\n" ); 869 913 870 914 TagCount = 0; … … 915 959 return -1; 916 960 917 if ( 128 != READ ( fp, tmp, 128) )961 if ( 128 != fread(tmp, 1, 128, fp) ) 918 962 return -1; 919 963 … … 970 1014 if ( -1 == fseek ( fp, -(long)sizeof T, SEEK_END ) ) 971 1015 return -1; 972 if ( sizeof(T) != READ ( fp, &T, sizeof T) )1016 if ( sizeof(T) != fread (&T, 1, sizeof T, fp) ) 973 1017 return -1; 974 1018 if ( memcmp ( T.ID, "APETAGEX", sizeof(T.ID) ) != 0 ) … … 983 1027 return -1; 984 1028 memset ( buff, 0, sizeof(buff) ); 985 if ( TagLen - sizeof T != READ ( fp, buff, TagLen - sizeof T) )1029 if ( TagLen - sizeof T != fread (buff, 1, TagLen - sizeof T, fp) ) 986 1030 return -1; 987 1031 … … 997 1041 998 1042 return 0; 999 }1000 1001 static void1002 FullPathName ( char* dst, size_t dstlen, const char* filename ) // Can contain stuff like ".." and "."1003 {1004 // const char* p;1005 char* q = dst;1006 1007 #if DRIVE_SEP != '\0'1008 int drive = 0;1009 1010 if ( isalpha (filename[0]) && filename[1] == DRIVE_SEP && filename[2] != PATH_SEP ) {1011 drive = filename[0] & 0x1F;1012 filename += 2;1013 }1014 #endif1015 1016 if ( filename[0] != PATH_SEP ) {1017 #ifdef _WIN321018 _getdcwd( drive, dst, dstlen );1019 #else1020 getcwd ( dst, dstlen );1021 #endif1022 q += strlen (q);1023 #ifdef _WIN321024 if ( dst[0] != PATH_SEP || dst[1] != '\0' )1025 #else1026 if ( dst[2] != PATH_SEP || dst[3] != '\0' )1027 #endif1028 *q++ = PATH_SEP;1029 }1030 1031 strcpy ( q, filename );1032 return;1033 1043 } 1034 1044 … … 1082 1092 }; 1083 1093 1084 1085 static void1086 copy ( char* dst, const char* src, size_t len )1087 {1088 memcpy ( dst, src, len );1089 dst [len] = '\0';1090 }1091 1092 1094 /* 1093 1095 * dst[0] = Artist … … 1103 1105 #endif 1104 1106 1105 static int1106 parse ( char** dst, const char* src, const char* format )1107 {1108 int i;1109 const char* srcend = src + strlen(src);1110 const char* p;1111 char* q;1112 1113 for ( i = 0; i < 6; i++)1114 dst[i][0] = '\0';1115 1116 for ( i = strlen(format); i-- > 0; ) {1117 p = srcend;1118 #ifndef STFU1119 stderr_printf ( "%c: ", format[i] );1120 #endif1121 switch ( format[i] ) {1122 case '.':1123 case ' ':1124 case '/': // !!!!!!!1125 if (p[-1] != format[i])1126 return 1;1127 p--;1128 break;1129 case '_':1130 if (0 != memcmp (p-4, " -- ", 4))1131 return 1;1132 p -= 4;1133 break;1134 case '-':1135 if (0 != memcmp (p-3, " - ", 3))1136 return 1;1137 p -= 3;1138 break;1139 case '0':1140 if (p[-1] != ']' || p[-2] != '0' || p[-3] != '0' || p[-4] != '[')1141 return 1;1142 copy (dst[4], p-3, 2);1143 p -= 4;1144 break;1145 case 'n':1146 if (p[-1] != ']' || !isdigit(p[-2]) || !isdigit(p[-3]) || p[-4] != '[')1147 return 1;1148 copy (dst[4], p-3, 2);1149 p -= 4;1150 break;1151 case 'M':1152 if ( !isdigit(p[-1]) || !isdigit(p[-2]) )1153 return 1;1154 copy (dst[4], p-2, 2);1155 p -= 2;1156 break;1157 case 'N':1158 if (p[-1] != ')' || !isdigit(p[-2]) || p[-3] != ' ' || p[-4] != 'D' || p[-5] != 'C' || p[-6] != '(')1159 return 1;1160 dst[3][0] = ' ';1161 copy (dst[3]+1, p-6, 6);1162 p -= 6;1163 break;1164 case 'A':1165 q = dst[0]; goto big;1166 case 'C':1167 q = dst[1]; goto big;1168 case 'T':1169 q = dst[2]; goto big;1170 big:1171 while ( 0 == memcmp (p-4, "/mpc", 4) ||1172 0 == memcmp (p-4, "/mp3", 4) ||1173 0 == memcmp (p-4, "/pac", 4) ||1174 0 == memcmp (p-4, "/ape", 4) ||1175 0 == memcmp (p-4, "/pac", 4) ||1176 0 == memcmp (p-3, "/.." , 3) ||1177 0 == memcmp (p-2, "/." , 2)1178 ) {1179 do {1180 p--;1181 srcend--;1182 } while ( *p != PATH_SEP );1183 }1184 while ( p[-1] != PATH_SEP &&1185 p[-1] != DRIVE_SEP &&1186 0 != memcmp (p-4, " -- ", 4 ) &&1187 (p[-1] != ')' || !isdigit(p[-2]) || p[-3] != ' ' || p[-4] != 'D' || p[-5] != 'C' || p[-6] != '(') &&1188 (p[-1] != ' ' || p[-2] != ']' || !isdigit(p[-3]) || !isdigit(p[-4]) || p[-5] != '[') &&1189 (p[-1] != ']' || p[-2] != '0' || p[-3] != '0' || p[-4] != '[')1190 )1191 p--;1192 copy ( q, p, srcend - p );1193 break;1194 case 'x':1195 do {1196 p--;1197 if (p[0] == PATH_SEP || p[0] == DRIVE_SEP)1198 return -1;1199 } while (*p != '.');1200 copy (dst[5], p, srcend-p );1201 break;1202 }1203 #ifndef STFU1204 stderr_printf ( "%*.*s\033[7m%*.*s\033[0m\n", p-src, p-src, src, srcend-p, srcend-p, p );1205 #endif1206 srcend = p;1207 }1208 return 0;1209 }1210 1211 static int1212 hexdigit ( const char s )1213 {1214 if ( (unsigned char)(s-'0') < 10u )1215 return s-'0';1216 if ( (unsigned char)(s-'A') < 6u )1217 return s-'A'+10;1218 return -1;1219 }1220 1221 static void1222 spaceconverting ( char* dst, const char* src ) // can work inplace1223 {1224 for ( ; src[0] != '\0' ; src++) {1225 if ( src[0] == '_' )1226 *dst++ = ' ';1227 else if ( src[0] == '%' && hexdigit(src[1]) >= 0 && hexdigit(src[2]) >= 0 )1228 *dst++ = hexdigit(src[1]) * 16 + hexdigit(src[2]), src += 2;1229 else1230 *dst++ = *src;1231 }1232 *dst = '\0';1233 }1234 1235 1236 static int1237 Parser ( const char* src )1238 {1239 size_t i;1240 char tmp [6] [1024];1241 char* buff [6] = { tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5] };1242 char merge [1024];1243 char* q;1244 1245 #ifndef STFU1246 stderr_printf ( "\n %s\n", src );1247 #endif1248 1249 memset ( tmp , 0, sizeof tmp );1250 memset ( merge, 0, sizeof merge );1251 1252 for ( i = 0; i < sizeof(parser_strings)/sizeof(*parser_strings); i++ ) {1253 if ( 0 == parse ( buff, src, parser_strings[i] ) ) {1254 sprintf ( merge, "%s%s", tmp[1], tmp[3] );1255 q = merge + strlen (merge);1256 1257 if ( q-7 >= merge && q[-7]==' ' && q[-6]=='(' && atoi(q-5) >= 1900 && atoi(q-5) < 2050 && q[-1] == ')' ) {1258 q[-1] = '\0';1259 q[-7] = '\0';1260 q -= 5;1261 }1262 else {1263 q = NULL;1264 }1265 1266 spaceconverting ( tmp[0], tmp[0] );1267 spaceconverting ( merge , merge );1268 spaceconverting ( tmp[2], tmp[2] );1269 spaceconverting ( tmp[4], tmp[4] );1270 spaceconverting ( tmp[5], tmp[5] );1271 1272 stderr_printf ("\n");1273 stderr_printf ("Artist = %s\n", tmp[0] );1274 stderr_printf ("CD = %s\n", merge );1275 stderr_printf ("Title = %s\n", tmp[2] );1276 stderr_printf ("No# = %s\n", tmp[4] );1277 stderr_printf ("Extent = %s\n", tmp[5] );1278 stderr_printf ("Year = %s\n", q ? q : "????" );1279 #if 11280 if ( tmp[0][0] && ! TagKeyExists ( "Artist", 0 ) ) addtag ( "Artist", 0, tmp[0], strlen (tmp[0]), 5, 0 );1281 if ( merge[0] && ! TagKeyExists ( "Album" , 0 ) ) addtag ( "Album" , 0, merge , strlen (merge) , 5, 0 );1282 if ( tmp[2][0] && ! TagKeyExists ( "Title" , 0 ) ) addtag ( "Title" , 0, tmp[2], strlen (tmp[2]), 5, 0 );1283 if ( tmp[4][0] && ! TagKeyExists ( "Track" , 0 ) ) addtag ( "Track" , 0, tmp[4], strlen (tmp[4]), 5, 0 );1284 if ( q != NULL && ! TagKeyExists ( "Year" , 0 ) ) addtag ( "Year" , 0, q , 4 , 5, 0 );1285 #endif1286 return 1;1287 }1288 #ifndef STFU1289 stderr_printf ("???\n--\n");1290 #endif1291 }1292 1293 return 0;1294 }1295 1296 1297 /*******************************************************************************/1298 1299 1300 static int1301 CopyTags_Name ( const char* filename )1302 {1303 char buff [4096];1304 1305 FullPathName ( buff, sizeof buff, filename );1306 Parser ( buff );1307 return 0;1308 }1309 1310 1311 1107 int 1312 1108 CopyTags ( const char* filename ) … … 1323 1119 CopyTags_APE (fp); // APE tags have higher priority than ID3V1 tags 1324 1120 CopyTags_ID3 (fp); 1325 // CopyTags_Name (filename);1326 1121 1327 1122 fclose (fp);
Note: See TracChangeset
for help on using the changeset viewer.