1/* 2 * libid3tag - ID3 tag manipulation library 3 * Copyright (C) 2000-2004 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: render.c,v 1.11 2004/01/23 09:41:32 rob Exp $ 20 */ 21 22# ifdef HAVE_CONFIG_H 23# include "config.h" 24# endif 25 26# include "global.h" 27 28# include <string.h> 29# include <stdlib.h> 30 31# ifdef HAVE_ASSERT_H 32# include <assert.h> 33# endif 34 35# include "id3tag.h" 36# include "render.h" 37# include "ucs4.h" 38# include "latin1.h" 39# include "utf16.h" 40# include "utf8.h" 41 42id3_length_t id3_render_immediate(id3_byte_t **ptr, 43 char const *value, unsigned int bytes) 44{ 45 assert(value); 46 assert(bytes == 8 || bytes == 4 || bytes == 3); 47 48 if (ptr) { 49 switch (bytes) { 50 case 8: *(*ptr)++ = *value++; 51 *(*ptr)++ = *value++; 52 *(*ptr)++ = *value++; 53 *(*ptr)++ = *value++; 54 case 4: *(*ptr)++ = *value++; 55 case 3: *(*ptr)++ = *value++; 56 *(*ptr)++ = *value++; 57 *(*ptr)++ = *value++; 58 } 59 } 60 61 return bytes; 62} 63 64id3_length_t id3_render_syncsafe(id3_byte_t **ptr, 65 unsigned long num, unsigned int bytes) 66{ 67 assert(bytes == 4 || bytes == 5); 68 69 if (ptr) { 70 switch (bytes) { 71 case 5: *(*ptr)++ = (num >> 28) & 0x0f; 72 case 4: *(*ptr)++ = (num >> 21) & 0x7f; 73 *(*ptr)++ = (num >> 14) & 0x7f; 74 *(*ptr)++ = (num >> 7) & 0x7f; 75 *(*ptr)++ = (num >> 0) & 0x7f; 76 } 77 } 78 79 return bytes; 80} 81 82id3_length_t id3_render_int(id3_byte_t **ptr, 83 signed long num, unsigned int bytes) 84{ 85 assert(bytes >= 1 && bytes <= 4); 86 87 if (ptr) { 88 switch (bytes) { 89 case 4: *(*ptr)++ = num >> 24; 90 case 3: *(*ptr)++ = num >> 16; 91 case 2: *(*ptr)++ = num >> 8; 92 case 1: *(*ptr)++ = num >> 0; 93 } 94 } 95 96 return bytes; 97} 98 99id3_length_t id3_render_binary(id3_byte_t **ptr, 100 id3_byte_t const *data, id3_length_t length) 101{ 102 if (data == 0) 103 return 0; 104 105 if (ptr) { 106 memcpy(*ptr, data, length); 107 *ptr += length; 108 } 109 110 return length; 111} 112 113id3_length_t id3_render_latin1(id3_byte_t **ptr, 114 id3_latin1_t const *latin1, int terminate) 115{ 116 id3_length_t size; 117 118 if (latin1 == 0) 119 latin1 = ""; 120 121 size = id3_latin1_size(latin1); 122 if (!terminate) 123 --size; 124 125 if (ptr) { 126 memcpy(*ptr, latin1, size); 127 *ptr += size; 128 } 129 130 return size; 131} 132 133id3_length_t id3_render_string(id3_byte_t **ptr, id3_ucs4_t const *ucs4, 134 enum id3_field_textencoding encoding, 135 int terminate) 136{ 137 enum id3_utf16_byteorder byteorder = ID3_UTF16_BYTEORDER_ANY; 138 139 if (ucs4 == 0) 140 ucs4 = id3_ucs4_empty; 141 142 switch (encoding) { 143 case ID3_FIELD_TEXTENCODING_ISO_8859_1: 144 return id3_latin1_serialize(ptr, ucs4, terminate); 145 146 case ID3_FIELD_TEXTENCODING_UTF_16BE: 147 byteorder = ID3_UTF16_BYTEORDER_BE; 148 case ID3_FIELD_TEXTENCODING_UTF_16: 149 return id3_utf16_serialize(ptr, ucs4, byteorder, terminate); 150 151 case ID3_FIELD_TEXTENCODING_UTF_8: 152 return id3_utf8_serialize(ptr, ucs4, terminate); 153 } 154 155 return 0; 156} 157 158id3_length_t id3_render_padding(id3_byte_t **ptr, id3_byte_t value, 159 id3_length_t length) 160{ 161 if (ptr) { 162 memset(*ptr, value, length); 163 *ptr += length; 164 } 165 166 return length; 167} 168 169/* 170 * NAME: render->paddedstring() 171 * DESCRIPTION: render a space-padded string using latin1 encoding 172 */ 173id3_length_t id3_render_paddedstring(id3_byte_t **ptr, id3_ucs4_t const *ucs4, 174 id3_length_t length) 175{ 176 id3_ucs4_t padded[31], *data, *end; 177 178 /* latin1 encoding only (this is used for ID3v1 fields) */ 179 180 assert(length <= 30); 181 182 data = padded; 183 end = data + length; 184 185 if (ucs4) { 186 while (*ucs4 && end - data > 0) { 187 *data++ = *ucs4++; 188 189 if (data[-1] == '\n') 190 data[-1] = ' '; 191 } 192 } 193 194 while (end - data > 0) 195 *data++ = ' '; 196 197 *data = 0; 198 199 return id3_latin1_serialize(ptr, padded, 0); 200} 201