1/* 2 * libid3tag - ID3 tag manipulation library 3 * Copyright (C) 2000-2003 Underbit Technologies, Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * 19 * $Id: parse.c,v 1.8 2003/04/19 00:14:33 rob Exp $ 20 */ 21 22# ifdef HAVE_CONFIG_H 23# include "config.h" 24# endif 25 26# include "global.h" 27 28# ifdef HAVE_ASSERT_H 29# include <assert.h> 30# endif 31 32# include <stdlib.h> 33# include <string.h> 34 35# include "id3tag.h" 36# include "parse.h" 37# include "latin1.h" 38# include "utf16.h" 39# include "utf8.h" 40 41signed long id3_parse_int(id3_byte_t const **ptr, unsigned int bytes) 42{ 43 signed long value = 0; 44 45 assert(bytes >= 1 && bytes <= 4); 46 47 if (**ptr & 0x80) 48 value = ~0; 49 50 switch (bytes) { 51 case 4: value = (value << 8) | *(*ptr)++; 52 case 3: value = (value << 8) | *(*ptr)++; 53 case 2: value = (value << 8) | *(*ptr)++; 54 case 1: value = (value << 8) | *(*ptr)++; 55 } 56 57 return value; 58} 59 60unsigned long id3_parse_uint(id3_byte_t const **ptr, unsigned int bytes) 61{ 62 unsigned long value = 0; 63 64 assert(bytes >= 1 && bytes <= 4); 65 66 switch (bytes) { 67 case 4: value = (value << 8) | *(*ptr)++; 68 case 3: value = (value << 8) | *(*ptr)++; 69 case 2: value = (value << 8) | *(*ptr)++; 70 case 1: value = (value << 8) | *(*ptr)++; 71 } 72 73 return value; 74} 75 76unsigned long id3_parse_syncsafe(id3_byte_t const **ptr, unsigned int bytes) 77{ 78 unsigned long value = 0; 79 80 assert(bytes == 4 || bytes == 5); 81 82 switch (bytes) { 83 case 5: value = (value << 4) | (*(*ptr)++ & 0x0f); 84 case 4: value = (value << 7) | (*(*ptr)++ & 0x7f); 85 value = (value << 7) | (*(*ptr)++ & 0x7f); 86 value = (value << 7) | (*(*ptr)++ & 0x7f); 87 value = (value << 7) | (*(*ptr)++ & 0x7f); 88 } 89 90 return value; 91} 92 93void id3_parse_immediate(id3_byte_t const **ptr, unsigned int bytes, 94 char *value) 95{ 96 assert(value); 97 assert(bytes == 8 || bytes == 4 || bytes == 3); 98 99 switch (bytes) { 100 case 8: *value++ = *(*ptr)++; 101 *value++ = *(*ptr)++; 102 *value++ = *(*ptr)++; 103 *value++ = *(*ptr)++; 104 case 4: *value++ = *(*ptr)++; 105 case 3: *value++ = *(*ptr)++; 106 *value++ = *(*ptr)++; 107 *value++ = *(*ptr)++; 108 } 109 110 *value = 0; 111} 112 113id3_latin1_t *id3_parse_latin1(id3_byte_t const **ptr, id3_length_t length, 114 int full) 115{ 116 id3_byte_t const *end; 117 int terminated = 0; 118 id3_latin1_t *latin1; 119 120 end = memchr(*ptr, 0, length); 121 if (end == 0) 122 end = *ptr + length; 123 else { 124 length = end - *ptr; 125 terminated = 1; 126 } 127 128 latin1 = malloc(length + 1); 129 if (latin1) { 130 memcpy(latin1, *ptr, length); 131 latin1[length] = 0; 132 133 if (!full) { 134 id3_latin1_t *check; 135 136 for (check = latin1; *check; ++check) { 137 if (*check == '\n') 138 *check = ' '; 139 } 140 } 141 } 142 143 *ptr += length + terminated; 144 145 return latin1; 146} 147 148id3_ucs4_t *id3_parse_string(id3_byte_t const **ptr, id3_length_t length, 149 enum id3_field_textencoding encoding, int full) 150{ 151 id3_ucs4_t *ucs4 = 0; 152 enum id3_utf16_byteorder byteorder = ID3_UTF16_BYTEORDER_ANY; 153 154 switch (encoding) { 155 case ID3_FIELD_TEXTENCODING_ISO_8859_1: 156 ucs4 = id3_latin1_deserialize(ptr, length); 157 break; 158 159 case ID3_FIELD_TEXTENCODING_UTF_16BE: 160 byteorder = ID3_UTF16_BYTEORDER_BE; 161 case ID3_FIELD_TEXTENCODING_UTF_16: 162 ucs4 = id3_utf16_deserialize(ptr, length, byteorder); 163 break; 164 165 case ID3_FIELD_TEXTENCODING_UTF_8: 166 ucs4 = id3_utf8_deserialize(ptr, length); 167 break; 168 } 169 170 if (ucs4 && !full) { 171 id3_ucs4_t *check; 172 173 for (check = ucs4; *check; ++check) { 174 if (*check == '\n') 175 *check = ' '; 176 } 177 } 178 179 return ucs4; 180} 181 182id3_byte_t *id3_parse_binary(id3_byte_t const **ptr, id3_length_t length) 183{ 184 id3_byte_t *data; 185 186 if (length == 0) 187 return malloc(1); 188 189 data = malloc(length); 190 if (data) 191 memcpy(data, *ptr, length); 192 193 *ptr += length; 194 195 return data; 196} 197