/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: render.c,v 1.11 2004/01/23 09:41:32 rob Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "global.h" #include #include #ifdef HAVE_ASSERT_H # include #endif #include "id3tag.h" #include "render.h" #include "ucs4.h" #include "latin1.h" #include "utf16.h" #include "utf8.h" id3_length_t id3_render_immediate(id3_byte_t ** ptr, char const *value, unsigned int bytes) { assert(value); assert(bytes == 8 || bytes == 4 || bytes == 3); if (ptr) { switch (bytes) { case 8: *(*ptr)++ = *value++; *(*ptr)++ = *value++; *(*ptr)++ = *value++; *(*ptr)++ = *value++; case 4: *(*ptr)++ = *value++; case 3: *(*ptr)++ = *value++; *(*ptr)++ = *value++; *(*ptr)++ = *value++; } } return bytes; } id3_length_t id3_render_syncsafe(id3_byte_t ** ptr, unsigned long num, unsigned int bytes) { assert(bytes == 4 || bytes == 5); if (ptr) { switch (bytes) { case 5: *(*ptr)++ = (num >> 28) & 0x0f; case 4: *(*ptr)++ = (num >> 21) & 0x7f; *(*ptr)++ = (num >> 14) & 0x7f; *(*ptr)++ = (num >> 7) & 0x7f; *(*ptr)++ = (num >> 0) & 0x7f; } } return bytes; } id3_length_t id3_render_int(id3_byte_t ** ptr, signed long num, unsigned int bytes) { assert(bytes >= 1 && bytes <= 4); if (ptr) { switch (bytes) { case 4: *(*ptr)++ = num >> 24; case 3: *(*ptr)++ = num >> 16; case 2: *(*ptr)++ = num >> 8; case 1: *(*ptr)++ = num >> 0; } } return bytes; } id3_length_t id3_render_binary(id3_byte_t ** ptr, id3_byte_t const *data, id3_length_t length) { if (data == 0) return 0; if (ptr) { memcpy(*ptr, data, length); *ptr += length; } return length; } id3_length_t id3_render_latin1(id3_byte_t ** ptr, id3_latin1_t const *latin1, int terminate) { id3_length_t size; if (latin1 == 0) latin1 = (id3_latin1_t*) ""; size = id3_latin1_size(latin1); if (!terminate) --size; if (ptr) { memcpy(*ptr, latin1, size); *ptr += size; } return size; } id3_length_t id3_render_string(id3_byte_t ** ptr, id3_ucs4_t const *ucs4, enum id3_field_textencoding encoding, int terminate) { enum id3_utf16_byteorder byteorder = ID3_UTF16_BYTEORDER_ANY; if (ucs4 == 0) ucs4 = id3_ucs4_empty; switch (encoding) { case ID3_FIELD_TEXTENCODING_ISO_8859_1: return id3_latin1_serialize(ptr, ucs4, terminate); case ID3_FIELD_TEXTENCODING_UTF_16BE: byteorder = ID3_UTF16_BYTEORDER_BE; case ID3_FIELD_TEXTENCODING_UTF_16: return id3_utf16_serialize(ptr, ucs4, byteorder, terminate); case ID3_FIELD_TEXTENCODING_UTF_8: return id3_utf8_serialize(ptr, ucs4, terminate); } return 0; } id3_length_t id3_render_padding(id3_byte_t ** ptr, id3_byte_t value, id3_length_t length) { if (ptr) { memset(*ptr, value, length); *ptr += length; } return length; } /* * NAME: render->paddedstring() * DESCRIPTION: render a space-padded string using latin1 encoding */ id3_length_t id3_render_paddedstring(id3_byte_t ** ptr, id3_ucs4_t const *ucs4, id3_length_t length) { id3_ucs4_t padded[31], *data, *end; /* * latin1 encoding only (this is used for ID3v1 fields) */ assert(length <= 30); data = padded; end = data + length; if (ucs4) { while (*ucs4 && end - data > 0) { *data++ = *ucs4++; if (data[-1] == '\n') data[-1] = ' '; } } while (end - data > 0) *data++ = ' '; *data = 0; return id3_latin1_serialize(ptr, padded, 0); }