diff options
303 files changed, 51792 insertions, 149 deletions
@@ -1,5 +1,4 @@ *.o -*.a *.bak *~ *.tar.gz @@ -7,7 +6,11 @@ .exec aclocal.m4 configure -Makefile +plugins/*/Makefile +intl/Makefile +icons/Makefile +pixmaps/Makefile +po/Makefile Makefile.in config.h config.h.in @@ -45,3 +48,5 @@ vala.stamp POTFILES stamp-it po/Makevars.template +*.so +tools/pluginfo/pluginfo diff --git a/PORTABLE_BUILD b/PORTABLE_BUILD new file mode 100644 index 00000000..00750edc --- /dev/null +++ b/PORTABLE_BUILD @@ -0,0 +1 @@ +3 diff --git a/PORTABLE_VERSION b/PORTABLE_VERSION new file mode 100644 index 00000000..17b2ccd9 --- /dev/null +++ b/PORTABLE_VERSION @@ -0,0 +1 @@ +0.4.3 @@ -18,12 +18,21 @@ #ifndef __COMMON_H #define __COMMON_H +#include <limits.h> +#ifndef PATH_MAX +#define PATH_MAX 1024 /* max # of characters in a path name */ +#endif + #define min(x,y) ((x)<(y)?(x):(y)) #define max(x,y) ((x)>(y)?(x):(y)) // those are defined in main.c -extern char confdir[1024]; // $HOME/.config -extern char dbconfdir[1024]; // $HOME/.config/deadbeef -extern char sessfile[1024]; // $HOME/.config/deadbeef/session +extern char confdir[PATH_MAX]; // $HOME/.config +extern char dbconfdir[PATH_MAX]; // $HOME/.config/deadbeef +extern char dbinstalldir[PATH_MAX]; // see deadbeef->get_prefix +extern char dbdocdir[PATH_MAX]; // see deadbeef->get_doc_dir +extern char dbplugindir[PATH_MAX]; // see deadbeef->get_plugin_dir +extern char dbpixmapdir[PATH_MAX]; // see deadbeef->get_pixmap_dir + #endif // __COMMON_H diff --git a/configure.ac b/configure.ac index 7a113167..2a364423 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT([deadbeef], [devel]) +AC_INIT([deadbeef], [0.4.3]) AC_CONFIG_HEADER(config.h) @@ -33,15 +33,19 @@ fi case "$host" in i386-*-* | i486-*-* | i586-*-* | i686-*-* | i86pc-*-*) AC_DEFINE(ARCH_X86_32, 1, [architecture is x86]) + LIB="lib-x86-32" ;; x86_64-*-* | amd64-*-*) AC_DEFINE(ARCH_X86_64, 1, [architecture is x86_64]) + LIB="lib-x86-64" ;; powerpc-*-* ) AC_DEFINE(ARCH_PPC_32, 1, [architecture is ppc32]) + LIB="lib-ppc-32" ;; powerpc64-*-* ) AC_DEFINE(ARCH_PPC_64, 1, [architecture is ppc64]) + LIB="lib-ppc-64" ;; *) AC_DEFINE(ARCH_UNKNOWN, 1, [architecture is unknown]) @@ -56,9 +60,6 @@ dnl INSANE_CXXFLAGS="-Wcomment -Wchar-subscripts -Wunused-function -Wunused-valu AC_SUBST(INSANE_CFLAGS) AC_SUBST(INSANE_CXXFLAGS) -CXXFLAGS="$CXXFLAGS $INSANE_CXXFLAGS -D_GNU_SOURCE -DLIBDIR=\\\"$libdir\\\" -DPREFIX=\\\"$prefix\\\" -DDOCDIR=\\\"$docdir\\\"" -CFLAGS="$CFLAGS $INSANE_CFLAGS -D_GNU_SOURCE -DLIBDIR=\\\"$libdir\\\" -DPREFIX=\\\"$prefix\\\" -DDOCDIR=\\\"$docdir\\\"" - AC_ARG_ENABLE(nullout, [AS_HELP_STRING([--disable-nullout ], [disable NULL output plugin (default: enabled)])], [enable_nullout=$enableval], [enable_nullout=yes]) AC_ARG_ENABLE(alsa, [AS_HELP_STRING([--disable-alsa ], [disable ALSA output plugin (default: enabled)])], [enable_alsa=$enableval], [enable_alsa=yes]) AC_ARG_ENABLE(oss, [AS_HELP_STRING([--disable-oss ], [disable Open Sound System output plugin (default: enabled)])], [enable_oss=$enableval], [enable_oss=yes]) @@ -93,8 +94,27 @@ AC_ARG_ENABLE(aac, [AS_HELP_STRING([--disable-aac ], [disable AAC decod AC_ARG_ENABLE(mms, [AS_HELP_STRING([--disable-mms ], [disable MMS streaming vfs plugin (default: enabled)])], [enable_mms=$enableval], [enable_mms=yes]) AC_ARG_ENABLE(shn, [AS_HELP_STRING([--disable-shn ], [disable shorten plugin (default: enabled)])], [enable_shn=$enableval], [enable_shn=yes]) AC_ARG_ENABLE(ao, [AS_HELP_STRING([--disable-ao ], [disable audio overload plugin (default: enabled)])], [enable_ao=$enableval], [enable_ao=yes]) +AC_ARG_ENABLE(mpris, [ --enable-mpris enable Ubuntu Sound Menu plugin (default: disabled)], [enable_mpris=$enableval], [enable_mpris=no]) +AC_ARG_ENABLE(portable, [ --enable-portable make portable static build (default: disabled)], [enable_portable=$enableval], [enable_portable=no]) + +if test "x$enable_portable" != "xno" ; then + AC_DEFINE_UNQUOTED([PORTABLE], [1], [Define if building portable version]) + PORTABLE=yes + PREFIXFLAGS="-DPREFIX=donotuse -DLIBDIR=donotuse -DDOCDIR=donotuse -I./include -I../../include" +else + PREFIXFLAGS=" -DLIBDIR=\\\"$libdir\\\" -DPREFIX=\\\"$prefix\\\" -DDOCDIR=\\\"$docdir\\\"" +fi + +CXXFLAGS="$CXXFLAGS $INSANE_CXXFLAGS -D_GNU_SOURCE $PREFIXFLAGS" +CFLAGS="$CFLAGS $INSANE_CFLAGS -D_GNU_SOURCE $PREFIXFLAGS" PKG_CHECK_MODULES(DEPS, samplerate) +if test "x$enable_portable" != "xno" ; then + DEPS_LIBS="$LIB/libsamplerate.a -lpthread -ldl" + AC_SUBST(DEPS_LIBS) +else + PKG_CHECK_MODULES(DEPS, samplerate) +fi if test "x$enable_gtkui" != "xno" ; then if test "x$enable_gtk3" == "xyes" ; then @@ -111,15 +131,21 @@ if test "x$enable_alsa" != "xno" ; then fi if test "x$enable_ffmpeg" != "xno" ; then +if test "x$enable_portable" != "xno" ; then + FFMPEG_DEPS_LIBS="../../$LIB/libavcodec.a -lpthread ../../$LIB/libavformat.a ../../$LIB/libavcodec.a ../../$LIB/libavutil.a ../../$LIB/libavcore.a -lm ../../$LIB/libz.a " + AC_SUBST(FFMPEG_DEPS_LIBS) + HAVE_FFMPEG=yes +else PKG_CHECK_MODULES(FFMPEG_DEPS, libavcodec >= 51.0.0 libavutil libavformat >= 52.0.0, HAVE_FFMPEG=yes, HAVE_FFMPEG=no) fi +fi if test "x$enable_pulse" != "xno" ; then PKG_CHECK_MODULES(PULSE_DEPS, libpulse-simple, HAVE_PULSE=yes, HAVE_PULSE=no) fi -AC_CHECK_LIB([pthread], [main]) -AC_CHECK_LIB([dl], [main]) +dnl AC_CHECK_LIB([pthread], [main]) +dnl AC_CHECK_LIB([dl], [main]) AC_CHECK_HEADER([iconv.h],[],[iconv.h not found.]) @@ -136,17 +162,33 @@ if test ${HAVE_SSE2}; then fi dnl curl lib -AC_CHECK_LIB([curl], [main], [HAVE_CURL=yes]) -if test "x$HAVE_CURL" = "xyes"; then +if test "x$enable_portable" != "xno" ; then + HAVE_CURL=yes + CURL_LIBS="../../$LIB/libcurl.a -lrt" + AC_SUBST(CURL_LIBS) +else + AC_CHECK_LIB([curl], [main], [HAVE_CURL=yes]) CURL_LIBS="-lcurl" AC_SUBST(CURL_LIBS) fi -PKG_CHECK_MODULES(DBUS_DEPS, dbus-1, HAVE_DBUS=yes, HAVE_DBUS=no) +if test "x$enable_portable" != "xno" ; then + HAVE_DBUS=yes + DBUS_DEPS_LIBS="../../$LIB/libdbus-1.a ../../$LIB/libexpat.a -lrt" + DBUS_DEPS_CFLAGS="-I../../include/dbus-1" + AC_SUBST(DBUS_DEPS_LIBS) +else + PKG_CHECK_MODULES(DBUS_DEPS, dbus-1, HAVE_DBUS=yes, HAVE_DBUS=no) +fi dnl mpgmad plugin if test "x$enable_mpgmad" != "xno" ; then +if test "x$enable_portable" != "xno" ; then + HAVE_MPGMAD=yes + MAD_LIBS="../../$LIB/libmad.a" + AC_SUBST(MAD_LIBS) +else AC_CHECK_LIB([mad], [main], [HAVE_LIBMAD=yes]) if test "x$HAVE_LIBMAD" = "xyes" ; then HAVE_MPGMAD=yes @@ -154,9 +196,15 @@ if test "x$enable_mpgmad" != "xno" ; then AC_SUBST(MAD_LIBS) fi fi +fi dnl vorbis plugin if test "x$enable_vorbis" != "xno" ; then +if test "x$enable_portable" != "xno" ; then + HAVE_VORBISPLUGIN=yes + VORBIS_LIBS="../../$LIB/libogg.a ../../$LIB/libvorbis.a ../../$LIB/libvorbisenc.a ../../$LIB/libvorbisfile.a" + AC_SUBST(VORBIS_LIBS) +else AC_CHECK_LIB([vorbis], [main], [HAVE_VORBIS=yes]) AC_CHECK_LIB([vorbisfile], [main], [HAVE_VORBISFILE=yes]) if test "x$HAVE_VORBIS" = "xyes" && test "x$HAVE_VORBISFILE" = "xyes" ; then @@ -165,9 +213,15 @@ if test "x$enable_vorbis" != "xno" ; then AC_SUBST(VORBIS_LIBS) fi fi +fi dnl flac plugin if test "x$enable_flac" != "xno" ; then +if test "x$enable_portable" != "xno" ; then + HAVE_FLACPLUGIN=yes + FLAC_LIBS="../../$LIB/libFLAC.a ../../$LIB/libogg.a" + AC_SUBST(FLAC_LIBS) +else AC_CHECK_LIB([FLAC], [main], [HAVE_FLAC=yes]) if test "x$HAVE_FLAC" = "xyes" ; then HAVE_FLACPLUGIN=yes @@ -175,9 +229,15 @@ if test "x$enable_flac" != "xno" ; then AC_SUBST(FLAC_LIBS) fi fi +fi dnl wavpack plugin if test "x$enable_wavpack" != "xno" ; then +if test "x$enable_portable" != "xno" ; then + HAVE_WAVPACKPLUGIN=yes + WAVPACK_LIBS="../../$LIB/libwavpack.a" + AC_SUBST(WAVPACK_LIBS) +else AC_CHECK_LIB([wavpack], [main], [HAVE_WAVPACK=yes]) if test "x$HAVE_WAVPACK" = "xyes" ; then HAVE_WAVPACKPLUGIN=yes @@ -185,9 +245,15 @@ if test "x$enable_wavpack" != "xno" ; then AC_SUBST(WAVPACK_LIBS) fi fi +fi dnl libsndfile plugin if test "x$enable_sndfile" != "xno" ; then +if test "x$enable_portable" != "xno" ; then + HAVE_SNDFILEPLUGIN=yes + SNDFILE_LIBS="../../$LIB/libsndfile.a" + AC_SUBST(SNDFILE_LIBS) +else AC_CHECK_LIB([sndfile], [main], [HAVE_SNDFILE=yes]) if test "x$HAVE_SNDFILE" = "xyes" ; then HAVE_SNDFILEPLUGIN=yes @@ -195,18 +261,24 @@ if test "x$enable_sndfile" != "xno" ; then AC_SUBST(SNDFILE_LIBS) fi fi +fi dnl vfs_curl plugin if test "x$enable_vfs_curl" != "xno" ; then if test "x$HAVE_CURL" = "xyes" ; then HAVE_VFS_CURL=yes - VFS_CURL_LIBS="-lcurl" + VFS_CURL_LIBS="$CURL_LIBS" AC_SUBST(VFS_CURL_LIBS) fi fi dnl cdda plugin if test "x$enable_cdda" != "xno" ; then +if test "x$enable_portable" != "xno" ; then + HAVE_CDDAPLUGIN=yes + CDDA_LIBS="../../$LIB/libcdio.a ../../$LIB/libudf.a ../../$LIB/libiso9660.a ../../$LIB/libcddb.a" + AC_SUBST(CDDA_LIBS) +else AC_CHECK_LIB([cdio], [main], [HAVE_CDIO=yes]) AC_CHECK_LIB([cddb], [main], [HAVE_CDDB=yes]) if test "x$HAVE_CDIO" = "xyes" && test "x$HAVE_CDDB" = "xyes" ; then @@ -215,6 +287,7 @@ if test "x$enable_cdda" != "xno" ; then AC_SUBST(CDDA_LIBS) fi fi +fi dnl gtkui plugin if test "x$enable_gtkui" != "xno" ; then @@ -230,10 +303,14 @@ if test "x$enable_alsa" != "xno" ; then fi if test "x$enable_ffmpeg" != "xno" ; then +if test "x$enable_portable" = "xno" ; then if test "x$HAVE_FFMPEG" = "xyes" ; then HAVE_FFMPEGPLUGIN=yes AC_CHECK_HEADER([ffmpeg/avformat.h], FFMPEG_DEPS_CFLAGS="$FFMPEG_DEPS_CFLAGS -D FFMPEG_OLD") fi +else + HAVE_FFMPEGPLUGIN=yes +fi fi if test "x$enable_hotkeys" != "xno" ; then @@ -365,6 +442,11 @@ if test "x$enable_dca" != "xno" ; then fi if test "x$enable_aac" != "xno" ; then +if test "x$enable_portable" != "xno" ; then + FAAD2_LIBS="../../$LIB/libfaad.a" + AC_SUBST(FAAD2_LIBS) + HAVE_AAC=yes +else AC_CHECK_LIB([faad], [main], [HAVE_FAAD=1]) if test ${HAVE_FAAD} ; then FAAD2_LIBS="-lfaad" @@ -372,6 +454,7 @@ if test "x$enable_aac" != "xno" ; then HAVE_AAC=yes fi fi +fi if test "x$enable_mms" != "xno" ; then LIBMMS_LIBS="" @@ -384,15 +467,24 @@ if test "x$enable_shn" != "xno" ; then fi if test "x$enable_ao" != "xno" ; then +if test "x$enable_portable" != "xno" ; then + HAVE_ZLIB=yes + ZLIB_LIBS="../../$LIB/libz.a" +else AC_CHECK_LIB([z], [main], [HAVE_ZLIB=yes]) + ZLIB_LIBS="-lz" +fi if test "x$HAVE_ZLIB" = "xyes"; then - ZLIB_LIBS="-lz" AC_SUBST(ZLIB_LIBS) HAVE_AO=yes fi fi -PLUGINS_DIRS="plugins/lastfm plugins/mpgmad plugins/vorbis plugins/flac plugins/wavpack plugins/sndfile plugins/vfs_curl plugins/cdda plugins/gtkui plugins/alsa plugins/ffmpeg plugins/hotkeys plugins/oss plugins/artwork plugins/adplug plugins/ffap plugins/sid plugins/nullout plugins/supereq plugins/vtx plugins/gme plugins/dumb plugins/pulse plugins/notify plugins/musepack plugins/wildmidi plugins/tta plugins/dca plugins/aac plugins/mms plugins/shn plugins/ao plugins/shellexec" +if test "x$enable_mpris" != "xno" ; then + PKG_CHECK_MODULES(MPRIS_DEPS, gio-2.0 glib-2.0 >= 2.26.0, HAVE_MPRIS=yes, HAVE_MPRIS=no) +fi + +PLUGINS_DIRS="plugins/lastfm plugins/mpgmad plugins/vorbis plugins/flac plugins/wavpack plugins/sndfile plugins/vfs_curl plugins/cdda plugins/gtkui plugins/alsa plugins/ffmpeg plugins/hotkeys plugins/oss plugins/artwork plugins/adplug plugins/ffap plugins/sid plugins/nullout plugins/supereq plugins/vtx plugins/gme plugins/dumb plugins/pulse plugins/notify plugins/musepack plugins/wildmidi plugins/tta plugins/dca plugins/aac plugins/mms plugins/shn plugins/ao plugins/shellexec plugins/mpris" AM_CONDITIONAL(HAVE_VORBIS, test "x$HAVE_VORBISPLUGIN" = "xyes") AM_CONDITIONAL(HAVE_FLAC, test "x$HAVE_FLACPLUGIN" = "xyes") @@ -427,6 +519,8 @@ AM_CONDITIONAL(HAVE_AAC, test "x$HAVE_AAC" = "xyes") AM_CONDITIONAL(HAVE_MMS, test "x$HAVE_MMS" = "xyes") AM_CONDITIONAL(HAVE_SHN, test "x$HAVE_SHN" = "xyes") AM_CONDITIONAL(HAVE_AO, test "x$HAVE_AO" = "xyes") +AM_CONDITIONAL(HAVE_MPRIS, test "x$HAVE_MPRIS" = "xyes") +AM_CONDITIONAL(PORTABLE, test "x$PORTABLE" = "xyes") AC_SUBST(PLUGINS_DIRS) @@ -487,6 +581,7 @@ PRINT_PLUGIN_INFO([aac],[AAC player (m4a, aac, mp4) based on FAAD2],[test "x$HAV PRINT_PLUGIN_INFO([mms],[mms streaming support],[test "x$HAVE_MMS" = "xyes"]) PRINT_PLUGIN_INFO([shn],[shorten player based on xmms-shn],[test "x$HAVE_SHN" = "xyes"]) PRINT_PLUGIN_INFO([ao],[psf1/psf2/spu/ssf player using Audio Overload],[test "x$HAVE_AO" = "xyes"]) +PRINT_PLUGIN_INFO([mpris],[Ubuntu Sound Menu integration],[test "x$HAVE_MPRIS" = "xyes"]) echo @@ -527,6 +622,7 @@ plugins/aac/Makefile plugins/mms/Makefile plugins/shn/Makefile plugins/ao/Makefile +plugins/mpris/Makefile intl/Makefile po/Makefile.in deadbeef.desktop @@ -55,6 +55,7 @@ extern "C" { // api version history: // 9.9 -- devel +// 0.9 -- deadbeef-0.4.3-portable-build3 // 0.8 -- deadbeef-0.4.2 // 0.7 -- deabdeef-0.4.0 // 0.6 -- deadbeef-0.3.3 @@ -65,7 +66,7 @@ extern "C" { // 0.1 -- deadbeef-0.2.0 #define DB_API_VERSION_MAJOR 0 -#define DB_API_VERSION_MINOR 8 +#define DB_API_VERSION_MINOR 9 #define DB_PLUGIN_SET_API_VERSION\ .plugin.api_vmajor = DB_API_VERSION_MAJOR,\ @@ -317,8 +318,15 @@ typedef struct { int (*streamer_get_apx_bitrate) (void); struct DB_fileinfo_s *(*streamer_get_current_fileinfo) (void); int (*streamer_get_current_playlist) (void); + // system folders + // normally functions will return standard folders derived from --prefix + // portable version will return pathes specified in comments below + const char *(*get_config_dir) (void); // installdir/config | $XDG_CONFIG_HOME/.config/deadbeef + const char *(*get_prefix) (void); // installdir | PREFIX + const char *(*get_doc_dir) (void); // installdir/doc | DOCDIR + const char *(*get_plugin_dir) (void); // installdir/plugins | LIBDIR/deadbeef + const char *(*get_pixmap_dir) (void); // installdir/pixmaps | PREFIX "/share/deadbeef/pixmaps" // process control - const char *(*get_config_dir) (void); void (*quit) (void); // threading intptr_t (*thread_start) (void (*fn)(void *ctx), void *ctx); diff --git a/include/FLAC/Makefile.am b/include/FLAC/Makefile.am new file mode 100644 index 00000000..19f49b1f --- /dev/null +++ b/include/FLAC/Makefile.am @@ -0,0 +1,42 @@ +# libFLAC - Free Lossless Audio Codec library +# Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# - Neither the name of the Xiph.org Foundation nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +flaccincludedir = $(includedir)/FLAC + +flaccinclude_HEADERS = \ + all.h \ + assert.h \ + callback.h \ + export.h \ + format.h \ + metadata.h \ + ordinals.h \ + stream_decoder.h \ + stream_encoder.h diff --git a/include/FLAC/all.h b/include/FLAC/all.h new file mode 100644 index 00000000..c542c0d5 --- /dev/null +++ b/include/FLAC/all.h @@ -0,0 +1,370 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__ALL_H +#define FLAC__ALL_H + +#include "export.h" + +#include "assert.h" +#include "callback.h" +#include "format.h" +#include "metadata.h" +#include "ordinals.h" +#include "stream_decoder.h" +#include "stream_encoder.h" + +/** \mainpage + * + * \section intro Introduction + * + * This is the documentation for the FLAC C and C++ APIs. It is + * highly interconnected; this introduction should give you a top + * level idea of the structure and how to find the information you + * need. As a prerequisite you should have at least a basic + * knowledge of the FLAC format, documented + * <A HREF="../format.html">here</A>. + * + * \section c_api FLAC C API + * + * The FLAC C API is the interface to libFLAC, a set of structures + * describing the components of FLAC streams, and functions for + * encoding and decoding streams, as well as manipulating FLAC + * metadata in files. The public include files will be installed + * in your include area (for example /usr/include/FLAC/...). + * + * By writing a little code and linking against libFLAC, it is + * relatively easy to add FLAC support to another program. The + * library is licensed under <A HREF="../license.html">Xiph's BSD license</A>. + * Complete source code of libFLAC as well as the command-line + * encoder and plugins is available and is a useful source of + * examples. + * + * Aside from encoders and decoders, libFLAC provides a powerful + * metadata interface for manipulating metadata in FLAC files. It + * allows the user to add, delete, and modify FLAC metadata blocks + * and it can automatically take advantage of PADDING blocks to avoid + * rewriting the entire FLAC file when changing the size of the + * metadata. + * + * libFLAC usually only requires the standard C library and C math + * library. In particular, threading is not used so there is no + * dependency on a thread library. However, libFLAC does not use + * global variables and should be thread-safe. + * + * libFLAC also supports encoding to and decoding from Ogg FLAC. + * However the metadata editing interfaces currently have limited + * read-only support for Ogg FLAC files. + * + * \section cpp_api FLAC C++ API + * + * The FLAC C++ API is a set of classes that encapsulate the + * structures and functions in libFLAC. They provide slightly more + * functionality with respect to metadata but are otherwise + * equivalent. For the most part, they share the same usage as + * their counterparts in libFLAC, and the FLAC C API documentation + * can be used as a supplement. The public include files + * for the C++ API will be installed in your include area (for + * example /usr/include/FLAC++/...). + * + * libFLAC++ is also licensed under + * <A HREF="../license.html">Xiph's BSD license</A>. + * + * \section getting_started Getting Started + * + * A good starting point for learning the API is to browse through + * the <A HREF="modules.html">modules</A>. Modules are logical + * groupings of related functions or classes, which correspond roughly + * to header files or sections of header files. Each module includes a + * detailed description of the general usage of its functions or + * classes. + * + * From there you can go on to look at the documentation of + * individual functions. You can see different views of the individual + * functions through the links in top bar across this page. + * + * If you prefer a more hands-on approach, you can jump right to some + * <A HREF="../documentation_example_code.html">example code</A>. + * + * \section porting_guide Porting Guide + * + * Starting with FLAC 1.1.3 a \link porting Porting Guide \endlink + * has been introduced which gives detailed instructions on how to + * port your code to newer versions of FLAC. + * + * \section embedded_developers Embedded Developers + * + * libFLAC has grown larger over time as more functionality has been + * included, but much of it may be unnecessary for a particular embedded + * implementation. Unused parts may be pruned by some simple editing of + * src/libFLAC/Makefile.am. In general, the decoders, encoders, and + * metadata interface are all independent from each other. + * + * It is easiest to just describe the dependencies: + * + * - All modules depend on the \link flac_format Format \endlink module. + * - The decoders and encoders depend on the bitbuffer. + * - The decoder is independent of the encoder. The encoder uses the + * decoder because of the verify feature, but this can be removed if + * not needed. + * - Parts of the metadata interface require the stream decoder (but not + * the encoder). + * - Ogg support is selectable through the compile time macro + * \c FLAC__HAS_OGG. + * + * For example, if your application only requires the stream decoder, no + * encoder, and no metadata interface, you can remove the stream encoder + * and the metadata interface, which will greatly reduce the size of the + * library. + * + * Also, there are several places in the libFLAC code with comments marked + * with "OPT:" where a #define can be changed to enable code that might be + * faster on a specific platform. Experimenting with these can yield faster + * binaries. + */ + +/** \defgroup porting Porting Guide for New Versions + * + * This module describes differences in the library interfaces from + * version to version. It assists in the porting of code that uses + * the libraries to newer versions of FLAC. + * + * One simple facility for making porting easier that has been added + * in FLAC 1.1.3 is a set of \c #defines in \c export.h of each + * library's includes (e.g. \c include/FLAC/export.h). The + * \c #defines mirror the libraries' + * <A HREF="http://www.gnu.org/software/libtool/manual.html#Libtool-versioning">libtool version numbers</A>, + * e.g. in libFLAC there are \c FLAC_API_VERSION_CURRENT, + * \c FLAC_API_VERSION_REVISION, and \c FLAC_API_VERSION_AGE. + * These can be used to support multiple versions of an API during the + * transition phase, e.g. + * + * \code + * #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7 + * legacy code + * #else + * new code + * #endif + * \endcode + * + * The the source will work for multiple versions and the legacy code can + * easily be removed when the transition is complete. + * + * Another available symbol is FLAC_API_SUPPORTS_OGG_FLAC (defined in + * include/FLAC/export.h), which can be used to determine whether or not + * the library has been compiled with support for Ogg FLAC. This is + * simpler than trying to call an Ogg init function and catching the + * error. + */ + +/** \defgroup porting_1_1_2_to_1_1_3 Porting from FLAC 1.1.2 to 1.1.3 + * \ingroup porting + * + * \brief + * This module describes porting from FLAC 1.1.2 to FLAC 1.1.3. + * + * The main change between the APIs in 1.1.2 and 1.1.3 is that they have + * been simplified. First, libOggFLAC has been merged into libFLAC and + * libOggFLAC++ has been merged into libFLAC++. Second, both the three + * decoding layers and three encoding layers have been merged into a + * single stream decoder and stream encoder. That is, the functionality + * of FLAC__SeekableStreamDecoder and FLAC__FileDecoder has been merged + * into FLAC__StreamDecoder, and FLAC__SeekableStreamEncoder and + * FLAC__FileEncoder into FLAC__StreamEncoder. Only the + * FLAC__StreamDecoder and FLAC__StreamEncoder remain. What this means + * is there is now a single API that can be used to encode or decode + * streams to/from native FLAC or Ogg FLAC and the single API can work + * on both seekable and non-seekable streams. + * + * Instead of creating an encoder or decoder of a certain layer, now the + * client will always create a FLAC__StreamEncoder or + * FLAC__StreamDecoder. The old layers are now differentiated by the + * initialization function. For example, for the decoder, + * FLAC__stream_decoder_init() has been replaced by + * FLAC__stream_decoder_init_stream(). This init function takes + * callbacks for the I/O, and the seeking callbacks are optional. This + * allows the client to use the same object for seekable and + * non-seekable streams. For decoding a FLAC file directly, the client + * can use FLAC__stream_decoder_init_file() and pass just a filename + * and fewer callbacks; most of the other callbacks are supplied + * internally. For situations where fopen()ing by filename is not + * possible (e.g. Unicode filenames on Windows) the client can instead + * open the file itself and supply the FILE* to + * FLAC__stream_decoder_init_FILE(). The init functions now returns a + * FLAC__StreamDecoderInitStatus instead of FLAC__StreamDecoderState. + * Since the callbacks and client data are now passed to the init + * function, the FLAC__stream_decoder_set_*_callback() functions and + * FLAC__stream_decoder_set_client_data() are no longer needed. The + * rest of the calls to the decoder are the same as before. + * + * There are counterpart init functions for Ogg FLAC, e.g. + * FLAC__stream_decoder_init_ogg_stream(). All the rest of the calls + * and callbacks are the same as for native FLAC. + * + * As an example, in FLAC 1.1.2 a seekable stream decoder would have + * been set up like so: + * + * \code + * FLAC__SeekableStreamDecoder *decoder = FLAC__seekable_stream_decoder_new(); + * if(decoder == NULL) do_something; + * FLAC__seekable_stream_decoder_set_md5_checking(decoder, true); + * [... other settings ...] + * FLAC__seekable_stream_decoder_set_read_callback(decoder, my_read_callback); + * FLAC__seekable_stream_decoder_set_seek_callback(decoder, my_seek_callback); + * FLAC__seekable_stream_decoder_set_tell_callback(decoder, my_tell_callback); + * FLAC__seekable_stream_decoder_set_length_callback(decoder, my_length_callback); + * FLAC__seekable_stream_decoder_set_eof_callback(decoder, my_eof_callback); + * FLAC__seekable_stream_decoder_set_write_callback(decoder, my_write_callback); + * FLAC__seekable_stream_decoder_set_metadata_callback(decoder, my_metadata_callback); + * FLAC__seekable_stream_decoder_set_error_callback(decoder, my_error_callback); + * FLAC__seekable_stream_decoder_set_client_data(decoder, my_client_data); + * if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) do_something; + * \endcode + * + * In FLAC 1.1.3 it is like this: + * + * \code + * FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new(); + * if(decoder == NULL) do_something; + * FLAC__stream_decoder_set_md5_checking(decoder, true); + * [... other settings ...] + * if(FLAC__stream_decoder_init_stream( + * decoder, + * my_read_callback, + * my_seek_callback, // or NULL + * my_tell_callback, // or NULL + * my_length_callback, // or NULL + * my_eof_callback, // or NULL + * my_write_callback, + * my_metadata_callback, // or NULL + * my_error_callback, + * my_client_data + * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; + * \endcode + * + * or you could do; + * + * \code + * [...] + * FILE *file = fopen("somefile.flac","rb"); + * if(file == NULL) do_somthing; + * if(FLAC__stream_decoder_init_FILE( + * decoder, + * file, + * my_write_callback, + * my_metadata_callback, // or NULL + * my_error_callback, + * my_client_data + * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; + * \endcode + * + * or just: + * + * \code + * [...] + * if(FLAC__stream_decoder_init_file( + * decoder, + * "somefile.flac", + * my_write_callback, + * my_metadata_callback, // or NULL + * my_error_callback, + * my_client_data + * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; + * \endcode + * + * Another small change to the decoder is in how it handles unparseable + * streams. Before, when the decoder found an unparseable stream + * (reserved for when the decoder encounters a stream from a future + * encoder that it can't parse), it changed the state to + * \c FLAC__STREAM_DECODER_UNPARSEABLE_STREAM. Now the decoder instead + * drops sync and calls the error callback with a new error code + * \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM. This is + * more robust. If your error callback does not discriminate on the the + * error state, your code does not need to be changed. + * + * The encoder now has a new setting: + * FLAC__stream_encoder_set_apodization(). This is for setting the + * method used to window the data before LPC analysis. You only need to + * add a call to this function if the default is not suitable. There + * are also two new convenience functions that may be useful: + * FLAC__metadata_object_cuesheet_calculate_cddb_id() and + * FLAC__metadata_get_cuesheet(). + * + * The \a bytes parameter to FLAC__StreamDecoderReadCallback, + * FLAC__StreamEncoderReadCallback, and FLAC__StreamEncoderWriteCallback + * is now \c size_t instead of \c unsigned. + */ + +/** \defgroup porting_1_1_3_to_1_1_4 Porting from FLAC 1.1.3 to 1.1.4 + * \ingroup porting + * + * \brief + * This module describes porting from FLAC 1.1.3 to FLAC 1.1.4. + * + * There were no changes to any of the interfaces from 1.1.3 to 1.1.4. + * There was a slight change in the implementation of + * FLAC__stream_encoder_set_metadata(); the function now makes a copy + * of the \a metadata array of pointers so the client no longer needs + * to maintain it after the call. The objects themselves that are + * pointed to by the array are still not copied though and must be + * maintained until the call to FLAC__stream_encoder_finish(). + */ + +/** \defgroup porting_1_1_4_to_1_2_0 Porting from FLAC 1.1.4 to 1.2.0 + * \ingroup porting + * + * \brief + * This module describes porting from FLAC 1.1.4 to FLAC 1.2.0. + * + * There were only very minor changes to the interfaces from 1.1.4 to 1.2.0. + * In libFLAC, \c FLAC__format_sample_rate_is_subset() was added. + * In libFLAC++, \c FLAC::Decoder::Stream::get_decode_position() was added. + * + * Finally, value of the constant \c FLAC__FRAME_HEADER_RESERVED_LEN + * has changed to reflect the conversion of one of the reserved bits + * into active use. It used to be \c 2 and now is \c 1. However the + * FLAC frame header length has not changed, so to skip the proper + * number of bits, use \c FLAC__FRAME_HEADER_RESERVED_LEN + + * \c FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN + */ + +/** \defgroup flac FLAC C API + * + * The FLAC C API is the interface to libFLAC, a set of structures + * describing the components of FLAC streams, and functions for + * encoding and decoding streams, as well as manipulating FLAC + * metadata in files. + * + * You should start with the format components as all other modules + * are dependent on it. + */ + +#endif diff --git a/include/FLAC/assert.h b/include/FLAC/assert.h new file mode 100644 index 00000000..3fc03f31 --- /dev/null +++ b/include/FLAC/assert.h @@ -0,0 +1,45 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__ASSERT_H +#define FLAC__ASSERT_H + +/* we need this since some compilers (like MSVC) leave assert()s on release code (and we don't want to use their ASSERT) */ +#ifdef DEBUG +#include <assert.h> +#define FLAC__ASSERT(x) assert(x) +#define FLAC__ASSERT_DECLARATION(x) x +#else +#define FLAC__ASSERT(x) +#define FLAC__ASSERT_DECLARATION(x) +#endif + +#endif diff --git a/include/FLAC/callback.h b/include/FLAC/callback.h new file mode 100644 index 00000000..c9541210 --- /dev/null +++ b/include/FLAC/callback.h @@ -0,0 +1,184 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2004,2005,2006,2007 Josh Coalson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__CALLBACK_H +#define FLAC__CALLBACK_H + +#include "ordinals.h" +#include <stdlib.h> /* for size_t */ + +/** \file include/FLAC/callback.h + * + * \brief + * This module defines the structures for describing I/O callbacks + * to the other FLAC interfaces. + * + * See the detailed documentation for callbacks in the + * \link flac_callbacks callbacks \endlink module. + */ + +/** \defgroup flac_callbacks FLAC/callback.h: I/O callback structures + * \ingroup flac + * + * \brief + * This module defines the structures for describing I/O callbacks + * to the other FLAC interfaces. + * + * The purpose of the I/O callback functions is to create a common way + * for the metadata interfaces to handle I/O. + * + * Originally the metadata interfaces required filenames as the way of + * specifying FLAC files to operate on. This is problematic in some + * environments so there is an additional option to specify a set of + * callbacks for doing I/O on the FLAC file, instead of the filename. + * + * In addition to the callbacks, a FLAC__IOHandle type is defined as an + * opaque structure for a data source. + * + * The callback function prototypes are similar (but not identical) to the + * stdio functions fread, fwrite, fseek, ftell, feof, and fclose. If you use + * stdio streams to implement the callbacks, you can pass fread, fwrite, and + * fclose anywhere a FLAC__IOCallback_Read, FLAC__IOCallback_Write, or + * FLAC__IOCallback_Close is required, and a FILE* anywhere a FLAC__IOHandle + * is required. \warning You generally CANNOT directly use fseek or ftell + * for FLAC__IOCallback_Seek or FLAC__IOCallback_Tell since on most systems + * these use 32-bit offsets and FLAC requires 64-bit offsets to deal with + * large files. You will have to find an equivalent function (e.g. ftello), + * or write a wrapper. The same is true for feof() since this is usually + * implemented as a macro, not as a function whose address can be taken. + * + * \{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** This is the opaque handle type used by the callbacks. Typically + * this is a \c FILE* or address of a file descriptor. + */ +typedef void* FLAC__IOHandle; + +/** Signature for the read callback. + * The signature and semantics match POSIX fread() implementations + * and can generally be used interchangeably. + * + * \param ptr The address of the read buffer. + * \param size The size of the records to be read. + * \param nmemb The number of records to be read. + * \param handle The handle to the data source. + * \retval size_t + * The number of records read. + */ +typedef size_t (*FLAC__IOCallback_Read) (void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); + +/** Signature for the write callback. + * The signature and semantics match POSIX fwrite() implementations + * and can generally be used interchangeably. + * + * \param ptr The address of the write buffer. + * \param size The size of the records to be written. + * \param nmemb The number of records to be written. + * \param handle The handle to the data source. + * \retval size_t + * The number of records written. + */ +typedef size_t (*FLAC__IOCallback_Write) (const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); + +/** Signature for the seek callback. + * The signature and semantics mostly match POSIX fseek() WITH ONE IMPORTANT + * EXCEPTION: the offset is a 64-bit type whereas fseek() is generally 'long' + * and 32-bits wide. + * + * \param handle The handle to the data source. + * \param offset The new position, relative to \a whence + * \param whence \c SEEK_SET, \c SEEK_CUR, or \c SEEK_END + * \retval int + * \c 0 on success, \c -1 on error. + */ +typedef int (*FLAC__IOCallback_Seek) (FLAC__IOHandle handle, FLAC__int64 offset, int whence); + +/** Signature for the tell callback. + * The signature and semantics mostly match POSIX ftell() WITH ONE IMPORTANT + * EXCEPTION: the offset is a 64-bit type whereas ftell() is generally 'long' + * and 32-bits wide. + * + * \param handle The handle to the data source. + * \retval FLAC__int64 + * The current position on success, \c -1 on error. + */ +typedef FLAC__int64 (*FLAC__IOCallback_Tell) (FLAC__IOHandle handle); + +/** Signature for the EOF callback. + * The signature and semantics mostly match POSIX feof() but WATCHOUT: + * on many systems, feof() is a macro, so in this case a wrapper function + * must be provided instead. + * + * \param handle The handle to the data source. + * \retval int + * \c 0 if not at end of file, nonzero if at end of file. + */ +typedef int (*FLAC__IOCallback_Eof) (FLAC__IOHandle handle); + +/** Signature for the close callback. + * The signature and semantics match POSIX fclose() implementations + * and can generally be used interchangeably. + * + * \param handle The handle to the data source. + * \retval int + * \c 0 on success, \c EOF on error. + */ +typedef int (*FLAC__IOCallback_Close) (FLAC__IOHandle handle); + +/** A structure for holding a set of callbacks. + * Each FLAC interface that requires a FLAC__IOCallbacks structure will + * describe which of the callbacks are required. The ones that are not + * required may be set to NULL. + * + * If the seek requirement for an interface is optional, you can signify that + * a data sorce is not seekable by setting the \a seek field to \c NULL. + */ +typedef struct { + FLAC__IOCallback_Read read; + FLAC__IOCallback_Write write; + FLAC__IOCallback_Seek seek; + FLAC__IOCallback_Tell tell; + FLAC__IOCallback_Eof eof; + FLAC__IOCallback_Close close; +} FLAC__IOCallbacks; + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/FLAC/export.h b/include/FLAC/export.h new file mode 100644 index 00000000..a525f29c --- /dev/null +++ b/include/FLAC/export.h @@ -0,0 +1,91 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__EXPORT_H +#define FLAC__EXPORT_H + +/** \file include/FLAC/export.h + * + * \brief + * This module contains #defines and symbols for exporting function + * calls, and providing version information and compiled-in features. + * + * See the \link flac_export export \endlink module. + */ + +/** \defgroup flac_export FLAC/export.h: export symbols + * \ingroup flac + * + * \brief + * This module contains #defines and symbols for exporting function + * calls, and providing version information and compiled-in features. + * + * If you are compiling with MSVC and will link to the static library + * (libFLAC.lib) you should define FLAC__NO_DLL in your project to + * make sure the symbols are exported properly. + * + * \{ + */ + +#if defined(FLAC__NO_DLL) || !defined(_MSC_VER) +#define FLAC_API + +#else + +#ifdef FLAC_API_EXPORTS +#define FLAC_API _declspec(dllexport) +#else +#define FLAC_API _declspec(dllimport) + +#endif +#endif + +/** These #defines will mirror the libtool-based library version number, see + * http://www.gnu.org/software/libtool/manual.html#Libtool-versioning + */ +#define FLAC_API_VERSION_CURRENT 10 +#define FLAC_API_VERSION_REVISION 0 /**< see above */ +#define FLAC_API_VERSION_AGE 2 /**< see above */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \c 1 if the library has been compiled with support for Ogg FLAC, else \c 0. */ +extern FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC; + +#ifdef __cplusplus +} +#endif + +/* \} */ + +#endif diff --git a/include/FLAC/format.h b/include/FLAC/format.h new file mode 100644 index 00000000..77e2d013 --- /dev/null +++ b/include/FLAC/format.h @@ -0,0 +1,1010 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__FORMAT_H +#define FLAC__FORMAT_H + +#include "export.h" +#include "ordinals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file include/FLAC/format.h + * + * \brief + * This module contains structure definitions for the representation + * of FLAC format components in memory. These are the basic + * structures used by the rest of the interfaces. + * + * See the detailed documentation in the + * \link flac_format format \endlink module. + */ + +/** \defgroup flac_format FLAC/format.h: format components + * \ingroup flac + * + * \brief + * This module contains structure definitions for the representation + * of FLAC format components in memory. These are the basic + * structures used by the rest of the interfaces. + * + * First, you should be familiar with the + * <A HREF="../format.html">FLAC format</A>. Many of the values here + * follow directly from the specification. As a user of libFLAC, the + * interesting parts really are the structures that describe the frame + * header and metadata blocks. + * + * The format structures here are very primitive, designed to store + * information in an efficient way. Reading information from the + * structures is easy but creating or modifying them directly is + * more complex. For the most part, as a user of a library, editing + * is not necessary; however, for metadata blocks it is, so there are + * convenience functions provided in the \link flac_metadata metadata + * module \endlink to simplify the manipulation of metadata blocks. + * + * \note + * It's not the best convention, but symbols ending in _LEN are in bits + * and _LENGTH are in bytes. _LENGTH symbols are \#defines instead of + * global variables because they are usually used when declaring byte + * arrays and some compilers require compile-time knowledge of array + * sizes when declared on the stack. + * + * \{ + */ + + +/* + Most of the values described in this file are defined by the FLAC + format specification. There is nothing to tune here. +*/ + +/** The largest legal metadata type code. */ +#define FLAC__MAX_METADATA_TYPE_CODE (126u) + +/** The minimum block size, in samples, permitted by the format. */ +#define FLAC__MIN_BLOCK_SIZE (16u) + +/** The maximum block size, in samples, permitted by the format. */ +#define FLAC__MAX_BLOCK_SIZE (65535u) + +/** The maximum block size, in samples, permitted by the FLAC subset for + * sample rates up to 48kHz. */ +#define FLAC__SUBSET_MAX_BLOCK_SIZE_48000HZ (4608u) + +/** The maximum number of channels permitted by the format. */ +#define FLAC__MAX_CHANNELS (8u) + +/** The minimum sample resolution permitted by the format. */ +#define FLAC__MIN_BITS_PER_SAMPLE (4u) + +/** The maximum sample resolution permitted by the format. */ +#define FLAC__MAX_BITS_PER_SAMPLE (32u) + +/** The maximum sample resolution permitted by libFLAC. + * + * \warning + * FLAC__MAX_BITS_PER_SAMPLE is the limit of the FLAC format. However, + * the reference encoder/decoder is currently limited to 24 bits because + * of prevalent 32-bit math, so make sure and use this value when + * appropriate. + */ +#define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (24u) + +/** The maximum sample rate permitted by the format. The value is + * ((2 ^ 16) - 1) * 10; see <A HREF="../format.html">FLAC format</A> + * as to why. + */ +#define FLAC__MAX_SAMPLE_RATE (655350u) + +/** The maximum LPC order permitted by the format. */ +#define FLAC__MAX_LPC_ORDER (32u) + +/** The maximum LPC order permitted by the FLAC subset for sample rates + * up to 48kHz. */ +#define FLAC__SUBSET_MAX_LPC_ORDER_48000HZ (12u) + +/** The minimum quantized linear predictor coefficient precision + * permitted by the format. + */ +#define FLAC__MIN_QLP_COEFF_PRECISION (5u) + +/** The maximum quantized linear predictor coefficient precision + * permitted by the format. + */ +#define FLAC__MAX_QLP_COEFF_PRECISION (15u) + +/** The maximum order of the fixed predictors permitted by the format. */ +#define FLAC__MAX_FIXED_ORDER (4u) + +/** The maximum Rice partition order permitted by the format. */ +#define FLAC__MAX_RICE_PARTITION_ORDER (15u) + +/** The maximum Rice partition order permitted by the FLAC Subset. */ +#define FLAC__SUBSET_MAX_RICE_PARTITION_ORDER (8u) + +/** The version string of the release, stamped onto the libraries and binaries. + * + * \note + * This does not correspond to the shared library version number, which + * is used to determine binary compatibility. + */ +extern FLAC_API const char *FLAC__VERSION_STRING; + +/** The vendor string inserted by the encoder into the VORBIS_COMMENT block. + * This is a NUL-terminated ASCII string; when inserted into the + * VORBIS_COMMENT the trailing null is stripped. + */ +extern FLAC_API const char *FLAC__VENDOR_STRING; + +/** The byte string representation of the beginning of a FLAC stream. */ +extern FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4]; /* = "fLaC" */ + +/** The 32-bit integer big-endian representation of the beginning of + * a FLAC stream. + */ +extern FLAC_API const unsigned FLAC__STREAM_SYNC; /* = 0x664C6143 */ + +/** The length of the FLAC signature in bits. */ +extern FLAC_API const unsigned FLAC__STREAM_SYNC_LEN; /* = 32 bits */ + +/** The length of the FLAC signature in bytes. */ +#define FLAC__STREAM_SYNC_LENGTH (4u) + + +/***************************************************************************** + * + * Subframe structures + * + *****************************************************************************/ + +/*****************************************************************************/ + +/** An enumeration of the available entropy coding methods. */ +typedef enum { + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0, + /**< Residual is coded by partitioning into contexts, each with it's own + * 4-bit Rice parameter. */ + + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 = 1 + /**< Residual is coded by partitioning into contexts, each with it's own + * 5-bit Rice parameter. */ +} FLAC__EntropyCodingMethodType; + +/** Maps a FLAC__EntropyCodingMethodType to a C string. + * + * Using a FLAC__EntropyCodingMethodType as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[]; + + +/** Contents of a Rice partitioned residual + */ +typedef struct { + + unsigned *parameters; + /**< The Rice parameters for each context. */ + + unsigned *raw_bits; + /**< Widths for escape-coded partitions. Will be non-zero for escaped + * partitions and zero for unescaped partitions. + */ + + unsigned capacity_by_order; + /**< The capacity of the \a parameters and \a raw_bits arrays + * specified as an order, i.e. the number of array elements + * allocated is 2 ^ \a capacity_by_order. + */ +} FLAC__EntropyCodingMethod_PartitionedRiceContents; + +/** Header for a Rice partitioned residual. (c.f. <A HREF="../format.html#partitioned_rice">format specification</A>) + */ +typedef struct { + + unsigned order; + /**< The partition order, i.e. # of contexts = 2 ^ \a order. */ + + const FLAC__EntropyCodingMethod_PartitionedRiceContents *contents; + /**< The context's Rice parameters and/or raw bits. */ + +} FLAC__EntropyCodingMethod_PartitionedRice; + +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN; /**< == 5 (bits) */ +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN; /**< == 5 (bits) */ + +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; +/**< == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */ +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER; +/**< == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */ + +/** Header for the entropy coding method. (c.f. <A HREF="../format.html#residual">format specification</A>) + */ +typedef struct { + FLAC__EntropyCodingMethodType type; + union { + FLAC__EntropyCodingMethod_PartitionedRice partitioned_rice; + } data; +} FLAC__EntropyCodingMethod; + +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN; /**< == 2 (bits) */ + +/*****************************************************************************/ + +/** An enumeration of the available subframe types. */ +typedef enum { + FLAC__SUBFRAME_TYPE_CONSTANT = 0, /**< constant signal */ + FLAC__SUBFRAME_TYPE_VERBATIM = 1, /**< uncompressed signal */ + FLAC__SUBFRAME_TYPE_FIXED = 2, /**< fixed polynomial prediction */ + FLAC__SUBFRAME_TYPE_LPC = 3 /**< linear prediction */ +} FLAC__SubframeType; + +/** Maps a FLAC__SubframeType to a C string. + * + * Using a FLAC__SubframeType as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__SubframeTypeString[]; + + +/** CONSTANT subframe. (c.f. <A HREF="../format.html#subframe_constant">format specification</A>) + */ +typedef struct { + FLAC__int32 value; /**< The constant signal value. */ +} FLAC__Subframe_Constant; + + +/** VERBATIM subframe. (c.f. <A HREF="../format.html#subframe_verbatim">format specification</A>) + */ +typedef struct { + const FLAC__int32 *data; /**< A pointer to verbatim signal. */ +} FLAC__Subframe_Verbatim; + + +/** FIXED subframe. (c.f. <A HREF="../format.html#subframe_fixed">format specification</A>) + */ +typedef struct { + FLAC__EntropyCodingMethod entropy_coding_method; + /**< The residual coding method. */ + + unsigned order; + /**< The polynomial order. */ + + FLAC__int32 warmup[FLAC__MAX_FIXED_ORDER]; + /**< Warmup samples to prime the predictor, length == order. */ + + const FLAC__int32 *residual; + /**< The residual signal, length == (blocksize minus order) samples. */ +} FLAC__Subframe_Fixed; + + +/** LPC subframe. (c.f. <A HREF="../format.html#subframe_lpc">format specification</A>) + */ +typedef struct { + FLAC__EntropyCodingMethod entropy_coding_method; + /**< The residual coding method. */ + + unsigned order; + /**< The FIR order. */ + + unsigned qlp_coeff_precision; + /**< Quantized FIR filter coefficient precision in bits. */ + + int quantization_level; + /**< The qlp coeff shift needed. */ + + FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; + /**< FIR filter coefficients. */ + + FLAC__int32 warmup[FLAC__MAX_LPC_ORDER]; + /**< Warmup samples to prime the predictor, length == order. */ + + const FLAC__int32 *residual; + /**< The residual signal, length == (blocksize minus order) samples. */ +} FLAC__Subframe_LPC; + +extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN; /**< == 5 (bits) */ + + +/** FLAC subframe structure. (c.f. <A HREF="../format.html#subframe">format specification</A>) + */ +typedef struct { + FLAC__SubframeType type; + union { + FLAC__Subframe_Constant constant; + FLAC__Subframe_Fixed fixed; + FLAC__Subframe_LPC lpc; + FLAC__Subframe_Verbatim verbatim; + } data; + unsigned wasted_bits; +} FLAC__Subframe; + +/** == 1 (bit) + * + * This used to be a zero-padding bit (hence the name + * FLAC__SUBFRAME_ZERO_PAD_LEN) but is now a reserved bit. It still has a + * mandatory value of \c 0 but in the future may take on the value \c 0 or \c 1 + * to mean something else. + */ +extern FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN; +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN; /**< == 6 (bits) */ +extern FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN; /**< == 1 (bit) */ + +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK; /**< = 0x00 */ +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK; /**< = 0x02 */ +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK; /**< = 0x10 */ +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK; /**< = 0x40 */ + +/*****************************************************************************/ + + +/***************************************************************************** + * + * Frame structures + * + *****************************************************************************/ + +/** An enumeration of the available channel assignments. */ +typedef enum { + FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT = 0, /**< independent channels */ + FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE = 1, /**< left+side stereo */ + FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE = 2, /**< right+side stereo */ + FLAC__CHANNEL_ASSIGNMENT_MID_SIDE = 3 /**< mid+side stereo */ +} FLAC__ChannelAssignment; + +/** Maps a FLAC__ChannelAssignment to a C string. + * + * Using a FLAC__ChannelAssignment as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__ChannelAssignmentString[]; + +/** An enumeration of the possible frame numbering methods. */ +typedef enum { + FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER, /**< number contains the frame number */ + FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER /**< number contains the sample number of first sample in frame */ +} FLAC__FrameNumberType; + +/** Maps a FLAC__FrameNumberType to a C string. + * + * Using a FLAC__FrameNumberType as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__FrameNumberTypeString[]; + + +/** FLAC frame header structure. (c.f. <A HREF="../format.html#frame_header">format specification</A>) + */ +typedef struct { + unsigned blocksize; + /**< The number of samples per subframe. */ + + unsigned sample_rate; + /**< The sample rate in Hz. */ + + unsigned channels; + /**< The number of channels (== number of subframes). */ + + FLAC__ChannelAssignment channel_assignment; + /**< The channel assignment for the frame. */ + + unsigned bits_per_sample; + /**< The sample resolution. */ + + FLAC__FrameNumberType number_type; + /**< The numbering scheme used for the frame. As a convenience, the + * decoder will always convert a frame number to a sample number because + * the rules are complex. */ + + union { + FLAC__uint32 frame_number; + FLAC__uint64 sample_number; + } number; + /**< The frame number or sample number of first sample in frame; + * use the \a number_type value to determine which to use. */ + + FLAC__uint8 crc; + /**< CRC-8 (polynomial = x^8 + x^2 + x^1 + x^0, initialized with 0) + * of the raw frame header bytes, meaning everything before the CRC byte + * including the sync code. + */ +} FLAC__FrameHeader; + +extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC; /**< == 0x3ffe; the frame header sync code */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN; /**< == 14 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN; /**< == 1 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN; /**< == 1 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN; /**< == 3 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN; /**< == 8 (bits) */ + + +/** FLAC frame footer structure. (c.f. <A HREF="../format.html#frame_footer">format specification</A>) + */ +typedef struct { + FLAC__uint16 crc; + /**< CRC-16 (polynomial = x^16 + x^15 + x^2 + x^0, initialized with + * 0) of the bytes before the crc, back to and including the frame header + * sync code. + */ +} FLAC__FrameFooter; + +extern FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN; /**< == 16 (bits) */ + + +/** FLAC frame structure. (c.f. <A HREF="../format.html#frame">format specification</A>) + */ +typedef struct { + FLAC__FrameHeader header; + FLAC__Subframe subframes[FLAC__MAX_CHANNELS]; + FLAC__FrameFooter footer; +} FLAC__Frame; + +/*****************************************************************************/ + + +/***************************************************************************** + * + * Meta-data structures + * + *****************************************************************************/ + +/** An enumeration of the available metadata block types. */ +typedef enum { + + FLAC__METADATA_TYPE_STREAMINFO = 0, + /**< <A HREF="../format.html#metadata_block_streaminfo">STREAMINFO</A> block */ + + FLAC__METADATA_TYPE_PADDING = 1, + /**< <A HREF="../format.html#metadata_block_padding">PADDING</A> block */ + + FLAC__METADATA_TYPE_APPLICATION = 2, + /**< <A HREF="../format.html#metadata_block_application">APPLICATION</A> block */ + + FLAC__METADATA_TYPE_SEEKTABLE = 3, + /**< <A HREF="../format.html#metadata_block_seektable">SEEKTABLE</A> block */ + + FLAC__METADATA_TYPE_VORBIS_COMMENT = 4, + /**< <A HREF="../format.html#metadata_block_vorbis_comment">VORBISCOMMENT</A> block (a.k.a. FLAC tags) */ + + FLAC__METADATA_TYPE_CUESHEET = 5, + /**< <A HREF="../format.html#metadata_block_cuesheet">CUESHEET</A> block */ + + FLAC__METADATA_TYPE_PICTURE = 6, + /**< <A HREF="../format.html#metadata_block_picture">PICTURE</A> block */ + + FLAC__METADATA_TYPE_UNDEFINED = 7 + /**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */ + +} FLAC__MetadataType; + +/** Maps a FLAC__MetadataType to a C string. + * + * Using a FLAC__MetadataType as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__MetadataTypeString[]; + + +/** FLAC STREAMINFO structure. (c.f. <A HREF="../format.html#metadata_block_streaminfo">format specification</A>) + */ +typedef struct { + unsigned min_blocksize, max_blocksize; + unsigned min_framesize, max_framesize; + unsigned sample_rate; + unsigned channels; + unsigned bits_per_sample; + FLAC__uint64 total_samples; + FLAC__byte md5sum[16]; +} FLAC__StreamMetadata_StreamInfo; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN; /**< == 16 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN; /**< == 16 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN; /**< == 24 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN; /**< == 24 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN; /**< == 20 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN; /**< == 3 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN; /**< == 5 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN; /**< == 36 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN; /**< == 128 (bits) */ + +/** The total stream length of the STREAMINFO block in bytes. */ +#define FLAC__STREAM_METADATA_STREAMINFO_LENGTH (34u) + +/** FLAC PADDING structure. (c.f. <A HREF="../format.html#metadata_block_padding">format specification</A>) + */ +typedef struct { + int dummy; + /**< Conceptually this is an empty struct since we don't store the + * padding bytes. Empty structs are not allowed by some C compilers, + * hence the dummy. + */ +} FLAC__StreamMetadata_Padding; + + +/** FLAC APPLICATION structure. (c.f. <A HREF="../format.html#metadata_block_application">format specification</A>) + */ +typedef struct { + FLAC__byte id[4]; + FLAC__byte *data; +} FLAC__StreamMetadata_Application; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN; /**< == 32 (bits) */ + +/** SeekPoint structure used in SEEKTABLE blocks. (c.f. <A HREF="../format.html#seekpoint">format specification</A>) + */ +typedef struct { + FLAC__uint64 sample_number; + /**< The sample number of the target frame. */ + + FLAC__uint64 stream_offset; + /**< The offset, in bytes, of the target frame with respect to + * beginning of the first frame. */ + + unsigned frame_samples; + /**< The number of samples in the target frame. */ +} FLAC__StreamMetadata_SeekPoint; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN; /**< == 16 (bits) */ + +/** The total stream length of a seek point in bytes. */ +#define FLAC__STREAM_METADATA_SEEKPOINT_LENGTH (18u) + +/** The value used in the \a sample_number field of + * FLAC__StreamMetadataSeekPoint used to indicate a placeholder + * point (== 0xffffffffffffffff). + */ +extern FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; + + +/** FLAC SEEKTABLE structure. (c.f. <A HREF="../format.html#metadata_block_seektable">format specification</A>) + * + * \note From the format specification: + * - The seek points must be sorted by ascending sample number. + * - Each seek point's sample number must be the first sample of the + * target frame. + * - Each seek point's sample number must be unique within the table. + * - Existence of a SEEKTABLE block implies a correct setting of + * total_samples in the stream_info block. + * - Behavior is undefined when more than one SEEKTABLE block is + * present in a stream. + */ +typedef struct { + unsigned num_points; + FLAC__StreamMetadata_SeekPoint *points; +} FLAC__StreamMetadata_SeekTable; + + +/** Vorbis comment entry structure used in VORBIS_COMMENT blocks. (c.f. <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>) + * + * For convenience, the APIs maintain a trailing NUL character at the end of + * \a entry which is not counted toward \a length, i.e. + * \code strlen(entry) == length \endcode + */ +typedef struct { + FLAC__uint32 length; + FLAC__byte *entry; +} FLAC__StreamMetadata_VorbisComment_Entry; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN; /**< == 32 (bits) */ + + +/** FLAC VORBIS_COMMENT structure. (c.f. <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>) + */ +typedef struct { + FLAC__StreamMetadata_VorbisComment_Entry vendor_string; + FLAC__uint32 num_comments; + FLAC__StreamMetadata_VorbisComment_Entry *comments; +} FLAC__StreamMetadata_VorbisComment; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN; /**< == 32 (bits) */ + + +/** FLAC CUESHEET track index structure. (See the + * <A HREF="../format.html#cuesheet_track_index">format specification</A> for + * the full description of each field.) + */ +typedef struct { + FLAC__uint64 offset; + /**< Offset in samples, relative to the track offset, of the index + * point. + */ + + FLAC__byte number; + /**< The index point number. */ +} FLAC__StreamMetadata_CueSheet_Index; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN; /**< == 8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN; /**< == 3*8 (bits) */ + + +/** FLAC CUESHEET track structure. (See the + * <A HREF="../format.html#cuesheet_track">format specification</A> for + * the full description of each field.) + */ +typedef struct { + FLAC__uint64 offset; + /**< Track offset in samples, relative to the beginning of the FLAC audio stream. */ + + FLAC__byte number; + /**< The track number. */ + + char isrc[13]; + /**< Track ISRC. This is a 12-digit alphanumeric code plus a trailing \c NUL byte */ + + unsigned type:1; + /**< The track type: 0 for audio, 1 for non-audio. */ + + unsigned pre_emphasis:1; + /**< The pre-emphasis flag: 0 for no pre-emphasis, 1 for pre-emphasis. */ + + FLAC__byte num_indices; + /**< The number of track index points. */ + + FLAC__StreamMetadata_CueSheet_Index *indices; + /**< NULL if num_indices == 0, else pointer to array of index points. */ + +} FLAC__StreamMetadata_CueSheet_Track; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN; /**< == 8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN; /**< == 12*8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN; /**< == 6+13*8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN; /**< == 8 (bits) */ + + +/** FLAC CUESHEET structure. (See the + * <A HREF="../format.html#metadata_block_cuesheet">format specification</A> + * for the full description of each field.) + */ +typedef struct { + char media_catalog_number[129]; + /**< Media catalog number, in ASCII printable characters 0x20-0x7e. In + * general, the media catalog number may be 0 to 128 bytes long; any + * unused characters should be right-padded with NUL characters. + */ + + FLAC__uint64 lead_in; + /**< The number of lead-in samples. */ + + FLAC__bool is_cd; + /**< \c true if CUESHEET corresponds to a Compact Disc, else \c false. */ + + unsigned num_tracks; + /**< The number of tracks. */ + + FLAC__StreamMetadata_CueSheet_Track *tracks; + /**< NULL if num_tracks == 0, else pointer to array of tracks. */ + +} FLAC__StreamMetadata_CueSheet; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN; /**< == 128*8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN; /**< == 7+258*8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN; /**< == 8 (bits) */ + + +/** An enumeration of the PICTURE types (see FLAC__StreamMetadataPicture and id3 v2.4 APIC tag). */ +typedef enum { + FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER = 0, /**< Other */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD = 1, /**< 32x32 pixels 'file icon' (PNG only) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON = 2, /**< Other file icon */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER = 3, /**< Cover (front) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER = 4, /**< Cover (back) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE = 5, /**< Leaflet page */ + FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA = 6, /**< Media (e.g. label side of CD) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST = 7, /**< Lead artist/lead performer/soloist */ + FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST = 8, /**< Artist/performer */ + FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR = 9, /**< Conductor */ + FLAC__STREAM_METADATA_PICTURE_TYPE_BAND = 10, /**< Band/Orchestra */ + FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER = 11, /**< Composer */ + FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST = 12, /**< Lyricist/text writer */ + FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION = 13, /**< Recording Location */ + FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING = 14, /**< During recording */ + FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE = 15, /**< During performance */ + FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE = 16, /**< Movie/video screen capture */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FISH = 17, /**< A bright coloured fish */ + FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION = 18, /**< Illustration */ + FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE = 19, /**< Band/artist logotype */ + FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE = 20, /**< Publisher/Studio logotype */ + FLAC__STREAM_METADATA_PICTURE_TYPE_UNDEFINED +} FLAC__StreamMetadata_Picture_Type; + +/** Maps a FLAC__StreamMetadata_Picture_Type to a C string. + * + * Using a FLAC__StreamMetadata_Picture_Type as the index to this array + * will give the string equivalent. The contents should not be + * modified. + */ +extern FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[]; + +/** FLAC PICTURE structure. (See the + * <A HREF="../format.html#metadata_block_picture">format specification</A> + * for the full description of each field.) + */ +typedef struct { + FLAC__StreamMetadata_Picture_Type type; + /**< The kind of picture stored. */ + + char *mime_type; + /**< Picture data's MIME type, in ASCII printable characters + * 0x20-0x7e, NUL terminated. For best compatibility with players, + * use picture data of MIME type \c image/jpeg or \c image/png. A + * MIME type of '-->' is also allowed, in which case the picture + * data should be a complete URL. In file storage, the MIME type is + * stored as a 32-bit length followed by the ASCII string with no NUL + * terminator, but is converted to a plain C string in this structure + * for convenience. + */ + + FLAC__byte *description; + /**< Picture's description in UTF-8, NUL terminated. In file storage, + * the description is stored as a 32-bit length followed by the UTF-8 + * string with no NUL terminator, but is converted to a plain C string + * in this structure for convenience. + */ + + FLAC__uint32 width; + /**< Picture's width in pixels. */ + + FLAC__uint32 height; + /**< Picture's height in pixels. */ + + FLAC__uint32 depth; + /**< Picture's color depth in bits-per-pixel. */ + + FLAC__uint32 colors; + /**< For indexed palettes (like GIF), picture's number of colors (the + * number of palette entries), or \c 0 for non-indexed (i.e. 2^depth). + */ + + FLAC__uint32 data_length; + /**< Length of binary picture data in bytes. */ + + FLAC__byte *data; + /**< Binary picture data. */ + +} FLAC__StreamMetadata_Picture; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN; /**< == 32 (bits) */ + + +/** Structure that is used when a metadata block of unknown type is loaded. + * The contents are opaque. The structure is used only internally to + * correctly handle unknown metadata. + */ +typedef struct { + FLAC__byte *data; +} FLAC__StreamMetadata_Unknown; + + +/** FLAC metadata block structure. (c.f. <A HREF="../format.html#metadata_block">format specification</A>) + */ +typedef struct { + FLAC__MetadataType type; + /**< The type of the metadata block; used determine which member of the + * \a data union to dereference. If type >= FLAC__METADATA_TYPE_UNDEFINED + * then \a data.unknown must be used. */ + + FLAC__bool is_last; + /**< \c true if this metadata block is the last, else \a false */ + + unsigned length; + /**< Length, in bytes, of the block data as it appears in the stream. */ + + union { + FLAC__StreamMetadata_StreamInfo stream_info; + FLAC__StreamMetadata_Padding padding; + FLAC__StreamMetadata_Application application; + FLAC__StreamMetadata_SeekTable seek_table; + FLAC__StreamMetadata_VorbisComment vorbis_comment; + FLAC__StreamMetadata_CueSheet cue_sheet; + FLAC__StreamMetadata_Picture picture; + FLAC__StreamMetadata_Unknown unknown; + } data; + /**< Polymorphic block data; use the \a type value to determine which + * to use. */ +} FLAC__StreamMetadata; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN; /**< == 7 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN; /**< == 24 (bits) */ + +/** The total stream length of a metadata block header in bytes. */ +#define FLAC__STREAM_METADATA_HEADER_LENGTH (4u) + +/*****************************************************************************/ + + +/***************************************************************************** + * + * Utility functions + * + *****************************************************************************/ + +/** Tests that a sample rate is valid for FLAC. + * + * \param sample_rate The sample rate to test for compliance. + * \retval FLAC__bool + * \c true if the given sample rate conforms to the specification, else + * \c false. + */ +FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate); + +/** Tests that a sample rate is valid for the FLAC subset. The subset rules + * for valid sample rates are slightly more complex since the rate has to + * be expressible completely in the frame header. + * + * \param sample_rate The sample rate to test for compliance. + * \retval FLAC__bool + * \c true if the given sample rate conforms to the specification for the + * subset, else \c false. + */ +FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate); + +/** Check a Vorbis comment entry name to see if it conforms to the Vorbis + * comment specification. + * + * Vorbis comment names must be composed only of characters from + * [0x20-0x3C,0x3E-0x7D]. + * + * \param name A NUL-terminated string to be checked. + * \assert + * \code name != NULL \endcode + * \retval FLAC__bool + * \c false if entry name is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name); + +/** Check a Vorbis comment entry value to see if it conforms to the Vorbis + * comment specification. + * + * Vorbis comment values must be valid UTF-8 sequences. + * + * \param value A string to be checked. + * \param length A the length of \a value in bytes. May be + * \c (unsigned)(-1) to indicate that \a value is a plain + * UTF-8 NUL-terminated string. + * \assert + * \code value != NULL \endcode + * \retval FLAC__bool + * \c false if entry name is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length); + +/** Check a Vorbis comment entry to see if it conforms to the Vorbis + * comment specification. + * + * Vorbis comment entries must be of the form 'name=value', and 'name' and + * 'value' must be legal according to + * FLAC__format_vorbiscomment_entry_name_is_legal() and + * FLAC__format_vorbiscomment_entry_value_is_legal() respectively. + * + * \param entry An entry to be checked. + * \param length The length of \a entry in bytes. + * \assert + * \code value != NULL \endcode + * \retval FLAC__bool + * \c false if entry name is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length); + +/** Check a seek table to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * seek table. + * + * \param seek_table A pointer to a seek table to be checked. + * \assert + * \code seek_table != NULL \endcode + * \retval FLAC__bool + * \c false if seek table is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table); + +/** Sort a seek table's seek points according to the format specification. + * This includes a "unique-ification" step to remove duplicates, i.e. + * seek points with identical \a sample_number values. Duplicate seek + * points are converted into placeholder points and sorted to the end of + * the table. + * + * \param seek_table A pointer to a seek table to be sorted. + * \assert + * \code seek_table != NULL \endcode + * \retval unsigned + * The number of duplicate seek points converted into placeholders. + */ +FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table); + +/** Check a cue sheet to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * cue sheet. + * + * \param cue_sheet A pointer to an existing cue sheet to be checked. + * \param check_cd_da_subset If \c true, check CUESHEET against more + * stringent requirements for a CD-DA (audio) disc. + * \param violation Address of a pointer to a string. If there is a + * violation, a pointer to a string explanation of the + * violation will be returned here. \a violation may be + * \c NULL if you don't need the returned string. Do not + * free the returned string; it will always point to static + * data. + * \assert + * \code cue_sheet != NULL \endcode + * \retval FLAC__bool + * \c false if cue sheet is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation); + +/** Check picture data to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * PICTURE block. + * + * \param picture A pointer to existing picture data to be checked. + * \param violation Address of a pointer to a string. If there is a + * violation, a pointer to a string explanation of the + * violation will be returned here. \a violation may be + * \c NULL if you don't need the returned string. Do not + * free the returned string; it will always point to static + * data. + * \assert + * \code picture != NULL \endcode + * \retval FLAC__bool + * \c false if picture data is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/FLAC/metadata.h b/include/FLAC/metadata.h new file mode 100644 index 00000000..fff90b0b --- /dev/null +++ b/include/FLAC/metadata.h @@ -0,0 +1,2181 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__METADATA_H +#define FLAC__METADATA_H + +#include <sys/types.h> /* for off_t */ +#include "export.h" +#include "callback.h" +#include "format.h" + +/* -------------------------------------------------------------------- + (For an example of how all these routines are used, see the source + code for the unit tests in src/test_libFLAC/metadata_*.c, or + metaflac in src/metaflac/) + ------------------------------------------------------------------*/ + +/** \file include/FLAC/metadata.h + * + * \brief + * This module provides functions for creating and manipulating FLAC + * metadata blocks in memory, and three progressively more powerful + * interfaces for traversing and editing metadata in FLAC files. + * + * See the detailed documentation for each interface in the + * \link flac_metadata metadata \endlink module. + */ + +/** \defgroup flac_metadata FLAC/metadata.h: metadata interfaces + * \ingroup flac + * + * \brief + * This module provides functions for creating and manipulating FLAC + * metadata blocks in memory, and three progressively more powerful + * interfaces for traversing and editing metadata in native FLAC files. + * Note that currently only the Chain interface (level 2) supports Ogg + * FLAC files, and it is read-only i.e. no writing back changed + * metadata to file. + * + * There are three metadata interfaces of increasing complexity: + * + * Level 0: + * Read-only access to the STREAMINFO, VORBIS_COMMENT, CUESHEET, and + * PICTURE blocks. + * + * Level 1: + * Read-write access to all metadata blocks. This level is write- + * efficient in most cases (more on this below), and uses less memory + * than level 2. + * + * Level 2: + * Read-write access to all metadata blocks. This level is write- + * efficient in all cases, but uses more memory since all metadata for + * the whole file is read into memory and manipulated before writing + * out again. + * + * What do we mean by efficient? Since FLAC metadata appears at the + * beginning of the file, when writing metadata back to a FLAC file + * it is possible to grow or shrink the metadata such that the entire + * file must be rewritten. However, if the size remains the same during + * changes or PADDING blocks are utilized, only the metadata needs to be + * overwritten, which is much faster. + * + * Efficient means the whole file is rewritten at most one time, and only + * when necessary. Level 1 is not efficient only in the case that you + * cause more than one metadata block to grow or shrink beyond what can + * be accomodated by padding. In this case you should probably use level + * 2, which allows you to edit all the metadata for a file in memory and + * write it out all at once. + * + * All levels know how to skip over and not disturb an ID3v2 tag at the + * front of the file. + * + * All levels access files via their filenames. In addition, level 2 + * has additional alternative read and write functions that take an I/O + * handle and callbacks, for situations where access by filename is not + * possible. + * + * In addition to the three interfaces, this module defines functions for + * creating and manipulating various metadata objects in memory. As we see + * from the Format module, FLAC metadata blocks in memory are very primitive + * structures for storing information in an efficient way. Reading + * information from the structures is easy but creating or modifying them + * directly is more complex. The metadata object routines here facilitate + * this by taking care of the consistency and memory management drudgery. + * + * Unless you will be using the level 1 or 2 interfaces to modify existing + * metadata however, you will not probably not need these. + * + * From a dependency standpoint, none of the encoders or decoders require + * the metadata module. This is so that embedded users can strip out the + * metadata module from libFLAC to reduce the size and complexity. + */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \defgroup flac_metadata_level0 FLAC/metadata.h: metadata level 0 interface + * \ingroup flac_metadata + * + * \brief + * The level 0 interface consists of individual routines to read the + * STREAMINFO, VORBIS_COMMENT, CUESHEET, and PICTURE blocks, requiring + * only a filename. + * + * They try to skip any ID3v2 tag at the head of the file. + * + * \{ + */ + +/** Read the STREAMINFO metadata block of the given FLAC file. This function + * will try to skip any ID3v2 tag at the head of the file. + * + * \param filename The path to the FLAC file to read. + * \param streaminfo A pointer to space for the STREAMINFO block. Since + * FLAC__StreamMetadata is a simple structure with no + * memory allocation involved, you pass the address of + * an existing structure. It need not be initialized. + * \assert + * \code filename != NULL \endcode + * \code streaminfo != NULL \endcode + * \retval FLAC__bool + * \c true if a valid STREAMINFO block was read from \a filename. Returns + * \c false if there was a memory allocation error, a file decoder error, + * or the file contained no STREAMINFO block. (A memory allocation error + * is possible because this function must set up a file decoder.) + */ +FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo); + +/** Read the VORBIS_COMMENT metadata block of the given FLAC file. This + * function will try to skip any ID3v2 tag at the head of the file. + * + * \param filename The path to the FLAC file to read. + * \param tags The address where the returned pointer will be + * stored. The \a tags object must be deleted by + * the caller using FLAC__metadata_object_delete(). + * \assert + * \code filename != NULL \endcode + * \code tags != NULL \endcode + * \retval FLAC__bool + * \c true if a valid VORBIS_COMMENT block was read from \a filename, + * and \a *tags will be set to the address of the metadata structure. + * Returns \c false if there was a memory allocation error, a file + * decoder error, or the file contained no VORBIS_COMMENT block, and + * \a *tags will be set to \c NULL. + */ +FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags); + +/** Read the CUESHEET metadata block of the given FLAC file. This + * function will try to skip any ID3v2 tag at the head of the file. + * + * \param filename The path to the FLAC file to read. + * \param cuesheet The address where the returned pointer will be + * stored. The \a cuesheet object must be deleted by + * the caller using FLAC__metadata_object_delete(). + * \assert + * \code filename != NULL \endcode + * \code cuesheet != NULL \endcode + * \retval FLAC__bool + * \c true if a valid CUESHEET block was read from \a filename, + * and \a *cuesheet will be set to the address of the metadata + * structure. Returns \c false if there was a memory allocation + * error, a file decoder error, or the file contained no CUESHEET + * block, and \a *cuesheet will be set to \c NULL. + */ +FLAC_API FLAC__bool FLAC__metadata_get_cuesheet(const char *filename, FLAC__StreamMetadata **cuesheet); + +/** Read a PICTURE metadata block of the given FLAC file. This + * function will try to skip any ID3v2 tag at the head of the file. + * Since there can be more than one PICTURE block in a file, this + * function takes a number of parameters that act as constraints to + * the search. The PICTURE block with the largest area matching all + * the constraints will be returned, or \a *picture will be set to + * \c NULL if there was no such block. + * + * \param filename The path to the FLAC file to read. + * \param picture The address where the returned pointer will be + * stored. The \a picture object must be deleted by + * the caller using FLAC__metadata_object_delete(). + * \param type The desired picture type. Use \c -1 to mean + * "any type". + * \param mime_type The desired MIME type, e.g. "image/jpeg". The + * string will be matched exactly. Use \c NULL to + * mean "any MIME type". + * \param description The desired description. The string will be + * matched exactly. Use \c NULL to mean "any + * description". + * \param max_width The maximum width in pixels desired. Use + * \c (unsigned)(-1) to mean "any width". + * \param max_height The maximum height in pixels desired. Use + * \c (unsigned)(-1) to mean "any height". + * \param max_depth The maximum color depth in bits-per-pixel desired. + * Use \c (unsigned)(-1) to mean "any depth". + * \param max_colors The maximum number of colors desired. Use + * \c (unsigned)(-1) to mean "any number of colors". + * \assert + * \code filename != NULL \endcode + * \code picture != NULL \endcode + * \retval FLAC__bool + * \c true if a valid PICTURE block was read from \a filename, + * and \a *picture will be set to the address of the metadata + * structure. Returns \c false if there was a memory allocation + * error, a file decoder error, or the file contained no PICTURE + * block, and \a *picture will be set to \c NULL. + */ +FLAC_API FLAC__bool FLAC__metadata_get_picture(const char *filename, FLAC__StreamMetadata **picture, FLAC__StreamMetadata_Picture_Type type, const char *mime_type, const FLAC__byte *description, unsigned max_width, unsigned max_height, unsigned max_depth, unsigned max_colors); + +/* \} */ + + +/** \defgroup flac_metadata_level1 FLAC/metadata.h: metadata level 1 interface + * \ingroup flac_metadata + * + * \brief + * The level 1 interface provides read-write access to FLAC file metadata and + * operates directly on the FLAC file. + * + * The general usage of this interface is: + * + * - Create an iterator using FLAC__metadata_simple_iterator_new() + * - Attach it to a file using FLAC__metadata_simple_iterator_init() and check + * the exit code. Call FLAC__metadata_simple_iterator_is_writable() to + * see if the file is writable, or only read access is allowed. + * - Use FLAC__metadata_simple_iterator_next() and + * FLAC__metadata_simple_iterator_prev() to traverse the blocks. + * This is does not read the actual blocks themselves. + * FLAC__metadata_simple_iterator_next() is relatively fast. + * FLAC__metadata_simple_iterator_prev() is slower since it needs to search + * forward from the front of the file. + * - Use FLAC__metadata_simple_iterator_get_block_type() or + * FLAC__metadata_simple_iterator_get_block() to access the actual data at + * the current iterator position. The returned object is yours to modify + * and free. + * - Use FLAC__metadata_simple_iterator_set_block() to write a modified block + * back. You must have write permission to the original file. Make sure to + * read the whole comment to FLAC__metadata_simple_iterator_set_block() + * below. + * - Use FLAC__metadata_simple_iterator_insert_block_after() to add new blocks. + * Use the object creation functions from + * \link flac_metadata_object here \endlink to generate new objects. + * - Use FLAC__metadata_simple_iterator_delete_block() to remove the block + * currently referred to by the iterator, or replace it with padding. + * - Destroy the iterator with FLAC__metadata_simple_iterator_delete() when + * finished. + * + * \note + * The FLAC file remains open the whole time between + * FLAC__metadata_simple_iterator_init() and + * FLAC__metadata_simple_iterator_delete(), so make sure you are not altering + * the file during this time. + * + * \note + * Do not modify the \a is_last, \a length, or \a type fields of returned + * FLAC__StreamMetadata objects. These are managed automatically. + * + * \note + * If any of the modification functions + * (FLAC__metadata_simple_iterator_set_block(), + * FLAC__metadata_simple_iterator_delete_block(), + * FLAC__metadata_simple_iterator_insert_block_after(), etc.) return \c false, + * you should delete the iterator as it may no longer be valid. + * + * \{ + */ + +struct FLAC__Metadata_SimpleIterator; +/** The opaque structure definition for the level 1 iterator type. + * See the + * \link flac_metadata_level1 metadata level 1 module \endlink + * for a detailed description. + */ +typedef struct FLAC__Metadata_SimpleIterator FLAC__Metadata_SimpleIterator; + +/** Status type for FLAC__Metadata_SimpleIterator. + * + * The iterator's current status can be obtained by calling FLAC__metadata_simple_iterator_status(). + */ +typedef enum { + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK = 0, + /**< The iterator is in the normal OK state */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, + /**< The data passed into a function violated the function's usage criteria */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE, + /**< The iterator could not open the target file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE, + /**< The iterator could not find the FLAC signature at the start of the file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE, + /**< The iterator tried to write to a file that was not writable */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA, + /**< The iterator encountered input that does not conform to the FLAC metadata specification */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR, + /**< The iterator encountered an error while reading the FLAC file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, + /**< The iterator encountered an error while seeking in the FLAC file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR, + /**< The iterator encountered an error while writing the FLAC file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR, + /**< The iterator encountered an error renaming the FLAC file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR, + /**< The iterator encountered an error removing the temporary file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR, + /**< Memory allocation failed */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR + /**< The caller violated an assertion or an unexpected error occurred */ + +} FLAC__Metadata_SimpleIteratorStatus; + +/** Maps a FLAC__Metadata_SimpleIteratorStatus to a C string. + * + * Using a FLAC__Metadata_SimpleIteratorStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__Metadata_SimpleIteratorStatusString[]; + + +/** Create a new iterator instance. + * + * \retval FLAC__Metadata_SimpleIterator* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new(void); + +/** Free an iterator instance. Deletes the object pointed to by \a iterator. + * + * \param iterator A pointer to an existing iterator. + * \assert + * \code iterator != NULL \endcode + */ +FLAC_API void FLAC__metadata_simple_iterator_delete(FLAC__Metadata_SimpleIterator *iterator); + +/** Get the current status of the iterator. Call this after a function + * returns \c false to get the reason for the error. Also resets the status + * to FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK. + * + * \param iterator A pointer to an existing iterator. + * \assert + * \code iterator != NULL \endcode + * \retval FLAC__Metadata_SimpleIteratorStatus + * The current status of the iterator. + */ +FLAC_API FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__Metadata_SimpleIterator *iterator); + +/** Initialize the iterator to point to the first metadata block in the + * given FLAC file. + * + * \param iterator A pointer to an existing iterator. + * \param filename The path to the FLAC file. + * \param read_only If \c true, the FLAC file will be opened + * in read-only mode; if \c false, the FLAC + * file will be opened for edit even if no + * edits are performed. + * \param preserve_file_stats If \c true, the owner and modification + * time will be preserved even if the FLAC + * file is written to. + * \assert + * \code iterator != NULL \endcode + * \code filename != NULL \endcode + * \retval FLAC__bool + * \c false if a memory allocation error occurs, the file can't be + * opened, or another error occurs, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool read_only, FLAC__bool preserve_file_stats); + +/** Returns \c true if the FLAC file is writable. If \c false, calls to + * FLAC__metadata_simple_iterator_set_block() and + * FLAC__metadata_simple_iterator_insert_block_after() will fail. + * + * \param iterator A pointer to an existing iterator. + * \assert + * \code iterator != NULL \endcode + * \retval FLAC__bool + * See above. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_writable(const FLAC__Metadata_SimpleIterator *iterator); + +/** Moves the iterator forward one metadata block, returning \c false if + * already at the end. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c false if already at the last metadata block of the chain, else + * \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIterator *iterator); + +/** Moves the iterator backward one metadata block, returning \c false if + * already at the beginning. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c false if already at the first metadata block of the chain, else + * \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator); + +/** Returns a flag telling if the current metadata block is the last. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c true if the current metadata block is the last in the file, + * else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_last(const FLAC__Metadata_SimpleIterator *iterator); + +/** Get the offset of the metadata block at the current position. This + * avoids reading the actual block data which can save time for large + * blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval off_t + * The offset of the metadata block at the current iterator position. + * This is the byte offset relative to the beginning of the file of + * the current metadata block's header. + */ +FLAC_API off_t FLAC__metadata_simple_iterator_get_block_offset(const FLAC__Metadata_SimpleIterator *iterator); + +/** Get the type of the metadata block at the current position. This + * avoids reading the actual block data which can save time for large + * blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__MetadataType + * The type of the metadata block at the current iterator position. + */ +FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator); + +/** Get the length of the metadata block at the current position. This + * avoids reading the actual block data which can save time for large + * blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval unsigned + * The length of the metadata block at the current iterator position. + * The is same length as that in the + * <a href="http://flac.sourceforge.net/format.html#metadata_block_header">metadata block header</a>, + * i.e. the length of the metadata body that follows the header. + */ +FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator); + +/** Get the application ID of the \c APPLICATION block at the current + * position. This avoids reading the actual block data which can save + * time for large blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \param id A pointer to a buffer of at least \c 4 bytes where + * the ID will be stored. + * \assert + * \code iterator != NULL \endcode + * \code id != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c true if the ID was successfully read, else \c false, in which + * case you should check FLAC__metadata_simple_iterator_status() to + * find out why. If the status is + * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, then the + * current metadata block is not an \c APPLICATION block. Otherwise + * if the status is + * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR or + * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, an I/O error + * occurred and the iterator can no longer be used. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_get_application_id(FLAC__Metadata_SimpleIterator *iterator, FLAC__byte *id); + +/** Get the metadata block at the current position. You can modify the + * block but must use FLAC__metadata_simple_iterator_set_block() to + * write it back to the FLAC file. + * + * You must call FLAC__metadata_object_delete() on the returned object + * when you are finished with it. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__StreamMetadata* + * The current metadata block, or \c NULL if there was a memory + * allocation error. + */ +FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator); + +/** Write a block back to the FLAC file. This function tries to be + * as efficient as possible; how the block is actually written is + * shown by the following: + * + * Existing block is a STREAMINFO block and the new block is a + * STREAMINFO block: the new block is written in place. Make sure + * you know what you're doing when changing the values of a + * STREAMINFO block. + * + * Existing block is a STREAMINFO block and the new block is a + * not a STREAMINFO block: this is an error since the first block + * must be a STREAMINFO block. Returns \c false without altering the + * file. + * + * Existing block is not a STREAMINFO block and the new block is a + * STREAMINFO block: this is an error since there may be only one + * STREAMINFO block. Returns \c false without altering the file. + * + * Existing block and new block are the same length: the existing + * block will be replaced by the new block, written in place. + * + * Existing block is longer than new block: if use_padding is \c true, + * the existing block will be overwritten in place with the new + * block followed by a PADDING block, if possible, to make the total + * size the same as the existing block. Remember that a padding + * block requires at least four bytes so if the difference in size + * between the new block and existing block is less than that, the + * entire file will have to be rewritten, using the new block's + * exact size. If use_padding is \c false, the entire file will be + * rewritten, replacing the existing block by the new block. + * + * Existing block is shorter than new block: if use_padding is \c true, + * the function will try and expand the new block into the following + * PADDING block, if it exists and doing so won't shrink the PADDING + * block to less than 4 bytes. If there is no following PADDING + * block, or it will shrink to less than 4 bytes, or use_padding is + * \c false, the entire file is rewritten, replacing the existing block + * with the new block. Note that in this case any following PADDING + * block is preserved as is. + * + * After writing the block, the iterator will remain in the same + * place, i.e. pointing to the new block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block The block to set. + * \param use_padding See above. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \code block != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding); + +/** This is similar to FLAC__metadata_simple_iterator_set_block() + * except that instead of writing over an existing block, it appends + * a block after the existing block. \a use_padding is again used to + * tell the function to try an expand into following padding in an + * attempt to avoid rewriting the entire file. + * + * This function will fail and return \c false if given a STREAMINFO + * block. + * + * After writing the block, the iterator will be pointing to the + * new block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block The block to set. + * \param use_padding See above. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \code block != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_insert_block_after(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding); + +/** Deletes the block at the current position. This will cause the + * entire FLAC file to be rewritten, unless \a use_padding is \c true, + * in which case the block will be replaced by an equal-sized PADDING + * block. The iterator will be left pointing to the block before the + * one just deleted. + * + * You may not delete the STREAMINFO block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param use_padding See above. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c true if successful, else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding); + +/* \} */ + + +/** \defgroup flac_metadata_level2 FLAC/metadata.h: metadata level 2 interface + * \ingroup flac_metadata + * + * \brief + * The level 2 interface provides read-write access to FLAC file metadata; + * all metadata is read into memory, operated on in memory, and then written + * to file, which is more efficient than level 1 when editing multiple blocks. + * + * Currently Ogg FLAC is supported for read only, via + * FLAC__metadata_chain_read_ogg() but a subsequent + * FLAC__metadata_chain_write() will fail. + * + * The general usage of this interface is: + * + * - Create a new chain using FLAC__metadata_chain_new(). A chain is a + * linked list of FLAC metadata blocks. + * - Read all metadata into the the chain from a FLAC file using + * FLAC__metadata_chain_read() or FLAC__metadata_chain_read_ogg() and + * check the status. + * - Optionally, consolidate the padding using + * FLAC__metadata_chain_merge_padding() or + * FLAC__metadata_chain_sort_padding(). + * - Create a new iterator using FLAC__metadata_iterator_new() + * - Initialize the iterator to point to the first element in the chain + * using FLAC__metadata_iterator_init() + * - Traverse the chain using FLAC__metadata_iterator_next and + * FLAC__metadata_iterator_prev(). + * - Get a block for reading or modification using + * FLAC__metadata_iterator_get_block(). The pointer to the object + * inside the chain is returned, so the block is yours to modify. + * Changes will be reflected in the FLAC file when you write the + * chain. You can also add and delete blocks (see functions below). + * - When done, write out the chain using FLAC__metadata_chain_write(). + * Make sure to read the whole comment to the function below. + * - Delete the chain using FLAC__metadata_chain_delete(). + * + * \note + * Even though the FLAC file is not open while the chain is being + * manipulated, you must not alter the file externally during + * this time. The chain assumes the FLAC file will not change + * between the time of FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg() + * and FLAC__metadata_chain_write(). + * + * \note + * Do not modify the is_last, length, or type fields of returned + * FLAC__StreamMetadata objects. These are managed automatically. + * + * \note + * The metadata objects returned by FLAC__metadata_iterator_get_block() + * are owned by the chain; do not FLAC__metadata_object_delete() them. + * In the same way, blocks passed to FLAC__metadata_iterator_set_block() + * become owned by the chain and they will be deleted when the chain is + * deleted. + * + * \{ + */ + +struct FLAC__Metadata_Chain; +/** The opaque structure definition for the level 2 chain type. + */ +typedef struct FLAC__Metadata_Chain FLAC__Metadata_Chain; + +struct FLAC__Metadata_Iterator; +/** The opaque structure definition for the level 2 iterator type. + */ +typedef struct FLAC__Metadata_Iterator FLAC__Metadata_Iterator; + +typedef enum { + FLAC__METADATA_CHAIN_STATUS_OK = 0, + /**< The chain is in the normal OK state */ + + FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT, + /**< The data passed into a function violated the function's usage criteria */ + + FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE, + /**< The chain could not open the target file */ + + FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE, + /**< The chain could not find the FLAC signature at the start of the file */ + + FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE, + /**< The chain tried to write to a file that was not writable */ + + FLAC__METADATA_CHAIN_STATUS_BAD_METADATA, + /**< The chain encountered input that does not conform to the FLAC metadata specification */ + + FLAC__METADATA_CHAIN_STATUS_READ_ERROR, + /**< The chain encountered an error while reading the FLAC file */ + + FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR, + /**< The chain encountered an error while seeking in the FLAC file */ + + FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR, + /**< The chain encountered an error while writing the FLAC file */ + + FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR, + /**< The chain encountered an error renaming the FLAC file */ + + FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR, + /**< The chain encountered an error removing the temporary file */ + + FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR, + /**< Memory allocation failed */ + + FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR, + /**< The caller violated an assertion or an unexpected error occurred */ + + FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS, + /**< One or more of the required callbacks was NULL */ + + FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH, + /**< FLAC__metadata_chain_write() was called on a chain read by + * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), + * or + * FLAC__metadata_chain_write_with_callbacks()/FLAC__metadata_chain_write_with_callbacks_and_tempfile() + * was called on a chain read by + * FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). + * Matching read/write methods must always be used. */ + + FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL + /**< FLAC__metadata_chain_write_with_callbacks() was called when the + * chain write requires a tempfile; use + * FLAC__metadata_chain_write_with_callbacks_and_tempfile() instead. + * Or, FLAC__metadata_chain_write_with_callbacks_and_tempfile() was + * called when the chain write does not require a tempfile; use + * FLAC__metadata_chain_write_with_callbacks() instead. + * Always check FLAC__metadata_chain_check_if_tempfile_needed() + * before writing via callbacks. */ + +} FLAC__Metadata_ChainStatus; + +/** Maps a FLAC__Metadata_ChainStatus to a C string. + * + * Using a FLAC__Metadata_ChainStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__Metadata_ChainStatusString[]; + +/*********** FLAC__Metadata_Chain ***********/ + +/** Create a new chain instance. + * + * \retval FLAC__Metadata_Chain* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new(void); + +/** Free a chain instance. Deletes the object pointed to by \a chain. + * + * \param chain A pointer to an existing chain. + * \assert + * \code chain != NULL \endcode + */ +FLAC_API void FLAC__metadata_chain_delete(FLAC__Metadata_Chain *chain); + +/** Get the current status of the chain. Call this after a function + * returns \c false to get the reason for the error. Also resets the + * status to FLAC__METADATA_CHAIN_STATUS_OK. + * + * \param chain A pointer to an existing chain. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__Metadata_ChainStatus + * The current status of the chain. + */ +FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_Chain *chain); + +/** Read all metadata from a FLAC file into the chain. + * + * \param chain A pointer to an existing chain. + * \param filename The path to the FLAC file to read. + * \assert + * \code chain != NULL \endcode + * \code filename != NULL \endcode + * \retval FLAC__bool + * \c true if a valid list of metadata blocks was read from + * \a filename, else \c false. On failure, check the status with + * FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename); + +/** Read all metadata from an Ogg FLAC file into the chain. + * + * \note Ogg FLAC metadata data writing is not supported yet and + * FLAC__metadata_chain_write() will fail. + * + * \param chain A pointer to an existing chain. + * \param filename The path to the Ogg FLAC file to read. + * \assert + * \code chain != NULL \endcode + * \code filename != NULL \endcode + * \retval FLAC__bool + * \c true if a valid list of metadata blocks was read from + * \a filename, else \c false. On failure, check the status with + * FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg(FLAC__Metadata_Chain *chain, const char *filename); + +/** Read all metadata from a FLAC stream into the chain via I/O callbacks. + * + * The \a handle need only be open for reading, but must be seekable. + * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" + * for Windows). + * + * \param chain A pointer to an existing chain. + * \param handle The I/O handle of the FLAC stream to read. The + * handle will NOT be closed after the metadata is read; + * that is the duty of the caller. + * \param callbacks + * A set of callbacks to use for I/O. The mandatory + * callbacks are \a read, \a seek, and \a tell. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if a valid list of metadata blocks was read from + * \a handle, else \c false. On failure, check the status with + * FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); + +/** Read all metadata from an Ogg FLAC stream into the chain via I/O callbacks. + * + * The \a handle need only be open for reading, but must be seekable. + * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" + * for Windows). + * + * \note Ogg FLAC metadata data writing is not supported yet and + * FLAC__metadata_chain_write() will fail. + * + * \param chain A pointer to an existing chain. + * \param handle The I/O handle of the Ogg FLAC stream to read. The + * handle will NOT be closed after the metadata is read; + * that is the duty of the caller. + * \param callbacks + * A set of callbacks to use for I/O. The mandatory + * callbacks are \a read, \a seek, and \a tell. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if a valid list of metadata blocks was read from + * \a handle, else \c false. On failure, check the status with + * FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); + +/** Checks if writing the given chain would require the use of a + * temporary file, or if it could be written in place. + * + * Under certain conditions, padding can be utilized so that writing + * edited metadata back to the FLAC file does not require rewriting the + * entire file. If rewriting is required, then a temporary workfile is + * required. When writing metadata using callbacks, you must check + * this function to know whether to call + * FLAC__metadata_chain_write_with_callbacks() or + * FLAC__metadata_chain_write_with_callbacks_and_tempfile(). When + * writing with FLAC__metadata_chain_write(), the temporary file is + * handled internally. + * + * \param chain A pointer to an existing chain. + * \param use_padding + * Whether or not padding will be allowed to be used + * during the write. The value of \a use_padding given + * here must match the value later passed to + * FLAC__metadata_chain_write_with_callbacks() or + * FLAC__metadata_chain_write_with_callbacks_with_tempfile(). + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if writing the current chain would require a tempfile, or + * \c false if metadata can be written in place. + */ +FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata_Chain *chain, FLAC__bool use_padding); + +/** Write all metadata out to the FLAC file. This function tries to be as + * efficient as possible; how the metadata is actually written is shown by + * the following: + * + * If the current chain is the same size as the existing metadata, the new + * data is written in place. + * + * If the current chain is longer than the existing metadata, and + * \a use_padding is \c true, and the last block is a PADDING block of + * sufficient length, the function will truncate the final padding block + * so that the overall size of the metadata is the same as the existing + * metadata, and then just rewrite the metadata. Otherwise, if not all of + * the above conditions are met, the entire FLAC file must be rewritten. + * If you want to use padding this way it is a good idea to call + * FLAC__metadata_chain_sort_padding() first so that you have the maximum + * amount of padding to work with, unless you need to preserve ordering + * of the PADDING blocks for some reason. + * + * If the current chain is shorter than the existing metadata, and + * \a use_padding is \c true, and the final block is a PADDING block, the padding + * is extended to make the overall size the same as the existing data. If + * \a use_padding is \c true and the last block is not a PADDING block, a new + * PADDING block is added to the end of the new data to make it the same + * size as the existing data (if possible, see the note to + * FLAC__metadata_simple_iterator_set_block() about the four byte limit) + * and the new data is written in place. If none of the above apply or + * \a use_padding is \c false, the entire FLAC file is rewritten. + * + * If \a preserve_file_stats is \c true, the owner and modification time will + * be preserved even if the FLAC file is written. + * + * For this write function to be used, the chain must have been read with + * FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(), not + * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(). + * + * \param chain A pointer to an existing chain. + * \param use_padding See above. + * \param preserve_file_stats See above. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if the write succeeded, else \c false. On failure, + * check the status with FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats); + +/** Write all metadata out to a FLAC stream via callbacks. + * + * (See FLAC__metadata_chain_write() for the details on how padding is + * used to write metadata in place if possible.) + * + * The \a handle must be open for updating and be seekable. The + * equivalent minimum stdio fopen() file mode is \c "r+" (or \c "r+b" + * for Windows). + * + * For this write function to be used, the chain must have been read with + * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), + * not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). + * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned + * \c false. + * + * \param chain A pointer to an existing chain. + * \param use_padding See FLAC__metadata_chain_write() + * \param handle The I/O handle of the FLAC stream to write. The + * handle will NOT be closed after the metadata is + * written; that is the duty of the caller. + * \param callbacks A set of callbacks to use for I/O. The mandatory + * callbacks are \a write and \a seek. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if the write succeeded, else \c false. On failure, + * check the status with FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); + +/** Write all metadata out to a FLAC stream via callbacks. + * + * (See FLAC__metadata_chain_write() for the details on how padding is + * used to write metadata in place if possible.) + * + * This version of the write-with-callbacks function must be used when + * FLAC__metadata_chain_check_if_tempfile_needed() returns true. In + * this function, you must supply an I/O handle corresponding to the + * FLAC file to edit, and a temporary handle to which the new FLAC + * file will be written. It is the caller's job to move this temporary + * FLAC file on top of the original FLAC file to complete the metadata + * edit. + * + * The \a handle must be open for reading and be seekable. The + * equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" + * for Windows). + * + * The \a temp_handle must be open for writing. The + * equivalent minimum stdio fopen() file mode is \c "w" (or \c "wb" + * for Windows). It should be an empty stream, or at least positioned + * at the start-of-file (in which case it is the caller's duty to + * truncate it on return). + * + * For this write function to be used, the chain must have been read with + * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), + * not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). + * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned + * \c true. + * + * \param chain A pointer to an existing chain. + * \param use_padding See FLAC__metadata_chain_write() + * \param handle The I/O handle of the original FLAC stream to read. + * The handle will NOT be closed after the metadata is + * written; that is the duty of the caller. + * \param callbacks A set of callbacks to use for I/O on \a handle. + * The mandatory callbacks are \a read, \a seek, and + * \a eof. + * \param temp_handle The I/O handle of the FLAC stream to write. The + * handle will NOT be closed after the metadata is + * written; that is the duty of the caller. + * \param temp_callbacks + * A set of callbacks to use for I/O on temp_handle. + * The only mandatory callback is \a write. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if the write succeeded, else \c false. On failure, + * check the status with FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks_and_tempfile(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, FLAC__IOHandle temp_handle, FLAC__IOCallbacks temp_callbacks); + +/** Merge adjacent PADDING blocks into a single block. + * + * \note This function does not write to the FLAC file, it only + * modifies the chain. + * + * \warning Any iterator on the current chain will become invalid after this + * call. You should delete the iterator and get a new one. + * + * \param chain A pointer to an existing chain. + * \assert + * \code chain != NULL \endcode + */ +FLAC_API void FLAC__metadata_chain_merge_padding(FLAC__Metadata_Chain *chain); + +/** This function will move all PADDING blocks to the end on the metadata, + * then merge them into a single block. + * + * \note This function does not write to the FLAC file, it only + * modifies the chain. + * + * \warning Any iterator on the current chain will become invalid after this + * call. You should delete the iterator and get a new one. + * + * \param chain A pointer to an existing chain. + * \assert + * \code chain != NULL \endcode + */ +FLAC_API void FLAC__metadata_chain_sort_padding(FLAC__Metadata_Chain *chain); + + +/*********** FLAC__Metadata_Iterator ***********/ + +/** Create a new iterator instance. + * + * \retval FLAC__Metadata_Iterator* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__Metadata_Iterator *FLAC__metadata_iterator_new(void); + +/** Free an iterator instance. Deletes the object pointed to by \a iterator. + * + * \param iterator A pointer to an existing iterator. + * \assert + * \code iterator != NULL \endcode + */ +FLAC_API void FLAC__metadata_iterator_delete(FLAC__Metadata_Iterator *iterator); + +/** Initialize the iterator to point to the first metadata block in the + * given chain. + * + * \param iterator A pointer to an existing iterator. + * \param chain A pointer to an existing and initialized (read) chain. + * \assert + * \code iterator != NULL \endcode + * \code chain != NULL \endcode + */ +FLAC_API void FLAC__metadata_iterator_init(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Chain *chain); + +/** Moves the iterator forward one metadata block, returning \c false if + * already at the end. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if already at the last metadata block of the chain, else + * \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_next(FLAC__Metadata_Iterator *iterator); + +/** Moves the iterator backward one metadata block, returning \c false if + * already at the beginning. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if already at the first metadata block of the chain, else + * \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_prev(FLAC__Metadata_Iterator *iterator); + +/** Get the type of the metadata block at the current position. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__MetadataType + * The type of the metadata block at the current iterator position. + */ +FLAC_API FLAC__MetadataType FLAC__metadata_iterator_get_block_type(const FLAC__Metadata_Iterator *iterator); + +/** Get the metadata block at the current position. You can modify + * the block in place but must write the chain before the changes + * are reflected to the FLAC file. You do not need to call + * FLAC__metadata_iterator_set_block() to reflect the changes; + * the pointer returned by FLAC__metadata_iterator_get_block() + * points directly into the chain. + * + * \warning + * Do not call FLAC__metadata_object_delete() on the returned object; + * to delete a block use FLAC__metadata_iterator_delete_block(). + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__StreamMetadata* + * The current metadata block. + */ +FLAC_API FLAC__StreamMetadata *FLAC__metadata_iterator_get_block(FLAC__Metadata_Iterator *iterator); + +/** Set the metadata block at the current position, replacing the existing + * block. The new block passed in becomes owned by the chain and it will be + * deleted when the chain is deleted. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block A pointer to a metadata block. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \code block != NULL \endcode + * \retval FLAC__bool + * \c false if the conditions in the above description are not met, or + * a memory allocation error occurs, otherwise \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_set_block(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); + +/** Removes the current block from the chain. If \a replace_with_padding is + * \c true, the block will instead be replaced with a padding block of equal + * size. You can not delete the STREAMINFO block. The iterator will be + * left pointing to the block before the one just "deleted", even if + * \a replace_with_padding is \c true. + * + * \param iterator A pointer to an existing initialized iterator. + * \param replace_with_padding See above. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if the conditions in the above description are not met, + * otherwise \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_delete_block(FLAC__Metadata_Iterator *iterator, FLAC__bool replace_with_padding); + +/** Insert a new block before the current block. You cannot insert a block + * before the first STREAMINFO block. You cannot insert a STREAMINFO block + * as there can be only one, the one that already exists at the head when you + * read in a chain. The chain takes ownership of the new block and it will be + * deleted when the chain is deleted. The iterator will be left pointing to + * the new block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block A pointer to a metadata block to insert. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if the conditions in the above description are not met, or + * a memory allocation error occurs, otherwise \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_before(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); + +/** Insert a new block after the current block. You cannot insert a STREAMINFO + * block as there can be only one, the one that already exists at the head when + * you read in a chain. The chain takes ownership of the new block and it will + * be deleted when the chain is deleted. The iterator will be left pointing to + * the new block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block A pointer to a metadata block to insert. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if the conditions in the above description are not met, or + * a memory allocation error occurs, otherwise \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); + +/* \} */ + + +/** \defgroup flac_metadata_object FLAC/metadata.h: metadata object methods + * \ingroup flac_metadata + * + * \brief + * This module contains methods for manipulating FLAC metadata objects. + * + * Since many are variable length we have to be careful about the memory + * management. We decree that all pointers to data in the object are + * owned by the object and memory-managed by the object. + * + * Use the FLAC__metadata_object_new() and FLAC__metadata_object_delete() + * functions to create all instances. When using the + * FLAC__metadata_object_set_*() functions to set pointers to data, set + * \a copy to \c true to have the function make it's own copy of the data, or + * to \c false to give the object ownership of your data. In the latter case + * your pointer must be freeable by free() and will be free()d when the object + * is FLAC__metadata_object_delete()d. It is legal to pass a null pointer as + * the data pointer to a FLAC__metadata_object_set_*() function as long as + * the length argument is 0 and the \a copy argument is \c false. + * + * The FLAC__metadata_object_new() and FLAC__metadata_object_clone() function + * will return \c NULL in the case of a memory allocation error, otherwise a new + * object. The FLAC__metadata_object_set_*() functions return \c false in the + * case of a memory allocation error. + * + * We don't have the convenience of C++ here, so note that the library relies + * on you to keep the types straight. In other words, if you pass, for + * example, a FLAC__StreamMetadata* that represents a STREAMINFO block to + * FLAC__metadata_object_application_set_data(), you will get an assertion + * failure. + * + * For convenience the FLAC__metadata_object_vorbiscomment_*() functions + * maintain a trailing NUL on each Vorbis comment entry. This is not counted + * toward the length or stored in the stream, but it can make working with plain + * comments (those that don't contain embedded-NULs in the value) easier. + * Entries passed into these functions have trailing NULs added if missing, and + * returned entries are guaranteed to have a trailing NUL. + * + * The FLAC__metadata_object_vorbiscomment_*() functions that take a Vorbis + * comment entry/name/value will first validate that it complies with the Vorbis + * comment specification and return false if it does not. + * + * There is no need to recalculate the length field on metadata blocks you + * have modified. They will be calculated automatically before they are + * written back to a file. + * + * \{ + */ + + +/** Create a new metadata object instance of the given type. + * + * The object will be "empty"; i.e. values and data pointers will be \c 0, + * with the exception of FLAC__METADATA_TYPE_VORBIS_COMMENT, which will have + * the vendor string set (but zero comments). + * + * Do not pass in a value greater than or equal to + * \a FLAC__METADATA_TYPE_UNDEFINED unless you really know what you're + * doing. + * + * \param type Type of object to create + * \retval FLAC__StreamMetadata* + * \c NULL if there was an error allocating memory or the type code is + * greater than FLAC__MAX_METADATA_TYPE_CODE, else the new instance. + */ +FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_new(FLAC__MetadataType type); + +/** Create a copy of an existing metadata object. + * + * The copy is a "deep" copy, i.e. dynamically allocated data within the + * object is also copied. The caller takes ownership of the new block and + * is responsible for freeing it with FLAC__metadata_object_delete(). + * + * \param object Pointer to object to copy. + * \assert + * \code object != NULL \endcode + * \retval FLAC__StreamMetadata* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMetadata *object); + +/** Free a metadata object. Deletes the object pointed to by \a object. + * + * The delete is a "deep" delete, i.e. dynamically allocated data within the + * object is also deleted. + * + * \param object A pointer to an existing object. + * \assert + * \code object != NULL \endcode + */ +FLAC_API void FLAC__metadata_object_delete(FLAC__StreamMetadata *object); + +/** Compares two metadata objects. + * + * The compare is "deep", i.e. dynamically allocated data within the + * object is also compared. + * + * \param block1 A pointer to an existing object. + * \param block2 A pointer to an existing object. + * \assert + * \code block1 != NULL \endcode + * \code block2 != NULL \endcode + * \retval FLAC__bool + * \c true if objects are identical, else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetadata *block1, const FLAC__StreamMetadata *block2); + +/** Sets the application data of an APPLICATION block. + * + * If \a copy is \c true, a copy of the data is stored; otherwise, the object + * takes ownership of the pointer. The existing data will be freed if this + * function is successful, otherwise the original data will remain if \a copy + * is \c true and malloc() fails. + * + * \note It is safe to pass a const pointer to \a data if \a copy is \c true. + * + * \param object A pointer to an existing APPLICATION object. + * \param data A pointer to the data to set. + * \param length The length of \a data in bytes. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_APPLICATION \endcode + * \code (data != NULL && length > 0) || + * (data == NULL && length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_application_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, unsigned length, FLAC__bool copy); + +/** Resize the seekpoint array. + * + * If the size shrinks, elements will truncated; if it grows, new placeholder + * points will be added to the end. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param new_num_points The desired length of the array; may be \c 0. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code (object->data.seek_table.points == NULL && object->data.seek_table.num_points == 0) || + * (object->data.seek_table.points != NULL && object->data.seek_table.num_points > 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_resize_points(FLAC__StreamMetadata *object, unsigned new_num_points); + +/** Set a seekpoint in a seektable. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param point_num Index into seekpoint array to set. + * \param point The point to set. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code object->data.seek_table.num_points > point_num \endcode + */ +FLAC_API void FLAC__metadata_object_seektable_set_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point); + +/** Insert a seekpoint into a seektable. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param point_num Index into seekpoint array to set. + * \param point The point to set. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code object->data.seek_table.num_points >= point_num \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_insert_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point); + +/** Delete a seekpoint from a seektable. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param point_num Index into seekpoint array to set. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code object->data.seek_table.num_points > point_num \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_delete_point(FLAC__StreamMetadata *object, unsigned point_num); + +/** Check a seektable to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * seektable. + * + * \param object A pointer to an existing SEEKTABLE object. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if seek table is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_is_legal(const FLAC__StreamMetadata *object); + +/** Append a number of placeholder points to the end of a seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param num The number of placeholder points to append. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_placeholders(FLAC__StreamMetadata *object, unsigned num); + +/** Append a specific seek point template to the end of a seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param sample_number The sample number of the seek point template. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_point(FLAC__StreamMetadata *object, FLAC__uint64 sample_number); + +/** Append specific seek point templates to the end of a seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param sample_numbers An array of sample numbers for the seek points. + * \param num The number of seek point templates to append. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_points(FLAC__StreamMetadata *object, FLAC__uint64 sample_numbers[], unsigned num); + +/** Append a set of evenly-spaced seek point templates to the end of a + * seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param num The number of placeholder points to append. + * \param total_samples The total number of samples to be encoded; + * the seekpoints will be spaced approximately + * \a total_samples / \a num samples apart. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code total_samples > 0 \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points(FLAC__StreamMetadata *object, unsigned num, FLAC__uint64 total_samples); + +/** Append a set of evenly-spaced seek point templates to the end of a + * seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param samples The number of samples apart to space the placeholder + * points. The first point will be at sample \c 0, the + * second at sample \a samples, then 2*\a samples, and + * so on. As long as \a samples and \a total_samples + * are greater than \c 0, there will always be at least + * one seekpoint at sample \c 0. + * \param total_samples The total number of samples to be encoded; + * the seekpoints will be spaced + * \a samples samples apart. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code samples > 0 \endcode + * \code total_samples > 0 \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(FLAC__StreamMetadata *object, unsigned samples, FLAC__uint64 total_samples); + +/** Sort a seek table's seek points according to the format specification, + * removing duplicates. + * + * \param object A pointer to a seek table to be sorted. + * \param compact If \c false, behaves like FLAC__format_seektable_sort(). + * If \c true, duplicates are deleted and the seek table is + * shrunk appropriately; the number of placeholder points + * present in the seek table will be the same after the call + * as before. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_sort(FLAC__StreamMetadata *object, FLAC__bool compact); + +/** Sets the vendor string in a VORBIS_COMMENT block. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param entry The entry to set the vendor string to. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_vendor_string(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); + +/** Resize the comment array. + * + * If the size shrinks, elements will truncated; if it grows, new empty + * fields will be added to the end. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param new_num_comments The desired length of the array; may be \c 0. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code (object->data.vorbis_comment.comments == NULL && object->data.vorbis_comment.num_comments == 0) || + * (object->data.vorbis_comment.comments != NULL && object->data.vorbis_comment.num_comments > 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_resize_comments(FLAC__StreamMetadata *object, unsigned new_num_comments); + +/** Sets a comment in a VORBIS_COMMENT block. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param comment_num Index into comment array to set. + * \param entry The entry to set the comment to. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code comment_num < object->data.vorbis_comment.num_comments \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); + +/** Insert a comment in a VORBIS_COMMENT block at the given index. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param comment_num The index at which to insert the comment. The comments + * at and after \a comment_num move right one position. + * To append a comment to the end, set \a comment_num to + * \c object->data.vorbis_comment.num_comments . + * \param entry The comment to insert. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code object->data.vorbis_comment.num_comments >= comment_num \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_insert_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); + +/** Appends a comment to a VORBIS_COMMENT block. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param entry The comment to insert. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_append_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); + +/** Replaces comments in a VORBIS_COMMENT block with a new one. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * Depending on the the value of \a all, either all or just the first comment + * whose field name(s) match the given entry's name will be replaced by the + * given entry. If no comments match, \a entry will simply be appended. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param entry The comment to insert. + * \param all If \c true, all comments whose field name matches + * \a entry's field name will be removed, and \a entry will + * be inserted at the position of the first matching + * comment. If \c false, only the first comment whose + * field name matches \a entry's field name will be + * replaced with \a entry. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_replace_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool all, FLAC__bool copy); + +/** Delete a comment in a VORBIS_COMMENT block at the given index. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param comment_num The index of the comment to delete. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code object->data.vorbis_comment.num_comments > comment_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_delete_comment(FLAC__StreamMetadata *object, unsigned comment_num); + +/** Creates a Vorbis comment entry from NUL-terminated name and value strings. + * + * On return, the filled-in \a entry->entry pointer will point to malloc()ed + * memory and shall be owned by the caller. For convenience the entry will + * have a terminating NUL. + * + * \param entry A pointer to a Vorbis comment entry. The entry's + * \c entry pointer should not point to allocated + * memory as it will be overwritten. + * \param field_name The field name in ASCII, \c NUL terminated. + * \param field_value The field value in UTF-8, \c NUL terminated. + * \assert + * \code entry != NULL \endcode + * \code field_name != NULL \endcode + * \code field_value != NULL \endcode + * \retval FLAC__bool + * \c false if malloc() fails, or if \a field_name or \a field_value does + * not comply with the Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(FLAC__StreamMetadata_VorbisComment_Entry *entry, const char *field_name, const char *field_value); + +/** Splits a Vorbis comment entry into NUL-terminated name and value strings. + * + * The returned pointers to name and value will be allocated by malloc() + * and shall be owned by the caller. + * + * \param entry An existing Vorbis comment entry. + * \param field_name The address of where the returned pointer to the + * field name will be stored. + * \param field_value The address of where the returned pointer to the + * field value will be stored. + * \assert + * \code (entry.entry != NULL && entry.length > 0) \endcode + * \code memchr(entry.entry, '=', entry.length) != NULL \endcode + * \code field_name != NULL \endcode + * \code field_value != NULL \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(const FLAC__StreamMetadata_VorbisComment_Entry entry, char **field_name, char **field_value); + +/** Check if the given Vorbis comment entry's field name matches the given + * field name. + * + * \param entry An existing Vorbis comment entry. + * \param field_name The field name to check. + * \param field_name_length The length of \a field_name, not including the + * terminating \c NUL. + * \assert + * \code (entry.entry != NULL && entry.length > 0) \endcode + * \retval FLAC__bool + * \c true if the field names match, else \c false + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_matches(const FLAC__StreamMetadata_VorbisComment_Entry entry, const char *field_name, unsigned field_name_length); + +/** Find a Vorbis comment with the given field name. + * + * The search begins at entry number \a offset; use an offset of 0 to + * search from the beginning of the comment array. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param offset The offset into the comment array from where to start + * the search. + * \param field_name The field name of the comment to find. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code field_name != NULL \endcode + * \retval int + * The offset in the comment array of the first comment whose field + * name matches \a field_name, or \c -1 if no match was found. + */ +FLAC_API int FLAC__metadata_object_vorbiscomment_find_entry_from(const FLAC__StreamMetadata *object, unsigned offset, const char *field_name); + +/** Remove first Vorbis comment matching the given field name. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param field_name The field name of comment to delete. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \retval int + * \c -1 for memory allocation error, \c 0 for no matching entries, + * \c 1 for one matching entry deleted. + */ +FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entry_matching(FLAC__StreamMetadata *object, const char *field_name); + +/** Remove all Vorbis comments matching the given field name. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param field_name The field name of comments to delete. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \retval int + * \c -1 for memory allocation error, \c 0 for no matching entries, + * else the number of matching entries deleted. + */ +FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entries_matching(FLAC__StreamMetadata *object, const char *field_name); + +/** Create a new CUESHEET track instance. + * + * The object will be "empty"; i.e. values and data pointers will be \c 0. + * + * \retval FLAC__StreamMetadata_CueSheet_Track* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_new(void); + +/** Create a copy of an existing CUESHEET track object. + * + * The copy is a "deep" copy, i.e. dynamically allocated data within the + * object is also copied. The caller takes ownership of the new object and + * is responsible for freeing it with + * FLAC__metadata_object_cuesheet_track_delete(). + * + * \param object Pointer to object to copy. + * \assert + * \code object != NULL \endcode + * \retval FLAC__StreamMetadata_CueSheet_Track* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_clone(const FLAC__StreamMetadata_CueSheet_Track *object); + +/** Delete a CUESHEET track object + * + * \param object A pointer to an existing CUESHEET track object. + * \assert + * \code object != NULL \endcode + */ +FLAC_API void FLAC__metadata_object_cuesheet_track_delete(FLAC__StreamMetadata_CueSheet_Track *object); + +/** Resize a track's index point array. + * + * If the size shrinks, elements will truncated; if it grows, new blank + * indices will be added to the end. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index of the track to modify. NOTE: this is not + * necessarily the same as the track's \a number field. + * \param new_num_indices The desired length of the array; may be \c 0. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \code (object->data.cue_sheet.tracks[track_num].indices == NULL && object->data.cue_sheet.tracks[track_num].num_indices == 0) || + * (object->data.cue_sheet.tracks[track_num].indices != NULL && object->data.cue_sheet.tracks[track_num].num_indices > 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_resize_indices(FLAC__StreamMetadata *object, unsigned track_num, unsigned new_num_indices); + +/** Insert an index point in a CUESHEET track at the given index. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index of the track to modify. NOTE: this is not + * necessarily the same as the track's \a number field. + * \param index_num The index into the track's index array at which to + * insert the index point. NOTE: this is not necessarily + * the same as the index point's \a number field. The + * indices at and after \a index_num move right one + * position. To append an index point to the end, set + * \a index_num to + * \c object->data.cue_sheet.tracks[track_num].num_indices . + * \param index The index point to insert. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num, FLAC__StreamMetadata_CueSheet_Index index); + +/** Insert a blank index point in a CUESHEET track at the given index. + * + * A blank index point is one in which all field values are zero. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index of the track to modify. NOTE: this is not + * necessarily the same as the track's \a number field. + * \param index_num The index into the track's index array at which to + * insert the index point. NOTE: this is not necessarily + * the same as the index point's \a number field. The + * indices at and after \a index_num move right one + * position. To append an index point to the end, set + * \a index_num to + * \c object->data.cue_sheet.tracks[track_num].num_indices . + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_blank_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num); + +/** Delete an index point in a CUESHEET track at the given index. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index into the track array of the track to + * modify. NOTE: this is not necessarily the same + * as the track's \a number field. + * \param index_num The index into the track's index array of the index + * to delete. NOTE: this is not necessarily the same + * as the index's \a number field. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \code object->data.cue_sheet.tracks[track_num].num_indices > index_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_delete_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num); + +/** Resize the track array. + * + * If the size shrinks, elements will truncated; if it grows, new blank + * tracks will be added to the end. + * + * \param object A pointer to an existing CUESHEET object. + * \param new_num_tracks The desired length of the array; may be \c 0. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code (object->data.cue_sheet.tracks == NULL && object->data.cue_sheet.num_tracks == 0) || + * (object->data.cue_sheet.tracks != NULL && object->data.cue_sheet.num_tracks > 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMetadata *object, unsigned new_num_tracks); + +/** Sets a track in a CUESHEET block. + * + * If \a copy is \c true, a copy of the track is stored; otherwise, the object + * takes ownership of the \a track pointer. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num Index into track array to set. NOTE: this is not + * necessarily the same as the track's \a number field. + * \param track The track to set the track to. You may safely pass in + * a const pointer if \a copy is \c true. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code track_num < object->data.cue_sheet.num_tracks \endcode + * \code (track->indices != NULL && track->num_indices > 0) || + * (track->indices == NULL && track->num_indices == 0) + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_set_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy); + +/** Insert a track in a CUESHEET block at the given index. + * + * If \a copy is \c true, a copy of the track is stored; otherwise, the object + * takes ownership of the \a track pointer. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index at which to insert the track. NOTE: this + * is not necessarily the same as the track's \a number + * field. The tracks at and after \a track_num move right + * one position. To append a track to the end, set + * \a track_num to \c object->data.cue_sheet.num_tracks . + * \param track The track to insert. You may safely pass in a const + * pointer if \a copy is \c true. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks >= track_num \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy); + +/** Insert a blank track in a CUESHEET block at the given index. + * + * A blank track is one in which all field values are zero. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index at which to insert the track. NOTE: this + * is not necessarily the same as the track's \a number + * field. The tracks at and after \a track_num move right + * one position. To append a track to the end, set + * \a track_num to \c object->data.cue_sheet.num_tracks . + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks >= track_num \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_blank_track(FLAC__StreamMetadata *object, unsigned track_num); + +/** Delete a track in a CUESHEET block at the given index. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index into the track array of the track to + * delete. NOTE: this is not necessarily the same + * as the track's \a number field. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_delete_track(FLAC__StreamMetadata *object, unsigned track_num); + +/** Check a cue sheet to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * cue sheet. + * + * \param object A pointer to an existing CUESHEET object. + * \param check_cd_da_subset If \c true, check CUESHEET against more + * stringent requirements for a CD-DA (audio) disc. + * \param violation Address of a pointer to a string. If there is a + * violation, a pointer to a string explanation of the + * violation will be returned here. \a violation may be + * \c NULL if you don't need the returned string. Do not + * free the returned string; it will always point to static + * data. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \retval FLAC__bool + * \c false if cue sheet is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_is_legal(const FLAC__StreamMetadata *object, FLAC__bool check_cd_da_subset, const char **violation); + +/** Calculate and return the CDDB/freedb ID for a cue sheet. The function + * assumes the cue sheet corresponds to a CD; the result is undefined + * if the cuesheet's is_cd bit is not set. + * + * \param object A pointer to an existing CUESHEET object. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \retval FLAC__uint32 + * The unsigned integer representation of the CDDB/freedb ID + */ +FLAC_API FLAC__uint32 FLAC__metadata_object_cuesheet_calculate_cddb_id(const FLAC__StreamMetadata *object); + +/** Sets the MIME type of a PICTURE block. + * + * If \a copy is \c true, a copy of the string is stored; otherwise, the object + * takes ownership of the pointer. The existing string will be freed if this + * function is successful, otherwise the original string will remain if \a copy + * is \c true and malloc() fails. + * + * \note It is safe to pass a const pointer to \a mime_type if \a copy is \c true. + * + * \param object A pointer to an existing PICTURE object. + * \param mime_type A pointer to the MIME type string. The string must be + * ASCII characters 0x20-0x7e, NUL-terminated. No validation + * is done. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + * \code (mime_type != NULL) \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_picture_set_mime_type(FLAC__StreamMetadata *object, char *mime_type, FLAC__bool copy); + +/** Sets the description of a PICTURE block. + * + * If \a copy is \c true, a copy of the string is stored; otherwise, the object + * takes ownership of the pointer. The existing string will be freed if this + * function is successful, otherwise the original string will remain if \a copy + * is \c true and malloc() fails. + * + * \note It is safe to pass a const pointer to \a description if \a copy is \c true. + * + * \param object A pointer to an existing PICTURE object. + * \param description A pointer to the description string. The string must be + * valid UTF-8, NUL-terminated. No validation is done. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + * \code (description != NULL) \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_picture_set_description(FLAC__StreamMetadata *object, FLAC__byte *description, FLAC__bool copy); + +/** Sets the picture data of a PICTURE block. + * + * If \a copy is \c true, a copy of the data is stored; otherwise, the object + * takes ownership of the pointer. Also sets the \a data_length field of the + * metadata object to what is passed in as the \a length parameter. The + * existing data will be freed if this function is successful, otherwise the + * original data and data_length will remain if \a copy is \c true and + * malloc() fails. + * + * \note It is safe to pass a const pointer to \a data if \a copy is \c true. + * + * \param object A pointer to an existing PICTURE object. + * \param data A pointer to the data to set. + * \param length The length of \a data in bytes. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + * \code (data != NULL && length > 0) || + * (data == NULL && length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_picture_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, FLAC__uint32 length, FLAC__bool copy); + +/** Check a PICTURE block to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * PICTURE block. + * + * \param object A pointer to existing PICTURE block to be checked. + * \param violation Address of a pointer to a string. If there is a + * violation, a pointer to a string explanation of the + * violation will be returned here. \a violation may be + * \c NULL if you don't need the returned string. Do not + * free the returned string; it will always point to static + * data. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + * \retval FLAC__bool + * \c false if PICTURE block is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_picture_is_legal(const FLAC__StreamMetadata *object, const char **violation); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/FLAC/ordinals.h b/include/FLAC/ordinals.h new file mode 100644 index 00000000..a7a5cd96 --- /dev/null +++ b/include/FLAC/ordinals.h @@ -0,0 +1,80 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__ORDINALS_H +#define FLAC__ORDINALS_H + +#if !(defined(_MSC_VER) || defined(__BORLANDC__) || defined(__EMX__)) +#include <inttypes.h> +#endif + +typedef signed char FLAC__int8; +typedef unsigned char FLAC__uint8; + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int16 FLAC__int16; +typedef __int32 FLAC__int32; +typedef __int64 FLAC__int64; +typedef unsigned __int16 FLAC__uint16; +typedef unsigned __int32 FLAC__uint32; +typedef unsigned __int64 FLAC__uint64; +#elif defined(__EMX__) +typedef short FLAC__int16; +typedef long FLAC__int32; +typedef long long FLAC__int64; +typedef unsigned short FLAC__uint16; +typedef unsigned long FLAC__uint32; +typedef unsigned long long FLAC__uint64; +#else +typedef int16_t FLAC__int16; +typedef int32_t FLAC__int32; +typedef int64_t FLAC__int64; +typedef uint16_t FLAC__uint16; +typedef uint32_t FLAC__uint32; +typedef uint64_t FLAC__uint64; +#endif + +typedef int FLAC__bool; + +typedef FLAC__uint8 FLAC__byte; + +#ifdef true +#undef true +#endif +#ifdef false +#undef false +#endif +#ifndef __cplusplus +#define true 1 +#define false 0 +#endif + +#endif diff --git a/include/FLAC/stream_decoder.h b/include/FLAC/stream_decoder.h new file mode 100644 index 00000000..9ac15947 --- /dev/null +++ b/include/FLAC/stream_decoder.h @@ -0,0 +1,1559 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__STREAM_DECODER_H +#define FLAC__STREAM_DECODER_H + +#include <stdio.h> /* for FILE */ +#include "export.h" +#include "format.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \file include/FLAC/stream_decoder.h + * + * \brief + * This module contains the functions which implement the stream + * decoder. + * + * See the detailed documentation in the + * \link flac_stream_decoder stream decoder \endlink module. + */ + +/** \defgroup flac_decoder FLAC/ \*_decoder.h: decoder interfaces + * \ingroup flac + * + * \brief + * This module describes the decoder layers provided by libFLAC. + * + * The stream decoder can be used to decode complete streams either from + * the client via callbacks, or directly from a file, depending on how + * it is initialized. When decoding via callbacks, the client provides + * callbacks for reading FLAC data and writing decoded samples, and + * handling metadata and errors. If the client also supplies seek-related + * callback, the decoder function for sample-accurate seeking within the + * FLAC input is also available. When decoding from a file, the client + * needs only supply a filename or open \c FILE* and write/metadata/error + * callbacks; the rest of the callbacks are supplied internally. For more + * info see the \link flac_stream_decoder stream decoder \endlink module. + */ + +/** \defgroup flac_stream_decoder FLAC/stream_decoder.h: stream decoder interface + * \ingroup flac_decoder + * + * \brief + * This module contains the functions which implement the stream + * decoder. + * + * The stream decoder can decode native FLAC, and optionally Ogg FLAC + * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files. + * + * The basic usage of this decoder is as follows: + * - The program creates an instance of a decoder using + * FLAC__stream_decoder_new(). + * - The program overrides the default settings using + * FLAC__stream_decoder_set_*() functions. + * - The program initializes the instance to validate the settings and + * prepare for decoding using + * - FLAC__stream_decoder_init_stream() or FLAC__stream_decoder_init_FILE() + * or FLAC__stream_decoder_init_file() for native FLAC, + * - FLAC__stream_decoder_init_ogg_stream() or FLAC__stream_decoder_init_ogg_FILE() + * or FLAC__stream_decoder_init_ogg_file() for Ogg FLAC + * - The program calls the FLAC__stream_decoder_process_*() functions + * to decode data, which subsequently calls the callbacks. + * - The program finishes the decoding with FLAC__stream_decoder_finish(), + * which flushes the input and output and resets the decoder to the + * uninitialized state. + * - The instance may be used again or deleted with + * FLAC__stream_decoder_delete(). + * + * In more detail, the program will create a new instance by calling + * FLAC__stream_decoder_new(), then call FLAC__stream_decoder_set_*() + * functions to override the default decoder options, and call + * one of the FLAC__stream_decoder_init_*() functions. + * + * There are three initialization functions for native FLAC, one for + * setting up the decoder to decode FLAC data from the client via + * callbacks, and two for decoding directly from a FLAC file. + * + * For decoding via callbacks, use FLAC__stream_decoder_init_stream(). + * You must also supply several callbacks for handling I/O. Some (like + * seeking) are optional, depending on the capabilities of the input. + * + * For decoding directly from a file, use FLAC__stream_decoder_init_FILE() + * or FLAC__stream_decoder_init_file(). Then you must only supply an open + * \c FILE* or filename and fewer callbacks; the decoder will handle + * the other callbacks internally. + * + * There are three similarly-named init functions for decoding from Ogg + * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the + * library has been built with Ogg support. + * + * Once the decoder is initialized, your program will call one of several + * functions to start the decoding process: + * + * - FLAC__stream_decoder_process_single() - Tells the decoder to process at + * most one metadata block or audio frame and return, calling either the + * metadata callback or write callback, respectively, once. If the decoder + * loses sync it will return with only the error callback being called. + * - FLAC__stream_decoder_process_until_end_of_metadata() - Tells the decoder + * to process the stream from the current location and stop upon reaching + * the first audio frame. The client will get one metadata, write, or error + * callback per metadata block, audio frame, or sync error, respectively. + * - FLAC__stream_decoder_process_until_end_of_stream() - Tells the decoder + * to process the stream from the current location until the read callback + * returns FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM or + * FLAC__STREAM_DECODER_READ_STATUS_ABORT. The client will get one metadata, + * write, or error callback per metadata block, audio frame, or sync error, + * respectively. + * + * When the decoder has finished decoding (normally or through an abort), + * the instance is finished by calling FLAC__stream_decoder_finish(), which + * ensures the decoder is in the correct state and frees memory. Then the + * instance may be deleted with FLAC__stream_decoder_delete() or initialized + * again to decode another stream. + * + * Seeking is exposed through the FLAC__stream_decoder_seek_absolute() method. + * At any point after the stream decoder has been initialized, the client can + * call this function to seek to an exact sample within the stream. + * Subsequently, the first time the write callback is called it will be + * passed a (possibly partial) block starting at that sample. + * + * If the client cannot seek via the callback interface provided, but still + * has another way of seeking, it can flush the decoder using + * FLAC__stream_decoder_flush() and start feeding data from the new position + * through the read callback. + * + * The stream decoder also provides MD5 signature checking. If this is + * turned on before initialization, FLAC__stream_decoder_finish() will + * report when the decoded MD5 signature does not match the one stored + * in the STREAMINFO block. MD5 checking is automatically turned off + * (until the next FLAC__stream_decoder_reset()) if there is no signature + * in the STREAMINFO block or when a seek is attempted. + * + * The FLAC__stream_decoder_set_metadata_*() functions deserve special + * attention. By default, the decoder only calls the metadata_callback for + * the STREAMINFO block. These functions allow you to tell the decoder + * explicitly which blocks to parse and return via the metadata_callback + * and/or which to skip. Use a FLAC__stream_decoder_set_metadata_respond_all(), + * FLAC__stream_decoder_set_metadata_ignore() ... or FLAC__stream_decoder_set_metadata_ignore_all(), + * FLAC__stream_decoder_set_metadata_respond() ... sequence to exactly specify + * which blocks to return. Remember that metadata blocks can potentially + * be big (for example, cover art) so filtering out the ones you don't + * use can reduce the memory requirements of the decoder. Also note the + * special forms FLAC__stream_decoder_set_metadata_respond_application(id) + * and FLAC__stream_decoder_set_metadata_ignore_application(id) for + * filtering APPLICATION blocks based on the application ID. + * + * STREAMINFO and SEEKTABLE blocks are always parsed and used internally, but + * they still can legally be filtered from the metadata_callback. + * + * \note + * The "set" functions may only be called when the decoder is in the + * state FLAC__STREAM_DECODER_UNINITIALIZED, i.e. after + * FLAC__stream_decoder_new() or FLAC__stream_decoder_finish(), but + * before FLAC__stream_decoder_init_*(). If this is the case they will + * return \c true, otherwise \c false. + * + * \note + * FLAC__stream_decoder_finish() resets all settings to the constructor + * defaults, including the callbacks. + * + * \{ + */ + + +/** State values for a FLAC__StreamDecoder + * + * The decoder's state can be obtained by calling FLAC__stream_decoder_get_state(). + */ +typedef enum { + + FLAC__STREAM_DECODER_SEARCH_FOR_METADATA = 0, + /**< The decoder is ready to search for metadata. */ + + FLAC__STREAM_DECODER_READ_METADATA, + /**< The decoder is ready to or is in the process of reading metadata. */ + + FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC, + /**< The decoder is ready to or is in the process of searching for the + * frame sync code. + */ + + FLAC__STREAM_DECODER_READ_FRAME, + /**< The decoder is ready to or is in the process of reading a frame. */ + + FLAC__STREAM_DECODER_END_OF_STREAM, + /**< The decoder has reached the end of the stream. */ + + FLAC__STREAM_DECODER_OGG_ERROR, + /**< An error occurred in the underlying Ogg layer. */ + + FLAC__STREAM_DECODER_SEEK_ERROR, + /**< An error occurred while seeking. The decoder must be flushed + * with FLAC__stream_decoder_flush() or reset with + * FLAC__stream_decoder_reset() before decoding can continue. + */ + + FLAC__STREAM_DECODER_ABORTED, + /**< The decoder was aborted by the read callback. */ + + FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR, + /**< An error occurred allocating memory. The decoder is in an invalid + * state and can no longer be used. + */ + + FLAC__STREAM_DECODER_UNINITIALIZED + /**< The decoder is in the uninitialized state; one of the + * FLAC__stream_decoder_init_*() functions must be called before samples + * can be processed. + */ + +} FLAC__StreamDecoderState; + +/** Maps a FLAC__StreamDecoderState to a C string. + * + * Using a FLAC__StreamDecoderState as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderStateString[]; + + +/** Possible return values for the FLAC__stream_decoder_init_*() functions. + */ +typedef enum { + + FLAC__STREAM_DECODER_INIT_STATUS_OK = 0, + /**< Initialization was successful. */ + + FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER, + /**< The library was not compiled with support for the given container + * format. + */ + + FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS, + /**< A required callback was not supplied. */ + + FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR, + /**< An error occurred allocating memory. */ + + FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE, + /**< fopen() failed in FLAC__stream_decoder_init_file() or + * FLAC__stream_decoder_init_ogg_file(). */ + + FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED + /**< FLAC__stream_decoder_init_*() was called when the decoder was + * already initialized, usually because + * FLAC__stream_decoder_finish() was not called. + */ + +} FLAC__StreamDecoderInitStatus; + +/** Maps a FLAC__StreamDecoderInitStatus to a C string. + * + * Using a FLAC__StreamDecoderInitStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderInitStatusString[]; + + +/** Return values for the FLAC__StreamDecoder read callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, + /**< The read was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM, + /**< The read was attempted while at the end of the stream. Note that + * the client must only return this value when the read callback was + * called when already at the end of the stream. Otherwise, if the read + * itself moves to the end of the stream, the client should still return + * the data and \c FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, and then on + * the next read callback it should return + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM with a byte count + * of \c 0. + */ + + FLAC__STREAM_DECODER_READ_STATUS_ABORT + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + +} FLAC__StreamDecoderReadStatus; + +/** Maps a FLAC__StreamDecoderReadStatus to a C string. + * + * Using a FLAC__StreamDecoderReadStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderReadStatusString[]; + + +/** Return values for the FLAC__StreamDecoder seek callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_SEEK_STATUS_OK, + /**< The seek was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_SEEK_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + + FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED + /**< Client does not support seeking. */ + +} FLAC__StreamDecoderSeekStatus; + +/** Maps a FLAC__StreamDecoderSeekStatus to a C string. + * + * Using a FLAC__StreamDecoderSeekStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[]; + + +/** Return values for the FLAC__StreamDecoder tell callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_TELL_STATUS_OK, + /**< The tell was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_TELL_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + + FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED + /**< Client does not support telling the position. */ + +} FLAC__StreamDecoderTellStatus; + +/** Maps a FLAC__StreamDecoderTellStatus to a C string. + * + * Using a FLAC__StreamDecoderTellStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderTellStatusString[]; + + +/** Return values for the FLAC__StreamDecoder length callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_LENGTH_STATUS_OK, + /**< The length call was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + + FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED + /**< Client does not support reporting the length. */ + +} FLAC__StreamDecoderLengthStatus; + +/** Maps a FLAC__StreamDecoderLengthStatus to a C string. + * + * Using a FLAC__StreamDecoderLengthStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[]; + + +/** Return values for the FLAC__StreamDecoder write callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE, + /**< The write was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_WRITE_STATUS_ABORT + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + +} FLAC__StreamDecoderWriteStatus; + +/** Maps a FLAC__StreamDecoderWriteStatus to a C string. + * + * Using a FLAC__StreamDecoderWriteStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[]; + + +/** Possible values passed back to the FLAC__StreamDecoder error callback. + * \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC is the generic catch- + * all. The rest could be caused by bad sync (false synchronization on + * data that is not the start of a frame) or corrupted data. The error + * itself is the decoder's best guess at what happened assuming a correct + * sync. For example \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER + * could be caused by a correct sync on the start of a frame, but some + * data in the frame header was corrupted. Or it could be the result of + * syncing on a point the stream that looked like the starting of a frame + * but was not. \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM + * could be because the decoder encountered a valid frame made by a future + * version of the encoder which it cannot parse, or because of a false + * sync making it appear as though an encountered frame was generated by + * a future encoder. + */ +typedef enum { + + FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, + /**< An error in the stream caused the decoder to lose synchronization. */ + + FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, + /**< The decoder encountered a corrupted frame header. */ + + FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, + /**< The frame's data did not match the CRC in the footer. */ + + FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM + /**< The decoder encountered reserved fields in use in the stream. */ + +} FLAC__StreamDecoderErrorStatus; + +/** Maps a FLAC__StreamDecoderErrorStatus to a C string. + * + * Using a FLAC__StreamDecoderErrorStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[]; + + +/*********************************************************************** + * + * class FLAC__StreamDecoder + * + ***********************************************************************/ + +struct FLAC__StreamDecoderProtected; +struct FLAC__StreamDecoderPrivate; +/** The opaque structure definition for the stream decoder type. + * See the \link flac_stream_decoder stream decoder module \endlink + * for a detailed description. + */ +typedef struct { + struct FLAC__StreamDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */ + struct FLAC__StreamDecoderPrivate *private_; /* avoid the C++ keyword 'private' */ +} FLAC__StreamDecoder; + +/** Signature for the read callback. + * + * A function pointer matching this signature must be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder needs more input data. The address of the + * buffer to be filled is supplied, along with the number of bytes the + * buffer can hold. The callback may choose to supply less data and + * modify the byte count but must be careful not to overflow the buffer. + * The callback then returns a status code chosen from + * FLAC__StreamDecoderReadStatus. + * + * Here is an example of a read callback for stdio streams: + * \code + * FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * if(*bytes > 0) { + * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file); + * if(ferror(file)) + * return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + * else if(*bytes == 0) + * return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + * else + * return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + * } + * else + * return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param buffer A pointer to a location for the callee to store + * data to be decoded. + * \param bytes A pointer to the size of the buffer. On entry + * to the callback, it contains the maximum number + * of bytes that may be stored in \a buffer. The + * callee must set it to the actual number of bytes + * stored (0 in case of error or end-of-stream) before + * returning. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderReadStatus + * The callee's return status. Note that the callback should return + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM if and only if + * zero bytes were read and there is no more data to be read. + */ +typedef FLAC__StreamDecoderReadStatus (*FLAC__StreamDecoderReadCallback)(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); + +/** Signature for the seek callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder needs to seek the input stream. The decoder + * will pass the absolute byte offset to seek to, 0 meaning the + * beginning of the stream. + * + * Here is an example of a seek callback for stdio streams: + * \code + * FLAC__StreamDecoderSeekStatus seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * if(file == stdin) + * return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; + * else if(fseeko(file, (off_t)absolute_byte_offset, SEEK_SET) < 0) + * return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; + * else + * return FLAC__STREAM_DECODER_SEEK_STATUS_OK; + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param absolute_byte_offset The offset from the beginning of the stream + * to seek to. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderSeekStatus + * The callee's return status. + */ +typedef FLAC__StreamDecoderSeekStatus (*FLAC__StreamDecoderSeekCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); + +/** Signature for the tell callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder wants to know the current position of the + * stream. The callback should return the byte offset from the + * beginning of the stream. + * + * Here is an example of a tell callback for stdio streams: + * \code + * FLAC__StreamDecoderTellStatus tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * off_t pos; + * if(file == stdin) + * return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED; + * else if((pos = ftello(file)) < 0) + * return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; + * else { + * *absolute_byte_offset = (FLAC__uint64)pos; + * return FLAC__STREAM_DECODER_TELL_STATUS_OK; + * } + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param absolute_byte_offset A pointer to storage for the current offset + * from the beginning of the stream. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderTellStatus + * The callee's return status. + */ +typedef FLAC__StreamDecoderTellStatus (*FLAC__StreamDecoderTellCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); + +/** Signature for the length callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder wants to know the total length of the stream + * in bytes. + * + * Here is an example of a length callback for stdio streams: + * \code + * FLAC__StreamDecoderLengthStatus length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * struct stat filestats; + * + * if(file == stdin) + * return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; + * else if(fstat(fileno(file), &filestats) != 0) + * return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; + * else { + * *stream_length = (FLAC__uint64)filestats.st_size; + * return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; + * } + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param stream_length A pointer to storage for the length of the stream + * in bytes. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderLengthStatus + * The callee's return status. + */ +typedef FLAC__StreamDecoderLengthStatus (*FLAC__StreamDecoderLengthCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); + +/** Signature for the EOF callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder needs to know if the end of the stream has + * been reached. + * + * Here is an example of a EOF callback for stdio streams: + * FLAC__bool eof_cb(const FLAC__StreamDecoder *decoder, void *client_data) + * \code + * { + * FILE *file = ((MyClientData*)client_data)->file; + * return feof(file)? true : false; + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__bool + * \c true if the currently at the end of the stream, else \c false. + */ +typedef FLAC__bool (*FLAC__StreamDecoderEofCallback)(const FLAC__StreamDecoder *decoder, void *client_data); + +/** Signature for the write callback. + * + * A function pointer matching this signature must be passed to one of + * the FLAC__stream_decoder_init_*() functions. + * The supplied function will be called when the decoder has decoded a + * single audio frame. The decoder will pass the frame metadata as well + * as an array of pointers (one for each channel) pointing to the + * decoded audio. + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param frame The description of the decoded frame. See + * FLAC__Frame. + * \param buffer An array of pointers to decoded channels of data. + * Each pointer will point to an array of signed + * samples of length \a frame->header.blocksize. + * Channels will be ordered according to the FLAC + * specification; see the documentation for the + * <A HREF="../format.html#frame_header">frame header</A>. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderWriteStatus + * The callee's return status. + */ +typedef FLAC__StreamDecoderWriteStatus (*FLAC__StreamDecoderWriteCallback)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); + +/** Signature for the metadata callback. + * + * A function pointer matching this signature must be passed to one of + * the FLAC__stream_decoder_init_*() functions. + * The supplied function will be called when the decoder has decoded a + * metadata block. In a valid FLAC file there will always be one + * \c STREAMINFO block, followed by zero or more other metadata blocks. + * These will be supplied by the decoder in the same order as they + * appear in the stream and always before the first audio frame (i.e. + * write callback). The metadata block that is passed in must not be + * modified, and it doesn't live beyond the callback, so you should make + * a copy of it with FLAC__metadata_object_clone() if you will need it + * elsewhere. Since metadata blocks can potentially be large, by + * default the decoder only calls the metadata callback for the + * \c STREAMINFO block; you can instruct the decoder to pass or filter + * other blocks with FLAC__stream_decoder_set_metadata_*() calls. + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param metadata The decoded metadata block. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + */ +typedef void (*FLAC__StreamDecoderMetadataCallback)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); + +/** Signature for the error callback. + * + * A function pointer matching this signature must be passed to one of + * the FLAC__stream_decoder_init_*() functions. + * The supplied function will be called whenever an error occurs during + * decoding. + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param status The error encountered by the decoder. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + */ +typedef void (*FLAC__StreamDecoderErrorCallback)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); + + +/*********************************************************************** + * + * Class constructor/destructor + * + ***********************************************************************/ + +/** Create a new stream decoder instance. The instance is created with + * default settings; see the individual FLAC__stream_decoder_set_*() + * functions for each setting's default. + * + * \retval FLAC__StreamDecoder* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void); + +/** Free a decoder instance. Deletes the object pointed to by \a decoder. + * + * \param decoder A pointer to an existing decoder. + * \assert + * \code decoder != NULL \endcode + */ +FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder); + + +/*********************************************************************** + * + * Public class method prototypes + * + ***********************************************************************/ + +/** Set the serial number for the FLAC stream within the Ogg container. + * The default behavior is to use the serial number of the first Ogg + * page. Setting a serial number here will explicitly specify which + * stream is to be decoded. + * + * \note + * This does not need to be set for native FLAC decoding. + * + * \default \c use serial number of first page + * \param decoder A decoder instance to set. + * \param serial_number See above. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecoder *decoder, long serial_number); + +/** Set the "MD5 signature checking" flag. If \c true, the decoder will + * compute the MD5 signature of the unencoded audio data while decoding + * and compare it to the signature from the STREAMINFO block, if it + * exists, during FLAC__stream_decoder_finish(). + * + * MD5 signature checking will be turned off (until the next + * FLAC__stream_decoder_reset()) if there is no signature in the + * STREAMINFO block or when a seek is attempted. + * + * Clients that do not use the MD5 check should leave this off to speed + * up decoding. + * + * \default \c false + * \param decoder A decoder instance to set. + * \param value Flag value (see above). + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value); + +/** Direct the decoder to pass on all metadata blocks of type \a type. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \param type See above. + * \assert + * \code decoder != NULL \endcode + * \a type is valid + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type); + +/** Direct the decoder to pass on all APPLICATION metadata blocks of the + * given \a id. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \param id See above. + * \assert + * \code decoder != NULL \endcode + * \code id != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); + +/** Direct the decoder to pass on all metadata blocks of any type. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder); + +/** Direct the decoder to filter out all metadata blocks of type \a type. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \param type See above. + * \assert + * \code decoder != NULL \endcode + * \a type is valid + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type); + +/** Direct the decoder to filter out all APPLICATION metadata blocks of + * the given \a id. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \param id See above. + * \assert + * \code decoder != NULL \endcode + * \code id != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); + +/** Direct the decoder to filter out all metadata blocks of any type. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder); + +/** Get the current decoder state. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderState + * The current decoder state. + */ +FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder); + +/** Get the current decoder state as a C string. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval const char * + * The decoder state as a C string. Do not modify the contents. + */ +FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder); + +/** Get the "MD5 signature checking" flag. + * This is the value of the setting, not whether or not the decoder is + * currently checking the MD5 (remember, it can be turned off automatically + * by a seek). When the decoder is reset the flag will be restored to the + * value returned by this function. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * See above. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder); + +/** Get the total number of samples in the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the \c STREAMINFO block. A value of \c 0 means "unknown". + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder); + +/** Get the current number of channels in the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder); + +/** Get the current channel assignment in the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__ChannelAssignment + * See above. + */ +FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder); + +/** Get the current sample resolution in the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder); + +/** Get the current sample rate in Hz of the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder); + +/** Get the current blocksize of the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API unsigned FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder); + +/** Returns the decoder's current read position within the stream. + * The position is the byte offset from the start of the stream. + * Bytes before this position have been fully decoded. Note that + * there may still be undecoded bytes in the decoder's read FIFO. + * The returned position is correct even after a seek. + * + * \warning This function currently only works for native FLAC, + * not Ogg FLAC streams. + * + * \param decoder A decoder instance to query. + * \param position Address at which to return the desired position. + * \assert + * \code decoder != NULL \endcode + * \code position != NULL \endcode + * \retval FLAC__bool + * \c true if successful, \c false if the stream is not native FLAC, + * or there was an error from the 'tell' callback or it returned + * \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position); + +/** Initialize the decoder instance to decode native FLAC streams. + * + * This flavor of initialization sets up the decoder to decode from a + * native FLAC stream. I/O is performed via callbacks to the client. + * For decoding from a plain file via filename or open FILE*, + * FLAC__stream_decoder_init_file() and FLAC__stream_decoder_init_FILE() + * provide a simpler interface. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \param decoder An uninitialized decoder instance. + * \param read_callback See FLAC__StreamDecoderReadCallback. This + * pointer must not be \c NULL. + * \param seek_callback See FLAC__StreamDecoderSeekCallback. This + * pointer may be \c NULL if seeking is not + * supported. If \a seek_callback is not \c NULL then a + * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied. + * Alternatively, a dummy seek callback that just + * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param tell_callback See FLAC__StreamDecoderTellCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a tell_callback must also be supplied. + * Alternatively, a dummy tell callback that just + * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param length_callback See FLAC__StreamDecoderLengthCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a length_callback must also be supplied. + * Alternatively, a dummy length callback that just + * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param eof_callback See FLAC__StreamDecoderEofCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a eof_callback must also be supplied. + * Alternatively, a dummy length callback that just + * returns \c false + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream( + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode Ogg FLAC streams. + * + * This flavor of initialization sets up the decoder to decode from a + * FLAC stream in an Ogg container. I/O is performed via callbacks to the + * client. For decoding from a plain file via filename or open FILE*, + * FLAC__stream_decoder_init_ogg_file() and FLAC__stream_decoder_init_ogg_FILE() + * provide a simpler interface. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \note Support for Ogg FLAC in the library is optional. If this + * library has been built without support for Ogg FLAC, this function + * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. + * + * \param decoder An uninitialized decoder instance. + * \param read_callback See FLAC__StreamDecoderReadCallback. This + * pointer must not be \c NULL. + * \param seek_callback See FLAC__StreamDecoderSeekCallback. This + * pointer may be \c NULL if seeking is not + * supported. If \a seek_callback is not \c NULL then a + * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied. + * Alternatively, a dummy seek callback that just + * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param tell_callback See FLAC__StreamDecoderTellCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a tell_callback must also be supplied. + * Alternatively, a dummy tell callback that just + * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param length_callback See FLAC__StreamDecoderLengthCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a length_callback must also be supplied. + * Alternatively, a dummy length callback that just + * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param eof_callback See FLAC__StreamDecoderEofCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a eof_callback must also be supplied. + * Alternatively, a dummy length callback that just + * returns \c false + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream( + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode native FLAC files. + * + * This flavor of initialization sets up the decoder to decode from a + * plain native FLAC file. For non-stdio streams, you must use + * FLAC__stream_decoder_init_stream() and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \param decoder An uninitialized decoder instance. + * \param file An open FLAC file. The file should have been + * opened with mode \c "rb" and rewound. The file + * becomes owned by the decoder and should not be + * manipulated by the client while decoding. + * Unless \a file is \c stdin, it will be closed + * when FLAC__stream_decoder_finish() is called. + * Note however that seeking will not work when + * decoding from \c stdout since it is not seekable. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \code file != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE( + FLAC__StreamDecoder *decoder, + FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode Ogg FLAC files. + * + * This flavor of initialization sets up the decoder to decode from a + * plain Ogg FLAC file. For non-stdio streams, you must use + * FLAC__stream_decoder_init_ogg_stream() and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \note Support for Ogg FLAC in the library is optional. If this + * library has been built without support for Ogg FLAC, this function + * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. + * + * \param decoder An uninitialized decoder instance. + * \param file An open FLAC file. The file should have been + * opened with mode \c "rb" and rewound. The file + * becomes owned by the decoder and should not be + * manipulated by the client while decoding. + * Unless \a file is \c stdin, it will be closed + * when FLAC__stream_decoder_finish() is called. + * Note however that seeking will not work when + * decoding from \c stdout since it is not seekable. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \code file != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE( + FLAC__StreamDecoder *decoder, + FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode native FLAC files. + * + * This flavor of initialization sets up the decoder to decode from a plain + * native FLAC file. If POSIX fopen() semantics are not sufficient, (for + * example, with Unicode filenames on Windows), you must use + * FLAC__stream_decoder_init_FILE(), or FLAC__stream_decoder_init_stream() + * and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \param decoder An uninitialized decoder instance. + * \param filename The name of the file to decode from. The file will + * be opened with fopen(). Use \c NULL to decode from + * \c stdin. Note that \c stdin is not seekable. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file( + FLAC__StreamDecoder *decoder, + const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode Ogg FLAC files. + * + * This flavor of initialization sets up the decoder to decode from a plain + * Ogg FLAC file. If POSIX fopen() semantics are not sufficient, (for + * example, with Unicode filenames on Windows), you must use + * FLAC__stream_decoder_init_ogg_FILE(), or FLAC__stream_decoder_init_ogg_stream() + * and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \note Support for Ogg FLAC in the library is optional. If this + * library has been built without support for Ogg FLAC, this function + * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. + * + * \param decoder An uninitialized decoder instance. + * \param filename The name of the file to decode from. The file will + * be opened with fopen(). Use \c NULL to decode from + * \c stdin. Note that \c stdin is not seekable. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_file( + FLAC__StreamDecoder *decoder, + const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Finish the decoding process. + * Flushes the decoding buffer, releases resources, resets the decoder + * settings to their defaults, and returns the decoder state to + * FLAC__STREAM_DECODER_UNINITIALIZED. + * + * In the event of a prematurely-terminated decode, it is not strictly + * necessary to call this immediately before FLAC__stream_decoder_delete() + * but it is good practice to match every FLAC__stream_decoder_init_*() + * with a FLAC__stream_decoder_finish(). + * + * \param decoder An uninitialized decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if MD5 checking is on AND a STREAMINFO block was available + * AND the MD5 signature in the STREAMINFO block was non-zero AND the + * signature does not match the one computed by the decoder; else + * \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder); + +/** Flush the stream input. + * The decoder's input buffer will be cleared and the state set to + * \c FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC. This will also turn + * off MD5 checking. + * + * \param decoder A decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false if a memory allocation + * error occurs (in which case the state will be set to + * \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder); + +/** Reset the decoding process. + * The decoder's input buffer will be cleared and the state set to + * \c FLAC__STREAM_DECODER_SEARCH_FOR_METADATA. This is similar to + * FLAC__stream_decoder_finish() except that the settings are + * preserved; there is no need to call FLAC__stream_decoder_init_*() + * before decoding again. MD5 checking will be restored to its original + * setting. + * + * If the decoder is seekable, or was initialized with + * FLAC__stream_decoder_init*_FILE() or FLAC__stream_decoder_init*_file(), + * the decoder will also attempt to seek to the beginning of the file. + * If this rewind fails, this function will return \c false. It follows + * that FLAC__stream_decoder_reset() cannot be used when decoding from + * \c stdin. + * + * If the decoder was initialized with FLAC__stream_encoder_init*_stream() + * and is not seekable (i.e. no seek callback was provided or the seek + * callback returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED), it + * is the duty of the client to start feeding data from the beginning of + * the stream on the next FLAC__stream_decoder_process() or + * FLAC__stream_decoder_process_interleaved() call. + * + * \param decoder A decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false if a memory allocation occurs + * (in which case the state will be set to + * \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR) or a seek error + * occurs (the state will be unchanged). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder); + +/** Decode one metadata block or audio frame. + * This version instructs the decoder to decode a either a single metadata + * block or a single frame and stop, unless the callbacks return a fatal + * error or the read callback returns + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. + * + * As the decoder needs more input it will call the read callback. + * Depending on what was decoded, the metadata or write callback will be + * called with the decoded metadata block or audio frame. + * + * Unless there is a fatal read error or end of stream, this function + * will return once one whole frame is decoded. In other words, if the + * stream is not synchronized or points to a corrupt frame header, the + * decoder will continue to try and resync until it gets to a valid + * frame, then decode one frame, then return. If the decoder points to + * a frame whose frame CRC in the frame footer does not match the + * computed frame CRC, this function will issue a + * FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH error to the + * error callback, and return, having decoded one complete, although + * corrupt, frame. (Such corrupted frames are sent as silence of the + * correct length to the write callback.) + * + * \param decoder An initialized decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if any fatal read, write, or memory allocation error + * occurred (meaning decoding must stop), else \c true; for more + * information about the decoder, check the decoder state with + * FLAC__stream_decoder_get_state(). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder); + +/** Decode until the end of the metadata. + * This version instructs the decoder to decode from the current position + * and continue until all the metadata has been read, or until the + * callbacks return a fatal error or the read callback returns + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. + * + * As the decoder needs more input it will call the read callback. + * As each metadata block is decoded, the metadata callback will be called + * with the decoded metadata. + * + * \param decoder An initialized decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if any fatal read, write, or memory allocation error + * occurred (meaning decoding must stop), else \c true; for more + * information about the decoder, check the decoder state with + * FLAC__stream_decoder_get_state(). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder); + +/** Decode until the end of the stream. + * This version instructs the decoder to decode from the current position + * and continue until the end of stream (the read callback returns + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM), or until the + * callbacks return a fatal error. + * + * As the decoder needs more input it will call the read callback. + * As each metadata block and frame is decoded, the metadata or write + * callback will be called with the decoded metadata or frame. + * + * \param decoder An initialized decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if any fatal read, write, or memory allocation error + * occurred (meaning decoding must stop), else \c true; for more + * information about the decoder, check the decoder state with + * FLAC__stream_decoder_get_state(). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder); + +/** Skip one audio frame. + * This version instructs the decoder to 'skip' a single frame and stop, + * unless the callbacks return a fatal error or the read callback returns + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. + * + * The decoding flow is the same as what occurs when + * FLAC__stream_decoder_process_single() is called to process an audio + * frame, except that this function does not decode the parsed data into + * PCM or call the write callback. The integrity of the frame is still + * checked the same way as in the other process functions. + * + * This function will return once one whole frame is skipped, in the + * same way that FLAC__stream_decoder_process_single() will return once + * one whole frame is decoded. + * + * This function can be used in more quickly determining FLAC frame + * boundaries when decoding of the actual data is not needed, for + * example when an application is separating a FLAC stream into frames + * for editing or storing in a container. To do this, the application + * can use FLAC__stream_decoder_skip_single_frame() to quickly advance + * to the next frame, then use + * FLAC__stream_decoder_get_decode_position() to find the new frame + * boundary. + * + * This function should only be called when the stream has advanced + * past all the metadata, otherwise it will return \c false. + * + * \param decoder An initialized decoder instance not in a metadata + * state. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if any fatal read, write, or memory allocation error + * occurred (meaning decoding must stop), or if the decoder + * is in the FLAC__STREAM_DECODER_SEARCH_FOR_METADATA or + * FLAC__STREAM_DECODER_READ_METADATA state, else \c true; for more + * information about the decoder, check the decoder state with + * FLAC__stream_decoder_get_state(). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder); + +/** Flush the input and seek to an absolute sample. + * Decoding will resume at the given sample. Note that because of + * this, the next write callback may contain a partial block. The + * client must support seeking the input or this function will fail + * and return \c false. Furthermore, if the decoder state is + * \c FLAC__STREAM_DECODER_SEEK_ERROR, then the decoder must be flushed + * with FLAC__stream_decoder_flush() or reset with + * FLAC__stream_decoder_reset() before decoding can continue. + * + * \param decoder A decoder instance. + * \param sample The target sample number to seek to. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute(FLAC__StreamDecoder *decoder, FLAC__uint64 sample); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/FLAC/stream_encoder.h b/include/FLAC/stream_encoder.h new file mode 100644 index 00000000..dbbbb23e --- /dev/null +++ b/include/FLAC/stream_encoder.h @@ -0,0 +1,1768 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__STREAM_ENCODER_H +#define FLAC__STREAM_ENCODER_H + +#include <stdio.h> /* for FILE */ +#include "export.h" +#include "format.h" +#include "stream_decoder.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \file include/FLAC/stream_encoder.h + * + * \brief + * This module contains the functions which implement the stream + * encoder. + * + * See the detailed documentation in the + * \link flac_stream_encoder stream encoder \endlink module. + */ + +/** \defgroup flac_encoder FLAC/ \*_encoder.h: encoder interfaces + * \ingroup flac + * + * \brief + * This module describes the encoder layers provided by libFLAC. + * + * The stream encoder can be used to encode complete streams either to the + * client via callbacks, or directly to a file, depending on how it is + * initialized. When encoding via callbacks, the client provides a write + * callback which will be called whenever FLAC data is ready to be written. + * If the client also supplies a seek callback, the encoder will also + * automatically handle the writing back of metadata discovered while + * encoding, like stream info, seek points offsets, etc. When encoding to + * a file, the client needs only supply a filename or open \c FILE* and an + * optional progress callback for periodic notification of progress; the + * write and seek callbacks are supplied internally. For more info see the + * \link flac_stream_encoder stream encoder \endlink module. + */ + +/** \defgroup flac_stream_encoder FLAC/stream_encoder.h: stream encoder interface + * \ingroup flac_encoder + * + * \brief + * This module contains the functions which implement the stream + * encoder. + * + * The stream encoder can encode to native FLAC, and optionally Ogg FLAC + * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files. + * + * The basic usage of this encoder is as follows: + * - The program creates an instance of an encoder using + * FLAC__stream_encoder_new(). + * - The program overrides the default settings using + * FLAC__stream_encoder_set_*() functions. At a minimum, the following + * functions should be called: + * - FLAC__stream_encoder_set_channels() + * - FLAC__stream_encoder_set_bits_per_sample() + * - FLAC__stream_encoder_set_sample_rate() + * - FLAC__stream_encoder_set_ogg_serial_number() (if encoding to Ogg FLAC) + * - FLAC__stream_encoder_set_total_samples_estimate() (if known) + * - If the application wants to control the compression level or set its own + * metadata, then the following should also be called: + * - FLAC__stream_encoder_set_compression_level() + * - FLAC__stream_encoder_set_verify() + * - FLAC__stream_encoder_set_metadata() + * - The rest of the set functions should only be called if the client needs + * exact control over how the audio is compressed; thorough understanding + * of the FLAC format is necessary to achieve good results. + * - The program initializes the instance to validate the settings and + * prepare for encoding using + * - FLAC__stream_encoder_init_stream() or FLAC__stream_encoder_init_FILE() + * or FLAC__stream_encoder_init_file() for native FLAC + * - FLAC__stream_encoder_init_ogg_stream() or FLAC__stream_encoder_init_ogg_FILE() + * or FLAC__stream_encoder_init_ogg_file() for Ogg FLAC + * - The program calls FLAC__stream_encoder_process() or + * FLAC__stream_encoder_process_interleaved() to encode data, which + * subsequently calls the callbacks when there is encoder data ready + * to be written. + * - The program finishes the encoding with FLAC__stream_encoder_finish(), + * which causes the encoder to encode any data still in its input pipe, + * update the metadata with the final encoding statistics if output + * seeking is possible, and finally reset the encoder to the + * uninitialized state. + * - The instance may be used again or deleted with + * FLAC__stream_encoder_delete(). + * + * In more detail, the stream encoder functions similarly to the + * \link flac_stream_decoder stream decoder \endlink, but has fewer + * callbacks and more options. Typically the client will create a new + * instance by calling FLAC__stream_encoder_new(), then set the necessary + * parameters with FLAC__stream_encoder_set_*(), and initialize it by + * calling one of the FLAC__stream_encoder_init_*() functions. + * + * Unlike the decoders, the stream encoder has many options that can + * affect the speed and compression ratio. When setting these parameters + * you should have some basic knowledge of the format (see the + * <A HREF="../documentation.html#format">user-level documentation</A> + * or the <A HREF="../format.html">formal description</A>). The + * FLAC__stream_encoder_set_*() functions themselves do not validate the + * values as many are interdependent. The FLAC__stream_encoder_init_*() + * functions will do this, so make sure to pay attention to the state + * returned by FLAC__stream_encoder_init_*() to make sure that it is + * FLAC__STREAM_ENCODER_INIT_STATUS_OK. Any parameters that are not set + * before FLAC__stream_encoder_init_*() will take on the defaults from + * the constructor. + * + * There are three initialization functions for native FLAC, one for + * setting up the encoder to encode FLAC data to the client via + * callbacks, and two for encoding directly to a file. + * + * For encoding via callbacks, use FLAC__stream_encoder_init_stream(). + * You must also supply a write callback which will be called anytime + * there is raw encoded data to write. If the client can seek the output + * it is best to also supply seek and tell callbacks, as this allows the + * encoder to go back after encoding is finished to write back + * information that was collected while encoding, like seek point offsets, + * frame sizes, etc. + * + * For encoding directly to a file, use FLAC__stream_encoder_init_FILE() + * or FLAC__stream_encoder_init_file(). Then you must only supply a + * filename or open \c FILE*; the encoder will handle all the callbacks + * internally. You may also supply a progress callback for periodic + * notification of the encoding progress. + * + * There are three similarly-named init functions for encoding to Ogg + * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the + * library has been built with Ogg support. + * + * The call to FLAC__stream_encoder_init_*() currently will also immediately + * call the write callback several times, once with the \c fLaC signature, + * and once for each encoded metadata block. Note that for Ogg FLAC + * encoding you will usually get at least twice the number of callbacks than + * with native FLAC, one for the Ogg page header and one for the page body. + * + * After initializing the instance, the client may feed audio data to the + * encoder in one of two ways: + * + * - Channel separate, through FLAC__stream_encoder_process() - The client + * will pass an array of pointers to buffers, one for each channel, to + * the encoder, each of the same length. The samples need not be + * block-aligned, but each channel should have the same number of samples. + * - Channel interleaved, through + * FLAC__stream_encoder_process_interleaved() - The client will pass a single + * pointer to data that is channel-interleaved (i.e. channel0_sample0, + * channel1_sample0, ... , channelN_sample0, channel0_sample1, ...). + * Again, the samples need not be block-aligned but they must be + * sample-aligned, i.e. the first value should be channel0_sample0 and + * the last value channelN_sampleM. + * + * Note that for either process call, each sample in the buffers should be a + * signed integer, right-justified to the resolution set by + * FLAC__stream_encoder_set_bits_per_sample(). For example, if the resolution + * is 16 bits per sample, the samples should all be in the range [-32768,32767]. + * + * When the client is finished encoding data, it calls + * FLAC__stream_encoder_finish(), which causes the encoder to encode any + * data still in its input pipe, and call the metadata callback with the + * final encoding statistics. Then the instance may be deleted with + * FLAC__stream_encoder_delete() or initialized again to encode another + * stream. + * + * For programs that write their own metadata, but that do not know the + * actual metadata until after encoding, it is advantageous to instruct + * the encoder to write a PADDING block of the correct size, so that + * instead of rewriting the whole stream after encoding, the program can + * just overwrite the PADDING block. If only the maximum size of the + * metadata is known, the program can write a slightly larger padding + * block, then split it after encoding. + * + * Make sure you understand how lengths are calculated. All FLAC metadata + * blocks have a 4 byte header which contains the type and length. This + * length does not include the 4 bytes of the header. See the format page + * for the specification of metadata blocks and their lengths. + * + * \note + * If you are writing the FLAC data to a file via callbacks, make sure it + * is open for update (e.g. mode "w+" for stdio streams). This is because + * after the first encoding pass, the encoder will try to seek back to the + * beginning of the stream, to the STREAMINFO block, to write some data + * there. (If using FLAC__stream_encoder_init*_file() or + * FLAC__stream_encoder_init*_FILE(), the file is managed internally.) + * + * \note + * The "set" functions may only be called when the encoder is in the + * state FLAC__STREAM_ENCODER_UNINITIALIZED, i.e. after + * FLAC__stream_encoder_new() or FLAC__stream_encoder_finish(), but + * before FLAC__stream_encoder_init_*(). If this is the case they will + * return \c true, otherwise \c false. + * + * \note + * FLAC__stream_encoder_finish() resets all settings to the constructor + * defaults. + * + * \{ + */ + + +/** State values for a FLAC__StreamEncoder. + * + * The encoder's state can be obtained by calling FLAC__stream_encoder_get_state(). + * + * If the encoder gets into any other state besides \c FLAC__STREAM_ENCODER_OK + * or \c FLAC__STREAM_ENCODER_UNINITIALIZED, it becomes invalid for encoding and + * must be deleted with FLAC__stream_encoder_delete(). + */ +typedef enum { + + FLAC__STREAM_ENCODER_OK = 0, + /**< The encoder is in the normal OK state and samples can be processed. */ + + FLAC__STREAM_ENCODER_UNINITIALIZED, + /**< The encoder is in the uninitialized state; one of the + * FLAC__stream_encoder_init_*() functions must be called before samples + * can be processed. + */ + + FLAC__STREAM_ENCODER_OGG_ERROR, + /**< An error occurred in the underlying Ogg layer. */ + + FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR, + /**< An error occurred in the underlying verify stream decoder; + * check FLAC__stream_encoder_get_verify_decoder_state(). + */ + + FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA, + /**< The verify decoder detected a mismatch between the original + * audio signal and the decoded audio signal. + */ + + FLAC__STREAM_ENCODER_CLIENT_ERROR, + /**< One of the callbacks returned a fatal error. */ + + FLAC__STREAM_ENCODER_IO_ERROR, + /**< An I/O error occurred while opening/reading/writing a file. + * Check \c errno. + */ + + FLAC__STREAM_ENCODER_FRAMING_ERROR, + /**< An error occurred while writing the stream; usually, the + * write_callback returned an error. + */ + + FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR + /**< Memory allocation failed. */ + +} FLAC__StreamEncoderState; + +/** Maps a FLAC__StreamEncoderState to a C string. + * + * Using a FLAC__StreamEncoderState as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderStateString[]; + + +/** Possible return values for the FLAC__stream_encoder_init_*() functions. + */ +typedef enum { + + FLAC__STREAM_ENCODER_INIT_STATUS_OK = 0, + /**< Initialization was successful. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR, + /**< General failure to set up encoder; call FLAC__stream_encoder_get_state() for cause. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER, + /**< The library was not compiled with support for the given container + * format. + */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS, + /**< A required callback was not supplied. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS, + /**< The encoder has an invalid setting for number of channels. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE, + /**< The encoder has an invalid setting for bits-per-sample. + * FLAC supports 4-32 bps but the reference encoder currently supports + * only up to 24 bps. + */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE, + /**< The encoder has an invalid setting for the input sample rate. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE, + /**< The encoder has an invalid setting for the block size. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER, + /**< The encoder has an invalid setting for the maximum LPC order. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION, + /**< The encoder has an invalid setting for the precision of the quantized linear predictor coefficients. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER, + /**< The specified block size is less than the maximum LPC order. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE, + /**< The encoder is bound to the <A HREF="../format.html#subset">Subset</A> but other settings violate it. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA, + /**< The metadata input to the encoder is invalid, in one of the following ways: + * - FLAC__stream_encoder_set_metadata() was called with a null pointer but a block count > 0 + * - One of the metadata blocks contains an undefined type + * - It contains an illegal CUESHEET as checked by FLAC__format_cuesheet_is_legal() + * - It contains an illegal SEEKTABLE as checked by FLAC__format_seektable_is_legal() + * - It contains more than one SEEKTABLE block or more than one VORBIS_COMMENT block + */ + + FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED + /**< FLAC__stream_encoder_init_*() was called when the encoder was + * already initialized, usually because + * FLAC__stream_encoder_finish() was not called. + */ + +} FLAC__StreamEncoderInitStatus; + +/** Maps a FLAC__StreamEncoderInitStatus to a C string. + * + * Using a FLAC__StreamEncoderInitStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderInitStatusString[]; + + +/** Return values for the FLAC__StreamEncoder read callback. + */ +typedef enum { + + FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE, + /**< The read was OK and decoding can continue. */ + + FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM, + /**< The read was attempted at the end of the stream. */ + + FLAC__STREAM_ENCODER_READ_STATUS_ABORT, + /**< An unrecoverable error occurred. */ + + FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED + /**< Client does not support reading back from the output. */ + +} FLAC__StreamEncoderReadStatus; + +/** Maps a FLAC__StreamEncoderReadStatus to a C string. + * + * Using a FLAC__StreamEncoderReadStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderReadStatusString[]; + + +/** Return values for the FLAC__StreamEncoder write callback. + */ +typedef enum { + + FLAC__STREAM_ENCODER_WRITE_STATUS_OK = 0, + /**< The write was OK and encoding can continue. */ + + FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR + /**< An unrecoverable error occurred. The encoder will return from the process call. */ + +} FLAC__StreamEncoderWriteStatus; + +/** Maps a FLAC__StreamEncoderWriteStatus to a C string. + * + * Using a FLAC__StreamEncoderWriteStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderWriteStatusString[]; + + +/** Return values for the FLAC__StreamEncoder seek callback. + */ +typedef enum { + + FLAC__STREAM_ENCODER_SEEK_STATUS_OK, + /**< The seek was OK and encoding can continue. */ + + FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR, + /**< An unrecoverable error occurred. */ + + FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED + /**< Client does not support seeking. */ + +} FLAC__StreamEncoderSeekStatus; + +/** Maps a FLAC__StreamEncoderSeekStatus to a C string. + * + * Using a FLAC__StreamEncoderSeekStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderSeekStatusString[]; + + +/** Return values for the FLAC__StreamEncoder tell callback. + */ +typedef enum { + + FLAC__STREAM_ENCODER_TELL_STATUS_OK, + /**< The tell was OK and encoding can continue. */ + + FLAC__STREAM_ENCODER_TELL_STATUS_ERROR, + /**< An unrecoverable error occurred. */ + + FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED + /**< Client does not support seeking. */ + +} FLAC__StreamEncoderTellStatus; + +/** Maps a FLAC__StreamEncoderTellStatus to a C string. + * + * Using a FLAC__StreamEncoderTellStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderTellStatusString[]; + + +/*********************************************************************** + * + * class FLAC__StreamEncoder + * + ***********************************************************************/ + +struct FLAC__StreamEncoderProtected; +struct FLAC__StreamEncoderPrivate; +/** The opaque structure definition for the stream encoder type. + * See the \link flac_stream_encoder stream encoder module \endlink + * for a detailed description. + */ +typedef struct { + struct FLAC__StreamEncoderProtected *protected_; /* avoid the C++ keyword 'protected' */ + struct FLAC__StreamEncoderPrivate *private_; /* avoid the C++ keyword 'private' */ +} FLAC__StreamEncoder; + +/** Signature for the read callback. + * + * A function pointer matching this signature must be passed to + * FLAC__stream_encoder_init_ogg_stream() if seeking is supported. + * The supplied function will be called when the encoder needs to read back + * encoded data. This happens during the metadata callback, when the encoder + * has to read, modify, and rewrite the metadata (e.g. seekpoints) gathered + * while encoding. The address of the buffer to be filled is supplied, along + * with the number of bytes the buffer can hold. The callback may choose to + * supply less data and modify the byte count but must be careful not to + * overflow the buffer. The callback then returns a status code chosen from + * FLAC__StreamEncoderReadStatus. + * + * Here is an example of a read callback for stdio streams: + * \code + * FLAC__StreamEncoderReadStatus read_cb(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * if(*bytes > 0) { + * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file); + * if(ferror(file)) + * return FLAC__STREAM_ENCODER_READ_STATUS_ABORT; + * else if(*bytes == 0) + * return FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM; + * else + * return FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE; + * } + * else + * return FLAC__STREAM_ENCODER_READ_STATUS_ABORT; + * } + * \endcode + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param buffer A pointer to a location for the callee to store + * data to be encoded. + * \param bytes A pointer to the size of the buffer. On entry + * to the callback, it contains the maximum number + * of bytes that may be stored in \a buffer. The + * callee must set it to the actual number of bytes + * stored (0 in case of error or end-of-stream) before + * returning. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_set_client_data(). + * \retval FLAC__StreamEncoderReadStatus + * The callee's return status. + */ +typedef FLAC__StreamEncoderReadStatus (*FLAC__StreamEncoderReadCallback)(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data); + +/** Signature for the write callback. + * + * A function pointer matching this signature must be passed to + * FLAC__stream_encoder_init*_stream(). The supplied function will be called + * by the encoder anytime there is raw encoded data ready to write. It may + * include metadata mixed with encoded audio frames and the data is not + * guaranteed to be aligned on frame or metadata block boundaries. + * + * The only duty of the callback is to write out the \a bytes worth of data + * in \a buffer to the current position in the output stream. The arguments + * \a samples and \a current_frame are purely informational. If \a samples + * is greater than \c 0, then \a current_frame will hold the current frame + * number that is being written; otherwise it indicates that the write + * callback is being called to write metadata. + * + * \note + * Unlike when writing to native FLAC, when writing to Ogg FLAC the + * write callback will be called twice when writing each audio + * frame; once for the page header, and once for the page body. + * When writing the page header, the \a samples argument to the + * write callback will be \c 0. + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param buffer An array of encoded data of length \a bytes. + * \param bytes The byte length of \a buffer. + * \param samples The number of samples encoded by \a buffer. + * \c 0 has a special meaning; see above. + * \param current_frame The number of the current frame being encoded. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + * \retval FLAC__StreamEncoderWriteStatus + * The callee's return status. + */ +typedef FLAC__StreamEncoderWriteStatus (*FLAC__StreamEncoderWriteCallback)(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data); + +/** Signature for the seek callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_encoder_init*_stream(). The supplied function will be called + * when the encoder needs to seek the output stream. The encoder will pass + * the absolute byte offset to seek to, 0 meaning the beginning of the stream. + * + * Here is an example of a seek callback for stdio streams: + * \code + * FLAC__StreamEncoderSeekStatus seek_cb(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * if(file == stdin) + * return FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED; + * else if(fseeko(file, (off_t)absolute_byte_offset, SEEK_SET) < 0) + * return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR; + * else + * return FLAC__STREAM_ENCODER_SEEK_STATUS_OK; + * } + * \endcode + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param absolute_byte_offset The offset from the beginning of the stream + * to seek to. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + * \retval FLAC__StreamEncoderSeekStatus + * The callee's return status. + */ +typedef FLAC__StreamEncoderSeekStatus (*FLAC__StreamEncoderSeekCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data); + +/** Signature for the tell callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_encoder_init*_stream(). The supplied function will be called + * when the encoder needs to know the current position of the output stream. + * + * \warning + * The callback must return the true current byte offset of the output to + * which the encoder is writing. If you are buffering the output, make + * sure and take this into account. If you are writing directly to a + * FILE* from your write callback, ftell() is sufficient. If you are + * writing directly to a file descriptor from your write callback, you + * can use lseek(fd, SEEK_CUR, 0). The encoder may later seek back to + * these points to rewrite metadata after encoding. + * + * Here is an example of a tell callback for stdio streams: + * \code + * FLAC__StreamEncoderTellStatus tell_cb(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * off_t pos; + * if(file == stdin) + * return FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED; + * else if((pos = ftello(file)) < 0) + * return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR; + * else { + * *absolute_byte_offset = (FLAC__uint64)pos; + * return FLAC__STREAM_ENCODER_TELL_STATUS_OK; + * } + * } + * \endcode + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param absolute_byte_offset The address at which to store the current + * position of the output. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + * \retval FLAC__StreamEncoderTellStatus + * The callee's return status. + */ +typedef FLAC__StreamEncoderTellStatus (*FLAC__StreamEncoderTellCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data); + +/** Signature for the metadata callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_encoder_init*_stream(). The supplied function will be called + * once at the end of encoding with the populated STREAMINFO structure. This + * is so the client can seek back to the beginning of the file and write the + * STREAMINFO block with the correct statistics after encoding (like + * minimum/maximum frame size and total samples). + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param metadata The final populated STREAMINFO block. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + */ +typedef void (*FLAC__StreamEncoderMetadataCallback)(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data); + +/** Signature for the progress callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_encoder_init*_file() or FLAC__stream_encoder_init*_FILE(). + * The supplied function will be called when the encoder has finished + * writing a frame. The \c total_frames_estimate argument to the + * callback will be based on the value from + * FLAC__stream_encoder_set_total_samples_estimate(). + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param bytes_written Bytes written so far. + * \param samples_written Samples written so far. + * \param frames_written Frames written so far. + * \param total_frames_estimate The estimate of the total number of + * frames to be written. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + */ +typedef void (*FLAC__StreamEncoderProgressCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data); + + +/*********************************************************************** + * + * Class constructor/destructor + * + ***********************************************************************/ + +/** Create a new stream encoder instance. The instance is created with + * default settings; see the individual FLAC__stream_encoder_set_*() + * functions for each setting's default. + * + * \retval FLAC__StreamEncoder* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void); + +/** Free an encoder instance. Deletes the object pointed to by \a encoder. + * + * \param encoder A pointer to an existing encoder. + * \assert + * \code encoder != NULL \endcode + */ +FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder); + + +/*********************************************************************** + * + * Public class method prototypes + * + ***********************************************************************/ + +/** Set the serial number for the FLAC stream to use in the Ogg container. + * + * \note + * This does not need to be set for native FLAC encoding. + * + * \note + * It is recommended to set a serial number explicitly as the default of '0' + * may collide with other streams. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param serial_number See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncoder *encoder, long serial_number); + +/** Set the "verify" flag. If \c true, the encoder will verify it's own + * encoded output by feeding it through an internal decoder and comparing + * the original signal against the decoded signal. If a mismatch occurs, + * the process call will return \c false. Note that this will slow the + * encoding process by the extra time required for decoding and comparison. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value Flag value (see above). + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Set the <A HREF="../format.html#subset">Subset</A> flag. If \c true, + * the encoder will comply with the Subset and will check the + * settings during FLAC__stream_encoder_init_*() to see if all settings + * comply. If \c false, the settings may take advantage of the full + * range that the format allows. + * + * Make sure you know what it entails before setting this to \c false. + * + * \default \c true + * \param encoder An encoder instance to set. + * \param value Flag value (see above). + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Set the number of channels to be encoded. + * + * \default \c 2 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_channels(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the sample resolution of the input to be encoded. + * + * \warning + * Do not feed the encoder data that is wider than the value you + * set here or you will generate an invalid stream. + * + * \default \c 16 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_bits_per_sample(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the sample rate (in Hz) of the input to be encoded. + * + * \default \c 44100 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the compression level + * + * The compression level is roughly proportional to the amount of effort + * the encoder expends to compress the file. A higher level usually + * means more computation but higher compression. The default level is + * suitable for most applications. + * + * Currently the levels range from \c 0 (fastest, least compression) to + * \c 8 (slowest, most compression). A value larger than \c 8 will be + * treated as \c 8. + * + * This function automatically calls the following other \c _set_ + * functions with appropriate values, so the client does not need to + * unless it specifically wants to override them: + * - FLAC__stream_encoder_set_do_mid_side_stereo() + * - FLAC__stream_encoder_set_loose_mid_side_stereo() + * - FLAC__stream_encoder_set_apodization() + * - FLAC__stream_encoder_set_max_lpc_order() + * - FLAC__stream_encoder_set_qlp_coeff_precision() + * - FLAC__stream_encoder_set_do_qlp_coeff_prec_search() + * - FLAC__stream_encoder_set_do_escape_coding() + * - FLAC__stream_encoder_set_do_exhaustive_model_search() + * - FLAC__stream_encoder_set_min_residual_partition_order() + * - FLAC__stream_encoder_set_max_residual_partition_order() + * - FLAC__stream_encoder_set_rice_parameter_search_dist() + * + * The actual values set for each level are: + * <table> + * <tr> + * <td><b>level</b><td> + * <td>do mid-side stereo<td> + * <td>loose mid-side stereo<td> + * <td>apodization<td> + * <td>max lpc order<td> + * <td>qlp coeff precision<td> + * <td>qlp coeff prec search<td> + * <td>escape coding<td> + * <td>exhaustive model search<td> + * <td>min residual partition order<td> + * <td>max residual partition order<td> + * <td>rice parameter search dist<td> + * </tr> + * <tr> <td><b>0</b><td> <td>false<td> <td>false<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr> + * <tr> <td><b>1</b><td> <td>true<td> <td>true<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr> + * <tr> <td><b>2</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr> + * <tr> <td><b>3</b><td> <td>false<td> <td>false<td> <td>tukey(0.5)<td> <td>6<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>4<td> <td>0<td> </tr> + * <tr> <td><b>4</b><td> <td>true<td> <td>true<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>4<td> <td>0<td> </tr> + * <tr> <td><b>5</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>5<td> <td>0<td> </tr> + * <tr> <td><b>6</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>6<td> <td>0<td> </tr> + * <tr> <td><b>7</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>true<td> <td>0<td> <td>6<td> <td>0<td> </tr> + * <tr> <td><b>8</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>12<td> <td>0<td> <td>false<td> <td>false<td> <td>true<td> <td>0<td> <td>6<td> <td>0<td> </tr> + * </table> + * + * \default \c 5 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_compression_level(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the blocksize to use while encoding. + * + * The number of samples to use per frame. Use \c 0 to let the encoder + * estimate a blocksize; this is usually best. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set to \c true to enable mid-side encoding on stereo input. The + * number of channels must be 2 for this to have any effect. Set to + * \c false to use only independent channel coding. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value Flag value (see above). + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Set to \c true to enable adaptive switching between mid-side and + * left-right encoding on stereo input. Set to \c false to use + * exhaustive searching. Setting this to \c true requires + * FLAC__stream_encoder_set_do_mid_side_stereo() to also be set to + * \c true in order to have any effect. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value Flag value (see above). + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Sets the apodization function(s) the encoder will use when windowing + * audio data for LPC analysis. + * + * The \a specification is a plain ASCII string which specifies exactly + * which functions to use. There may be more than one (up to 32), + * separated by \c ';' characters. Some functions take one or more + * comma-separated arguments in parentheses. + * + * The available functions are \c bartlett, \c bartlett_hann, + * \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop, + * \c gauss(STDDEV), \c hamming, \c hann, \c kaiser_bessel, \c nuttall, + * \c rectangle, \c triangle, \c tukey(P), \c welch. + * + * For \c gauss(STDDEV), STDDEV specifies the standard deviation + * (0<STDDEV<=0.5). + * + * For \c tukey(P), P specifies the fraction of the window that is + * tapered (0<=P<=1). P=0 corresponds to \c rectangle and P=1 + * corresponds to \c hann. + * + * Example specifications are \c "blackman" or + * \c "hann;triangle;tukey(0.5);tukey(0.25);tukey(0.125)" + * + * Any function that is specified erroneously is silently dropped. Up + * to 32 functions are kept, the rest are dropped. If the specification + * is empty the encoder defaults to \c "tukey(0.5)". + * + * When more than one function is specified, then for every subframe the + * encoder will try each of them separately and choose the window that + * results in the smallest compressed subframe. + * + * Note that each function specified causes the encoder to occupy a + * floating point array in which to store the window. + * + * \default \c "tukey(0.5)" + * \param encoder An encoder instance to set. + * \param specification See above. + * \assert + * \code encoder != NULL \endcode + * \code specification != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *encoder, const char *specification); + +/** Set the maximum LPC order, or \c 0 to use only the fixed predictors. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_max_lpc_order(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the precision, in bits, of the quantized linear predictor + * coefficients, or \c 0 to let the encoder select it based on the + * blocksize. + * + * \note + * In the current implementation, qlp_coeff_precision + bits_per_sample must + * be less than 32. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_qlp_coeff_precision(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set to \c false to use only the specified quantized linear predictor + * coefficient precision, or \c true to search neighboring precision + * values and use the best one. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_qlp_coeff_prec_search(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Deprecated. Setting this value has no effect. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_escape_coding(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Set to \c false to let the encoder estimate the best model order + * based on the residual signal energy, or \c true to force the + * encoder to evaluate all order models and select the best. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_exhaustive_model_search(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Set the minimum partition order to search when coding the residual. + * This is used in tandem with + * FLAC__stream_encoder_set_max_residual_partition_order(). + * + * The partition order determines the context size in the residual. + * The context size will be approximately <tt>blocksize / (2 ^ order)</tt>. + * + * Set both min and max values to \c 0 to force a single context, + * whose Rice parameter is based on the residual signal variance. + * Otherwise, set a min and max order, and the encoder will search + * all orders, using the mean of each context for its Rice parameter, + * and use the best. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_min_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the maximum partition order to search when coding the residual. + * This is used in tandem with + * FLAC__stream_encoder_set_min_residual_partition_order(). + * + * The partition order determines the context size in the residual. + * The context size will be approximately <tt>blocksize / (2 ^ order)</tt>. + * + * Set both min and max values to \c 0 to force a single context, + * whose Rice parameter is based on the residual signal variance. + * Otherwise, set a min and max order, and the encoder will search + * all orders, using the mean of each context for its Rice parameter, + * and use the best. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_max_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value); + +/** Deprecated. Setting this value has no effect. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_rice_parameter_search_dist(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set an estimate of the total samples that will be encoded. + * This is merely an estimate and may be set to \c 0 if unknown. + * This value will be written to the STREAMINFO block before encoding, + * and can remove the need for the caller to rewrite the value later + * if the value is known before encoding. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__StreamEncoder *encoder, FLAC__uint64 value); + +/** Set the metadata blocks to be emitted to the stream before encoding. + * A value of \c NULL, \c 0 implies no metadata; otherwise, supply an + * array of pointers to metadata blocks. The array is non-const since + * the encoder may need to change the \a is_last flag inside them, and + * in some cases update seek point offsets. Otherwise, the encoder will + * not modify or free the blocks. It is up to the caller to free the + * metadata blocks after encoding finishes. + * + * \note + * The encoder stores only copies of the pointers in the \a metadata array; + * the metadata blocks themselves must survive at least until after + * FLAC__stream_encoder_finish() returns. Do not free the blocks until then. + * + * \note + * The STREAMINFO block is always written and no STREAMINFO block may + * occur in the supplied array. + * + * \note + * By default the encoder does not create a SEEKTABLE. If one is supplied + * in the \a metadata array, but the client has specified that it does not + * support seeking, then the SEEKTABLE will be written verbatim. However + * by itself this is not very useful as the client will not know the stream + * offsets for the seekpoints ahead of time. In order to get a proper + * seektable the client must support seeking. See next note. + * + * \note + * SEEKTABLE blocks are handled specially. Since you will not know + * the values for the seek point stream offsets, you should pass in + * a SEEKTABLE 'template', that is, a SEEKTABLE object with the + * required sample numbers (or placeholder points), with \c 0 for the + * \a frame_samples and \a stream_offset fields for each point. If the + * client has specified that it supports seeking by providing a seek + * callback to FLAC__stream_encoder_init_stream() or both seek AND read + * callback to FLAC__stream_encoder_init_ogg_stream() (or by using + * FLAC__stream_encoder_init*_file() or FLAC__stream_encoder_init*_FILE()), + * then while it is encoding the encoder will fill the stream offsets in + * for you and when encoding is finished, it will seek back and write the + * real values into the SEEKTABLE block in the stream. There are helper + * routines for manipulating seektable template blocks; see metadata.h: + * FLAC__metadata_object_seektable_template_*(). If the client does + * not support seeking, the SEEKTABLE will have inaccurate offsets which + * will slow down or remove the ability to seek in the FLAC stream. + * + * \note + * The encoder instance \b will modify the first \c SEEKTABLE block + * as it transforms the template to a valid seektable while encoding, + * but it is still up to the caller to free all metadata blocks after + * encoding. + * + * \note + * A VORBIS_COMMENT block may be supplied. The vendor string in it + * will be ignored. libFLAC will use it's own vendor string. libFLAC + * will not modify the passed-in VORBIS_COMMENT's vendor string, it + * will simply write it's own into the stream. If no VORBIS_COMMENT + * block is present in the \a metadata array, libFLAC will write an + * empty one, containing only the vendor string. + * + * \note The Ogg FLAC mapping requires that the VORBIS_COMMENT block be + * the second metadata block of the stream. The encoder already supplies + * the STREAMINFO block automatically. If \a metadata does not contain a + * VORBIS_COMMENT block, the encoder will supply that too. Otherwise, if + * \a metadata does contain a VORBIS_COMMENT block and it is not the + * first, the init function will reorder \a metadata by moving the + * VORBIS_COMMENT block to the front; the relative ordering of the other + * blocks will remain as they were. + * + * \note The Ogg FLAC mapping limits the number of metadata blocks per + * stream to \c 65535. If \a num_blocks exceeds this the function will + * return \c false. + * + * \default \c NULL, 0 + * \param encoder An encoder instance to set. + * \param metadata See above. + * \param num_blocks See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + * \c false if the encoder is already initialized, or if + * \a num_blocks > 65535 if encoding to Ogg FLAC, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks); + +/** Get the current encoder state. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamEncoderState + * The current encoder state. + */ +FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_get_state(const FLAC__StreamEncoder *encoder); + +/** Get the state of the verify stream decoder. + * Useful when the stream encoder state is + * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamDecoderState + * The verify stream decoder state. + */ +FLAC_API FLAC__StreamDecoderState FLAC__stream_encoder_get_verify_decoder_state(const FLAC__StreamEncoder *encoder); + +/** Get the current encoder state as a C string. + * This version automatically resolves + * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR by getting the + * verify decoder's state. + * + * \param encoder A encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval const char * + * The encoder state as a C string. Do not modify the contents. + */ +FLAC_API const char *FLAC__stream_encoder_get_resolved_state_string(const FLAC__StreamEncoder *encoder); + +/** Get relevant values about the nature of a verify decoder error. + * Useful when the stream encoder state is + * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. The arguments should + * be addresses in which the stats will be returned, or NULL if value + * is not desired. + * + * \param encoder An encoder instance to query. + * \param absolute_sample The absolute sample number of the mismatch. + * \param frame_number The number of the frame in which the mismatch occurred. + * \param channel The channel in which the mismatch occurred. + * \param sample The number of the sample (relative to the frame) in + * which the mismatch occurred. + * \param expected The expected value for the sample in question. + * \param got The actual value returned by the decoder. + * \assert + * \code encoder != NULL \endcode + */ +FLAC_API void FLAC__stream_encoder_get_verify_decoder_error_stats(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got); + +/** Get the "verify" flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_verify(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_verify(const FLAC__StreamEncoder *encoder); + +/** Get the <A HREF="../format.html#subset>Subset</A> flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_streamable_subset(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_streamable_subset(const FLAC__StreamEncoder *encoder); + +/** Get the number of input channels being processed. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_channels(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_channels(const FLAC__StreamEncoder *encoder); + +/** Get the input sample resolution setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_bits_per_sample(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_bits_per_sample(const FLAC__StreamEncoder *encoder); + +/** Get the input sample rate setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_sample_rate(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_sample_rate(const FLAC__StreamEncoder *encoder); + +/** Get the blocksize setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_blocksize(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_blocksize(const FLAC__StreamEncoder *encoder); + +/** Get the "mid/side stereo coding" flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_get_do_mid_side_stereo(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_mid_side_stereo(const FLAC__StreamEncoder *encoder); + +/** Get the "adaptive mid/side switching" flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_loose_mid_side_stereo(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_loose_mid_side_stereo(const FLAC__StreamEncoder *encoder); + +/** Get the maximum LPC order setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_max_lpc_order(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_max_lpc_order(const FLAC__StreamEncoder *encoder); + +/** Get the quantized linear predictor coefficient precision setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_qlp_coeff_precision(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_qlp_coeff_precision(const FLAC__StreamEncoder *encoder); + +/** Get the qlp coefficient precision search flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_do_qlp_coeff_prec_search(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__StreamEncoder *encoder); + +/** Get the "escape coding" flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_do_escape_coding(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_escape_coding(const FLAC__StreamEncoder *encoder); + +/** Get the exhaustive model search flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_do_exhaustive_model_search(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_exhaustive_model_search(const FLAC__StreamEncoder *encoder); + +/** Get the minimum residual partition order setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_min_residual_partition_order(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_min_residual_partition_order(const FLAC__StreamEncoder *encoder); + +/** Get maximum residual partition order setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_max_residual_partition_order(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_max_residual_partition_order(const FLAC__StreamEncoder *encoder); + +/** Get the Rice parameter search distance setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_rice_parameter_search_dist(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC__StreamEncoder *encoder); + +/** Get the previously set estimate of the total samples to be encoded. + * The encoder merely mimics back the value given to + * FLAC__stream_encoder_set_total_samples_estimate() since it has no + * other way of knowing how many samples the client will encode. + * + * \param encoder An encoder instance to set. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__uint64 + * See FLAC__stream_encoder_get_total_samples_estimate(). + */ +FLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder); + +/** Initialize the encoder instance to encode native FLAC streams. + * + * This flavor of initialization sets up the encoder to encode to a + * native FLAC stream. I/O is performed via callbacks to the client. + * For encoding to a plain file via filename or open \c FILE*, + * FLAC__stream_encoder_init_file() and FLAC__stream_encoder_init_FILE() + * provide a simpler interface. + * + * This function should be called after FLAC__stream_encoder_new() and + * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() + * or FLAC__stream_encoder_process_interleaved(). + * initialization succeeded. + * + * The call to FLAC__stream_encoder_init_stream() currently will also + * immediately call the write callback several times, once with the \c fLaC + * signature, and once for each encoded metadata block. + * + * \param encoder An uninitialized encoder instance. + * \param write_callback See FLAC__StreamEncoderWriteCallback. This + * pointer must not be \c NULL. + * \param seek_callback See FLAC__StreamEncoderSeekCallback. This + * pointer may be \c NULL if seeking is not + * supported. The encoder uses seeking to go back + * and write some some stream statistics to the + * STREAMINFO block; this is recommended but not + * necessary to create a valid FLAC stream. If + * \a seek_callback is not \c NULL then a + * \a tell_callback must also be supplied. + * Alternatively, a dummy seek callback that just + * returns \c FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the encoder. + * \param tell_callback See FLAC__StreamEncoderTellCallback. This + * pointer may be \c NULL if seeking is not + * supported. If \a seek_callback is \c NULL then + * this argument will be ignored. If + * \a seek_callback is not \c NULL then a + * \a tell_callback must also be supplied. + * Alternatively, a dummy tell callback that just + * returns \c FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the encoder. + * \param metadata_callback See FLAC__StreamEncoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. If the client provides a seek callback, + * this function is not necessary as the encoder + * will automatically seek back and update the + * STREAMINFO block. It may also be \c NULL if the + * client does not support seeking, since it will + * have no way of going back to update the + * STREAMINFO. However the client can still supply + * a callback if it would like to know the details + * from the STREAMINFO. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamEncoderInitStatus + * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamEncoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_stream(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderWriteCallback write_callback, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderTellCallback tell_callback, FLAC__StreamEncoderMetadataCallback metadata_callback, void *client_data); + +/** Initialize the encoder instance to encode Ogg FLAC streams. + * + * This flavor of initialization sets up the encoder to encode to a FLAC + * stream in an Ogg container. I/O is performed via callbacks to the + * client. For encoding to a plain file via filename or open \c FILE*, + * FLAC__stream_encoder_init_ogg_file() and FLAC__stream_encoder_init_ogg_FILE() + * provide a simpler interface. + * + * This function should be called after FLAC__stream_encoder_new() and + * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() + * or FLAC__stream_encoder_process_interleaved(). + * initialization succeeded. + * + * The call to FLAC__stream_encoder_init_ogg_stream() currently will also + * immediately call the write callback several times to write the metadata + * packets. + * + * \param encoder An uninitialized encoder instance. + * \param read_callback See FLAC__StreamEncoderReadCallback. This + * pointer must not be \c NULL if \a seek_callback + * is non-NULL since they are both needed to be + * able to write data back to the Ogg FLAC stream + * in the post-encode phase. + * \param write_callback See FLAC__StreamEncoderWriteCallback. This + * pointer must not be \c NULL. + * \param seek_callback See FLAC__StreamEncoderSeekCallback. This + * pointer may be \c NULL if seeking is not + * supported. The encoder uses seeking to go back + * and write some some stream statistics to the + * STREAMINFO block; this is recommended but not + * necessary to create a valid FLAC stream. If + * \a seek_callback is not \c NULL then a + * \a tell_callback must also be supplied. + * Alternatively, a dummy seek callback that just + * returns \c FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the encoder. + * \param tell_callback See FLAC__StreamEncoderTellCallback. This + * pointer may be \c NULL if seeking is not + * supported. If \a seek_callback is \c NULL then + * this argument will be ignored. If + * \a seek_callback is not \c NULL then a + * \a tell_callback must also be supplied. + * Alternatively, a dummy tell callback that just + * returns \c FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the encoder. + * \param metadata_callback See FLAC__StreamEncoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. If the client provides a seek callback, + * this function is not necessary as the encoder + * will automatically seek back and update the + * STREAMINFO block. It may also be \c NULL if the + * client does not support seeking, since it will + * have no way of going back to update the + * STREAMINFO. However the client can still supply + * a callback if it would like to know the details + * from the STREAMINFO. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamEncoderInitStatus + * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamEncoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_stream(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderReadCallback read_callback, FLAC__StreamEncoderWriteCallback write_callback, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderTellCallback tell_callback, FLAC__StreamEncoderMetadataCallback metadata_callback, void *client_data); + +/** Initialize the encoder instance to encode native FLAC files. + * + * This flavor of initialization sets up the encoder to encode to a + * plain native FLAC file. For non-stdio streams, you must use + * FLAC__stream_encoder_init_stream() and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_encoder_new() and + * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() + * or FLAC__stream_encoder_process_interleaved(). + * initialization succeeded. + * + * \param encoder An uninitialized encoder instance. + * \param file An open file. The file should have been opened + * with mode \c "w+b" and rewound. The file + * becomes owned by the encoder and should not be + * manipulated by the client while encoding. + * Unless \a file is \c stdout, it will be closed + * when FLAC__stream_encoder_finish() is called. + * Note however that a proper SEEKTABLE cannot be + * created when encoding to \c stdout since it is + * not seekable. + * \param progress_callback See FLAC__StreamEncoderProgressCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code encoder != NULL \endcode + * \code file != NULL \endcode + * \retval FLAC__StreamEncoderInitStatus + * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamEncoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_FILE(FLAC__StreamEncoder *encoder, FILE *file, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data); + +/** Initialize the encoder instance to encode Ogg FLAC files. + * + * This flavor of initialization sets up the encoder to encode to a + * plain Ogg FLAC file. For non-stdio streams, you must use + * FLAC__stream_encoder_init_ogg_stream() and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_encoder_new() and + * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() + * or FLAC__stream_encoder_process_interleaved(). + * initialization succeeded. + * + * \param encoder An uninitialized encoder instance. + * \param file An open file. The file should have been opened + * with mode \c "w+b" and rewound. The file + * becomes owned by the encoder and should not be + * manipulated by the client while encoding. + * Unless \a file is \c stdout, it will be closed + * when FLAC__stream_encoder_finish() is called. + * Note however that a proper SEEKTABLE cannot be + * created when encoding to \c stdout since it is + * not seekable. + * \param progress_callback See FLAC__StreamEncoderProgressCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code encoder != NULL \endcode + * \code file != NULL \endcode + * \retval FLAC__StreamEncoderInitStatus + * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamEncoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_FILE(FLAC__StreamEncoder *encoder, FILE *file, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data); + +/** Initialize the encoder instance to encode native FLAC files. + * + * This flavor of initialization sets up the encoder to encode to a plain + * FLAC file. If POSIX fopen() semantics are not sufficient (for example, + * with Unicode filenames on Windows), you must use + * FLAC__stream_encoder_init_FILE(), or FLAC__stream_encoder_init_stream() + * and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_encoder_new() and + * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() + * or FLAC__stream_encoder_process_interleaved(). + * initialization succeeded. + * + * \param encoder An uninitialized encoder instance. + * \param filename The name of the file to encode to. The file will + * be opened with fopen(). Use \c NULL to encode to + * \c stdout. Note however that a proper SEEKTABLE + * cannot be created when encoding to \c stdout since + * it is not seekable. + * \param progress_callback See FLAC__StreamEncoderProgressCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamEncoderInitStatus + * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamEncoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_file(FLAC__StreamEncoder *encoder, const char *filename, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data); + +/** Initialize the encoder instance to encode Ogg FLAC files. + * + * This flavor of initialization sets up the encoder to encode to a plain + * Ogg FLAC file. If POSIX fopen() semantics are not sufficient (for example, + * with Unicode filenames on Windows), you must use + * FLAC__stream_encoder_init_ogg_FILE(), or FLAC__stream_encoder_init_ogg_stream() + * and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_encoder_new() and + * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() + * or FLAC__stream_encoder_process_interleaved(). + * initialization succeeded. + * + * \param encoder An uninitialized encoder instance. + * \param filename The name of the file to encode to. The file will + * be opened with fopen(). Use \c NULL to encode to + * \c stdout. Note however that a proper SEEKTABLE + * cannot be created when encoding to \c stdout since + * it is not seekable. + * \param progress_callback See FLAC__StreamEncoderProgressCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamEncoderInitStatus + * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamEncoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_file(FLAC__StreamEncoder *encoder, const char *filename, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data); + +/** Finish the encoding process. + * Flushes the encoding buffer, releases resources, resets the encoder + * settings to their defaults, and returns the encoder state to + * FLAC__STREAM_ENCODER_UNINITIALIZED. Note that this can generate + * one or more write callbacks before returning, and will generate + * a metadata callback. + * + * Note that in the course of processing the last frame, errors can + * occur, so the caller should be sure to check the return value to + * ensure the file was encoded properly. + * + * In the event of a prematurely-terminated encode, it is not strictly + * necessary to call this immediately before FLAC__stream_encoder_delete() + * but it is good practice to match every FLAC__stream_encoder_init_*() + * with a FLAC__stream_encoder_finish(). + * + * \param encoder An uninitialized encoder instance. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if an error occurred processing the last frame; or if verify + * mode is set (see FLAC__stream_encoder_set_verify()), there was a + * verify mismatch; else \c true. If \c false, caller should check the + * state with FLAC__stream_encoder_get_state() for more information + * about the error. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder); + +/** Submit data for encoding. + * This version allows you to supply the input data via an array of + * pointers, each pointer pointing to an array of \a samples samples + * representing one channel. The samples need not be block-aligned, + * but each channel should have the same number of samples. Each sample + * should be a signed integer, right-justified to the resolution set by + * FLAC__stream_encoder_set_bits_per_sample(). For example, if the + * resolution is 16 bits per sample, the samples should all be in the + * range [-32768,32767]. + * + * For applications where channel order is important, channels must + * follow the order as described in the + * <A HREF="../format.html#frame_header">frame header</A>. + * + * \param encoder An initialized encoder instance in the OK state. + * \param buffer An array of pointers to each channel's signal. + * \param samples The number of samples in one channel. + * \assert + * \code encoder != NULL \endcode + * \code FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK \endcode + * \retval FLAC__bool + * \c true if successful, else \c false; in this case, check the + * encoder state with FLAC__stream_encoder_get_state() to see what + * went wrong. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples); + +/** Submit data for encoding. + * This version allows you to supply the input data where the channels + * are interleaved into a single array (i.e. channel0_sample0, + * channel1_sample0, ... , channelN_sample0, channel0_sample1, ...). + * The samples need not be block-aligned but they must be + * sample-aligned, i.e. the first value should be channel0_sample0 + * and the last value channelN_sampleM. Each sample should be a signed + * integer, right-justified to the resolution set by + * FLAC__stream_encoder_set_bits_per_sample(). For example, if the + * resolution is 16 bits per sample, the samples should all be in the + * range [-32768,32767]. + * + * For applications where channel order is important, channels must + * follow the order as described in the + * <A HREF="../format.html#frame_header">frame header</A>. + * + * \param encoder An initialized encoder instance in the OK state. + * \param buffer An array of channel-interleaved data (see above). + * \param samples The number of samples in one channel, the same as for + * FLAC__stream_encoder_process(). For example, if + * encoding two channels, \c 1000 \a samples corresponds + * to a \a buffer of 2000 values. + * \assert + * \code encoder != NULL \endcode + * \code FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK \endcode + * \retval FLAC__bool + * \c true if successful, else \c false; in this case, check the + * encoder state with FLAC__stream_encoder_get_state() to see what + * went wrong. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/cddb/Makefile.am b/include/cddb/Makefile.am new file mode 100644 index 00000000..f6c2f70f --- /dev/null +++ b/include/cddb/Makefile.am @@ -0,0 +1,9 @@ + +pkgincludedir=$(includedir)/cddb +pkginclude_HEADERS = cddb.h cddb_config.h cddb_disc.h cddb_track.h \ + cddb_error.h cddb_conn.h cddb_cmd.h cddb_log.h \ + version.h cddb_site.h +noinst_HEADERS = cddb_ni.h cddb_regex.h cddb_conn_ni.h cddb_cmd_ni.h \ + cddb_net.h cddb_log_ni.h ll.h + +EXTRA_DIST = version.h.in diff --git a/include/cddb/cddb.h b/include/cddb/cddb.h new file mode 100644 index 00000000..c46700a6 --- /dev/null +++ b/include/cddb/cddb.h @@ -0,0 +1,97 @@ +/* + $Id: cddb.h,v 1.14 2006/10/15 12:54:33 airborne Exp $ + + Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_H +#define CDDB_H 1 + +#include <cddb/version.h> + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <cddb/cddb_config.h> +#include <cddb/cddb_error.h> +#include <cddb/cddb_track.h> +#include <cddb/cddb_disc.h> +#include <cddb/cddb_site.h> +#include <cddb/cddb_conn.h> +#include <cddb/cddb_cmd.h> +#include <cddb/cddb_log.h> + + +/** + * \mainpage libCDDB, a C API for CDDB server access + */ + + +#define BIT(n) (1 << n) + +/** + * An enumeration of flags that influence the behaviour of the + * library. You can set or reset these flags using the + * #libcddb_set_flags and #libcddb_reset_flags functions. + */ +typedef enum { + CDDB_F_EMPTY_STR = BIT(0), /**< never return NULL pointer strings + (default), return an empty string + instead */ + CDDB_F_NO_TRACK_ARTIST = BIT(1), /**< do not return the disc artist as the + track artist (default), return NULL + instead */ +} cddb_flag_t; + +/** + * Initializes the library. This is used to setup any globally used + * variables. The first time you create a new CDDB connection structure + * the library will automatically initialize itself. So, there is no + * need to explicitly call this function. + */ +void libcddb_init(void); + +/** + * Frees up any global (cross connection) resources. You should call + * this function before terminating your program. Using any library + * calls after shutting down are bound to give problems. + */ +void libcddb_shutdown(void); + +/** + * Set one or more flags that influence the library behvaiour + * + * @param flags A bitwise ORed set of values from #cddb_flag_t. + */ +void libcddb_set_flags(unsigned int flags); + +/** + * Reset one or more flags that influence the library behvaiour + * + * @param flags A bitwise ORed set of values from #cddb_flag_t. + */ +void libcddb_reset_flags(unsigned int flags); + + +#ifdef __cplusplus + } +#endif + +#endif /* CDDB_H */ diff --git a/include/cddb/cddb_cmd.h b/include/cddb/cddb_cmd.h new file mode 100644 index 00000000..c5a01fef --- /dev/null +++ b/include/cddb/cddb_cmd.h @@ -0,0 +1,185 @@ +/* + $Id: cddb_cmd.h,v 1.17 2006/10/15 08:58:51 airborne Exp $ + + Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_CMD_H +#define CDDB_CMD_H 1 + +#ifdef __cplusplus + extern "C" { +#endif + + +/* --- accessing data on the CDDB server --- */ + + +/** + * Retrieve a disc record from the CDDB server. This function + * requires that the category and disc ID of the provided disc + * structure are valid. + * + * If nothing goes wrong, the function will return 1 and the error + * code will be reset to: + * - #CDDB_ERR_OK: + * If everything went as planned. + * + * If there is a problem with reading data from the CDDB server one of + * the following error codes will be set: + * - #CDDB_ERR_DATA_MISSING: + * If some required data is missing from the given disc + * structure to execute this command. + * - #CDDB_ERR_DISC_NOT_FOUND: + * If the requested disc is not known by the CDDB server. + * - #CDDB_ERR_SERVER_ERROR: + * If the server encountered an error while trying to process your + * request. + * - #CDDB_ERR_UNKNOWN: + * If the server specified an unknown response code. Please + * report this as a libcddb bug. + * + * When there are problems with the connection to the CDDB server one + * of the following error codes will be set: + * - #CDDB_ERR_UNKNOWN_HOST_NAME: + * If there was an error when resolving the host name of the CDDB + * server. + * - #CDDB_ERR_CONNECT: + * If a connection to the CDDB server could not be established. + * This can be due to incorrect data about the location of the + * server (host name, port). + * - #CDDB_ERR_NOT_CONNECTED: + * If something when wrong in the process and you got + * disconnected. Retrying might succeed (but no guarantees). + * - #CDDB_ERR_PERMISSION_DENIED: + * If the server is up and running but denied the connection. + * This can occur when the server is too highly loaded or the + * handshake information (user name, ...) is considered to be + * invalid. + * + * @param c The CDDB connection structure. + * @param disc A non-null CDDB disc structure. + * @return 1 on succes, 0 on failure + */ +int cddb_read(cddb_conn_t *c, cddb_disc_t *disc); + +/** + * Query the CDDB database for a list of possible disc matches. This + * function requires that the disc ID and disc length of the provided + * disc structure are valid. The disc should also contain a number of + * tracks and for each track its frame offset on the CD should be + * valid. + * + * If there are multiple matches then only the first one will be + * returned by this function. For other matches you will have to use + * the #cddb_query_next function. + * + * @param c The CDDB connection structure. + * @param disc A non-null CDDB disc structure. + * + * @return The number of matches found or -1 on error. + */ +int cddb_query(cddb_conn_t *c, cddb_disc_t *disc); + +/** + * Returns the next match in a CDDB query result set. This function + * should be used in conjunction with #cddb_query. + * + * @param c The CDDB connection structure. + * @param disc A non-null CDDB disc structure. + */ +int cddb_query_next(cddb_conn_t *c, cddb_disc_t *disc); + +/** + * Perform a text search in the CDDB database. Instead of actually + * needing information about a real disc like in #cddb_query this + * function accept a string that is used for searching the database. + * + * If there are multiple matches then only the first one will be + * returned by this function. For other matches you will have to use + * the #cddb_search_next function. + * + * @param c The CDDB connection structure. + * @param disc A non-null CDDB disc structure. + * @param str The search string + * + * @return The number of matches found or -1 on error. + */ +int cddb_search(cddb_conn_t *c, cddb_disc_t *disc, const char *str); + +/** + * Returns the next match in a CDDB search result set. This function + * should be used in conjunction with #cddb_search. + * + * @param c The CDDB connection structure. + * @param disc A non-null CDDB disc structure. + */ +int cddb_search_next(cddb_conn_t *c, cddb_disc_t *disc); + +/** + * Perform a text search in the CDDB database. It uses the album + * command implemented on the freedb2.org servers. Either the album + * title or artist's name should be filled in, in the disc structure. + * + * If there are multiple matches then only the first one will be + * returned by this function. For other matches you will have to use + * the #cddb_album_next function. + * + * @param c The CDDB connection structure. + * @param disc A non-null CDDB disc structure. + * + * @return The number of matches found or -1 on error. + */ +int cddb_album(cddb_conn_t *c, cddb_disc_t *disc); + +/** + * Returns the next match in a CDDB album result set. This function + * should be used in conjunction with #cddb_album. + * + * @param c The CDDB connection structure. + * @param disc A non-null CDDB disc structure. + */ +int cddb_album_next(cddb_conn_t *c, cddb_disc_t *disc); + +/** + * Submit a new or updated disc to the CDDB database. This function + * requires that the disc ID, length, category, artist and title of + * the provided disc structure are valid. The disc should also + * contain a number of tracks and for each track its frame offset on + * the CD and title should be valid. + * + * @param c The CDDB connection structure. + * @param disc A non-null CDDB disc structure. + */ +int cddb_write(cddb_conn_t *c, cddb_disc_t *disc); + +/** + * Query the currently configured server for a list of mirrors. + * Accessing the list of mirror sites is done with the iterator + * functions #cddb_first_site and #cddb_next_site. + * + * @param c The CDDB connection structure. + */ +int cddb_sites(cddb_conn_t *c); + + +#ifdef __cplusplus + } +#endif + +#endif /* CDDB_CMD_H */ diff --git a/include/cddb/cddb_cmd_ni.h b/include/cddb/cddb_cmd_ni.h new file mode 100644 index 00000000..4b02190a --- /dev/null +++ b/include/cddb/cddb_cmd_ni.h @@ -0,0 +1,68 @@ +/* + $Id: cddb_cmd_ni.h,v 1.12 2006/10/15 08:59:20 airborne Exp $ + + Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_CMD_NI_H +#define CDDB_CMD_NI_H 1 + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef enum { + CMD_HELLO = 0, + CMD_QUIT, + CMD_READ, + CMD_QUERY, + CMD_WRITE, + CMD_PROTO, + CMD_SITES, + CMD_SEARCH, + CMD_ALBUM, + /* dummy for array size */ + CMD_LAST +} cddb_cmd_t; + + +/* --- utility functions --- */ + + +/** + * Will read in one line from the response input stream and parse both + * the code and message in that line. Errors will be signaled by + * returning -1. + * + * @param c the CDDB connection structure + * @param msg the CDDB response msg + * @return the CDDB response code or -1 on error + */ +int cddb_get_response_code(cddb_conn_t *c, char **msg); + +/** + */ +int cddb_send_cmd(cddb_conn_t *c, int cmd, ...); + + +#ifdef __cplusplus + } +#endif + +#endif /* CDDB_CMD_H */ diff --git a/include/cddb/cddb_config.h b/include/cddb/cddb_config.h new file mode 100644 index 00000000..fd0d3769 --- /dev/null +++ b/include/cddb/cddb_config.h @@ -0,0 +1,37 @@ +/* + $Id: cddb_config.h.in,v 1.3 2005/03/11 21:29:29 airborne Exp $ + + Copyright (C) 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_CONFIG_H +#define CDDB_CONFIG_H 1 + +/* Define if you have <unistd.h> and need it included. + On MacOS, <regex.h> needs this but that header doesn't + include it. +*/ +#undef CDDB_NEED_UNISTD_H + +/* Define if you have <sys/socket.h> and need it included. + On MacOS, <cddb_net.h> needs this but that header doesn't + include it. +*/ +#undef CDDB_NEED_SYS_SOCKET_H + +#endif /* CDDB_CONFIG_H */ diff --git a/include/cddb/cddb_config.h.in b/include/cddb/cddb_config.h.in new file mode 100644 index 00000000..fd0d3769 --- /dev/null +++ b/include/cddb/cddb_config.h.in @@ -0,0 +1,37 @@ +/* + $Id: cddb_config.h.in,v 1.3 2005/03/11 21:29:29 airborne Exp $ + + Copyright (C) 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_CONFIG_H +#define CDDB_CONFIG_H 1 + +/* Define if you have <unistd.h> and need it included. + On MacOS, <regex.h> needs this but that header doesn't + include it. +*/ +#undef CDDB_NEED_UNISTD_H + +/* Define if you have <sys/socket.h> and need it included. + On MacOS, <cddb_net.h> needs this but that header doesn't + include it. +*/ +#undef CDDB_NEED_SYS_SOCKET_H + +#endif /* CDDB_CONFIG_H */ diff --git a/include/cddb/cddb_conn.h b/include/cddb/cddb_conn.h new file mode 100644 index 00000000..ada3cdda --- /dev/null +++ b/include/cddb/cddb_conn.h @@ -0,0 +1,562 @@ +/* + $Id: cddb_conn.h,v 1.31 2009/03/01 03:28:07 jcaratzas Exp $ + + Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_CONN_H +#define CDDB_CONN_H 1 + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <stdio.h> +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif + +#include "cddb/cddb_site.h" + + +typedef enum { + CACHE_OFF = 0, /**< do not use local CDDB cache, network + only */ + CACHE_ON, /**< use local CDDB cache, if possible */ + CACHE_ONLY /**< only use local CDDB cache, no network + access */ +} cddb_cache_mode_t; + +/** + * Forward declaration of opaque structure used for character set + * conversions. + */ +typedef struct cddb_iconv_s *cddb_iconv_t; + +/** + * An opaque structure for keeping state about the connection to a + * CDDB server. + */ +typedef struct cddb_conn_s cddb_conn_t; + +/** + * Which fields to use for the full text search is defined by one or + * more of the constants below. + */ +typedef enum { + SEARCH_NONE = 0, /**< no fields */ + SEARCH_ARTIST = 1, /**< artist name field */ + SEARCH_TITLE = 2, /**< disc title field */ + SEARCH_TRACK = 4, /**< track title field */ + SEARCH_OTHER = 8, /**< other fields */ + SEARCH_ALL = ~0, /**< all fields */ +} cddb_search_t; + +/** + * Macro to be used for building the category search bit-string from + * the values of #cddb_cat_t. + */ +#define SEARCHCAT(c) (1 << (c)) + + +/* --- construction / destruction --- */ + + +/** + * Creates a new CDDB connection structure. This structure will have + * to be passed to all libcddb functions. Default values will be used + * for the connection parameters allowing it to contact the CDDB + * server at freedb.org. + * + * @return The CDDB connection structure or NULL if something went wrong. + */ +cddb_conn_t *cddb_new(void); + +/** + * Free all resources associated with the given CDDB connection + * structure. + */ +void cddb_destroy(cddb_conn_t *c); + + +/* --- getters & setters --- */ + + +/** + * Set the character set. By default the FreeDB server uses UTF-8 when + * providing CD data. When a character set is defined with this function + * any strings retrieved from or sent to the server will automatically be + * converted. + * + * @param c The connection structure. + * @param cs The character set that will be used. + * @return False if the specified character set is unknown, or no conversion + * from/to UTF-8 is available. True otherwise. + */ +int cddb_set_charset(cddb_conn_t *c, const char *cs); + +/** + * Change the size of the internal buffer. + * + * @param c The connection structure. + * @param size The new buffer size. + */ +void cddb_set_buf_size(cddb_conn_t *c, unsigned int size); + +/** + * Set all server details in one go through the use of a site structure. This + * function initializzes the server address, port, protocol and query path in + * case of HTTP. + * + * @see cddb_sites + * @see cddb_first_site + * @see cddb_next_site + * + * @param c The connection structure. + * @param site The site to use. + * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID. + */ +cddb_error_t cddb_set_site(cddb_conn_t *c, const cddb_site_t *site); + +/** + * Get the host name of the CDDB server that is currently being used. + * + * @see cddb_set_server_name + * + * @param c The connection structure. + * @return The server host name. + */ +const char *cddb_get_server_name(const cddb_conn_t *c); + +/** + * Set the host name of the CDDB server. The default value for the + * server is 'freedb.org'. + * + * @see cddb_get_server_name + * + * @param c The connection structure. + * @param server The server host name. + */ +void cddb_set_server_name(cddb_conn_t *c, const char *server); + +/** + * Get the port of the CDDB server that is currently being used. + * + * @see cddb_set_server_port + * + * @param c The connection structure. + * @return The server port. + */ +unsigned int cddb_get_server_port(const cddb_conn_t *c); + +/** + * Set the port of the CDDB server. The default value is 888. + * + * @see cddb_get_server_port + * + * @param c The connection structure. + * @param port The server port. + */ +void cddb_set_server_port(cddb_conn_t *c, int port); + +/** + * Get the network time out value (in seconds). + * + * @see cddb_set_timeout + * + * @param c The connection structure. + * @return The current time out in seconds. + */ +unsigned int cddb_get_timeout(const cddb_conn_t *c); + +/** + * Set the network time out value (in seconds). The default is 10 + * seconds. + * + * @see cddb_get_timeout + * + * @param c The connection structure. + * @param t The new time out in seconds. + */ +void cddb_set_timeout(cddb_conn_t *c, unsigned int t); + +/** + * Get the URL path for querying a CDDB server through HTTP. + * + * @see cddb_set_http_path_query + * + * @param c The connection structure. + * @return The URL path. + */ +const char *cddb_get_http_path_query(const cddb_conn_t *c); + +/** + * Set the URL path for querying a CDDB server through HTTP. The + * default value is '/~cddb/cddb.cgi'. + * + * @see cddb_get_http_path_query + * + * @param c The connection structure. + * @param path The URL path. + */ +void cddb_set_http_path_query(cddb_conn_t *c, const char *path); + +/** + * Get the URL path for submitting to a CDDB server through HTTP. + * + * @see cddb_set_http_path_submit + * + * @param c The connection structure. + * @return The URL path. + */ +const char *cddb_get_http_path_submit(const cddb_conn_t *c); + +/** + * Set the URL path for submitting to a CDDB server through HTTP. The + * default value is '/~cddb/submit.cgi'. + * + * @see cddb_get_http_path_submit + * + * @param c The connection structure. + * @param path The URL path. + */ +void cddb_set_http_path_submit(cddb_conn_t *c, const char *path); + +/** + * Returns true if the HTTP protocol is currently enabled and false if + * CDDBP is enabled. + * + * @see cddb_http_enable + * @see cddb_http_disable + * + * @param c The CDDB connection structure. + * @return True or false. + */ +unsigned int cddb_is_http_enabled(const cddb_conn_t *c); + +/** + * Enable HTTP tunneling to connect to the CDDB server. By default + * this option is disabled. + * + * @see cddb_is_http_enabled + * @see cddb_http_disable + * + * @param c The CDDB connection structure. + */ +void cddb_http_enable(cddb_conn_t *c); + +/** + * Disable HTTP tunneling to connect to the CDDB server. By default this + * option is disabled. + * + * @see cddb_is_http_enabled + * @see cddb_http_enable + * + * @param c The CDDB connection structure. + */ +void cddb_http_disable(cddb_conn_t *c); + +/** + * Returns true if the proxy support is currently enabled and false if + * it is not. This fucntion does not check whether HTTP is enabled. + * So it is possible that true will be returned while in reality the + * CDDBP protocol is being used (no proxy support). + * + * @see cddb_http_proxy_enable + * @see cddb_http_proxy_disable + * + * @param c The CDDB connection structure. + * @return True or false. + */ +unsigned int cddb_is_http_proxy_enabled(const cddb_conn_t *c); + +/** + * Enable HTTP tunneling through an HTTP proxy server to connect to + * the CDDB server. The usage of an HTTP proxy implies normal HTTP + * tunneling instead of connecting directly to the CDDB server. By + * default this option is disabled. + * + * @see cddb_is_http_proxy_enabled + * @see cddb_http_proxy_disable + * + * @param c The CDDB connection structure. + */ +void cddb_http_proxy_enable(cddb_conn_t *c); + +/** + * Disable HTTP tunneling through an HTTP proxy server to connect to + * the CDDB server. By default this option is disabled. + * + * @see cddb_is_http_proxy_enabled + * @see cddb_http_proxy_enable + * + * @param c The CDDB connection structure. + */ +void cddb_http_proxy_disable(cddb_conn_t *c); + +/** + * Get the host name of the HTTP proxy server. + * + * @see cddb_set_http_proxy_server_name + * + * @param c The connection structure. + * @return The proxy server host name. + */ +const char *cddb_get_http_proxy_server_name(const cddb_conn_t *c); + +/** + * Set the host name of the HTTP proxy server. There is no default + * value. + * + * @see cddb_get_http_proxy_server_name + * + * @param c The connection structure. + * @param server The server host name. + */ +void cddb_set_http_proxy_server_name(cddb_conn_t *c, const char *server); + +/** + * Get the port of the HTTP proxy server. + * + * @see cddb_set_http_proxy_server_port + * + * @param c The connection structure. + * @return The proxy server port. + */ +unsigned int cddb_get_http_proxy_server_port(const cddb_conn_t *c); + +/** + * Set the port of the HTTP proxy server. The default value is 8080. + * + * @see cddb_get_http_proxy_server_port + * + * @param c The connection structure. + * @param port The server port. + */ +void cddb_set_http_proxy_server_port(cddb_conn_t *c, int port); + +/** + * Set the HTTP proxy user name which is used when Basic Authentication + * is required. + * + * @param c The connection structure. + * @param username The user name. + */ +void cddb_set_http_proxy_username(cddb_conn_t* c, const char* username); + +/** + * Get the HTTP proxy user name. + * + * @param c The connection structure. + * @return The user name. + */ +const char *cddb_get_http_proxy_username(const cddb_conn_t *c); + +/** + * Set the HTTP proxy password which is used when Basic Authentication + * is required. + * + * @param c The connection structure. + * @param passwd The password. + */ +void cddb_set_http_proxy_password(cddb_conn_t* c, const char* passwd); + +/** + * Get the HTTP proxy password. + * + * @param c The connection structure. + * @return The password. + */ +const char *cddb_get_http_proxy_password(const cddb_conn_t *c); + +/** + * Set the HTTP proxy user name and password in one go. These + * credentials are used when Basic Authentication is required. The + * advantage of using this function over setting the user name and + * password seperately is that the cleartext user name and password + * are not kept in memory longer than needed. + * + * @param c The connection structure. + * @param username The user name. + * @param passwd The password. + */ +void cddb_set_http_proxy_credentials(cddb_conn_t* c, + const char *username, const char* passwd); + +/** + * Get the error number returned by the last libcddb command. + * + * @param c The CDDB connection structure. + * @return The error number. + */ +cddb_error_t cddb_errno(const cddb_conn_t *c); + +/** + * Set the name and version of the client program overwriting the + * previous values. This function will make a copy of the provided + * strings. The defaults are 'libcddb' and the version number of the + * libcddb library in use. Both parameters must be valid strings. If + * any of teh strings is NULL, this fucntion will return without + * changing anything. + * + * @param c The connection structure. + * @param cname The name of the client program. + * @param cversion The version number of the client program. + */ +void cddb_set_client(cddb_conn_t *c, const char *cname, const char *cversion); + +/** + * Sets the user name and host name of the local machine. This + * function will parse out the user name and host name from the e-mail + * address. + * + * @param c The connection structure. + * @param email The e-mail address of the user. + */ +int cddb_set_email_address(cddb_conn_t *c, const char *email); + +/** + * Returns the current cache mode. This can be either on, off or + * cache only. + * + * @see CACHE_ON + * @see CACHE_ONLY + * @see CACHE_OFF + * @see cddb_cache_enable + * @see cddb_cache_only + * @see cddb_cache_disable + * + * @param c The connection structure. + */ +cddb_cache_mode_t cddb_cache_mode(const cddb_conn_t *c); + +/** + * Enable caching of CDDB entries locally. Caching is enabled by + * default. The cache directory can be changed with the + * cddb_cache_set_dir function. + * + * @see cddb_cache_mode + * @see cddb_cache_disable + * @see cddb_cache_only + * + * @param c The connection structure. + */ +void cddb_cache_enable(cddb_conn_t *c); + +/** + * Only use the local CDDB cache. Never contact a server to retrieve + * any data. The cache directory can be changed with the + * cddb_cache_set_dir function. + * + * @see cddb_cache_mode + * @see cddb_cache_enable + * @see cddb_cache_disable + * + * @param c The connection structure. + */ +void cddb_cache_only(cddb_conn_t *c); + +/** + * Disable caching of CDDB entries locally. All data will be fetched + * from a CDDB server everytime and the retrieved data will not be + * cached locally. + * + * @see cddb_cache_mode + * @see cddb_cache_enable + * @see cddb_cache_only + * + * @param c The connection structure. + */ +void cddb_cache_disable(cddb_conn_t *c); + +/** + * Return the directory currently being used for caching. + * + * @see cddb_cache_set_dir + * + * @param c The connection structure. + * @return The directory being used for caching. + */ +const char *cddb_cache_get_dir(const cddb_conn_t *c); + +/** + * Change the directory used for caching CDDB entries locally. The + * default location of the cached entries is a subdirectory + * (.cddbslave) of the user's home directory. If the first character + * of the directory is '~', then it will be expanded to the contents + * of $HOME. + * + * @see cddb_cache_get_dir + * + * @param c The connection structure. + * @param dir The directory to use for caching. + */ +int cddb_cache_set_dir(cddb_conn_t *c, const char *dir); + +/** + * Retrieve the first CDDB mirror site. + * + * @param c The connection structure. + * @return The first mirror site or NULL if not found. + */ +const cddb_site_t *cddb_first_site(cddb_conn_t *c); + +/** + * Retrieve the next CDDB mirror site. + * + * @param c The connection structure. + * @return The next mirror site or NULL if not found. + */ +const cddb_site_t *cddb_next_site(cddb_conn_t *c); + +/** + * Set the bit-string specifying which fields to examine when + * performing a text search. By default only the artist and disc + * title fields are searched. + * + * @param c The connection structure. + * @param fields A bitwise ORed set of values from #cddb_search_t. + */ +void cddb_search_set_fields(cddb_conn_t *c, unsigned int fields); + +/** + * Set the bit-string specifying which categories to examine when + * performing a text search. The #SEARCHCAT macro needs to be used to + * build the actual bit-string from individual categories. The + * #cddb_search_t values #SEARCH_NONE and #SEARCH_ALL are also valid. + * The example below shows some possible combinations. By default all + * categories are searched. + * + * @code + * unsigned int cats = SEARCHCAT(CDDB_CAT_ROCK) | SEARCHCAT(CDDB_CAT_MISC); + * unsigned int cats = SEARCH_ALL; + * unsigned int cats = SEARCH_NONE; + * @endcode + * + * @param c The connection structure. + * @param cats A bitwise ORed set of values from #SEARCHCAT(#cddb_cat_t). + */ +void cddb_search_set_categories(cddb_conn_t *c, unsigned int cats); + + +#ifdef __cplusplus + } +#endif + +#endif /* CDDB_CONN_H */ diff --git a/include/cddb/cddb_conn_ni.h b/include/cddb/cddb_conn_ni.h new file mode 100644 index 00000000..6eddbdcf --- /dev/null +++ b/include/cddb/cddb_conn_ni.h @@ -0,0 +1,178 @@ +/* + $Id: cddb_conn_ni.h,v 1.14 2005/08/03 18:27:19 airborne Exp $ + + Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_CONN_NI_H +#define CDDB_CONN_NI_H 1 + +#ifdef __cplusplus + extern "C" { +#endif + + +#include "cddb_ni.h" +#include "ll.h" + + +/* --- type definitions */ + + +/** Actual definition of iconv structure. */ +struct cddb_iconv_s +{ + iconv_t cd_to_freedb; /**< character set conversion descriptor for + converting from user to FreeDB format */ + iconv_t cd_from_freedb; /**< character set conversion descriptor for + converting from FreeDB to user format */ +}; + +/** Actual definition of serach parameters structure. */ +typedef struct cddb_search_params_s +{ + unsigned int fields; /**< fields to search (cddb_search_t + bit string) */ + unsigned int cats; /**< categories to search (cddb_cat_t + bit string) */ +} cddb_search_params_t; + +/** Actual definition of connection structure. */ +struct cddb_conn_s +{ + unsigned int buf_size; /**< maximum line/buffer size, defaults to 1024 + (see DEFAULT_BUF_SIZE) */ + char *line; /**< last line read */ + + int is_connected; /**< are we already connected to the server? */ + struct sockaddr_in sa; /**< the socket address structure for + connecting to the CDDB server */ + int socket; /**< the socket file descriptor */ + char *server_name; /**< host name of the CDDB server, defaults + to 'freedb.org' (see DEFAULT_SERVER) */ + int server_port; /**< port of the CDDB server, defaults to 888 + (see DEFAULT_PORT) */ + int timeout; /**< time out interval (in seconds) used during + network operations, defaults to 10 seconds + (see DEFAULT_TIMEOUT) */ + + char *http_path_query; /**< URL for querying the server through HTTP, + defaults to /~cddb/cddb.cgi' + (see DEFAULT_PATH_QUERY) */ + char *http_path_submit; /**< URL for submitting to the server through HTTP, + defaults to /~cddb/submit.cgi' + (see DEFAULT_PATH_SUBMIT) */ + int is_http_enabled; /**< use HTTP, disabled by default */ + + int is_http_proxy_enabled; /**< use HTTP through a proxy server, + disabled by default */ + char *http_proxy_server; /**< host name of the HTTP proxy server */ + int http_proxy_server_port; /**< port of the HTTP proxy server, + defaults to 8080 (see DEFAULT_PROXY_PORT) */ + char *http_proxy_username; /**< HTTP proxy user name */ + char *http_proxy_password; /**< HTTP proxy password */ + char *http_proxy_auth; /**< Base64 encoded username:password */ + + FILE *cache_fp; /**< a file pointer to a cached CDDB entry or + NULL if no cached version is available */ + cddb_cache_mode_t use_cache;/**< field to specify local CDDB cache behaviour, + enabled by default (CACHE_ON) */ + char *cache_dir; /**< CDDB slave cache, defaults to + '~/.cddbslave' (see DEFAULT_CACHE) */ + int cache_read; /**< read data from cached file instead of + from the network */ + + char *cname; /**< name of the client program, 'libcddb' by + default */ + char *cversion; /**< version of the client program, current + libcddb version by default */ + char *user; /**< user name supplied to CDDB server, defaults + to the value of the 'USER' environment + variable or 'anonymous' if undefined */ + char *hostname; /**< host name of the local machine, defaults + to the value of the 'HOSTNAME' environment + variable or 'localhost' if undefined */ + + cddb_error_t errnum; /**< error number of last CDDB command */ + + list_t *query_data; /**< list to keep CDDB query results */ + list_t *sites_data; /**< list to keep FreeDB mirror sites */ + cddb_search_params_t srch; /**< parameters for text search */ + + cddb_iconv_t charset; /**< character set conversion settings */ +}; + + +/* --- getters & setters --- */ + + +#define cddb_cache_file(c) (c)->cache_fp + + +/* --- connecting / disconnecting --- */ + + +int cddb_connect(cddb_conn_t *c); + +void cddb_disconnect(cddb_conn_t *c); + + +/* --- miscellaneous --- */ + + +/** + * Clone proxy settings from source connection to destinaton + * connection. + */ +void cddb_clone_proxy(cddb_conn_t *dst, cddb_conn_t *src); + + +/* --- error handling --- */ + + +/** + * Set the error number for the last libcddb command. + * + * @param c The CDDB connection structure. + * @param n The error number + */ +#define cddb_errno_set(c, n) (c)->errnum = n + +/** + * Set the error number for the last libcddb command. If this number + * is different from CDDB_ERR_OK, a message is also logged with the + * level specified. + * + * @param c The CDDB connection structure. + * @param n The error number + * @param l The log level + */ +#define cddb_errno_log(c, n, l) cddb_errno_set(c, n); cddb_log(l, cddb_error_str(n)) + +#define cddb_errno_log_debug(c, n) cddb_errno_log(c, n, CDDB_LOG_DEBUG) +#define cddb_errno_log_info(c, n) cddb_errno_log(c, n, CDDB_LOG_INFO) +#define cddb_errno_log_warn(c, n) cddb_errno_log(c, n, CDDB_LOG_WARN) +#define cddb_errno_log_error(c, n) cddb_errno_log(c, n, CDDB_LOG_ERROR) +#define cddb_errno_log_crit(c, n) cddb_errno_log(c, n, CDDB_LOG_CRITICAL) + + +#ifdef __cplusplus + } +#endif + +#endif /* CDDB_CONN_NI_H */ diff --git a/include/cddb/cddb_disc.h b/include/cddb/cddb_disc.h new file mode 100644 index 00000000..7951ae96 --- /dev/null +++ b/include/cddb/cddb_disc.h @@ -0,0 +1,450 @@ +/* + $Id: cddb_disc.h,v 1.22 2007/08/07 03:12:53 jcaratzas Exp $ + + Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_DISC_H +#define CDDB_DISC_H 1 + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <cddb/cddb_track.h> + + +/** + * The number of frames that fit into one second. + */ +#define FRAMES_PER_SECOND 75 + +/** + * This macro converts an amount of frames into an amount of seconds. + */ +#define FRAMES_TO_SECONDS(f) ((f) / FRAMES_PER_SECOND) + +/** + * This macro converts an amount of seconds into an amount of frames. + */ +#define SECONDS_TO_FRAMES(s) ((s) * FRAMES_PER_SECOND) + +/** + * The different CDDB categories. + */ +typedef enum { + CDDB_CAT_DATA = 0, /**< data disc */ + CDDB_CAT_FOLK, /**< folk music */ + CDDB_CAT_JAZZ, /**< jazz music */ + CDDB_CAT_MISC, /**< miscellaneous, use if no other + category matches */ + CDDB_CAT_ROCK, /**< rock and pop music */ + CDDB_CAT_COUNTRY, /**< country music */ + CDDB_CAT_BLUES, /**< blues music */ + CDDB_CAT_NEWAGE, /**< new age music */ + CDDB_CAT_REGGAE, /**< reggae music */ + CDDB_CAT_CLASSICAL, /**< classical music */ + CDDB_CAT_SOUNDTRACK, /**< soundtracks */ + CDDB_CAT_INVALID, /**< (internal) invalid category */ + CDDB_CAT_LAST /**< (internal) category counter */ +} cddb_cat_t; + +/** + * String values for the CDDB categories. + */ +extern const char *CDDB_CATEGORY[CDDB_CAT_LAST]; + +/** + * The CDDB disc structure. Contains all information associated with + * a full CD. + */ +typedef struct cddb_disc_s cddb_disc_t; + + +/* --- construction / destruction */ + + +/** + * Creates a new CDDB disc structure. + * + * @return The CDDB disc structure or NULL if memory allocation failed. + */ +cddb_disc_t *cddb_disc_new(void); + +/** + * Free all resources associated with the given CDDB disc structure. + * The tracks will also be freed automatically. + * + * @param disc The CDDB disc structure. + */ +void cddb_disc_destroy(cddb_disc_t *disc); + +/** + * Creates a clone of the given disc. + * + * @param disc The CDDB disc structure. + */ +cddb_disc_t *cddb_disc_clone(const cddb_disc_t *disc); + + +/* --- track manipulation */ + + +/** + * Add a new track to a disc. The track is added to the end of the + * existing list of tracks. + * + * @param disc The CDDB disc structure. + * @param track The CDDB track structure. + */ +void cddb_disc_add_track(cddb_disc_t *disc, cddb_track_t *track); + +/** + * Retrieves a numbered track from the disc. If there is no track + * with the given number, then NULL will be returned. + * + * @param disc The CDDB disc structure. + * @param track_no The track number; starting at 0. + */ +cddb_track_t *cddb_disc_get_track(const cddb_disc_t *disc, int track_no); + +/** + * Returns the first track of the disc. If there is no such track + * then NULL will be returned. The internal track iterator will also + * be reset. This function should be called before the first call to + * cddb_disc_get_track_next. + * + * @see cddb_disc_get_track_next + * + * @param disc The CDDB disc structure. + */ +cddb_track_t *cddb_disc_get_track_first(cddb_disc_t *disc); + +/** + * Returns the next track on the disc and advances the internal track + * iterator. If there is no such track then NULL will be returned. + * This function should be called after calling + * cddb_disc_get_track_first. + * + * @see cddb_disc_get_track_first + * + * @param disc The CDDB disc structure. + */ +cddb_track_t *cddb_disc_get_track_next(cddb_disc_t *disc); + + +/* --- setters / getters --- */ + + +/** + * Get the ID of the disc. If the disc is invalid or the disc ID is + * not yet initialized 0 will be returned. + * + * @param disc The CDDB disc structure. + */ +unsigned int cddb_disc_get_discid(const cddb_disc_t *disc); + +/** + * Set the ID of the disc. When the disc ID is not known yet, then it + * can be calculated with the cddb_disc_calc_discid function (which + * will automatically initialize the correct field in the disc + * structure). + * + * @see cddb_disc_calc_discid + * + * @param disc The CDDB disc structure. + * @param id The disc ID. + */ +void cddb_disc_set_discid(cddb_disc_t *disc, unsigned int id); + +/** + * Get the disc CDDB category ID. If the disc is invalid or no + * category is set then CDDB_CAT_INVALID will be returned. If you + * want a string representation of the category use the + * cddb_disc_get_category_str function. + * + * @see cddb_disc_set_category + * @see cddb_disc_get_category_str + * @see cddb_disc_set_category_str + * @see cddb_cat_t + * @see CDDB_CATEGORY + * + * @param disc The CDDB disc structure. + * @return The CDDB category ID. + */ +cddb_cat_t cddb_disc_get_category(const cddb_disc_t *disc); + +/** + * Set the disc CDDB category ID. + * + * @see cddb_disc_get_category + * @see cddb_disc_get_category_str + * @see cddb_disc_set_category_str + * @see cddb_cat_t + * @see CDDB_CATEGORY + * + * @param disc The CDDB disc structure. + * @param cat The CDDB category ID. + */ +void cddb_disc_set_category(cddb_disc_t *disc, cddb_cat_t cat); + +/** + * Get the disc CDDB category as a string. If no category is set for + * this disc then 'invalid' will be returned. If the disc structure + * is invalid NULL is returned. If you only want the ID of the + * category use the cddb_disc_get_category function. + * + * @see cddb_disc_get_category + * @see cddb_disc_set_category + * @see cddb_disc_set_category_str + * + * @param disc The CDDB disc structure. + * @return The CDDB category ID. + */ +const char *cddb_disc_get_category_str(cddb_disc_t *disc); + +/** + * Sets the category of the disc. If the specified category is + * an invalid CDDB category, then CDDB_CAT_MISC will be used. + * + * @see cddb_disc_get_category + * @see cddb_disc_set_category + * @see cddb_disc_get_category_str + * @see CDDB_CATEGORY + * + * @param disc The CDDB disc structure. + * @param cat The category string. + */ +void cddb_disc_set_category_str(cddb_disc_t *disc, const char *cat); + +/** + * Get the disc genre. If no genre is set for this disc then NULL + * will be returned. As opposed to the disc category, this field is + * not limited to a predefined set. + * + * @param disc The CDDB disc structure. + * @return The disc genre. + */ +const char *cddb_disc_get_genre(const cddb_disc_t *disc); + +/** + * Set the disc genre. As opposed to the disc category, this field is + * not limited to a predefined set. If the disc already had a genre, + * then the memory for that string will be freed. The new genre will + * be copied into a new chunk of memory. + * + * @see cddb_disc_get_category_str + * + * @param disc The CDDB disc structure. + * @param genre The disc genre. + */ +void cddb_disc_set_genre(cddb_disc_t *disc, const char *genre); + +/** + * Get the disc length. If no length is set for this disc then 0 will + * be returned. + * + * @param disc The CDDB disc structure. + * @return The disc length in seconds. + */ +unsigned int cddb_disc_get_length(const cddb_disc_t *disc); + +/** + * Set the disc length. + * + * @param disc The CDDB disc structure. + * @param l The disc length in seconds. + */ +void cddb_disc_set_length(cddb_disc_t *disc, unsigned int l); + +/** + * Get the revision number of the disc. + * + * @param disc The CDDB disc structure. + */ +unsigned int cddb_disc_get_revision(const cddb_disc_t *disc); + +/** + * Set the revision number of the disc. + * + * @param disc The CDDB disc structure. + * @param rev The revision number. + */ +void cddb_disc_set_revision(cddb_disc_t *disc, unsigned int rev); + +/** + * Get the year of publication for this disc. If no year is defined 0 + * is returned. + * + * @param disc The CDDB disc structure. + * @return The disc year. + */ +unsigned int cddb_disc_get_year(const cddb_disc_t *disc); + +/** + * Set the year of publication for this disc. + * + * @param disc The CDDB disc structure. + * @param y The disc year. + */ +void cddb_disc_set_year(cddb_disc_t *disc, unsigned int y); + +/** + * Get the number of tracks on the disc. If the disc is invalid -1 is + * returned. + * + * @param disc The CDDB disc structure. + * @return The number of tracks. + */ +int cddb_disc_get_track_count(const cddb_disc_t *disc); + +/** + * Get the disc title. If the disc is invalid or no title is set then + * NULL will be returned. + * + * @param disc The CDDB disc structure. + * @return The disc title. + */ +const char *cddb_disc_get_title(const cddb_disc_t *disc); + +/** + * Set the disc title. If the disc already had a title, then the + * memory for that string will be freed. The new title will be copied + * into a new chunk of memory. If the given title is NULL, then the + * title of the disc will be deleted. + * + * @param disc The CDDB disc structure. + * @param title The new disc title. + */ +void cddb_disc_set_title(cddb_disc_t *disc, const char *title); + +/** + * Append to the disc title. If the disc does not have a title yet, + * then a new one will be created from the given string, otherwise + * that string will be appended to the existing title. + * + * @param disc The CDDB disc structure. + * @param title Part of the disc title. + */ +void cddb_disc_append_title(cddb_disc_t *disc, const char *title); + +/** + * Get the disc artist name. If the disc is invalid or no artist is + * set then NULL will be returned. + * + * @param disc The CDDB disc structure. + * @return The disc artist name. + */ +const char *cddb_disc_get_artist(const cddb_disc_t *disc); + +/** + * Set the disc artist name. If the disc already had an artist name, + * then the memory for that string will be freed. The new artist name + * will be copied into a new chunk of memory. If the given artist + * name is NULL, then the artist name of the disc will be deleted. + * + * @param disc The CDDB disc structure. + * @param artist The new disc artist name. + */ +void cddb_disc_set_artist(cddb_disc_t *disc, const char *artist); + +/** + * Append to the disc artist. If the disc does not have an artist + * yet, then a new one will be created from the given string, + * otherwise that string will be appended to the existing artist. + * + * @param disc The CDDB disc structure. + * @param artist Part of the artist name. + */ +void cddb_disc_append_artist(cddb_disc_t *disc, const char *artist); + +/** + * Get the extended disc data. If the disc is invalid or no extended + * data is set then NULL will be returned. + * + * @param disc The CDDB disc structure. + * @return The extended data. + */ +const char *cddb_disc_get_ext_data(const cddb_disc_t *disc); + +/** + * Set the extended data for the disc. If the disc already had + * extended data, then the memory for that string will be freed. The + * new extended data will be copied into a new chunk of memory. If + * the given extended data is NULL, then the existing data will be + * deleted. + * + * @param disc The CDDB disc structure. + * @param ext_data The new extended data. + */ +void cddb_disc_set_ext_data(cddb_disc_t *disc, const char *ext_data); + +/** + * Append to the extended disc data. If the disc does not have an + * extended data section yet, then a new one will be created from the + * given string, otherwise that string will be appended to the + * existing data. + * + * @param disc The CDDB disc structure. + * @param ext_data Part of the extended disc data. + */ +void cddb_disc_append_ext_data(cddb_disc_t *disc, const char *ext_data); + + +/* --- miscellaneous */ + + +/** + * Copy all data from one disc to another. Any fields that are + * unavailable in the source disc structure will not result in a reset + * of the same field in the destination disc structure; e.g. if there + * is no title in the source disc, but there is one in the destination + * disc, then the destination's title will remain unchanged. + * + * @param dst The destination CDDB disc structure. + * @param src The source CDDB disc structure. + */ +void cddb_disc_copy(cddb_disc_t *dst, cddb_disc_t *src); + +/** + * Calculate the CDDB disc ID. To calculate a disc ID the provided + * disc needs to have its length set, and every track in the disc + * structure needs to have its frame offset initialized. The disc ID + * field will be set in the disc structure. + * + * @param disc The CDDB disc structure. + * @return A non-zero value if the calculation succeeded, zero + * otherwise. + */ +int cddb_disc_calc_discid(cddb_disc_t *disc); + +/** + * Prints information about the disc on stdout. This is just a + * debugging routine to display the structure's content. + * + * @param disc The CDDB disc structure. + */ +void cddb_disc_print(cddb_disc_t *disc); + + +#ifdef __cplusplus + } +#endif + +#endif /* CDDB_DISC_H */ diff --git a/include/cddb/cddb_error.h b/include/cddb/cddb_error.h new file mode 100644 index 00000000..6e779900 --- /dev/null +++ b/include/cddb/cddb_error.h @@ -0,0 +1,118 @@ +/* + $Id: cddb_error.h,v 1.12 2005/05/29 08:11:04 airborne Exp $ + + Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_ERROR_H +#define CDDB_ERROR_H 1 + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <stdio.h> + + +/** + * A list of error codes returned by various libcddb functions. + */ +typedef enum { + + CDDB_ERR_OK = 0, /**< no error occurred */ + + /* --- general errors --- */ + + CDDB_ERR_OUT_OF_MEMORY, /**< out of memory */ + CDDB_ERR_LINE_SIZE, /**< internal buffer too small */ + CDDB_ERR_NOT_IMPLEMENTED, /**< feature not (yet) implemented */ + CDDB_ERR_UNKNOWN, /**< problem unknown */ + + /* --- connection errors --- */ + + CDDB_ERR_SERVER_ERROR, /**< CDDB server error */ + CDDB_ERR_UNKNOWN_HOST_NAME, /**< unknown host name */ + CDDB_ERR_CONNECT, /**< connection error */ + CDDB_ERR_PERMISSION_DENIED, /**< permission denied */ + CDDB_ERR_NOT_CONNECTED, /**< not yet connected or connection + has been closed */ + + /* --- response parsing errors --- */ + + CDDB_ERR_UNEXPECTED_EOF, /**< unexpected end-of-file encountered */ + CDDB_ERR_INVALID_RESPONSE, /**< invalid response data */ + CDDB_ERR_DISC_NOT_FOUND, /**< no results found */ + + /* --- library errors --- */ + + CDDB_ERR_DATA_MISSING, /**< some data is missing for executing + a certain command */ + CDDB_ERR_TRACK_NOT_FOUND, /**< specified track is not present */ + CDDB_ERR_REJECTED, /**< posted data rejected */ + CDDB_ERR_EMAIL_INVALID, /**< the e-mail address used when + submitting is invalid */ + + CDDB_ERR_INVALID_CHARSET, /**< invalid character set or unsupported + conversion */ + CDDB_ERR_ICONV_FAIL, /**< character set conversion failed */ + + /* --- new errors added to back of list for backward compatibility --- */ + + CDDB_ERR_PROXY_AUTH, /**< proxy authentication failed */ + CDDB_ERR_INVALID, /**< invalid input parameter(s) */ + + /* --- terminator --- */ + + CDDB_ERR_LAST +} cddb_error_t; + + +/* --- error handling --- */ + + +/** + * Returns a string representation of the CDDB error code. + * + * @return The error string + */ +const char *cddb_error_str(cddb_error_t errnum); + +/** + * Prints the error message associated with the current error number + * on the given stream. + * + * @param stream The stream + * @param errnum The error number + */ +void cddb_error_stream_print(FILE *stream, cddb_error_t errnum); + +/** + * Prints the error message associated with the current error number + * to stderr. + * + * @param errnum The error number + */ +void cddb_error_print(cddb_error_t errnum); + + +#ifdef __cplusplus + } +#endif + +#endif /* CDDB_ERROR_H */ diff --git a/include/cddb/cddb_log.h b/include/cddb/cddb_log.h new file mode 100644 index 00000000..30fe7899 --- /dev/null +++ b/include/cddb/cddb_log.h @@ -0,0 +1,87 @@ +/* + $Id: cddb_log.h,v 1.4 2005/03/11 21:29:29 airborne Exp $ + + Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_LOH_H +#define CDDB_LOG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * The different log levels supported by libcddb. + */ +typedef enum { + CDDB_LOG_DEBUG = 1, /**< Debug-level messages. */ + CDDB_LOG_INFO, /**< Informational. */ + CDDB_LOG_WARN, /**< Warning conditions. */ + CDDB_LOG_ERROR, /**< Error conditions. */ + CDDB_LOG_CRITICAL, /**< Critical conditions. */ + CDDB_LOG_NONE = 99 /**< No log messages. */ +} cddb_log_level_t; + + +/** + * This type defines the signature of a libcddb log handler. For + * every message being logged by libcddb, the handler will receive the + * log level and the message string. + * + * @see cddb_log_set_handler + * @see cddb_log_level_t + * + * @param level The log level. + * @param message The log message. + */ +typedef void (*cddb_log_handler_t)(cddb_log_level_t level, const char *message); + +/** + * Set a custom log handler for libcddb. The return value is the log + * handler being replaced. If the provided parameter is NULL, then + * the handler will be reset to the default handler. + * + * @see cddb_log_handler_t + * + * @param new_handler The new log handler. + * @return The previous log handler. + */ +cddb_log_handler_t cddb_log_set_handler(cddb_log_handler_t new_handler); + +/** + * Set the minimum log level. This function is only useful in + * conjunction with the default log handler. The default log handler + * will print any log messages that have a log level equal or higher + * than this minimum log level to stderr. By default the minimum log + * level is set to CDDB_LOG_WARN. This means that only warning, error + * and critical messages will be printed. You can silence the default + * log handler by setting the minimum log level to CDDB_LOG_NONE. + * + * @see cddb_log_level_t + * + * @param level The minimum log level. + */ +void cddb_log_set_level(cddb_log_level_t level); + + +#ifdef __cplusplus + } +#endif + +#endif /* CDDB_LOG_H */ diff --git a/include/cddb/cddb_log_ni.h b/include/cddb/cddb_log_ni.h new file mode 100644 index 00000000..ea7727fc --- /dev/null +++ b/include/cddb/cddb_log_ni.h @@ -0,0 +1,59 @@ +/* + $Id: cddb_log_ni.h,v 1.3 2005/03/11 21:29:29 airborne Exp $ + + Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_LOH_NI_H +#define CDDB_LOG_NI_H + +#ifdef __cplusplus + extern "C" { +#endif + + +/** + */ +void cddb_log(cddb_log_level_t level, const char *format, ...); + +/** + */ +#define cddb_log_debug(...) cddb_log(CDDB_LOG_DEBUG, __VA_ARGS__) + +/** + */ +#define cddb_log_info(...) cddb_log(CDDB_LOG_INFO, __VA_ARGS__) + +/** + */ +#define cddb_log_warn(...) cddb_log(CDDB_LOG_WARN, __VA_ARGS__) + +/** + */ +#define cddb_log_error(...) cddb_log(CDDB_LOG_ERROR, __VA_ARGS__) + +/** + */ +#define cddb_log_crit(...) cddb_log(CDDB_LOG_CRITICAL, __VA_ARGS__) + + +#ifdef __cplusplus + } +#endif + +#endif /* CDDB_LOG_NI_H */ diff --git a/include/cddb/cddb_net.h b/include/cddb/cddb_net.h new file mode 100644 index 00000000..60c5464b --- /dev/null +++ b/include/cddb/cddb_net.h @@ -0,0 +1,133 @@ +/* + $Id: cddb_net.h,v 1.11 2005/03/11 21:29:29 airborne Exp $ + + Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_NET_H +#define CDDB_NET_H 1 + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <stdarg.h> + +#if defined( UNDER_CE ) +# include <winsock.h> +#elif defined( WIN32 ) +# include <winsock2.h> +# include <ws2tcpip.h> +#endif + +#include <cddb/cddb_ni.h> +#include <cddb/cddb_config.h> + +#if defined(CDDB_NEED_SYS_SOCKET_H) || defined(HAVE_SYS_SOCKET_H) +#include <sys/socket.h> +#endif + + +/* --- socket-based work-alikes --- */ + + +/** + * This function performs the same task as the standard fgets except + * for the fact that it might time-out if the socket read takes too + * long. In case of a time out, errno will be set to ETIMEDOUT. + * + * @param s The string buffer. + * @param size Size of the buffer. + * @param c The CDDB connection structure. + * @return The string that was read or NULL on error or EOF when no + * characters were read. + */ +char *sock_fgets(char *s, int size, cddb_conn_t *c); + +/** + * This function performs the same task as the standard fwrite except + * for the fact that it might time-out if the socket write takes too + * long. In case of a time out, errno will be set to ETIMEDOUT. + * + * @param ptr Pointer to data record. + * @param size Size of data record. + * @param nmemb The number of data records to write. + * @param c The CDDB connection structure. + * @return The number of records written. + */ +size_t sock_fwrite(const void *ptr, size_t size, size_t nmemb, cddb_conn_t *c); + +/** + * This function performs the same task as the standard fprintf except + * for the fact that it might time-out if the socket write takes too + * long. In case of a time out, errno will be set to ETIMEDOUT. + * + * @param c The CDDB connection structure. + * @param format Pointer to data record. + * @return The number of characters written. + */ +int sock_fprintf(cddb_conn_t *c, const char *format, ...); + +/** + * This function performs the same task as the standard vfprintf + * except for the fact that it might time-out if the socket write + * takes too long. In case of a time out, errno will be set to + * ETIMEDOUT. + * + * @param c The CDDB connection structure. + * @param format Pointer to data record. + * @param ap Variable argument list. + * @return The number of characters written. + */ +int sock_vfprintf(cddb_conn_t *c, const char *format, va_list ap); + +/* --- time-out enabled work-alikes --- */ + +/** + * This function performs the same task as the standard gethostbyname + * except for the fact that it might time-out if the query takes too + * long. In case of a time out, errno will be set to ETIMEDOUT. + * + * @param hostname The hostname that needs to be resolved. + * @param timeout Number of seconds after which to time out. + * @return The host entity for given host name or NULL if not found or + * timed out (errno will be set). + */ +struct hostent *timeout_gethostbyname(const char *hostname, int timeout); + +/** + * This function performs the same task as the standard connect except + * for the fact that it might time-out if the connect takes too long. + * In case of a time out, errno will be set to ETIMEDOUT. + * + * @param sockfd The socket. + * @param addr The address to connect to. + * @param len The size of the address structure. + * @param timeout Number of seconds after which to time out. + * @return Zero on success, -1 on failure (errno will be set). + */ +int timeout_connect(int sockfd, const struct sockaddr *addr, size_t len, + int timeout); + + +#ifdef __cplusplus + } +#endif + +#endif /* CDDB_NET_H */ diff --git a/include/cddb/cddb_ni.h b/include/cddb/cddb_ni.h new file mode 100644 index 00000000..d32fdc13 --- /dev/null +++ b/include/cddb/cddb_ni.h @@ -0,0 +1,189 @@ +/* + $Id: cddb_ni.h,v 1.32 2009/03/01 03:28:07 jcaratzas Exp $ + + Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_NI_H +#define CDDB_NI_H 1 + +#ifdef __cplusplus + extern "C" { +#endif + + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#ifdef HAVE_ICONV_H +# include <iconv.h> +#else + typedef void *iconv_t; /* for code uniformity */ +#endif + +#ifdef HAVE_WINDOWS_H +#include <windows.h> +#endif + +#ifdef HAVE_WINSOCK2_H +#include <winsock2.h> +#ifndef ETIMEDOUT +#define ETIMEDOUT WSAETIMEDOUT +#endif +#ifndef EWOULDBLOCK +#define EWOULDBLOCK WSAEWOULDBLOCK +#endif +#ifndef EINPROGRESS +#define EINPROGRESS WSAEINPROGRESS +#endif +#endif + +#include "cddb/cddb_regex.h" +#include "cddb/cddb.h" +#include "cddb/cddb_conn_ni.h" +#include "cddb/cddb_net.h" +#include "cddb/cddb_cmd_ni.h" +#include "cddb/cddb_log_ni.h" + + +#define FALSE 0 +#define TRUE 1 + +#define CHR_CR '\r' +#define CHR_LF '\n' +#define CHR_EOS '\0' +#define CHR_SPACE ' ' +#define CHR_DOT '.' + +#define DEFAULT_BUF_SIZE 1024 + +#define CLIENT_NAME PACKAGE +#define CLIENT_VERSION VERSION + +#define DEFAULT_USER "anonymous" +#define DEFAULT_HOST "localhost" +#define DEFAULT_SERVER "freedb.org" +#define DEFAULT_PORT 888 +#define DEFAULT_TIMEOUT 10 +#define DEFAULT_PATH_QUERY "/~cddb/cddb.cgi" +#define DEFAULT_PATH_SUBMIT "/~cddb/submit.cgi" +#define DEFAULT_CACHE ".cddbslave" +#define DEFAULT_PROXY_PORT 8080 + +#define DEFAULT_PROTOCOL_VERSION 6 +#define SERVER_CHARSET "UTF8" + + +#define FREE_NOT_NULL(p) if (p) { free(p); p = NULL; } +#define CONNECTION_OK(c) (c->socket != -1) +#define STR_OR_NULL(s) ((s) ? s : "NULL") +#define STR_OR_EMPTY(s) ((s) ? s : "") + +#define RETURN_STR_OR_EMPTY(s) \ + return (!s && (libcddb_flags() & CDDB_F_EMPTY_STR)) ? "" : s + +#define ASSERT(cond, error) \ + if (!(cond)) { return error; } +#define ASSERT_NOT_NULL(ptr) \ + ASSERT(ptr!=NULL, CDDB_ERR_INVALID) +#define ASSERT_RANGE(num,lo,hi) \ + ASSERT((num>=lo)&&(num<=hi), CDDB_ERR_INVALID) + + +/* --- type definitions */ + + +/** Actual definition of track structure. */ +struct cddb_track_s +{ + int num; /**< track number on the disc */ + int frame_offset; /**< frame offset of the track on the disc */ + int length; /**< track length in seconds */ + char *title; /**< track title */ + char *artist; /**< (optional) track artist */ + char *ext_data; /**< (optional) extended disc data */ + struct cddb_track_s *prev; /**< pointer to previous track, or NULL */ + struct cddb_track_s *next; /**< pointer to next track, or NULL */ + struct cddb_disc_s *disc; /**< disc of which this is a track */ +}; + +/** Actual definition of disc structure. */ +struct cddb_disc_s +{ + unsigned int revision; /**< revision number */ + unsigned int discid; /**< four byte disc ID */ + cddb_cat_t category; /**< CDDB category */ + char *genre; /**< disc genre */ + char *title; /**< disc title */ + char *artist; /**< disc artist */ + unsigned int length; /**< disc length in seconds */ + unsigned int year; /**< (optional) disc year YYYY */ + char *ext_data; /**< (optional) extended disc data */ + int track_cnt; /**< number of tracks on the disc */ + cddb_track_t *tracks; /**< pointer to the first track */ + cddb_track_t *iterator; /**< track iterator */ +}; + + +/* --- global variables */ + + +/** Server connection used especially for text searches. */ +extern cddb_conn_t *cddb_search_conn; + + +/* --- non-exported function prototypes */ + + +unsigned int libcddb_flags(void); + +/** + * Convert a string to a new character encoding according to the given + * conversion descriptor. + */ +int cddb_str_iconv(iconv_t cd, ICONV_CONST char *in, char **out); + +/** + * Converts all disc and track strings to user character encoding. + */ +int cddb_disc_iconv(iconv_t cd, cddb_disc_t *disc); + +/** + * Converts all track strings to user character encoding. + */ +int cddb_track_iconv(iconv_t cd, cddb_track_t *track); + +/** + * Converts all site strings to user character encoding. + */ +int cddb_site_iconv(iconv_t cd, cddb_site_t *site); + +/** + * Base64 encode the source string and write it to the destination + * buffer. The destination buffer should be large enough (= 4/3 of + * src string length). + */ +void cddb_b64_encode(char *dst, const char *src); + + +#ifdef __cplusplus + } +#endif + +#endif /* CDDB_NI_H */ diff --git a/include/cddb/cddb_regex.h b/include/cddb/cddb_regex.h new file mode 100644 index 00000000..9b50e097 --- /dev/null +++ b/include/cddb/cddb_regex.h @@ -0,0 +1,74 @@ +/* + $Id: cddb_regex.h,v 1.14 2007/08/07 03:12:53 jcaratzas Exp $ + + Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_REGEX_H +#define CDDB_REGEX_H 1 + +#ifdef HAVE_REGEX_H +#ifdef __cplusplus + extern "C" { +#endif + +#include <cddb/cddb_config.h> +#include <stdlib.h> + +#ifdef CDDB_NEED_UNISTD_H +#include <unistd.h> +#endif +#include <sys/types.h> /* need for MacOS X */ +#include <regex.h> + + +extern regex_t *REGEX_TRACK_FRAME_OFFSETS; +extern regex_t *REGEX_TRACK_FRAME_OFFSET; +extern regex_t *REGEX_DISC_LENGTH; +extern regex_t *REGEX_DISC_REVISION; +extern regex_t *REGEX_DISC_TITLE; +extern regex_t *REGEX_DISC_YEAR; +extern regex_t *REGEX_DISC_GENRE; +extern regex_t *REGEX_DISC_EXT; +extern regex_t *REGEX_TRACK_TITLE; +extern regex_t *REGEX_TRACK_EXT; +extern regex_t *REGEX_PLAY_ORDER; +extern regex_t *REGEX_QUERY_MATCH; +extern regex_t *REGEX_SITE; +extern regex_t *REGEX_TEXT_SEARCH; + + +void cddb_regex_init(void); + +void cddb_regex_destroy(void); + +int cddb_regex_get_int(const char *s, regmatch_t matches[], int idx); + +unsigned long cddb_regex_get_hex(const char *s, regmatch_t matches[], int idx); + +double cddb_regex_get_float(const char *s, regmatch_t matches[], int idx); + +char *cddb_regex_get_string(const char *s, regmatch_t matches[], int idx); + + +#ifdef __cplusplus + } +#endif +#endif /* HAVE_REGEX_H */ + +#endif /* CDDB_REGEX_H */ diff --git a/include/cddb/cddb_site.h b/include/cddb/cddb_site.h new file mode 100644 index 00000000..9c48ac6c --- /dev/null +++ b/include/cddb/cddb_site.h @@ -0,0 +1,248 @@ +/* + $Id: cddb_site.h,v 1.3 2005/06/15 16:08:28 airborne Exp $ + + Copyright (C) 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_SITE_H +#define CDDB_SITE_H 1 + +#ifdef __cplusplus + extern "C" { +#endif + + +#include "cddb/cddb_error.h" + + +/* --- type and structure definitions */ + + +/** + * Enumeration defining the CDDB protocol supported by a specific + * site. + */ +typedef enum { + PROTO_UNKNOWN = 0, /**< Unknown protocol */ + PROTO_CDDBP, /**< FreeDB custom protocol */ + PROTO_HTTP /**< Command tunneling over HTTP */ +} cddb_protocol_t; + +/** + * The CDDB site structure. Contains all information about one + * particular CDDB server. + */ +typedef struct cddb_site_s cddb_site_t; + + +/* --- construction / destruction */ + + +/** + * Creates a new CDDB site structure. + * + * @return The CDDB site structure or NULL if memory allocation failed. + */ +cddb_site_t *cddb_site_new(void); + +/** + * Free all resources associated with the given CDDB site structure. + * + * @param site The CDDB site structure. + */ +cddb_error_t cddb_site_destroy(cddb_site_t *site); + +/** + * Creates a clone of the given site. + * + * @param site The CDDB site structure. + */ +cddb_site_t *cddb_site_clone(cddb_site_t *site); + + +/* --- setters / getters --- */ + + +/** + * Get the site's address. + * + * @param site The CDDB site structure. + * @param address The address of the server upon returning. + * @param port The port of the server upon returning. + * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID. + */ +cddb_error_t cddb_site_get_address(const cddb_site_t *site, + const char **address, unsigned int *port); + +/** + * Set the site's address. A copy of the address string is made. So the caller + * should free any memory associated with the input parameter. + * + * @param site The CDDB site structure. + * @param address The address of the server. + * @param port The port of the server. + * @return Error code: CDDB_ERR_OK, CDDB_ERR_INVALID or CDDB_ERR_OUT_OF_MEMORY. + */ +cddb_error_t cddb_site_set_address(cddb_site_t *site, + const char *address, unsigned int port); + +/** + * Get the protocol used by the site. + * + * @see cddb_protocol_t + * + * @param site The CDDB site structure. + * @return The protocol. + */ +cddb_protocol_t cddb_site_get_protocol(const cddb_site_t *site); + +/** + * Set the protocol used by the site. + * + * @see cddb_protocol_t + * + * @param site The CDDB site structure. + * @param proto The protocol. + * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID. + */ +cddb_error_t cddb_site_set_protocol(cddb_site_t *site, cddb_protocol_t proto); + +/** + * Get the query path in case the HTTP protocol is used. + * + * @param site The CDDB site structure. + * @param path The query path upon returning. + * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID. + */ +cddb_error_t cddb_site_get_query_path(const cddb_site_t *site, + const char **path); + +/** + * Set the query path in case the HTTP protocol is used. A copy of the path + * string is made. So the caller should free any memory associated with the + * input parameter. + * + * @param site The CDDB site structure. + * @param path The query path. A value of NULL deletes the current path. + * @return Error code: CDDB_ERR_OK, CDDB_ERR_INVALID or CDDB_ERR_OUT_OF_MEMORY. + */ +cddb_error_t cddb_site_set_query_path(cddb_site_t *site, const char *path); + +/** + * Get the submit path in case the HTTP protocol is used. + * + * @param site The CDDB site structure. + * @param path The submit path upon returning. + * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID. + */ +cddb_error_t cddb_site_get_submit_path(const cddb_site_t *site, + const char **path); + +/** + * Set the submit path in case the HTTP protocol is used. A copy of the path + * string is made. So the caller should free any memory associated with the + * input parameter. + * + * @param site The CDDB site structure. + * @param path The query path. A value of NULL deletes the current path. + * @return Error code: CDDB_ERR_OK, CDDB_ERR_INVALID or CDDB_ERR_OUT_OF_MEMORY. + */ +cddb_error_t cddb_site_set_submit_path(cddb_site_t *site, const char *path); + +/** + * Get the site's location. + * + * @param site The CDDB site structure. + * @param latitude Will contain the server's latitude upon returning. + * A positive number is used for the northern + * hemisphere, a negative one for the southern + * hemisphere. + * @param longitude Will contain the server's longitude upon returning. + * A positive number is used for the eastern + * hemisphere, a negative one for the western + * hemisphere. + * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID. + */ +cddb_error_t cddb_site_get_location(const cddb_site_t *site, + float *latitude, float *longitude); + +/** + * Set the site's location. + * + * @param site The CDDB site structure. + * @param latitude The server's latitude. Use a positive number for the + * northern hemisphere, a negative one for the southern + * hemisphere. + * @param longitude The server's longitude. Use a positive number for the + * eastern hemisphere, a negative one for the western + * hemisphere. + * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID. + */ +cddb_error_t cddb_site_set_location(cddb_site_t *site, + float latitude, float longitude); + +/** + * Get a description of the site. + * + * @param site The CDDB site structure. + * @param desc The description upon returning. + * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID. + */ +cddb_error_t cddb_site_get_description(const cddb_site_t *site, + const char **desc); + +/** + * Set a description for the site. A copy of the description string is made. + * So the caller should free any memory associated with the input parameter. + * + * @param site The CDDB site structure. + * @param desc The description. A value of NULL deletes the current + * description. + * @return Error code: CDDB_ERR_OK, CDDB_ERR_INVALID or CDDB_ERR_OUT_OF_MEMORY. + */ +cddb_error_t cddb_site_set_description(cddb_site_t *site, const char *desc); + + +/* --- miscellaneous */ + + +/** + * Parses one line of data as returned by the sites command and + * populates the given structure. + * + * @param site The CDDB site structure. + * @param line The result line. + * @return True in case of success or false on failure. + */ +int cddb_site_parse(cddb_site_t *site, const char *line); + +/** + * Prints information about the site on stdout. This is just a + * debugging routine to display the structure's content. + * + * @param site The CDDB site structure. + * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID. + */ +cddb_error_t cddb_site_print(const cddb_site_t *site); + + +#ifdef __cplusplus + } +#endif + +#endif /* CDDB_SITE_H */ diff --git a/include/cddb/cddb_track.h b/include/cddb/cddb_track.h new file mode 100644 index 00000000..0f6ee0f9 --- /dev/null +++ b/include/cddb/cddb_track.h @@ -0,0 +1,244 @@ +/* + $Id: cddb_track.h,v 1.20 2006/10/15 06:51:11 airborne Exp $ + + Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef CDDB_TRACK_H +#define CDDB_TRACK_H 1 + +#ifdef __cplusplus + extern "C" { +#endif + + +/** + * The CDDB track structure. Contains all information associated with + * a single CD track. This structure will be used to populate the + * tracks linked list of the cddb_disc_s structure. + */ +typedef struct cddb_track_s cddb_track_t; + + +/* --- construction / destruction */ + + +/** + * Creates a new CDDB track structure. + * + * @return The CDDB track structure or NULL if memory allocation failed. + */ +cddb_track_t *cddb_track_new(void); + +/** + * Free all resources associated with the given CDDB track structure. + * The linked list pointer (next) will not be touched. So you have to + * make sure that no other tracks are attached to this one before + * calling this function. + * + * @param track The CDDB track structure. + */ +void cddb_track_destroy(cddb_track_t *track); + +/** + * Creates a clone of the given track. + * + * @param track The CDDB track structure. + */ +cddb_track_t *cddb_track_clone(const cddb_track_t *track); + + +/* --- getters & setters --- */ + + +/** + * Get the number of this track. This track number starts counting at + * 1. If the track is invalid or the track number is not defined -1 + * will be returned. + * + * @param track The CDDB track structure. + * @return The track number. + */ +int cddb_track_get_number(const cddb_track_t *track); + +/** + * Get the frame offset of this track on the disc. If the track is + * invalid -1 will be returned. + * + * @param track The CDDB track structure. + * @return The frame offset. + */ +int cddb_track_get_frame_offset(const cddb_track_t *track); + +/** + * Set the frame offset of this track on the disc. + * + * @param track The CDDB track structure. + * @param offset The frame offset. + * @return The frame offset. + */ +void cddb_track_set_frame_offset(cddb_track_t *track, int offset); + +/** + * Get the length of the track in seconds. If the track length is not + * defined this routine will try to calculate it using the frame + * offsets of the tracks and the total disc length. These + * calculations will do no rounding to the nearest second. So it is + * possible that the sum off all track lengths does not add up to the + * actual disc length. If the length can not be calculated -1 will be + * returned. + * + * @param track The CDDB track structure. + * @return The track length. + */ +int cddb_track_get_length(cddb_track_t *track); + +/** + * Set the length of the track. If no frame offset is yet known for + * this track, and it is part of a disc, then the frame offset will be + * calculated. + * + * @param track The CDDB track structure. + * @param length The track length in seconds. + */ +void cddb_track_set_length(cddb_track_t *track, int length); + +/** + * Get the track title. If the track is invalid or no title is set + * for this track then NULL will be returned. + * + * @param track The CDDB track structure. + * @return The track title. + */ +const char *cddb_track_get_title(const cddb_track_t *track); + +/** + * Set the track title. If the track already had a title, then the + * memory for that string will be freed. The new title will be copied + * into a new chunk of memory. If the given title is NULL, then the + * title of the track will be deleted. + * + * @param track The CDDB track structure. + * @param title The new track title. + */ +void cddb_track_set_title(cddb_track_t *track, const char *title); + +/** + * Append to the track title. If the track does not have a title yet, + * then a new one will be created from the given string, otherwise + * that string will be appended to the existing title. + * + * @param track The CDDB track structure. + * @param title Part of the track title. + */ +void cddb_track_append_title(cddb_track_t *track, const char *title); + +/** + * Get the track artist name. If there is no track artist defined, + * the disc artist will be returned. NULL will be returned if neither + * is defined. + * + * @param track The CDDB track structure. + */ +const char *cddb_track_get_artist(cddb_track_t *track); + +/** + * Set the track artist name. If the track already had an artist + * name, then the memory for that string will be freed. The new + * artist name will be copied into a new chunk of memory. If the given artist + * name is NULL, then the artist name of the track will be deleted. + * + * @param track The CDDB track structure. + * @param artist The new track artist name. + */ +void cddb_track_set_artist(cddb_track_t *track, const char *artist); + +/** + * Append to the track artist. If the track does not have an artist + * yet, then a new one will be created from the given string, + * otherwise that string will be appended to the existing artist. + * + * @param track The CDDB track structure. + * @param artist Part of the artist name. + */ +void cddb_track_append_artist(cddb_track_t *track, const char *artist); + +/** + * Get the extended track data. If no extended data is set for this + * track then NULL will be returned. + * + * @param track The CDDB track structure. + * @return The extended data. + */ +const char *cddb_track_get_ext_data(cddb_track_t *track); + +/** + * Set the extended data for the track. If the track already had + * extended data, then the memory for that string will be freed. The + * new extended data will be copied into a new chunk of memory. If + * the given extended data is NULL, then the existing data will be + * deleted. + * + * @param track The CDDB track structure. + * @param ext_data The new extended data. + */ +void cddb_track_set_ext_data(cddb_track_t *track, const char *ext_data); + +/** + * Append to the extended track data. If the track does not have an + * extended data section yet, then a new one will be created from the + * given string, otherwise that string will be appended to the + * existing data. + * + * @param track The CDDB track structure. + * @param ext_data Part of the extended track data. + */ +void cddb_track_append_ext_data(cddb_track_t *track, const char *ext_data); + + +/* --- miscellaneous */ + + +/** + * Copy all data from one track to another. Any fields that are + * unavailable in the source track structure will not result in a + * reset of the same field in the destination track structure; e.g. if + * there is no title in the source track, but there is one in the + * destination track, then the destination's title will remain + * unchanged. + * + * @param dst The destination CDDB track structure. + * @param src The source CDDB track structure. + */ +void cddb_track_copy(cddb_track_t *dst, cddb_track_t *src); + +/** + * Prints information about the track on stdout. This is just a + * debugging routine to display the structure's content. It is used + * by cddb_disc_print to print the contents of a complete disc. + * + * @param track The CDDB track structure. + */ +void cddb_track_print(cddb_track_t *track); + + +#ifdef __cplusplus + } +#endif + +#endif /* CDDB_TRACK_H */ diff --git a/include/cddb/ll.h b/include/cddb/ll.h new file mode 100644 index 00000000..9486e59f --- /dev/null +++ b/include/cddb/ll.h @@ -0,0 +1,148 @@ +/* + $Id: ll.h,v 1.1 2005/05/29 08:24:04 airborne Exp $ + + Copyright (C) 2005 Kris Verbeeck <airborne@advalvas.be> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef LL_H +#define LL_H 1 + +#ifdef __cplusplus + extern "C" { +#endif + + +/* --- type definitions */ + + +/** + * Linked list element. + */ +typedef struct elem_s elem_t; + +/** + * Linked list. + */ +typedef struct list_s list_t; + +/** + * Callback prototype for destroying element data. + */ +typedef void elem_destroy_cb(void *data); + + +/* --- construction / destruction */ + + +/** + * Creates a new linked list. + * + * @param cb The callback used to destroy the element data or NULL if + * no further action is required. + * @return The linked list structure or NULL if memory allocation failed. + */ +list_t *list_new(elem_destroy_cb *cb); + +/** + * Free all resources associated with the given linked list. Embedded + * data will be freed by use of the callback registered at list + * creation. + * + * @param list The linked list. + */ +void list_destroy(list_t *list); + +/** + * Remove all elements from the list without destroying the list + * itself. Embedded data will be freed by use of the callback + * registered at list creation. + * + * @param list The linked list. + */ +void list_flush(list_t *list); + + +/* --- list elements --- */ + +/** + * Retrieves the data associated with a list element. + * + * @param elem The list element. + * @return The data associated with the element or NULL if the element + * was invalid. + */ +void *element_data(elem_t *elem); + + +/* --- getters & setters --- */ + + +/** + * Append a new element to the end of the list. + * + * @param list The linked list. + * @param data The data to append to the list. + * @return The list element that was appended or NULL if memory + * allocation fails or the list is invalid. + */ +elem_t *list_append(list_t *list, void *data); + +/** + * Returns the number of elements in the list. + * + * @param list The linked list. + * @return The number of elements. + */ +int list_size(list_t *list); + +/** + * Returns the list element at the specified index or NULL if the + * index is invalid. + * + * @param list The linked list. + * @param idx The element index (first = 0). + * @return The element or NULL if not found. + */ +elem_t *list_get(list_t *list, int idx); + +/** + * Returns the first list element. + * + * @param list The linked list. + * @return The first element or NULL if the list is empty. + */ +elem_t *list_first(list_t *list); + +/** + * Returns the next list element. Before using this function you + * should call list_first to initialize the iterator. + * + * @param list The linked list. + * @return The next element or NULL if not found. + */ +elem_t *list_next(list_t *list); + + +/* --- iteration */ + + +#ifdef __cplusplus + } +#endif + +#endif /* LL_H */ diff --git a/include/cddb/version.h b/include/cddb/version.h new file mode 100644 index 00000000..f72839b2 --- /dev/null +++ b/include/cddb/version.h @@ -0,0 +1,12 @@ +/* $Id: version.h.in,v 1.1 2005/04/08 01:49:35 rockyb Exp $ */ +/** \file version.h + * + * \brief A file containing the libcdio package version + * number (131) and OS build name. + */ + +/*! CDDB_VERSION can as a string in programs to show what version is used. */ +#define CDDB_VERSION "1.3.2 i686-pc-linux-gnu" + +/*! LIBCDDB_VERSION_NUM can be used for testing in the C preprocessor */ +#define LIBCDDB_VERSION_NUM 131 diff --git a/include/cddb/version.h.in b/include/cddb/version.h.in new file mode 100644 index 00000000..48d4c3fc --- /dev/null +++ b/include/cddb/version.h.in @@ -0,0 +1,12 @@ +/* $Id: version.h.in,v 1.1 2005/04/08 01:49:35 rockyb Exp $ */ +/** \file version.h + * + * \brief A file containing the libcdio package version + * number (@LIBCDDB_VERSION_NUM@) and OS build name. + */ + +/*! CDDB_VERSION can as a string in programs to show what version is used. */ +#define CDDB_VERSION "@VERSION@ @build@" + +/*! LIBCDDB_VERSION_NUM can be used for testing in the C preprocessor */ +#define LIBCDDB_VERSION_NUM @LIBCDDB_VERSION_NUM@ diff --git a/include/cdio/Makefile.am b/include/cdio/Makefile.am new file mode 100644 index 00000000..ea695618 --- /dev/null +++ b/include/cdio/Makefile.am @@ -0,0 +1,62 @@ +# $Id: Makefile.am,v 1.34 2008/03/20 19:02:37 karl Exp $ +# +# Copyright (C) 2003, 2004, 2006, 2008 Rocky Bernstein <rocky@gnu.org> +# +# 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 3 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, see <http://www.gnu.org/licenses/>. + +######################################################## +# Things to make the install (public) libcdio headers +######################################################## +# + +if BUILD_CD_PARANOIA +paranoiaheaders = cdda.h cdtext.h +endif + +libcdioincludedir=$(includedir)/cdio +libcdioinclude_HEADERS = \ + audio.h \ + bytesex.h \ + bytesex_asm.h \ + cdio.h \ + cdio_config.h \ + cd_types.h \ + device.h \ + disc.h \ + ds.h \ + dvd.h \ + ecma_167.h \ + iso9660.h \ + logging.h \ + mmc.h \ + paranoia.h \ + posix.h \ + read.h \ + rock.h \ + sector.h \ + track.h \ + types.h \ + udf.h \ + udf_file.h \ + udf_time.h \ + utf8.h \ + util.h \ + version.h \ + xa.h \ + $(paranoiaheaders) + +EXTRA_DIST = version.h.in +BUILT_SOURCES = version.h + +DISTCLEANFILES = cdio_config.h diff --git a/include/cdio/audio.h b/include/cdio/audio.h new file mode 100644 index 00000000..880cd541 --- /dev/null +++ b/include/cdio/audio.h @@ -0,0 +1,148 @@ +/* -*- c -*- + $Id: audio.h,v 1.12 2008/03/25 15:59:08 karl Exp $ + + Copyright (C) 2005, 2007, 2008 Rocky Bernstein <rocky@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** \file audio.h + * + * \brief The top-level header for CD audio-related libcdio + * calls. These control playing of the CD-ROM through its + * line-out jack. + */ +#ifndef __CDIO_AUDIO_H__ +#define __CDIO_AUDIO_H__ + +#include <cdio/types.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /*! This struct is used by the cdio_audio_read_subchannel */ + typedef struct cdio_subchannel_s + { + uint8_t format; + uint8_t audio_status; + uint8_t address: 4; + uint8_t control: 4; + uint8_t track; + uint8_t index; + msf_t abs_addr; + msf_t rel_addr; + } cdio_subchannel_t; + + /*! This struct is used by cdio_audio_get_volume and cdio_audio_set_volume */ + typedef struct cdio_audio_volume_s + { + uint8_t level[4]; + } cdio_audio_volume_t; + + + /*! This struct is used by the CDROMPLAYTRKIND ioctl */ + typedef struct cdio_track_index_s + { + uint8_t i_start_track; /**< start track */ + uint8_t i_start_index; /**< start index */ + uint8_t i_end_track; /**< end track */ + uint8_t i_end_index; /**< end index */ + } cdio_track_index_t; + + /*! + Get volume of an audio CD. + + @param p_cdio the CD object to be acted upon. + @param p_volume place to put the list of volume outputs levels + + p_volume can be NULL in which case we return only whether the driver + has the ability to get the volume or not. + + */ + driver_return_code_t cdio_audio_get_volume (CdIo_t *p_cdio, /*out*/ + cdio_audio_volume_t *p_volume); + + /*! + Return the number of seconds (discarding frame portion) of an MSF + */ + uint32_t cdio_audio_get_msf_seconds(msf_t *p_msf); + + /*! + Pause playing CD through analog output + + @param p_cdio the CD object to be acted upon. + */ + driver_return_code_t cdio_audio_pause (CdIo_t *p_cdio); + + /*! + Playing CD through analog output at the given MSF. + + @param p_cdio the CD object to be acted upon. + @param p_start_msf pointer to staring MSF + @param p_end_msf pointer to ending MSF + */ + driver_return_code_t cdio_audio_play_msf (CdIo_t *p_cdio, + /*in*/msf_t *p_start_msf, + /*in*/ msf_t *p_end_msf); + + /*! + Playing CD through analog output at the desired track and index + + @param p_cdio the CD object to be acted upon. + @param p_track_index location to start/end. + */ + driver_return_code_t cdio_audio_play_track_index + ( CdIo_t *p_cdio, cdio_track_index_t *p_track_index); + + /*! + Get subchannel information. + + @param p_cdio the CD object to be acted upon. + @param p_subchannel place for returned subchannel information + */ + driver_return_code_t cdio_audio_read_subchannel (CdIo_t *p_cdio, + /*out*/ cdio_subchannel_t *p_subchannel); + + /*! + Resume playing an audio CD. + + @param p_cdio the CD object to be acted upon. + + */ + driver_return_code_t cdio_audio_resume (CdIo_t *p_cdio); + + /*! + Set volume of an audio CD. + + @param p_cdio the CD object to be acted upon. + @param p_volume place for returned volume-level information + + */ + driver_return_code_t cdio_audio_set_volume (CdIo_t *p_cdio, /*out*/ + cdio_audio_volume_t *p_volume); + + /*! + Stop playing an audio CD. + + @param p_cdio the CD object to be acted upon. + + */ + driver_return_code_t cdio_audio_stop (CdIo_t *p_cdio); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CDIO_AUDIO_H__ */ diff --git a/include/cdio/bytesex.h b/include/cdio/bytesex.h new file mode 100644 index 00000000..e1be483e --- /dev/null +++ b/include/cdio/bytesex.h @@ -0,0 +1,220 @@ +/* + $Id: bytesex.h,v 1.5 2008/03/25 15:59:08 karl Exp $ + + Copyright (C) 2000, 2004 Herbert Valerio Riedel <hvr@gnu.org> + Copyright (C) 2005, 2008 Rocky Bernstein <rocky@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** \file bytesex.h + * \brief Generic Byte-swapping routines. + * + * Note: this header will is slated to get removed and libcdio will + * use glib.h routines instead. +*/ + +#ifndef __CDIO_BYTESEX_H__ +#define __CDIO_BYTESEX_H__ + +#include <cdio/types.h> +#include <cdio/bytesex_asm.h> +#include <cdio/logging.h> + +/** 16-bit big-endian to little-endian */ +#define UINT16_SWAP_LE_BE_C(val) ((uint16_t) ( \ + (((uint16_t) (val) & (uint16_t) 0x00ffU) << 8) | \ + (((uint16_t) (val) & (uint16_t) 0xff00U) >> 8))) + +/** 32-bit big-endian to little-endian */ +#define UINT32_SWAP_LE_BE_C(val) ((uint32_t) ( \ + (((uint32_t) (val) & (uint32_t) 0x000000ffU) << 24) | \ + (((uint32_t) (val) & (uint32_t) 0x0000ff00U) << 8) | \ + (((uint32_t) (val) & (uint32_t) 0x00ff0000U) >> 8) | \ + (((uint32_t) (val) & (uint32_t) 0xff000000U) >> 24))) + +/** 64-bit big-endian to little-endian */ +#define UINT64_SWAP_LE_BE_C(val) ((uint64_t) ( \ + (((uint64_t) (val) & (uint64_t) UINT64_C(0x00000000000000ff)) << 56) | \ + (((uint64_t) (val) & (uint64_t) UINT64_C(0x000000000000ff00)) << 40) | \ + (((uint64_t) (val) & (uint64_t) UINT64_C(0x0000000000ff0000)) << 24) | \ + (((uint64_t) (val) & (uint64_t) UINT64_C(0x00000000ff000000)) << 8) | \ + (((uint64_t) (val) & (uint64_t) UINT64_C(0x000000ff00000000)) >> 8) | \ + (((uint64_t) (val) & (uint64_t) UINT64_C(0x0000ff0000000000)) >> 24) | \ + (((uint64_t) (val) & (uint64_t) UINT64_C(0x00ff000000000000)) >> 40) | \ + (((uint64_t) (val) & (uint64_t) UINT64_C(0xff00000000000000)) >> 56))) + +#ifndef UINT16_SWAP_LE_BE +# define UINT16_SWAP_LE_BE UINT16_SWAP_LE_BE_C +#endif + +#ifndef UINT32_SWAP_LE_BE +# define UINT32_SWAP_LE_BE UINT32_SWAP_LE_BE_C +#endif + +#ifndef UINT64_SWAP_LE_BE +# define UINT64_SWAP_LE_BE UINT64_SWAP_LE_BE_C +#endif + +inline static +uint16_t uint16_swap_le_be (const uint16_t val) +{ + return UINT16_SWAP_LE_BE (val); +} + +inline static +uint32_t uint32_swap_le_be (const uint32_t val) +{ + return UINT32_SWAP_LE_BE (val); +} + +inline static +uint64_t uint64_swap_le_be (const uint64_t val) +{ + return UINT64_SWAP_LE_BE (val); +} + +# define UINT8_TO_BE(val) ((uint8_t) (val)) +# define UINT8_TO_LE(val) ((uint8_t) (val)) +#ifdef WORDS_BIGENDIAN +# define UINT16_TO_BE(val) ((uint16_t) (val)) +# define UINT16_TO_LE(val) ((uint16_t) UINT16_SWAP_LE_BE(val)) + +# define UINT32_TO_BE(val) ((uint32_t) (val)) +# define UINT32_TO_LE(val) ((uint32_t) UINT32_SWAP_LE_BE(val)) + +# define UINT64_TO_BE(val) ((uint64_t) (val)) +# define UINT64_TO_LE(val) ((uint64_t) UINT64_SWAP_LE_BE(val)) +#else +# define UINT16_TO_BE(val) ((uint16_t) UINT16_SWAP_LE_BE(val)) +# define UINT16_TO_LE(val) ((uint16_t) (val)) + +# define UINT32_TO_BE(val) ((uint32_t) UINT32_SWAP_LE_BE(val)) +# define UINT32_TO_LE(val) ((uint32_t) (val)) + +# define UINT64_TO_BE(val) ((uint64_t) UINT64_SWAP_LE_BE(val)) +# define UINT64_TO_LE(val) ((uint64_t) (val)) +#endif + +/** symmetric conversions */ +#define UINT8_FROM_BE(val) (UINT8_TO_BE (val)) +#define UINT8_FROM_LE(val) (UINT8_TO_LE (val)) +#define UINT16_FROM_BE(val) (UINT16_TO_BE (val)) +#define UINT16_FROM_LE(val) (UINT16_TO_LE (val)) +#define UINT32_FROM_BE(val) (UINT32_TO_BE (val)) +#define UINT32_FROM_LE(val) (UINT32_TO_LE (val)) +#define UINT64_FROM_BE(val) (UINT64_TO_BE (val)) +#define UINT64_FROM_LE(val) (UINT64_TO_LE (val)) + +/** converter function template */ +#define CVT_TO_FUNC(bits) \ + static inline uint ## bits ## _t \ + uint ## bits ## _to_be (uint ## bits ## _t val) \ + { return UINT ## bits ## _TO_BE (val); } \ + static inline uint ## bits ## _t \ + uint ## bits ## _to_le (uint ## bits ## _t val) \ + { return UINT ## bits ## _TO_LE (val); } \ + +CVT_TO_FUNC(8) +CVT_TO_FUNC(16) +CVT_TO_FUNC(32) +CVT_TO_FUNC(64) + +#undef CVT_TO_FUNC + +#define uint8_from_be(val) (uint8_to_be (val)) +#define uint8_from_le(val) (uint8_to_le (val)) +#define uint16_from_be(val) (uint16_to_be (val)) +#define uint16_from_le(val) (uint16_to_le (val)) +#define uint32_from_be(val) (uint32_to_be (val)) +#define uint32_from_le(val) (uint32_to_le (val)) +#define uint64_from_be(val) (uint64_to_be (val)) +#define uint64_from_le(val) (uint64_to_le (val)) + +/** ISO9660-related field conversion routines */ + +/** Convert from uint8_t to ISO 9660 7.1.1 format */ +#define to_711(i) uint8_to_le(i) + +/** Convert from ISO 9660 7.1.1 format to uint8_t */ +#define from_711(i) uint8_from_le(i) + +/** Convert from uint16_t to ISO 9669 7.2.1 format */ +#define to_721(i) uint16_to_le(i) + +/** Convert from ISO 9660 7.2.1 format to uint16_t */ +#define from_721(i) uint16_from_le(i) + +/** Convert from uint16_t to ISO 9669 7.2.2 format */ +#define to_722(i) uint16_to_be(i) + +/** Convert from ISO 9660 7.2.2 format to uint16_t */ +#define from_722(i) uint16_from_be(i) + +/** Convert from uint16_t to ISO 9669 7.2.3 format */ +static inline uint32_t +to_723(uint16_t i) +{ + return uint32_swap_le_be(i) | i; +} + +/** Convert from ISO 9660 7.2.3 format to uint16_t */ +static inline uint16_t +from_723 (uint32_t p) +{ + if (uint32_swap_le_be (p) != p) + cdio_warn ("from_723: broken byte order"); + + return (0xFFFF & p); +} + +/** Convert from uint16_t to ISO 9669 7.3.1 format */ +#define to_731(i) uint32_to_le(i) + +/** Convert from ISO 9660 7.3.1 format to uint32_t */ +#define from_731(i) uint32_from_le(i) + +/** Convert from uint32_t to ISO 9669 7.3.2 format */ +#define to_732(i) uint32_to_be(i) + +/** Convert from ISO 9660 7.3.2 format to uint32_t */ +#define from_732(i) uint32_from_be(i) + +/** Convert from uint16_t to ISO 9669 7.3.3 format */ +static inline uint64_t +to_733(uint32_t i) +{ + return uint64_swap_le_be(i) | i; +} + +/** Convert from ISO 9660 7.3.3 format to uint32_t */ +static inline uint32_t +from_733 (uint64_t p) +{ + if (uint64_swap_le_be (p) != p) + cdio_warn ("from_733: broken byte order"); + + return (UINT32_C(0xFFFFFFFF) & p); +} + +#endif /* __CDIO_BYTESEX_H__ */ + + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/cdio/bytesex_asm.h b/include/cdio/bytesex_asm.h new file mode 100644 index 00000000..7f1f131a --- /dev/null +++ b/include/cdio/bytesex_asm.h @@ -0,0 +1,130 @@ +/* + $Id: bytesex_asm.h,v 1.3 2008/03/25 15:59:08 karl Exp $ + + Copyright (C) 2008 Rocky Bernstein <rocky@gnu.org> + 2001, 2004, 2005 Herbert Valerio Riedel <hvr@gnu.org> + 2001 Sven Ottemann <ac-logic@freenet.de> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** \file bytesex_asm.h + * \brief Assembly code to handle byte-swapping. + + Note: this header will is slated to get removed and libcdio will use + glib.h routines instead. +*/ + +#ifndef __CDIO_BYTESEX_ASM_H__ +#define __CDIO_BYTESEX_ASM_H__ +#if !defined(DISABLE_ASM_OPTIMIZE) + +#include <cdio/types.h> + +#if defined(__powerpc__) && defined(__GNUC__) + +inline static +uint32_t uint32_swap_le_be_asm(const uint32_t a) +{ + uint32_t b; + + __asm__ ("lwbrx %0,0,%1" + :"=r"(b) + :"r"(&a), "m"(a)); + + return b; +} + +inline static +uint16_t uint16_swap_le_be_asm(const uint16_t a) +{ + uint32_t b; + + __asm__ ("lhbrx %0,0,%1" + :"=r"(b) + :"r"(&a), "m"(a)); + + return b; +} + +#define UINT16_SWAP_LE_BE uint16_swap_le_be_asm +#define UINT32_SWAP_LE_BE uint32_swap_le_be_asm + +#elif defined(__mc68000__) && defined(__STORMGCC__) + +inline static +uint32_t uint32_swap_le_be_asm(uint32_t a __asm__("d0")) +{ + /* __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); */ + + __asm__("move.l %1,d0;rol.w #8,d0;swap d0;rol.w #8,d0;move.l d0,%0" + :"=r"(a) + :"r"(a)); + + return(a); +} + +inline static +uint16_t uint16_swap_le_be_asm(uint16_t a __asm__("d0")) +{ + __asm__("move.l %1,d0;rol.w #8,d0;move.l d0,%0" + :"=r"(a) + :"r"(a)); + + return(a); +} + +#define UINT16_SWAP_LE_BE uint16_swap_le_be_asm +#define UINT32_SWAP_LE_BE uint32_swap_le_be_asm + +#elif 0 && defined(__i386__) && defined(__GNUC__) + +inline static +uint32_t uint32_swap_le_be_asm(uint32_t a) +{ + __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ + "rorl $16,%0\n\t" /* swap words */ + "xchgb %b0,%h0" /* swap higher bytes */ + :"=q" (a) + : "0" (a)); + + return(a); +} + +inline static +uint16_t uint16_swap_le_be_asm(uint16_t a) +{ + __asm__("xchgb %b0,%h0" /* swap bytes */ + : "=q" (a) + : "0" (a)); + + return(a); +} + +#define UINT16_SWAP_LE_BE uint16_swap_le_be_asm +#define UINT32_SWAP_LE_BE uint32_swap_le_be_asm + +#endif + +#endif /* !defined(DISABLE_ASM_OPTIMIZE) */ +#endif /* __CDIO_BYTESEX_ASM_H__ */ + + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/cdio/cd_types.h b/include/cdio/cd_types.h new file mode 100644 index 00000000..bc1f16c0 --- /dev/null +++ b/include/cdio/cd_types.h @@ -0,0 +1,175 @@ +/* + $Id: cd_types.h,v 1.18 2008/03/25 15:59:08 karl Exp $ + + Copyright (C) 2003, 2006, 2008 Rocky Bernstein <rocky@cpan.org> + Copyright (C) 1996,1997,1998 Gerd Knorr <kraxel@bytesex.org> + and Heiko Eißfeldt <heiko@hexco.de> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** \file cd_types.h + * \brief Header for routines which automatically determine the Compact Disc + * format and possibly filesystem on the CD. + * + */ + +#ifndef __CDIO_CD_TYPES_H__ +#define __CDIO_CD_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * Filesystem types we understand. The highest-numbered fs type should + * be less than CDIO_FS_MASK defined below. + */ + typedef enum { + CDIO_FS_AUDIO = 1, /**< audio only - not really a + filesystem */ + CDIO_FS_HIGH_SIERRA = 2, /**< High-Sierra Filesystem */ + CDIO_FS_ISO_9660 = 3, /**< ISO 9660 filesystem */ + CDIO_FS_INTERACTIVE = 4, + CDIO_FS_HFS = 5, /**< file system used on the Macintosh + system in MacOS 6 through MacOS 9 + and deprecated in OSX. */ + CDIO_FS_UFS = 6, /**< Generic Unix file system derived + from the Berkeley fast file + system. */ + + /**< + * EXT2 was the GNU/Linux native filesystem for early kernels. Newer + * GNU/Linux OS's may use EXT3 which is EXT2 with a journal. + */ + CDIO_FS_EXT2 = 7, + + CDIO_FS_ISO_HFS = 8, /**< both HFS & ISO-9660 filesystem */ + CDIO_FS_ISO_9660_INTERACTIVE = 9, /**< both CD-RTOS and ISO filesystem */ + + + /**< + * The 3DO is, technically, a set of specifications created by the 3DO + * company. These specs are for making a 3DO Interactive Multiplayer + * which uses a CD-player. Panasonic in the early 90's was the first + * company to manufacture and market a 3DO player. + */ + CDIO_FS_3DO = 10, + + + /**< + Microsoft X-BOX CD. + */ + CDIO_FS_XISO = 11, + CDIO_FS_UDFX = 12, + CDIO_FS_UDF = 13, + CDIO_FS_ISO_UDF = 14 + } cdio_fs_t; + + +/** + * Macro to extract just the FS type portion defined above +*/ +#define CDIO_FSTYPE(fs) (fs & CDIO_FS_MASK) + +/** + * Bit masks for the classes of CD-images. These are generally + * higher-level than the fs-type information above and may be determined + * based of the fs type information. This + */ + typedef enum { + CDIO_FS_MASK = 0x000f, /**< Note: this should be 2**n-1 and + and greater than the highest + CDIO_FS number above */ + CDIO_FS_ANAL_XA = 0x00010, /**< eXtended Architecture format */ + CDIO_FS_ANAL_MULTISESSION = 0x00020, /**< CD has multisesion */ + CDIO_FS_ANAL_PHOTO_CD = 0x00040, /**< Is a Kodak Photo CD */ + CDIO_FS_ANAL_HIDDEN_TRACK = 0x00080, /**< Hidden track at the + beginning of the CD */ + CDIO_FS_ANAL_CDTV = 0x00100, + CDIO_FS_ANAL_BOOTABLE = 0x00200, /**< CD is bootable */ + CDIO_FS_ANAL_VIDEOCD = 0x00400, /**< VCD 1.1 */ + CDIO_FS_ANAL_ROCKRIDGE = 0x00800, /**< Has Rock Ridge Extensions to + ISO 9660, */ + CDIO_FS_ANAL_JOLIET = 0x01000, /**< Microsoft Joliet extensions + to ISO 9660, */ + CDIO_FS_ANAL_SVCD = 0x02000, /**< Super VCD or Choiji Video CD */ + CDIO_FS_ANAL_CVD = 0x04000, /**< Choiji Video CD */ + CDIO_FS_ANAL_XISO = 0x08000, /**< XBOX CD */ + CDIO_FS_ANAL_ISO9660_ANY = 0x10000, /**< Any sort fo ISO9660 FS */ + CDIO_FS_ANAL_VCD_ANY = (CDIO_FS_ANAL_VIDEOCD|CDIO_FS_ANAL_SVCD| + CDIO_FS_ANAL_CVD), + CDIO_FS_MATCH_ALL = ~CDIO_FS_MASK /**< bitmask which can + be used by + cdio_get_devices to + specify matching any + sort of CD. */ + } cdio_fs_cap_t; + + +#define CDIO_FS_UNKNOWN CDIO_FS_MASK + +/** + * + */ +#define CDIO_FS_MATCH_ALL (cdio_fs_anal_t) (~CDIO_FS_MASK) + + +/*! + \brief The type used to return analysis information from + cdio_guess_cd_type. + + These fields make sense only for when an ISO-9660 filesystem is used. + */ +typedef struct +{ + unsigned int joliet_level; /**< If has Joliet extensions, this is the + associated level number (i.e. 1, 2, or 3). */ + char iso_label[33]; /**< This is 32 + 1 for null byte at the end in + formatting the string */ + unsigned int isofs_size; + uint8_t UDFVerMinor; /**< For UDF filesystems only */ + uint8_t UDFVerMajor; /**< For UDF filesystems only */ +} cdio_iso_analysis_t; + +/** + * Try to determine what kind of CD-image and/or filesystem we + * have at track track_num. Return information about the CD image + * is returned in iso_analysis and the return value. + */ +cdio_fs_anal_t cdio_guess_cd_type(const CdIo_t *cdio, int start_session, + track_t track_num, + /*out*/ cdio_iso_analysis_t *iso_analysis); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/** The below variables are trickery to force the above enum symbol + values to be recorded in debug symbol tables. They are used to + allow one to refer to the enumeration value names in the typedefs + above in a debugger and debugger expressions. +*/ +extern cdio_fs_cap_t debug_cdio_fs_cap; +extern cdio_fs_t debug_cdio_fs; + +#endif /* __CDIO_CD_TYPES_H__ */ + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/cdio/cdda.h b/include/cdio/cdda.h new file mode 100644 index 00000000..c30e129d --- /dev/null +++ b/include/cdio/cdda.h @@ -0,0 +1,411 @@ +/* + $Id: cdda.h,v 1.30 2008/03/25 15:59:08 karl Exp $ + + Copyright (C) 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org> + Copyright (C) 2001 Xiph.org and Heiko Eissfeldt heiko@escape.colossus.de + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** \file cdda.h + * + * \brief The top-level interface header for libcdio_cdda. + * Applications include this for paranoia access. + * + ******************************************************************/ + +#ifndef _CDDA_INTERFACE_H_ +#define _CDDA_INTERFACE_H_ + +#include <cdio/cdio.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /** cdrom_paranoia is an opaque structure which is used in all of the + library operations. + */ + typedef struct cdrom_paranoia_s cdrom_paranoia_t; + typedef struct cdrom_drive_s cdrom_drive_t; + + /** For compatibility. cdrom_drive_t is deprecated, use cdrom_drive_t + instead. */ + + /** + Flags for simulating jitter used in testing. + + The enumeration type one probably wouldn't really use in a program. + It is here instead of defines to give symbolic names that can be + helpful in debuggers where wants just to say refer to + CDDA_TEST_JITTER_SMALL and get the correct value. + */ + typedef enum { + CDDA_MESSAGE_FORGETIT = 0, + CDDA_MESSAGE_PRINTIT = 1, + CDDA_MESSAGE_LOGIT = 2, + CD_FRAMESAMPLES = CDIO_CD_FRAMESIZE_RAW / 4, + MAXTRK = (CDIO_CD_MAX_TRACKS+1) + } paranoia_cdda_enums_t; + + +#include <signal.h> + +/** We keep MAXTRK since this header is exposed publicly and other + programs may have used this. +*/ +#define MAXTRK (CDIO_CD_MAX_TRACKS+1) + +/** \brief Structure for cdparanoia's CD Table of Contents */ +typedef struct TOC_s { + unsigned char bTrack; + int32_t dwStartSector; +} TOC_t; + +/** For compatibility. TOC is deprecated, use TOC_t instead. */ +#define TOC TOC_t + +/** \brief Structure for cdparanoia's CD-ROM access */ +struct cdrom_drive_s { + + CdIo_t *p_cdio; + int opened; /**< This struct may just represent a candidate for opening */ + + char *cdda_device_name; + + char *drive_model; + int drive_type; + int bigendianp; /**< Whether data returned on the CDDA is bigendian or + not. 1 if big endian, 0 if little endian and -1 if + we don't know. + */ + int nsectors; /**< Number of sectors use in reading. Multiply by + CDIO_CD_FRAMESIZE_RAW to get number of bytes used in + the read buffer. */ + + int cd_extra; /**< -1 if we can't get multisession info, 0 if + there is one session only or the multi-session + LBA is less than or 100 (don't ask me why -- I + don't know), and 1 if the multi-session lba is + greater than 100. */ + + bool b_swap_bytes; /**< Swap bytes if Endian-ness of drive + mismatches the endian-ness of the + computer? */ + track_t tracks; + TOC_t disc_toc[MAXTRK]; /**< info here starts origin 0 rather than the + first track number (usually 1). So to take + a track number and use it here, subtract + off cdio_get_first_track_num() beforehand. + */ + lsn_t audio_first_sector; + lsn_t audio_last_sector; + + int errordest; + int messagedest; + char *errorbuf; + char *messagebuf; + + /* functions specific to particular drives/interfaces */ + + int (*enable_cdda) (cdrom_drive_t *d, int onoff); + int (*read_toc) (cdrom_drive_t *d); + long (*read_audio) (cdrom_drive_t *d, void *p, lsn_t begin, + long sectors); + int (*set_speed) (cdrom_drive_t *d, int speed); + int error_retry; + int report_all; + + int is_atapi; + int is_mmc; + + int i_test_flags; /**< Normally set 0. But if we are testing + paranoia operation this can be set to one of + the flag masks to simulate a particular kind of + failure. */ + +}; + + + /** + Flags for simulating jitter used in testing. + + The enumeration type one probably wouldn't really use in a program. + It is here instead of defines to give symbolic names that can be + helpful in debuggers where wants just to say refer to + CDDA_TEST_JITTER_SMALL and get the correct value. + */ + typedef enum { + CDDA_TEST_JITTER_SMALL = 1, + CDDA_TEST_JITTER_LARGE = 2, + CDDA_TEST_JITTER_MASSIVE = 3, + CDDA_TEST_FRAG_SMALL = (1<<3), + CDDA_TEST_FRAG_LARGE = (2<<3), + CDDA_TEST_FRAG_MASSIVE = (3<<3), + CDDA_TEST_UNDERRUN = 64 + } paranoia_jitter_t; + +/** jitter testing. The first two bits are set to determine the + byte-distance we will jitter the data; 0 is no shifting. + */ + +/**< jitter testing. Set the below bit to always cause jittering on reads. + The below bit only has any effect if the first two (above) bits are + nonzero. If the above bits are set, but the below bit isn't we'll + jitter 90% of the time. + */ +#define CDDA_TEST_ALWAYS_JITTER 4 + +/** fragment testing */ +#define CDDA_TEST_FRAG_SMALL (1<<3) +#define CDDA_TEST_FRAG_LARGE (2<<3) +#define CDDA_TEST_FRAG_MASSIVE (3<<3) + +/**< under-run testing. The below bit is set for testing. */ +#define CDDA_TEST_UNDERRUN 64 + +#if TESTING_IS_FINISHED + + /** scratch testing */ +#define CDDA_TEST_SCRATCH 128 +#undef CDDA_TEST_BOGUS_BYTES 256 +#undef CDDA_TEST_DROPDUPE_BYTES 512 +#endif /* TESTING_IS_FINISHED */ + +/** autosense functions */ + +/** Get a CD-ROM drive with a CD-DA in it. + If mesagedest is 1, then any messages in the process will be stored + in message. +*/ +extern cdrom_drive_t *cdio_cddap_find_a_cdrom(int messagedest, + char **ppsz_message); + +/** Returns a paranoia CD-ROM drive object with a CD-DA in it or NULL + if there was an error. + @see cdio_cddap_identify_cdio + */ +extern cdrom_drive_t *cdio_cddap_identify(const char *psz_device, + int messagedest, + char **ppsz_message); + +/** Returns a paranoia CD-ROM drive object with a CD-DA in it or NULL + if there was an error. In contrast to cdio_cddap_identify, we + start out with an initialized p_cdio object. For example you may + have used that for other purposes such as to get CDDB/CD-Text + information. @see cdio_cddap_identify + */ +cdrom_drive_t *cdio_cddap_identify_cdio(CdIo_t *p_cdio, + int messagedest, char **ppsz_messages); + +/** drive-oriented functions */ + +extern int cdio_cddap_speed_set(cdrom_drive_t *d, int speed); +extern void cdio_cddap_verbose_set(cdrom_drive_t *d, int err_action, + int mes_action); +extern char *cdio_cddap_messages(cdrom_drive_t *d); +extern char *cdio_cddap_errors(cdrom_drive_t *d); + +/*! + Closes d and releases all storage associated with it except + the internal p_cdio pointer. + + @param d cdrom_drive_t object to be closed. + @return 0 if passed a null pointer and 1 if not in which case + some work was probably done. + + @see cdio_cddap_close +*/ +bool cdio_cddap_close_no_free_cdio(cdrom_drive_t *d); + +/*! + Closes d and releases all storage associated with it. + Doubles as "cdrom_drive_free()". + + @param d cdrom_drive_t object to be closed. + @return 0 if passed a null pointer and 1 if not in which case + some work was probably done. + + @see cdio_cddap_close_no_free_cdio +*/ +extern int cdio_cddap_close(cdrom_drive_t *d); + +extern int cdio_cddap_open(cdrom_drive_t *d); + +extern long cdio_cddap_read(cdrom_drive_t *d, void *p_buffer, + lsn_t beginsector, long sectors); + +/*! Return the lsn for the start of track i_track */ +extern lsn_t cdio_cddap_track_firstsector(cdrom_drive_t *d, + track_t i_track); + +/*! Get last lsn of the track. This generally one less than the start + of the next track. -1 is returned on error. */ +extern lsn_t cdio_cddap_track_lastsector(cdrom_drive_t *d, track_t i_track); + +/*! Return the number of tracks on the CD. */ +extern track_t cdio_cddap_tracks(cdrom_drive_t *d); + +/*! Return the track containing the given LSN. If the LSN is before + the first track (in the pregap), 0 is returned. If there was an + error or the LSN after the LEADOUT (beyond the end of the CD), then + CDIO_INVALID_TRACK is returned. + */ +extern int cdio_cddap_sector_gettrack(cdrom_drive_t *d, lsn_t lsn); + +/*! Return the number of channels in track: 2 or 4; -2 if not + implemented or -1 for error. + Not meaningful if track is not an audio track. +*/ +extern int cdio_cddap_track_channels(cdrom_drive_t *d, track_t i_track); + +/*! Return 1 is track is an audio track, 0 otherwise. */ +extern int cdio_cddap_track_audiop(cdrom_drive_t *d, track_t i_track); + +/*! Return 1 is track has copy permit set, 0 otherwise. */ +extern int cdio_cddap_track_copyp(cdrom_drive_t *d, track_t i_track); + +/*! Return 1 is audio track has linear preemphasis set, 0 otherwise. + Only makes sense for audio tracks. + */ +extern int cdio_cddap_track_preemp(cdrom_drive_t *d, track_t i_track); + +/*! Get first lsn of the first audio track. -1 is returned on error. */ +extern lsn_t cdio_cddap_disc_firstsector(cdrom_drive_t *d); + +/*! Get last lsn of the last audio track. The last lsn is generally one + less than the start of the next track after the audio track. -1 is + returned on error. */ +extern lsn_t cdio_cddap_disc_lastsector(cdrom_drive_t *d); + +/*! Determine Endian-ness of the CD-drive based on reading data from + it. Some drives return audio data Big Endian while some (most) + return data Little Endian. Drives known to return data bigendian are + SCSI drives from Kodak, Ricoh, HP, Philips, Plasmon, Grundig + CDR100IPW, and Mitsumi CD-R. ATAPI and MMC drives are little endian. + + rocky: As someone who didn't write the code, I have to say this is + nothing less than brilliant. An FFT is done both ways and the the + transform is looked at to see which has data in the FFT (or audible) + portion. (Or so that's how I understand it.) + + @return 1 if big-endian, 0 if little-endian, -1 if we couldn't + figure things out or some error. + */ +extern int data_bigendianp(cdrom_drive_t *d); + +/** transport errors: */ + +typedef enum { + TR_OK = 0, + TR_EWRITE = 1 /**< Error writing packet command (transport) */, + TR_EREAD = 2 /**< Error reading packet data (transport) */, + TR_UNDERRUN = 3 /**< Read underrun */, + TR_OVERRUN = 4 /**< Read overrun */, + TR_ILLEGAL = 5 /**< Illegal/rejected request */, + TR_MEDIUM = 6 /**< Medium error */, + TR_BUSY = 7 /**< Device busy */, + TR_NOTREADY = 8 /**< Device not ready */, + TR_FAULT = 9 /**< Device failure */, + TR_UNKNOWN = 10 /**< Unspecified error */, + TR_STREAMING = 11 /**< loss of streaming */, +} transport_error_t; + + +#ifdef NEED_STRERROR_TR +const char *strerror_tr[]={ + "Success", + "Error writing packet command to device", + "Error reading command from device", + "SCSI packet data underrun (too little data)", + "SCSI packet data overrun (too much data)", + "Illegal SCSI request (rejected by target)", + "Medium reading data from medium", + "Device busy", + "Device not ready", + "Target hardware fault", + "Unspecified error", + "Drive lost streaming" +}; +#endif /*NEED_STERROR_TR*/ + +/** Errors returned by lib: + +\verbatim +001: Unable to set CDROM to read audio mode +002: Unable to read table of contents lead-out +003: CDROM reporting illegal number of tracks +004: Unable to read table of contents header +005: Unable to read table of contents entry +006: Could not read any data from drive +007: Unknown, unrecoverable error reading data +008: Unable to identify CDROM model +009: CDROM reporting illegal table of contents +010: Unaddressable sector + +100: Interface not supported +101: Drive is neither a CDROM nor a WORM device +102: Permision denied on cdrom (ioctl) device +103: Permision denied on cdrom (data) device + +300: Kernel memory error + +400: Device not open +401: Invalid track number +402: Track not audio data +403: No audio tracks on disc +\endverbatim + +*/ + +#ifndef DO_NOT_WANT_PARANOIA_COMPATIBILITY +/** For compatibility with good ol' paranoia */ +#define cdda_find_a_cdrom cdio_cddap_find_a_cdrom +#define cdda_identify cdio_cddap_identify +#define cdda_speed_set cdio_cddap_speed_set +#define cdda_verbose_set cdio_cddap_verbose_set +#define cdda_messages cdio_cddap_messages +#define cdda_errors cdio_cddap_errors +#define cdda_close cdio_cddap_close +#define cdda_open cdio_cddap_open +#define cdda_read cdio_cddap_read +#define cdda_track_firstsector cdio_cddap_track_firstsector +#define cdda_track_lastsector cdio_cddap_track_lastsector +#define cdda_tracks cdio_cddap_tracks +#define cdda_sector_gettrack cdio_cddap_sector_gettrack +#define cdda_track_channels cdio_cddap_track_channels +#define cdda_track_audiop cdio_cddap_track_audiop +#define cdda_track_copyp cdio_cddap_track_copyp +#define cdda_track_preemp cdio_cddap_track_preemp +#define cdda_disc_firstsector cdio_cddap_disc_firstsector +#define cdda_disc_lastsector cdio_cddap_disc_lastsector +#define cdrom_drive cdrom_drive_t + +#endif /*DO_NOT_WANT_PARANOIA_COMPATIBILITY*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/** The below variables are trickery to force the above enum symbol + values to be recorded in debug symbol tables. They are used to + allow one to refer to the enumeration value names in the typedefs + above in a debugger and debugger expressions +*/ + +extern paranoia_jitter_t debug_paranoia_jitter; +extern paranoia_cdda_enums_t debug_paranoia_cdda_enums; + +#endif /*_CDDA_INTERFACE_H_*/ + diff --git a/include/cdio/cdio.h b/include/cdio/cdio.h new file mode 100644 index 00000000..84e54b10 --- /dev/null +++ b/include/cdio/cdio.h @@ -0,0 +1,84 @@ +/* -*- c -*- + $Id: cdio.h,v 1.82 2008/03/25 15:59:08 karl Exp $ + + Copyright (C) 2003, 2004, 2005, 2008 Rocky Bernstein <rocky@gnu.org> + Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** \file cdio.h + * + * \brief The top-level header for libcdio: the CD Input and Control + * library. Applications include this for anything regarding libcdio. + */ + + +#ifndef __CDIO_H__ +#define __CDIO_H__ + +/** Application Interface or Protocol version number. If the public + * interface changes, we increase this number. + */ +#define CDIO_API_VERSION 5 + +#include <cdio/version.h> + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <cdio/types.h> +#include <cdio/sector.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* For compatibility. */ +#define CdIo CdIo_t + + /** This is an opaque structure for the CD object. */ + typedef struct _CdIo CdIo_t; + + /** This is an opaque structure for the CD-Text object. */ + typedef struct cdtext cdtext_t; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/* Drive(r)/Device-related functions. Perhaps we should break out + Driver from device? +*/ +#include <cdio/device.h> + +/* Disc-related functions. */ +#include <cdio/disc.h> + +/* Sector (frame, or block)-related functions. Uses driver_return_code_t + from <cdio/device.h> so it should come after that. +*/ +#include <cdio/read.h> + +/* CD-Text-related functions. */ +#include <cdio/cdtext.h> + +/* Track-related functions. */ +#include <cdio/track.h> + +#endif /* __CDIO_H__ */ diff --git a/include/cdio/cdio_config.h b/include/cdio/cdio_config.h new file mode 100644 index 00000000..2005b888 --- /dev/null +++ b/include/cdio/cdio_config.h @@ -0,0 +1,258 @@ +/** \file cdio_config.h + * \brief configuration-time settings useful in compilation; a run-time + version of config.h +*/ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* Define 1 if you are compiling using cygwin */ +/* #undef CYGWIN */ + +/* what to put between the brackets for empty arrays */ +#define EMPTY_ARRAY_SIZE + +/* Define 1 if you have BSDI-type CD-ROM support */ +/* #undef HAVE_BSDI_CDROM */ + +/* Define to 1 if you have the `bzero' function. */ +#define HAVE_BZERO 1 + +/* Define this if you have libcddb installed */ +#define HAVE_CDDB /**/ + +/* Define to 1 if you have the <CoreFoundation/CFBase.h> header file. */ +/* #undef HAVE_COREFOUNDATION_CFBASE_H */ + +/* Define to 1 if you have the <curses.h> header file. */ +/* #undef HAVE_CURSES_H */ + +/* Define 1 if you have Darwin OS X-type CD-ROM support */ +/* #undef HAVE_DARWIN_CDROM */ + +/* Define if time.h defines extern long timezone and int daylight vars. */ +#define HAVE_DAYLIGHT 1 + +/* Define to 1 if you have the Apple DiskArbitration framework */ +/* #undef HAVE_DISKARBITRATION */ + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `drand48' function. */ +#define HAVE_DRAND48 1 + +/* Define to 1 if you have the <dvd.h> header file. */ +/* #undef HAVE_DVD_H */ + +/* Define to 1 if you have the <errno.h> header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the <fcntl.h> header file. */ +#define HAVE_FCNTL_H 1 + +/* Define 1 if you have FreeBSD CD-ROM support */ +/* #undef HAVE_FREEBSD_CDROM */ + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +/* #undef HAVE_FSEEKO */ + +/* Define to 1 if you have the `ftruncate' function. */ +#define HAVE_FTRUNCATE 1 + +/* Define to 1 if you have the `geteuid' function. */ +#define HAVE_GETEUID 1 + +/* Define to 1 if you have the `getgid' function. */ +#define HAVE_GETGID 1 + +/* Define to 1 if you have the <getopt.h> header file. */ +#define HAVE_GETOPT_H 1 + +/* Define to 1 if you have the `getpwuid' function. */ +#define HAVE_GETPWUID 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the `getuid' function. */ +#define HAVE_GETUID 1 + +/* Define to 1 if you have the <glob.h> header file. */ +#define HAVE_GLOB_H 1 + +/* Define to 1 if you have the `gmtime_r' function. */ +#define HAVE_GMTIME_R 1 + +/* Define if you have the iconv() function and it works. */ +#define HAVE_ICONV 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the <IOKit/IOKitLib.h> header file. */ +/* #undef HAVE_IOKIT_IOKITLIB_H */ + +/* Supports ISO _Pragma() macro */ +#define HAVE_ISOC99_PRAGMA /**/ + +/* Define 1 if you want ISO-9660 Joliet extension support. You must have also + libiconv installed to get Joliet extension support. */ +#define HAVE_JOLIET 1 + +/* Define this if your libcurses has keypad */ +#define HAVE_KEYPAD /**/ + +/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */ +#define HAVE_LANGINFO_CODESET 1 + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +/* #undef HAVE_LIBNSL */ + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the <limits.h> header file. */ +#define HAVE_LIMITS_H 1 + +/* Define 1 if you have Linux-type CD-ROM support */ +#define HAVE_LINUX_CDROM 1 + +/* Define to 1 if you have the <linux/cdrom.h> header file. */ +#define HAVE_LINUX_CDROM_H 1 + +/* Define 1 if timeout is in cdrom_generic_command struct */ +/* #undef HAVE_LINUX_CDROM_TIMEOUT */ + +/* Define to 1 if you have the <linux/major.h> header file. */ +#define HAVE_LINUX_MAJOR_H 1 + +/* Define to 1 if you have the <linux/version.h> header file. */ +#define HAVE_LINUX_VERSION_H 1 + +/* Define to 1 if you have the `localtime_r' function. */ +#define HAVE_LOCALTIME_R 1 + +/* Define to 1 if you have the `lstat' function. */ +#define HAVE_LSTAT 1 + +/* Define to 1 if you have the `memcpy' function. */ +#define HAVE_MEMCPY 1 + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset' function. */ +#define HAVE_MEMSET 1 + +/* Define to 1 if you have the <ncurses.h> header file. */ +#define HAVE_NCURSES_H 1 + +/* Define 1 if you have NetBSD CD-ROM support */ +/* #undef HAVE_NETBSD_CDROM */ + +/* Define 1 if you have OS/2 CD-ROM support */ +/* #undef HAVE_OS2_CDROM */ + +/* Define to 1 if you have the <pwd.h> header file. */ +#define HAVE_PWD_H 1 + +/* Define to 1 if you have the `rand' function. */ +#define HAVE_RAND 1 + +/* Define to 1 if you have the `readlink' function. */ +#define HAVE_READLINK 1 + +/* Define 1 if you want ISO-9660 Rock-Ridge extension support. */ +#define HAVE_ROCK 1 + +/* Define to 1 if you have the `setegid' function. */ +#define HAVE_SETEGID 1 + +/* Define to 1 if you have the `setenv' function. */ +#define HAVE_SETENV 1 + +/* Define to 1 if you have the `seteuid' function. */ +#define HAVE_SETEUID 1 + +/* Define to 1 if you have the `sleep' function. */ +#define HAVE_SLEEP 1 + +/* Define to 1 if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 + +/* Define 1 if you have Solaris CD-ROM support */ +/* #undef HAVE_SOLARIS_CDROM */ + +/* Define to 1 if you have the <stdarg.h> header file. */ +#define HAVE_STDARG_H 1 + +/* Define to 1 if you have the <stdbool.h> header file. */ +#define HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdio.h> header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define this if you have struct timespec */ +#define HAVE_STRUCT_TIMESPEC /**/ + +/* Define to 1 if you have the <sys/cdio.h> header file. */ +/* #undef HAVE_SYS_CDIO_H */ + +/* Define to 1 if you have the <sys/param.h> header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/timeb.h> header file. */ +#define HAVE_SYS_TIMEB_H 1 + +/* Define to 1 if you have the <sys/time.h> header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <sys/utsname.h> header file. */ +#define HAVE_SYS_UTSNAME_H 1 + +/* Define this <sys/stat.h> defines S_ISLNK() */ +#define HAVE_S_ISLNK /**/ + +/* Define this <sys/stat.h> defines S_ISSOCK() */ +#define HAVE_S_ISSOCK /**/ + +/* Define to 1 if timegm is available */ +#define HAVE_TIMEGM 1 + +/* Define if you have an extern long timenzone variable. */ +#define HAVE_TIMEZONE_VAR 1 + +/* Define if struct tm has the tm_gmtoff member. */ +#define HAVE_TM_GMTOFF 1 + +/* Define if time.h defines extern extern char *tzname[2] variable */ +#define HAVE_TZNAME 1 + +/* Define to 1 if you have the `tzset' function. */ +#define HAVE_TZSET 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `unsetenv' function. */ diff --git a/include/cdio/cdtext.h b/include/cdio/cdtext.h new file mode 100644 index 00000000..daac733f --- /dev/null +++ b/include/cdio/cdtext.h @@ -0,0 +1,125 @@ +/* + $Id: cdtext.h,v 1.14 2008/03/25 15:59:08 karl Exp $ + + Copyright (C) 2004, 2005, 2008 Rocky Bernstein <rocky@gnu.org> + adapted from cuetools + Copyright (C) 2003 Svend Sanjay Sorensen <ssorensen@fastmail.fm> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ +/*! + * \file cdtext.h + * + * \brief The top-level header for CD-Text information. Applications + * include this for CD-Text access. +*/ + + +#ifndef __CDIO_CDTEXT_H__ +#define __CDIO_CDTEXT_H__ + +#include <cdio/cdio.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define MAX_CDTEXT_FIELDS 13 +#define MIN_CDTEXT_FIELD 0 + + /*! \brief structure for holding CD-Text information + + @see cdtext_init, cdtext_destroy, cdtext_get, and cdtext_set. + */ + struct cdtext { + char *field[MAX_CDTEXT_FIELDS]; + }; + + /*! \brief A list of all of the CD-Text fields. Because + the interval has no gaps, we can use ++ to iterate over fields. + */ + typedef enum { + CDTEXT_ARRANGER = 0, /**< name(s) of the arranger(s) */ + CDTEXT_COMPOSER = 1, /**< name(s) of the composer(s) */ + CDTEXT_DISCID = 2, /**< disc identification information */ + CDTEXT_GENRE = 3, /**< genre identification and genre information */ + CDTEXT_MESSAGE = 4, /**< ISRC code of each track */ + CDTEXT_ISRC = 5, /**< message(s) from the content provider or artist */ + CDTEXT_PERFORMER = 6, /**< name(s) of the performer(s) */ + CDTEXT_SIZE_INFO = 7, /**< size information of the block */ + CDTEXT_SONGWRITER = 8, /**< name(s) of the songwriter(s) */ + CDTEXT_TITLE = 9, /**< title of album name or track titles */ + CDTEXT_TOC_INFO = 10, /**< table of contents information */ + CDTEXT_TOC_INFO2 = 11, /**< second table of contents information */ + CDTEXT_UPC_EAN = 12, + CDTEXT_INVALID = MAX_CDTEXT_FIELDS + } cdtext_field_t; + + /*! Return string representation of the enum values above */ + const char *cdtext_field2str (cdtext_field_t i); + + /*! Initialize a new cdtext structure. + When the structure is no longer needed, release the + resources using cdtext_delete. + */ + void cdtext_init (cdtext_t *cdtext); + + /*! Free memory assocated with cdtext*/ + void cdtext_destroy (cdtext_t *cdtext); + + /*! returns an allocated string associated with the given field. NULL is + returned if key is CDTEXT_INVALID or the field is not set. + + The user needs to free the string when done with it. + + @see cdio_get_const to retrieve a constant string that doesn't + have to be freed. + */ + char *cdtext_get (cdtext_field_t key, const cdtext_t *cdtext); + + /*! returns a const string associated with the given field. NULL is + returned if key is CDTEXT_INVALID or the field is not set. + + Don't use the string when the cdtext object (i.e. the CdIo_t object + you got it from) is no longer valid. + + @see cdio_get to retrieve an allocated string that persists past + the cdtext object. + */ + const char *cdtext_get_const (cdtext_field_t key, const cdtext_t *cdtext); + + /*! + returns enum of keyword if key is a CD-Text keyword, + returns MAX_CDTEXT_FIELDS non-zero otherwise. + */ + cdtext_field_t cdtext_is_keyword (const char *key); + + /*! + sets cdtext's keyword entry to field + */ + void cdtext_set (cdtext_field_t key, const char *value, cdtext_t *cdtext); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CDIO_CDTEXT_H__ */ + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/cdio/device.h b/include/cdio/device.h new file mode 100644 index 00000000..cc84e79a --- /dev/null +++ b/include/cdio/device.h @@ -0,0 +1,995 @@ +/* -*- c -*- + $Id: device.h,v 1.39 2008/03/28 01:28:50 rocky Exp $ + + Copyright (C) 2005, 2006, 2008, 2009 Rocky Bernstein <rocky@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** \file device.h + * + * \brief C header for driver- or device-related libcdio + * calls. ("device" includes CD-image reading devices). + */ +#ifndef __CDIO_DEVICE_H__ +#define __CDIO_DEVICE_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /*! The type of an drive capability bit mask. See below for values*/ + typedef uint32_t cdio_drive_read_cap_t; + typedef uint32_t cdio_drive_write_cap_t; + typedef uint32_t cdio_drive_misc_cap_t; + + /*! + \brief Drive capability bits returned by cdio_get_drive_cap() + NOTE: Setting a bit here means the presence of a capability. + */ + + /** Miscellaneous capabilities. */ + typedef enum { + CDIO_DRIVE_CAP_ERROR = 0x40000, /**< Error */ + CDIO_DRIVE_CAP_UNKNOWN = 0x80000, /**< Dunno. It can be on if we + have only partial information + or are not completely certain + */ + CDIO_DRIVE_CAP_MISC_CLOSE_TRAY = 0x00001, /**< caddy systems can't + close... */ + CDIO_DRIVE_CAP_MISC_EJECT = 0x00002, /**< but can eject. */ + CDIO_DRIVE_CAP_MISC_LOCK = 0x00004, /**< disable manual eject */ + CDIO_DRIVE_CAP_MISC_SELECT_SPEED = 0x00008, /**< programmable speed */ + CDIO_DRIVE_CAP_MISC_SELECT_DISC = 0x00010, /**< select disc from + juke-box */ + CDIO_DRIVE_CAP_MISC_MULTI_SESSION= 0x00020, /**< read sessions>1 */ + CDIO_DRIVE_CAP_MISC_MEDIA_CHANGED= 0x00080, /**< media changed */ + CDIO_DRIVE_CAP_MISC_RESET = 0x00100, /**< hard reset device */ + CDIO_DRIVE_CAP_MISC_FILE = 0x20000 /**< drive is really a file, + i.e a CD file image */ + } cdio_drive_cap_misc_t; + + /*! Reading masks.. */ + typedef enum { + CDIO_DRIVE_CAP_READ_AUDIO = 0x00001, /**< drive can play CD audio */ + CDIO_DRIVE_CAP_READ_CD_DA = 0x00002, /**< drive can read CD-DA */ + CDIO_DRIVE_CAP_READ_CD_G = 0x00004, /**< drive can read CD+G */ + CDIO_DRIVE_CAP_READ_CD_R = 0x00008, /**< drive can read CD-R */ + CDIO_DRIVE_CAP_READ_CD_RW = 0x00010, /**< drive can read CD-RW */ + CDIO_DRIVE_CAP_READ_DVD_R = 0x00020, /**< drive can read DVD-R */ + CDIO_DRIVE_CAP_READ_DVD_PR = 0x00040, /**< drive can read DVD+R */ + CDIO_DRIVE_CAP_READ_DVD_RAM = 0x00080, /**< drive can read DVD-RAM */ + CDIO_DRIVE_CAP_READ_DVD_ROM = 0x00100, /**< drive can read DVD-ROM */ + CDIO_DRIVE_CAP_READ_DVD_RW = 0x00200, /**< drive can read DVD-RW */ + CDIO_DRIVE_CAP_READ_DVD_RPW = 0x00400, /**< drive can read DVD+RW */ + CDIO_DRIVE_CAP_READ_C2_ERRS = 0x00800, /**< has C2 error correction */ + CDIO_DRIVE_CAP_READ_MODE2_FORM1 = 0x01000, /**< can read mode 2 form 1 */ + CDIO_DRIVE_CAP_READ_MODE2_FORM2 = 0x02000, /**< can read mode 2 form 2 */ + CDIO_DRIVE_CAP_READ_MCN = 0x04000, /**< can read MCN */ + CDIO_DRIVE_CAP_READ_ISRC = 0x08000 /**< can read ISRC */ + } cdio_drive_cap_read_t; + + /*! Writing masks.. */ + typedef enum { + CDIO_DRIVE_CAP_WRITE_CD_R = 0x00001, /**< drive can write CD-R */ + CDIO_DRIVE_CAP_WRITE_CD_RW = 0x00002, /**< drive can write CD-RW */ + CDIO_DRIVE_CAP_WRITE_DVD_R = 0x00004, /**< drive can write DVD-R */ + CDIO_DRIVE_CAP_WRITE_DVD_PR = 0x00008, /**< drive can write DVD+R */ + CDIO_DRIVE_CAP_WRITE_DVD_RAM = 0x00010, /**< drive can write DVD-RAM */ + CDIO_DRIVE_CAP_WRITE_DVD_RW = 0x00020, /**< drive can write DVD-RW */ + CDIO_DRIVE_CAP_WRITE_DVD_RPW = 0x00040, /**< drive can write DVD+RW */ + CDIO_DRIVE_CAP_WRITE_MT_RAINIER = 0x00080, /**< Mount Rainier */ + CDIO_DRIVE_CAP_WRITE_BURN_PROOF = 0x00100, /**< burn proof */ + CDIO_DRIVE_CAP_WRITE_CD = + (CDIO_DRIVE_CAP_WRITE_CD_R | CDIO_DRIVE_CAP_WRITE_CD_RW), + /**< Has some sort of CD writer ability */ + + CDIO_DRIVE_CAP_WRITE_DVD = + (CDIO_DRIVE_CAP_WRITE_DVD_R | CDIO_DRIVE_CAP_WRITE_DVD_PR + | CDIO_DRIVE_CAP_WRITE_DVD_RAM | CDIO_DRIVE_CAP_WRITE_DVD_RW + | CDIO_DRIVE_CAP_WRITE_DVD_RPW ), + /**< Has some sort of DVD writer ability */ + + CDIO_DRIVE_CAP_WRITE = + (CDIO_DRIVE_CAP_WRITE_CD | CDIO_DRIVE_CAP_WRITE_DVD) + /**< Has some sort of DVD or CD writing ability */ + } cdio_drive_cap_write_t; + +/*! Size of fields returned by an INQUIRY command */ + typedef enum { + CDIO_MMC_HW_VENDOR_LEN = 8, /**< length of vendor field */ + CDIO_MMC_HW_MODEL_LEN = 16, /**< length of model field */ + CDIO_MMC_HW_REVISION_LEN = 4 /**< length of revision field */ + } cdio_mmc_hw_len_t; + + + /*! \brief Structure to return CD vendor, model, and revision-level + strings obtained via the INQUIRY command */ + typedef struct cdio_hwinfo + { + char psz_vendor [CDIO_MMC_HW_VENDOR_LEN+1]; + char psz_model [CDIO_MMC_HW_MODEL_LEN+1]; + char psz_revision[CDIO_MMC_HW_REVISION_LEN+1]; + } cdio_hwinfo_t; + + + /** Flags specifying the category of device to open or is opened. */ + typedef enum { + CDIO_SRC_IS_DISK_IMAGE_MASK = 0x0001, /**< Read source is a CD image. */ + CDIO_SRC_IS_DEVICE_MASK = 0x0002, /**< Read source is a CD device. */ + CDIO_SRC_IS_SCSI_MASK = 0x0004, /**< Read source SCSI device. */ + CDIO_SRC_IS_NATIVE_MASK = 0x0008 + } cdio_src_category_mask_t; + + + /** The driver_id_t enumerations may be used to tag a specific driver + * that is opened or is desired to be opened. Note that this is + * different than what is available on a given host. + * + * Order should not be changed lightly because it breaks the ABI. + * One is not supposed to iterate over the values, but iterate over the + * cdio_drivers and cdio_device_drivers arrays. + * + * NOTE: IF YOU MODIFY ENUM MAKE SURE INITIALIZATION IN CDIO.C AGREES. + * + */ + typedef enum { + DRIVER_UNKNOWN, /**< Used as input when we don't care what kind + of driver to use. */ + DRIVER_AIX, /**< AIX driver */ + DRIVER_BSDI, /**< BSDI driver */ + DRIVER_FREEBSD, /**< FreeBSD driver - includes CAM and ioctl access */ + DRIVER_NETBSD, /**< NetBSD Driver. */ + DRIVER_LINUX, /**< GNU/Linux Driver */ + DRIVER_SOLARIS, /**< Sun Solaris Driver */ + DRIVER_OS2, /**< IBM OS/2 Driver */ + DRIVER_OSX, /**< Apple OSX Driver */ + DRIVER_WIN32, /**< Microsoft Windows Driver. Includes ASPI and + ioctl access. */ + DRIVER_CDRDAO, /**< cdrdao format CD image. This is listed + before BIN/CUE, to make the code prefer cdrdao + over BIN/CUE when both exist. */ + DRIVER_BINCUE, /**< CDRWIN BIN/CUE format CD image. This is + listed before NRG, to make the code prefer + BIN/CUE over NRG when both exist. */ + DRIVER_NRG, /**< Nero NRG format CD image. */ + DRIVER_DEVICE /**< Is really a set of the above; should come last */ + } driver_id_t; + + /** A null-terminated (that is DRIVER_UNKNOWN-terminated) ordered (in + order of preference) array of drivers. + */ + extern const driver_id_t cdio_drivers[]; + /** A null-terminated (that is DRIVER_UNKNOWN-terminated) ordered (in + order of preference) array of device drivers. + */ + extern const driver_id_t cdio_device_drivers[]; + + /** There will generally be only one hardware for a given + build/platform from the list above. You can use the variable + below to determine which you've got. If the build doesn't make an + hardware driver, then the value will be DRIVER_UNKNOWN. + */ + extern const driver_id_t cdio_os_driver; + + +/** Those are deprecated; use cdio_drivers or cdio_device_drivers to + iterate over all drivers or only the device drivers. + Make sure what's listed for CDIO_MIN_DRIVER is the last + enumeration in driver_id_t. Since we have a bogus (but useful) 0th + entry above we don't have to add one. +*/ +#define CDIO_MIN_DRIVER DRIVER_AIX +#define CDIO_MIN_DEVICE_DRIVER CDIO_MIN_DRIVER +#define CDIO_MAX_DRIVER DRIVER_NRG +#define CDIO_MAX_DEVICE_DRIVER DRIVER_WIN32 + + /** The following are status codes for completion of a given cdio + operation. By design 0 is successful completion and -1 is error + completion. This is compatable with ioctl so those routines that + call ioctl can just pass the value the get back (cast as this + enum). Also, by using negative numbers for errors, the + enumeration values below can be used in places where a positive + value is expected when things complete successfully. For example, + get_blocksize returns the blocksize, but on error uses the error + codes below. So note that this enumeration is often cast to an + integer. C seems to tolerate this. + */ + typedef enum { + DRIVER_OP_SUCCESS = 0, /**< in cases where an int is returned, + like cdio_set_speed, more the negative + return codes are for errors and the + positive ones for success. */ + DRIVER_OP_ERROR = -1, /**< operation returned an error */ + DRIVER_OP_UNSUPPORTED = -2, /**< returned when a particular driver + doesn't support a particular operation. + For example an image driver which doesn't + really "eject" a CD. + */ + DRIVER_OP_UNINIT = -3, /**< returned when a particular driver + hasn't been initialized or a null + pointer has been passed. + */ + DRIVER_OP_NOT_PERMITTED = -4, /**< Operation not permitted. + For example might be a permission + problem. + */ + DRIVER_OP_BAD_PARAMETER = -5, /**< Bad parameter passed */ + DRIVER_OP_BAD_POINTER = -6, /**< Bad pointer to memory area */ + DRIVER_OP_NO_DRIVER = -7, /**< Operaton called on a driver + not available on this OS */ + } driver_return_code_t; + + /*! + Close media tray in CD drive if there is a routine to do so. + + @param psz_drive the name of CD-ROM to be closed. If NULL, we will + use the default device. + @param p_driver_id is the driver to be used or that got used if + it was DRIVER_UNKNOWN or DRIVER_DEVICE; If this is NULL, we won't + report back the driver used. + */ + driver_return_code_t cdio_close_tray (const char *psz_drive, + /*in/out*/ driver_id_t *p_driver_id); + + /*! + @param drc the return code you want interpreted. + @return the string information about drc + */ + const char *cdio_driver_errmsg(driver_return_code_t drc); + + /*! + Eject media in CD drive if there is a routine to do so. + + @param p_cdio the CD object to be acted upon. + If the CD is ejected *p_cdio is free'd and p_cdio set to NULL. + */ + driver_return_code_t cdio_eject_media (CdIo_t **p_cdio); + + /*! + Eject media in CD drive if there is a routine to do so. + + @param psz_drive the name of the device to be acted upon. + If NULL is given as the drive, we'll use the default driver device. + */ + driver_return_code_t cdio_eject_media_drive (const char *psz_drive); + + /*! + Free device list returned by cdio_get_devices or + cdio_get_devices_with_cap. + + @param device_list list returned by cdio_get_devices or + cdio_get_devices_with_cap + + @see cdio_get_devices, cdio_get_devices_with_cap + + */ + void cdio_free_device_list (char * device_list[]); + + /*! + Get the default CD device. + if p_cdio is NULL (we haven't initialized a specific device driver), + then find a suitable one and return the default device for that. + + @param p_cdio the CD object queried + @return a string containing the default CD device or NULL is + if we couldn't get a default device. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it and it is possible for this routine to return + NULL even though there may be a hardware CD-ROM. + */ + char * cdio_get_default_device (const CdIo_t *p_cdio); + + /*! + Return a string containing the default CD device if none is specified. + if p_driver_id is DRIVER_UNKNOWN or DRIVER_DEVICE + then find a suitable one set the default device for that. + + NULL is returned if we couldn't get a default device. + */ + char * cdio_get_default_device_driver (/*in/out*/ driver_id_t *p_driver_id); + + /*! Return an array of device names. If you want a specific + devices for a driver, give that device. If you want hardware + devices, give DRIVER_DEVICE and if you want all possible devices, + image drivers and hardware drivers give DRIVER_UNKNOWN. + + NULL is returned if we couldn't return a list of devices. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it and it is possible for this routine to return + NULL even though there may be a hardware CD-ROM. + */ + char ** cdio_get_devices (driver_id_t driver_id); + + /*! + Get an array of device names in search_devices that have at least + the capabilities listed by the capabities parameter. If + search_devices is NULL, then we'll search all possible CD drives. + + Capabilities have two parts to them, a "filesystem" part and an + "analysis" part. + + The filesystem part is mutually exclusive. For example either the + filesystem is at most one of the High-Sierra, UFS, or HFS, ISO9660, + fileystems. Valid combinations of say HFS and ISO9660 are + specified as a separate "filesystem". + + Capabilities on the other hand are not mutually exclusive. For example + a filesystem may have none, either, or both of the XA or Rock-Ridge + extension properties. + + If "b_any" is set false then every capability listed in the + analysis portion of capabilities (i.e. not the basic filesystem) + must be satisified. If no analysis capabilities are specified, + that's a match. + + If "b_any" is set true, then if any of the analysis capabilities + matches, we call that a success. + + In either case, in the filesystem portion different filesystem + either specify 0 to match any filesystem or the specific + filesystem type. + + To find a CD-drive of any type, use the mask CDIO_FS_MATCH_ALL. + + @return the array of device names or NULL if we couldn't get a + default device. It is also possible to return a non NULL but + after dereferencing the the value is NULL. This also means nothing + was found. + */ + char ** cdio_get_devices_with_cap (/*in*/ char *ppsz_search_devices[], + cdio_fs_anal_t capabilities, bool b_any); + + /*! + Like cdio_get_devices_with_cap but we return the driver we found + as well. This is because often one wants to search for kind of drive + and then *open* it afterwards. Giving the driver back facilitates this, + and speeds things up for libcdio as well. + */ + char ** cdio_get_devices_with_cap_ret (/*in*/ char* ppsz_search_devices[], + cdio_fs_anal_t capabilities, + bool b_any, + /*out*/ driver_id_t *p_driver_id); + + /*! Like cdio_get_devices, but we may change the p_driver_id if we + were given DRIVER_DEVICE or DRIVER_UNKNOWN. This is because + often one wants to get a drive name and then *open* it + afterwards. Giving the driver back facilitates this, and speeds + things up for libcdio as well. + */ + + char ** cdio_get_devices_ret (/*in/out*/ driver_id_t *p_driver_id); + + /*! + Get the what kind of device we've got. + + @param p_cdio the CD object queried + @param p_read_cap pointer to return read capabilities + @param p_write_cap pointer to return write capabilities + @param p_misc_cap pointer to return miscellaneous other capabilities + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it. In this situation capabilities will show up as + NULL even though there isa hardware CD-ROM. + */ + void cdio_get_drive_cap (const CdIo_t *p_cdio, + cdio_drive_read_cap_t *p_read_cap, + cdio_drive_write_cap_t *p_write_cap, + cdio_drive_misc_cap_t *p_misc_cap); + + /*! + Get the drive capabilities for a specified device. + + Return a list of device capabilities. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it. In this situation capabilities will show up as + NULL even though there isa hardware CD-ROM. + */ + void cdio_get_drive_cap_dev (const char *device, + cdio_drive_read_cap_t *p_read_cap, + cdio_drive_write_cap_t *p_write_cap, + cdio_drive_misc_cap_t *p_misc_cap); + + /*! + Get a string containing the name of the driver in use. + + @return a string with driver name or NULL if CdIo_t is NULL (we + haven't initialized a specific device. + */ + const char * cdio_get_driver_name (const CdIo_t *p_cdio); + + /*! + Get the driver id. + if CdIo_t is NULL (we haven't initialized a specific device driver), + then return DRIVER_UNKNOWN. + + @return the driver id.. + */ + driver_id_t cdio_get_driver_id (const CdIo_t *p_cdio); + + /*! + Get the CD-ROM hardware info via a SCSI MMC INQUIRY command. + False is returned if we had an error getting the information. + */ + bool cdio_get_hwinfo ( const CdIo_t *p_cdio, + /*out*/ cdio_hwinfo_t *p_hw_info ); + + + /*! Get the LSN of the first track of the last session of + on the CD. + + @param p_cdio the CD object to be acted upon. + @param i_last_session pointer to the session number to be returned. + */ + driver_return_code_t cdio_get_last_session (CdIo_t *p_cdio, + /*out*/ lsn_t *i_last_session); + + /*! + Find out if media has changed since the last call. + @param p_cdio the CD object to be acted upon. + @return 1 if media has changed since last call, 0 if not. Error + return codes are the same as driver_return_code_t + */ + int cdio_get_media_changed(CdIo_t *p_cdio); + + /*! True if CD-ROM understand ATAPI commands. */ + bool_3way_t cdio_have_atapi (CdIo_t *p_cdio); + + /*! Like cdio_have_xxx but uses an enumeration instead. */ + bool cdio_have_driver (driver_id_t driver_id); + + /* + Free any resources associated with p_cdio. Call this when done using p_cdio + and using CD reading/control operations. + + @param p_cdio the CD object to eliminated. + */ + void cdio_destroy (CdIo_t *p_cdio); + + /*! + Get a string decribing driver_id. + + @param driver_id the driver you want the description for + @return a string of driver description + */ + const char *cdio_driver_describe (driver_id_t driver_id); + + /*! Sets up to read from place specified by psz_source and + driver_id. This or cdio_open_* should be called before using any + other routine, except cdio_init or any routine that accesses the + CD-ROM drive by name. cdio_open will call cdio_init, if that hasn't + been done previously. + + @return the cdio object or NULL on error or no device. If NULL + is given as the source, we'll use the default driver device. + */ + CdIo_t * cdio_open (const char *psz_source, driver_id_t driver_id); + + /*! Sets up to read from place specified by psz_source, driver_id + and access mode. This or cdio_open* should be called before using + any other routine, except cdio_init or any routine that accesses + the CD-ROM drive by name. This will call cdio_init, if that + hasn't been done previously. + + If NULL is given as the source, we'll use the default driver device. + + @return the cdio object or NULL on error or no device. + */ + CdIo_t * cdio_open_am (const char *psz_source, + driver_id_t driver_id, const char *psz_access_mode); + + /*! Set up BIN/CUE CD disk-image for reading. Source is the .bin or + .cue file + + @return the cdio object or NULL on error or no device. + */ + CdIo_t * cdio_open_bincue (const char *psz_cue_name); + + /*! Set up BIN/CUE CD disk-image for reading. Source is the .bin or + .cue file + + @return the cdio object or NULL on error or no device.. + */ + CdIo_t * cdio_open_am_bincue (const char *psz_cue_name, + const char *psz_access_mode); + + /*! Set up cdrdao CD disk-image for reading. Source is the .toc file + + @return the cdio object or NULL on error or no device. + */ + CdIo_t * cdio_open_cdrdao (const char *psz_toc_name); + + /*! Set up cdrdao CD disk-image for reading. Source is the .toc file + + @return the cdio object or NULL on error or no device.. + */ + CdIo_t * cdio_open_am_cdrdao (const char *psz_toc_name, + const char *psz_access_mode); + + /*! Return a string containing the default CUE file that would + be used when none is specified. + + @return the cdio object or NULL on error or no device. + */ + char * cdio_get_default_device_bincue(void); + + char **cdio_get_devices_bincue(void); + + /*! @return string containing the default CUE file that would be + used when none is specified. NULL is returned on error or there + is no device. + */ + char * cdio_get_default_device_cdrdao(void); + + char **cdio_get_devices_cdrdao(void); + + /*! Set up CD-ROM for reading. The device_name is + the some sort of device name. + + @return the cdio object for subsequent operations. + NULL on error or there is no driver for a some sort of hardware CD-ROM. + */ + CdIo_t * cdio_open_cd (const char *device_name); + + /*! Set up CD-ROM for reading. The device_name is + the some sort of device name. + + @return the cdio object for subsequent operations. + NULL on error or there is no driver for a some sort of hardware CD-ROM. + */ + CdIo_t * cdio_open_am_cd (const char *psz_device, + const char *psz_access_mode); + + /*! CDRWIN BIN/CUE CD disc-image routines. Source is the .cue file + + @return the cdio object for subsequent operations. + NULL on error. + */ + CdIo_t * cdio_open_cue (const char *cue_name); + + /*! Set up CD-ROM for reading using the AIX driver. The device_name is + the some sort of device name. + + @return the cdio object for subsequent operations. + NULL on error or there is no AIX driver. + + @see cdio_open + */ + CdIo_t * cdio_open_am_aix (const char *psz_source, + const char *psz_access_mode); + + /*! Set up CD-ROM for reading using the AIX driver. The device_name is + the some sort of device name. + + @return the cdio object for subsequent operations. + NULL on error or there is no AIX driver. + + @see cdio_open + */ + CdIo_t * cdio_open_aix (const char *psz_source); + + /*! Return a string containing the default device name that the + AIX driver would use when none is specified. + + @return the cdio object for subsequent operations. + NULL on error or there is no AIX driver. + + @see cdio_open_cd, cdio_open + */ + char * cdio_get_default_device_aix(void); + + /*! Return a list of all of the CD-ROM devices that the AIX driver + can find. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it and it is possible for this routine to return + NULL even though there may be a hardware CD-ROM. + */ + char **cdio_get_devices_aix(void); + + /*! Set up CD-ROM for reading using the BSDI driver. The device_name is + the some sort of device name. + + @param psz_source the name of the device to open + @return the cdio object for subsequent operations. + NULL on error or there is no BSDI driver. + + @see cdio_open + */ + CdIo_t * cdio_open_bsdi (const char *psz_source); + + /*! Set up CD-ROM for reading using the BSDI driver. The device_name is + the some sort of device name. + + @return the cdio object for subsequent operations. + NULL on error or there is no BSDI driver. + + @see cdio_open + */ + CdIo_t * cdio_open_am_bsdi (const char *psz_source, + const char *psz_access_mode); + + /*! Return a string containing the default device name that the + BSDI driver would use when none is specified. + + @return the cdio object for subsequent operations. + NULL on error or there is no BSDI driver. + + @see cdio_open_cd, cdio_open + */ + char * cdio_get_default_device_bsdi(void); + + /*! Return a list of all of the CD-ROM devices that the BSDI driver + can find. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it and it is possible for this routine to return + NULL even though there may be a hardware CD-ROM. + */ + char **cdio_get_devices_bsdi(void); + + /*! Set up CD-ROM for reading using the FreeBSD driver. The device_name is + the some sort of device name. + + NULL is returned on error or there is no FreeBSD driver. + + @see cdio_open_cd, cdio_open + */ + CdIo_t * cdio_open_freebsd (const char *paz_psz_source); + + /*! Set up CD-ROM for reading using the FreeBSD driver. The device_name is + the some sort of device name. + + NULL is returned on error or there is no FreeBSD driver. + + @see cdio_open_cd, cdio_open + */ + CdIo_t * cdio_open_am_freebsd (const char *psz_source, + const char *psz_access_mode); + + /*! Return a string containing the default device name that the + FreeBSD driver would use when none is specified. + + NULL is returned on error or there is no CD-ROM device. + */ + char * cdio_get_default_device_freebsd(void); + + /*! Return a list of all of the CD-ROM devices that the FreeBSD driver + can find. + */ + char **cdio_get_devices_freebsd(void); + + /*! Set up CD-ROM for reading using the GNU/Linux driver. The device_name is + the some sort of device name. + + @return the cdio object for subsequent operations. + NULL on error or there is no GNU/Linux driver. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it and it is possible for this routine to return + NULL even though there may be a hardware CD-ROM. + */ + CdIo_t * cdio_open_linux (const char *psz_source); + + /*! Set up CD-ROM for reading using the GNU/Linux driver. The + device_name is the some sort of device name. + + @return the cdio object for subsequent operations. + NULL on error or there is no GNU/Linux driver. + */ + CdIo_t * cdio_open_am_linux (const char *psz_source, + const char *access_mode); + + /*! Return a string containing the default device name that the + GNU/Linux driver would use when none is specified. A scan is made + for CD-ROM drives with CDs in them. + + NULL is returned on error or there is no CD-ROM device. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it and it is possible for this routine to return + NULL even though there may be a hardware CD-ROM. + + @see cdio_open_cd, cdio_open + */ + char * cdio_get_default_device_linux(void); + + /*! Return a list of all of the CD-ROM devices that the GNU/Linux driver + can find. + */ + char **cdio_get_devices_linux(void); + + /*! Set up CD-ROM for reading using the Sun Solaris driver. The + device_name is the some sort of device name. + + @return the cdio object for subsequent operations. + NULL on error or there is no Solaris driver. + */ + CdIo_t * cdio_open_solaris (const char *psz_source); + + /*! Set up CD-ROM for reading using the Sun Solaris driver. The + device_name is the some sort of device name. + + @return the cdio object for subsequent operations. + NULL on error or there is no Solaris driver. + */ + CdIo_t * cdio_open_am_solaris (const char *psz_source, + const char *psz_access_mode); + + /*! Return a string containing the default device name that the + Solaris driver would use when none is specified. A scan is made + for CD-ROM drives with CDs in them. + + NULL is returned on error or there is no CD-ROM device. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it and it is possible for this routine to return + NULL even though there may be a hardware CD-ROM. + + @see cdio_open_cd, cdio_open + */ + char * cdio_get_default_device_solaris(void); + + /*! Return a list of all of the CD-ROM devices that the Solaris driver + can find. + */ + char **cdio_get_devices_solaris(void); + + /*! Set up CD-ROM for reading using the Apple OSX driver. The + device_name is the some sort of device name. + + NULL is returned on error or there is no OSX driver. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it and it is possible for this routine to return + NULL even though there may be a hardware CD-ROM. + + @see cdio_open_cd, cdio_open + */ + CdIo_t * cdio_open_osx (const char *psz_source); + + /*! Set up CD-ROM for reading using the Apple OSX driver. The + device_name is the some sort of device name. + + NULL is returned on error or there is no OSX driver. + + @see cdio_open_cd, cdio_open + */ + CdIo_t * cdio_open_am_osx (const char *psz_source, + const char *psz_access_mode); + + /*! Return a string containing the default device name that the + OSX driver would use when none is specified. A scan is made + for CD-ROM drives with CDs in them. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it and it is possible for this routine to return + NULL even though there may be a hardware CD-ROM. + */ + char * cdio_get_default_device_osx(void); + + /*! Return a list of all of the CD-ROM devices that the OSX driver + can find. + */ + char **cdio_get_devices_osx(void); + + /*! Set up CD-ROM for reading using the Microsoft Windows driver. The + device_name is the some sort of device name. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it and it is possible for this routine to return + NULL even though there may be a hardware CD-ROM. + */ + CdIo_t * cdio_open_win32 (const char *psz_source); + + /*! Set up CD-ROM for reading using the Microsoft Windows driver. The + device_name is the some sort of device name. + + NULL is returned on error or there is no Microsof Windows driver. + */ + CdIo_t * cdio_open_am_win32 (const char *psz_source, + const char *psz_access_mode); + + /*! Return a string containing the default device name that the + Win32 driver would use when none is specified. A scan is made + for CD-ROM drives with CDs in them. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it and it is possible for this routine to return + NULL even though there may be a hardware CD-ROM. + + @see cdio_open_cd, cdio_open + */ + char * cdio_get_default_device_win32(void); + + char **cdio_get_devices_win32(void); + + /*! Set up CD-ROM for reading using the IBM OS/2 driver. The + device_name is the some sort of device name. + + NULL is returned on error or there is no OS/2 driver. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it and it is possible for this routine to return + NULL even though there may be a hardware CD-ROM. + + @see cdio_open_cd, cdio_open + */ + CdIo_t * cdio_open_os2 (const char *psz_source); + + /*! Set up CD-ROM for reading using the IBM OS/2 driver. The + device_name is the some sort of device name. + + NULL is returned on error or there is no OS/2 driver. + + @see cdio_open_cd, cdio_open + */ + CdIo_t * cdio_open_am_os2 (const char *psz_source, + const char *psz_access_mode); + + /*! Return a string containing the default device name that the + OS/2 driver would use when none is specified. A scan is made + for CD-ROM drives with CDs in them. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it and it is possible for this routine to return + NULL even though there may be a hardware CD-ROM. + */ + char * cdio_get_default_device_os2(void); + + /*! Return a list of all of the CD-ROM devices that the OS/2 driver + can find. + */ + char **cdio_get_devices_os2(void); + + /*! Set up CD-ROM for reading using the Nero driver. The + device_name is the some sort of device name. + + @return true on success; NULL on error or there is no Nero driver. + */ + CdIo_t * cdio_open_nrg (const char *psz_source); + + /*! Set up CD-ROM for reading using the Nero driver. The + device_name is the some sort of device name. + + @return true on success; NULL on error or there is no Nero driver. + */ + CdIo_t * cdio_open_am_nrg (const char *psz_source, + const char *psz_access_mode); + + /*! Get a string containing the default device name that the NRG + driver would use when none is specified. A scan is made for NRG + disk images in the current directory. + + @return string containing the default device. NULL on error or + there is no CD-ROM device. + */ + char * cdio_get_default_device_nrg(void); + + char **cdio_get_devices_nrg(void); + + /*! + + Determine if bin_name is the bin file part of a CDRWIN CD disk image. + + @param bin_name location of presumed CDRWIN bin image file. + @return the corresponding CUE file if bin_name is a BIN file or + NULL if not a BIN file. + */ + char *cdio_is_binfile(const char *bin_name); + + /*! + Determine if cue_name is the cue sheet for a CDRWIN CD disk image. + + @return corresponding BIN file if cue_name is a CDRWIN cue file or + NULL if not a CUE file. + */ + char *cdio_is_cuefile(const char *cue_name); + + /*! + Determine if psg_nrg is a Nero CD disc image. + + @param psz_nrg location of presumed NRG image file. + @return true if psz_nrg is a Nero NRG image or false + if not a NRG image. + */ + bool cdio_is_nrg(const char *psz_nrg); + + /*! + Determine if psz_toc is a TOC file for a cdrdao CD disc image. + + @param psz_toc location of presumed TOC image file. + @return true if toc_name is a cdrdao TOC file or false + if not a TOC file. + */ + bool cdio_is_tocfile(const char *psz_toc); + + /*! + Determine if psz_source refers to a real hardware CD-ROM. + + @param psz_source location name of object + @param driver_id driver for reading object. Use DRIVER_UNKNOWN if you + don't know what driver to use. + @return true if psz_source is a device; If false is returned we + could have a CD disk image. + */ + bool cdio_is_device(const char *psz_source, driver_id_t driver_id); + + /*! + Set the blocksize for subsequent reads. + */ + driver_return_code_t cdio_set_blocksize ( const CdIo_t *p_cdio, + int i_blocksize ); + + /*! + Set the drive speed. + + @param p_cdio CD structure set by cdio_open(). + @param i_drive_speed speed in CD-ROM speed units. Note this + not Kbs as would be used in the MMC spec or + in mmc_set_speed(). To convert CD-ROM speed units + to Kbs, multiply the number by 176 (for raw data) + and by 150 (for filesystem data). On many CD-ROM + drives, specifying a value too large will result + in using the fastest speed. + + @see mmc_set_speed and mmc_set_drive_speed + */ + driver_return_code_t cdio_set_speed ( const CdIo_t *p_cdio, + int i_drive_speed ); + + /*! + Get the value associatied with key. + + @param p_cdio the CD object queried + @param key the key to retrieve + @return the value associatd with "key" or NULL if p_cdio is NULL + or "key" does not exist. + */ + const char * cdio_get_arg (const CdIo_t *p_cdio, const char key[]); + + /*! + Set the arg "key" with "value" in "p_cdio". + + @param p_cdio the CD object to set + @param key the key to set + @param value the value to assocaiate with key + */ + driver_return_code_t cdio_set_arg (CdIo_t *p_cdio, const char key[], + const char value[]); + + /*! + Initialize CD Reading and control routines. Should be called first. + */ + bool cdio_init(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/** The below variables are trickery to force the above enum symbol + values to be recorded in debug symbol tables. They are used to + allow one to refer to the enumeration value names in the typedefs + above in a debugger and debugger expressions. +*/ +extern cdio_drive_cap_misc_t debug_cdio_drive_cap_misc; +extern cdio_drive_cap_read_t debug_cdio_drive_cap_read_t; +extern cdio_drive_cap_write_t debug_drive_cap_write_t; +extern cdio_mmc_hw_len_t debug_cdio_mmc_hw_len; +extern cdio_src_category_mask_t debug_cdio_src_category_mask; + +#endif /* __CDIO_DEVICE_H__ */ diff --git a/include/cdio/disc.h b/include/cdio/disc.h new file mode 100644 index 00000000..b5ae3c49 --- /dev/null +++ b/include/cdio/disc.h @@ -0,0 +1,108 @@ +/* -*- c -*- + $Id: disc.h,v 1.9 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** \file disc.h + * \brief The top-level header for disc-related libcdio calls. + */ +#ifndef __CDIO_DISC_H__ +#define __CDIO_DISC_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /*! disc modes. The first combined from MMC-3 5.29.2.8 (Send CUESHEET) + and GNU/Linux /usr/include/linux/cdrom.h and we've added DVD. + */ + typedef enum { + CDIO_DISC_MODE_CD_DA, /**< CD-DA */ + CDIO_DISC_MODE_CD_DATA, /**< CD-ROM form 1 */ + CDIO_DISC_MODE_CD_XA, /**< CD-ROM XA form2 */ + CDIO_DISC_MODE_CD_MIXED, /**< Some combo of above. */ + CDIO_DISC_MODE_DVD_ROM, /**< DVD ROM (e.g. movies) */ + CDIO_DISC_MODE_DVD_RAM, /**< DVD-RAM */ + CDIO_DISC_MODE_DVD_R, /**< DVD-R */ + CDIO_DISC_MODE_DVD_RW, /**< DVD-RW */ + CDIO_DISC_MODE_DVD_PR, /**< DVD+R */ + CDIO_DISC_MODE_DVD_PRW, /**< DVD+RW */ + CDIO_DISC_MODE_DVD_OTHER, /**< Unknown/unclassified DVD type */ + CDIO_DISC_MODE_NO_INFO, + CDIO_DISC_MODE_ERROR, + CDIO_DISC_MODE_CD_I /**< CD-i. */ + } discmode_t; + + extern const char *discmode2str[]; + + /*! + Get disc mode - the kind of CD (CD-DA, CD-ROM mode 1, CD-MIXED, etc. + that we've got. The notion of "CD" is extended a little to include + DVD's. + */ + discmode_t cdio_get_discmode (CdIo_t *p_cdio); + + /*! + Get the lsn of the end of the CD + + @return the lsn. On error 0 or CDIO_INVALD_LSN. + */ + lsn_t cdio_get_disc_last_lsn(const CdIo_t *p_cdio); + + /*! + Return the Joliet level recognized for p_cdio. + */ + uint8_t cdio_get_joliet_level(const CdIo_t *p_cdio); + + /*! + Get the media catalog number (MCN) from the CD. + + @return the media catalog number or NULL if there is none or we + don't have the ability to get it. + + Note: string is malloc'd so caller has to free() the returned + string when done with it. + + */ + char * cdio_get_mcn (const CdIo_t *p_cdio); + + /*! + Get the number of tracks on the CD. + + @return the number of tracks, or CDIO_INVALID_TRACK if there is + an error. + */ + track_t cdio_get_num_tracks (const CdIo_t *p_cdio); + + /*! + Return true if discmode is some sort of CD. + */ + bool cdio_is_discmode_cdrom (discmode_t discmode); + + /*! + Return true if discmode is some sort of DVD. + */ + bool cdio_is_discmode_dvd (discmode_t discmode); + + /*! cdio_stat_size is deprecated. @see cdio_get_disc_last_lsn */ +#define cdio_stat_size cdio_get_disc_last_lsn + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CDIO_DISC_H__ */ diff --git a/include/cdio/ds.h b/include/cdio/ds.h new file mode 100644 index 00000000..447e30df --- /dev/null +++ b/include/cdio/ds.h @@ -0,0 +1,98 @@ +/* + $Id: ds.h,v 1.5 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2005, 2008 Rocky Bernstein <rocky@gnu.org> + Copyright (C) 2000, 2004 Herbert Valerio Riedel <hvr@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** \file ds.h + * \brief The top-level header for list-related data structures. + + Note: this header will is slated to get removed and libcdio will use + glib.h routines instead. +*/ + + +#ifndef __CDIO_DS_H__ +#define __CDIO_DS_H__ + +#include <cdio/types.h> + +/** opaque types... */ +typedef struct _CdioList CdioList_t; +typedef struct _CdioListNode CdioListNode_t; + +typedef int (*_cdio_list_cmp_func_t) (void *p_data1, void *p_data2); +typedef int (*_cdio_list_iterfunc_t) (void *p_data, void *p_user_data); + +/** The below are given compatibility with old code. Please use + the above type names, not these. */ +#define CdioList CdioList_t +#define CdioListNode CdioListNode_t +#define _cdio_list_cmp_func _cdio_list_cmp_func_t +#define _cdio_list_iterfunc _cdio_list_iterfunc_t + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** methods */ +CdioList_t *_cdio_list_new (void); + +void _cdio_list_free (CdioList_t *p_list, int free_data); + +unsigned _cdio_list_length (const CdioList_t *list); + +void _cdio_list_prepend (CdioList_t *p_list, void *p_data); + +void _cdio_list_append (CdioList_t *p_list, void *p_data); + +void _cdio_list_foreach (CdioList_t *p_list, _cdio_list_iterfunc_t func, + void *p_user_data); + +CdioListNode_t *_cdio_list_find (CdioList_t *p_list, + _cdio_list_iterfunc_t cmp_func, + void *p_user_data); + +#define _CDIO_LIST_FOREACH(node, list) \ + for (node = _cdio_list_begin (list); node; node = _cdio_list_node_next (node)) + +/** node operations */ + +CdioListNode_t *_cdio_list_begin (const CdioList_t *p_list); + +CdioListNode_t *_cdio_list_end (CdioList_t *p_list); + +CdioListNode_t *_cdio_list_node_next (CdioListNode_t *p_node); + +void _cdio_list_node_free (CdioListNode_t *p_node, int i_free_data); + +void *_cdio_list_node_data (CdioListNode_t *p_node); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CDIO_DS_H__ */ + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ + diff --git a/include/cdio/dvd.h b/include/cdio/dvd.h new file mode 100644 index 00000000..8be8317b --- /dev/null +++ b/include/cdio/dvd.h @@ -0,0 +1,112 @@ +/* + $Id: dvd.h,v 1.5 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2004 Rocky Bernstein <rocky@gnu.org> + Modeled after GNU/Linux definitions in linux/cdrom.h + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/*! + \file dvd.h + \brief Definitions for DVD access. +*/ + +#ifndef __CDIO_DVD_H__ +#define __CDIO_DVD_H__ + +#include <cdio/types.h> + +/*! Values used in a READ DVD STRUCTURE */ + +#define CDIO_DVD_STRUCT_PHYSICAL 0x00 +#define CDIO_DVD_STRUCT_COPYRIGHT 0x01 +#define CDIO_DVD_STRUCT_DISCKEY 0x02 +#define CDIO_DVD_STRUCT_BCA 0x03 +#define CDIO_DVD_STRUCT_MANUFACT 0x04 + +/*! Media definitions for "Book Type" */ +#define CDIO_DVD_BOOK_DVD_ROM 0 +#define CDIO_DVD_BOOK_DVD_RAM 1 +#define CDIO_DVD_BOOK_DVD_R 2 /**< DVD-R */ +#define CDIO_DVD_BOOK_DVD_RW 3 /**< DVD-RW */ +#define CDIO_DVD_BOOK_DVD_PR 8 /**< DVD+R */ +#define CDIO_DVD_BOOK_DVD_PRW 9 /**< DVD+RW */ + +typedef struct cdio_dvd_layer { + uint8_t book_version : 4; + uint8_t book_type : 4; + uint8_t min_rate : 4; + uint8_t disc_size : 4; + uint8_t layer_type : 4; + uint8_t track_path : 1; + uint8_t nlayers : 2; + uint8_t track_density : 4; + uint8_t linear_density: 4; + uint8_t bca : 1; + uint32_t start_sector; + uint32_t end_sector; + uint32_t end_sector_l0; +} cdio_dvd_layer_t; + +/*! Maximum number of layers in a DVD. */ +#define CDIO_DVD_MAX_LAYERS 4 + +typedef struct cdio_dvd_physical { + uint8_t type; + uint8_t layer_num; + cdio_dvd_layer_t layer[CDIO_DVD_MAX_LAYERS]; +} cdio_dvd_physical_t; + +typedef struct cdio_dvd_copyright { + uint8_t type; + + uint8_t layer_num; + uint8_t cpst; + uint8_t rmi; +} cdio_dvd_copyright_t; + +typedef struct cdio_dvd_disckey { + uint8_t type; + + unsigned agid : 2; + uint8_t value[2048]; +} cdio_dvd_disckey_t; + +typedef struct cdio_dvd_bca { + uint8_t type; + + int len; + uint8_t value[188]; +} cdio_dvd_bca_t; + +typedef struct cdio_dvd_manufact { + uint8_t type; + + uint8_t layer_num; + int len; + uint8_t value[2048]; +} cdio_dvd_manufact_t; + +typedef union { + uint8_t type; + + cdio_dvd_physical_t physical; + cdio_dvd_copyright_t copyright; + cdio_dvd_disckey_t disckey; + cdio_dvd_bca_t bca; + cdio_dvd_manufact_t manufact; +} cdio_dvd_struct_t; + +#endif /* __SCSI_MMC_H__ */ diff --git a/include/cdio/ecma_167.h b/include/cdio/ecma_167.h new file mode 100644 index 00000000..78da7ae0 --- /dev/null +++ b/include/cdio/ecma_167.h @@ -0,0 +1,1006 @@ +/* + Copyright (c) 2005, 2006, 2008 Rocky Bernstein <rocky@cpan.org> + Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ +/* + * Some portions taken from FreeBSD ecma167-udf.h which states: + * Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*! + * \file ecma_167.h + * + * \brief Definitions based on ECMA-167 3rd edition (June 1997) + * See http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-167.pdf +*/ + +#ifndef _ECMA_167_H +#define _ECMA_167_H 1 + +#include <cdio/types.h> + +/** + Imagine the below enum values as \#define'd values rather than + distinct values of an enum. +*/ +typedef enum { + VSD_STD_ID_SIZE = 5, /** Volume Structure Descriptor (ECMA 167r3 + 2/9.1) */ + UDF_REGID_ID_SIZE = 23, /**< See identifier (ECMA 167r3 1/7.4) */ + UDF_VOLID_SIZE = 32, + UDF_FID_SIZE = 38, + UDF_VOLSET_ID_SIZE = 128 +} ecma_167_enum1_t ; + +/** Tag Identifier (ECMA 167r3 3/7.2.1) */ + +typedef enum { + TAGID_PRI_VOL = 0x0001, + TAGID_ANCHOR = 0x0002, + TAGID_VOL = 0x0003, + TAGID_IMP_VOL = 0x0004, + TAGID_PARTITION = 0x0005, + TAGID_LOGVOL = 0x0006, + TAGID_UNALLOC_SPACE = 0x0007, + TAGID_TERM = 0x0008, + TAGID_LOGVOL_INTEGRITY = 0x0009, + TAGID_FSD = 0x0100, + TAGID_FID = 0x0101, + TAGID_AED = 0x0102, + TAGID_IE = 0x0103, + TAGID_TE = 0x0104, + TAGID_FILE_ENTRY = 0x0105, + TAGID_EAHD = 0x0106, + TAGID_USE = 0x0107, + TAGID_SBD = 0x0108, + TAGID_PIE = 0x0109, + TAGID_EFE = 0x010A, +} tag_id_t ; + +/** Character Set Type (ECMA 167r3 1/7.2.1.1) */ +typedef enum { + CHARSPEC_TYPE_CS0 = 0x00, /**< Section 1/7.2.2 */ + CHARSPEC_TYPE_CS1 = 0x01, /**< Section 1/7.2.3 */ + CHARSPEC_TYPE_CS2 = 0x02, /**< Section 1/7.2.4 */ + CHARSPEC_TYPE_CS3 = 0x03, /**< Section 1/7.2.5 */ + CHARSPEC_TYPE_CS4 = 0x04, /**< Section 1/7.2.6 */ + CHARSPEC_TYPE_CS5 = 0x05, /**< Section 1/7.2.7 */ + CHARSPEC_TYPE_CS6 = 0x06, /**< Section 1/7.2.8 */ + CHARSPEC_TYPE_CS7 = 0x07, /**< Section 1/7.2.9 */ + + CHARSPEC_TYPE_CS8 = 0x08, /**< Section 1/7.2.10 */ +} udf_charspec_enum_t; + +typedef uint8_t udf_Uint8_t; /*! Section 1/7/1.1 */ +typedef uint16_t udf_Uint16_t; /*! Section 1/7.1.3 */ +typedef uint32_t udf_Uint32_t; /*! Section 1/7.1.5 */ +typedef uint64_t udf_Uint64_t; /*! Section 1/7.1.7 */ +typedef char udf_dstring; /*! Section 1/7.1.12 */ + +#define UDF_LENGTH_MASK 0x3fffffff + +PRAGMA_BEGIN_PACKED + +/** Character set specification (ECMA 167r3 1/7.2.1) */ +struct udf_charspec_s +{ + udf_Uint8_t charset_type; + udf_Uint8_t charset_info[63]; +} GNUC_PACKED; + +typedef struct udf_charspec_s udf_charspec_t; + +/** Timestamp (ECMA 167r3 1/7.3) */ +struct udf_timestamp_s +{ + udf_Uint16_t type_tz; + udf_Uint16_t year; + udf_Uint8_t month; + udf_Uint8_t day; + udf_Uint8_t hour; + udf_Uint8_t minute; + udf_Uint8_t second; + udf_Uint8_t centiseconds; + udf_Uint8_t hundreds_of_microseconds; + udf_Uint8_t microseconds; +} GNUC_PACKED; + +typedef struct udf_timestamp_s udf_timestamp_t; + +/** Type and Time Zone (ECMA 167r3 1/7.3.1) + + Imagine the below enum values as \#define'd values rather than + distinct values of an enum. +*/ +typedef enum { + TIMESTAMP_TYPE_CUT = 0x0000, + TIMESTAMP_TYPE_LOCAL = 0x1000, + TIMESTAMP_TYPE_AGREEMENT = 0x2000, + TIMESTAMP_TYPE_MASK = 0xF000, + TIMESTAMP_TIMEZONE_MASK = 0x0FFF, +} ecma_167_timezone_enum_t ; + + +#define TIMESTAMP_TYPE_MASK 0xF000 +#define TIMESTAMP_TYPE_CUT 0x0000 +#define TIMESTAMP_TYPE_LOCAL 0x1000 +#define TIMESTAMP_TYPE_AGREEMENT 0x2000 +#define TIMESTAMP_TIMEZONE_MASK 0x0FFF + +struct udf_id_suffix_s +{ + udf_Uint16_t udf_revision; + udf_Uint8_t os_class; + udf_Uint8_t os_identifier; + udf_Uint8_t reserved[4]; +} GNUC_PACKED; + +typedef struct udf_id_suffix_s udf_id_suffix_t; + +/** Entity identifier (ECMA 167r3 1/7.4) */ +struct udf_regid_s +{ + udf_Uint8_t flags; + udf_Uint8_t id[UDF_REGID_ID_SIZE]; + udf_id_suffix_t id_suffix; +} GNUC_PACKED; + +typedef struct udf_regid_s udf_regid_t; + +/** Flags (ECMA 167r3 1/7.4.1) */ +#define ENTITYID_FLAGS_DIRTY 0x00 +#define ENTITYID_FLAGS_PROTECTED 0x01 + +/** Volume Structure Descriptor (ECMA 167r3 2/9.1) */ +struct vol_struct_desc_s +{ + udf_Uint8_t struct_type; + udf_Uint8_t std_id[VSD_STD_ID_SIZE]; + udf_Uint8_t struct_version; + udf_Uint8_t struct_data[2041]; +} GNUC_PACKED; + +/** Standard Identifier (EMCA 167r2 2/9.1.2) */ +#define VSD_STD_ID_NSR02 "NSR02" /* (3/9.1) */ + +/** Standard Identifier (ECMA 167r3 2/9.1.2) */ + +/* The below const definitions are to faciltate debugging of the + values #define'd below. */ +extern const char VSD_STD_ID_BEA01[sizeof("BEA01")-1]; +extern const char VSD_STD_ID_BOOT2[sizeof("BOOT2")-1]; +extern const char VSD_STD_ID_CD001[sizeof("CD001")-1]; +extern const char VSD_STD_ID_CDW01[sizeof("CDW02")-1]; +extern const char VSD_STD_ID_NSR03[sizeof("NSR03")-1]; +extern const char VSD_STD_ID_TEA01[sizeof("TEA01")-1]; + +#define VSD_STD_ID_BEA01 "BEA01" /**< ECMA-167 2/9.2 */ +#define VSD_STD_ID_BOOT2 "BOOT2" /**< ECMA-167 2/9.4 */ +#define VSD_STD_ID_CD001 "CD001" /**< ECMA-119 */ +#define VSD_STD_ID_CDW02 "CDW02" /**< ECMA-168 */ +#define VSD_STD_ID_NSR02 "NSR02" /**< ECMA-167, 3/9.1 + NOTE: ECMA-167, 2nd edition */ +#define VSD_STD_ID_NSR03 "NSR03" /**< ECMA-167 3/9.1 */ +#define VSD_STD_ID_TEA01 "TEA01" /**< ECMA-168 2/9.3 */ + +/** Beginning Extended Area Descriptor (ECMA 167r3 2/9.2) */ +struct beginning_extended_area_desc_s +{ + udf_Uint8_t struct_type; + udf_Uint8_t std_id[VSD_STD_ID_SIZE]; + udf_Uint8_t struct_version; + udf_Uint8_t struct_data[2041]; +} GNUC_PACKED; + +/** Terminating Extended Area Descriptor (ECMA 167r3 2/9.3) */ +struct terminating_extended_area_desc_s +{ + udf_Uint8_t struct_type; + udf_Uint8_t std_id[VSD_STD_ID_SIZE]; + udf_Uint8_t struct_version; + udf_Uint8_t struct_data[2041]; +} GNUC_PACKED; + +/** Boot Descriptor (ECMA 167r3 2/9.4) */ +struct boot_desc_s +{ + udf_Uint8_t struct_type; + udf_Uint8_t std_ident[VSD_STD_ID_SIZE]; + udf_Uint8_t struct_version; + udf_Uint8_t reserved1; + udf_regid_t arch_type; + udf_regid_t boot_ident; + udf_Uint32_t bool_ext_location; + udf_Uint32_t bool_ext_length; + udf_Uint64_t load_address; + udf_Uint64_t start_address; + udf_timestamp_t desc_creation_time; + udf_Uint16_t flags; + udf_Uint8_t reserved2[32]; + udf_Uint8_t boot_use[1906]; +} GNUC_PACKED; + +/** Flags (ECMA 167r3 2/9.4.12) */ +#define BOOT_FLAGS_ERASE 0x01 + +/** Extent Descriptor (ECMA 167r3 3/7.1) */ +struct udf_extent_ad_s +{ + udf_Uint32_t len; + udf_Uint32_t loc; +} GNUC_PACKED; + +typedef struct udf_extent_ad_s udf_extent_ad_t; + +/** Descriptor Tag (ECMA 167r3 3/7.2) */ +struct udf_tag_s +{ + udf_Uint16_t id; + udf_Uint16_t desc_version; + udf_Uint8_t cksum; + udf_Uint8_t reserved; + udf_Uint16_t i_serial; + udf_Uint16_t desc_CRC; + udf_Uint16_t desc_CRC_len; + udf_Uint32_t loc; +} GNUC_PACKED; + +typedef struct udf_tag_s udf_tag_t; + +/** NSR Descriptor (ECMA 167r3 3/9.1) */ +struct NSR_desc_s +{ + udf_Uint8_t struct_type; + udf_Uint8_t std_id[VSD_STD_ID_SIZE]; + udf_Uint8_t struct_version; + udf_Uint8_t reserved; + udf_Uint8_t struct_data[2040]; +} GNUC_PACKED; + +/** Primary Volume Descriptor (ECMA 167r3 3/10.1) */ +struct udf_pvd_s +{ + udf_tag_t tag; + udf_Uint32_t vol_desc_seq_num; + udf_Uint32_t primary_vol_desc_num; + udf_dstring vol_ident[UDF_VOLID_SIZE]; + udf_Uint16_t vol_seq_num; + udf_Uint16_t max_vol_seqnum; + udf_Uint16_t interchange_lvl; + udf_Uint16_t max_interchange_lvl; + udf_Uint32_t charset_list; + udf_Uint32_t max_charset_list; + udf_dstring volset_id[UDF_VOLSET_ID_SIZE]; + udf_charspec_t desc_charset; + udf_charspec_t explanatory_charset; + udf_extent_ad_t vol_abstract; + udf_extent_ad_t vol_copyright; + udf_regid_t app_ident; + udf_timestamp_t recording_time; + udf_regid_t imp_ident; + udf_Uint8_t imp_use[64]; + udf_Uint32_t predecessor_vol_desc_seq_location; + udf_Uint16_t flags; + udf_Uint8_t reserved[22]; +} GNUC_PACKED; + +typedef struct udf_pvd_s udf_pvd_t; + +/** Flags (ECMA 167r3 3/10.1.21) */ +#define PVD_FLAGS_VSID_COMMON 0x0001 + +/** Anchor Volume Descriptor Pointer (ECMA 167r3 3/10.2) */ +struct anchor_vol_desc_ptr_s +{ + udf_tag_t tag; + udf_extent_ad_t main_vol_desc_seq_ext; + udf_extent_ad_t reserve_vol_desc_seq_ext; + udf_Uint8_t reserved[480]; +} GNUC_PACKED; + +typedef struct anchor_vol_desc_ptr_s anchor_vol_desc_ptr_t; + +/** Volume Descriptor Pointer (ECMA 167r3 3/10.3) */ +struct vol_desc_ptr_s +{ + udf_tag_t tag; + udf_Uint32_t vol_desc_seq_num; + udf_extent_ad_t next_vol_desc_set_ext; + udf_Uint8_t reserved[484]; +} GNUC_PACKED; + +/** Implementation Use Volume Descriptor (ECMA 167r3 3/10.4) */ +struct imp_use_vol_desc_s +{ + udf_tag_t tag; + udf_Uint32_t vol_desc_seq_num; + udf_regid_t imp_id; + udf_Uint8_t imp_use[460]; +} GNUC_PACKED; + +/** Partition Descriptor (ECMA 167r3 3/10.5) */ +struct partition_desc_s +{ + udf_tag_t tag; + udf_Uint32_t vol_desc_seq_num; + udf_Uint16_t flags; + udf_Uint16_t number; /**< Partition number */ + udf_regid_t contents; + udf_Uint8_t contents_use[128]; + udf_Uint32_t access_type; + udf_Uint32_t start_loc; + udf_Uint32_t part_len; + udf_regid_t imp_id; + udf_Uint8_t imp_use[128]; + udf_Uint8_t reserved[156]; +} GNUC_PACKED; + +typedef struct partition_desc_s partition_desc_t; + +/** Partition Flags (ECMA 167r3 3/10.5.3) */ +#define PD_PARTITION_FLAGS_ALLOC 0x0001 + +/** Partition Contents (ECMA 167r2 3/10.5.3) */ +#define PD_PARTITION_CONTENTS_NSR02 "+NSR02" + +/** Partition Contents (ECMA 167r3 3/10.5.5) */ +#define PD_PARTITION_CONTENTS_FDC01 "+FDC01" +#define PD_PARTITION_CONTENTS_CD001 "+CD001" +#define PD_PARTITION_CONTENTS_CDW02 "+CDW02" +#define PD_PARTITION_CONTENTS_NSR03 "+NSR03" + +/** Access Type (ECMA 167r3 3/10.5.7) */ +#define PD_ACCESS_TYPE_NONE 0x00000000 +#define PD_ACCESS_TYPE_READ_ONLY 0x00000001 +#define PD_ACCESS_TYPE_WRITE_ONCE 0x00000002 +#define PD_ACCESS_TYPE_REWRITABLE 0x00000003 +#define PD_ACCESS_TYPE_OVERWRITABLE 0x00000004 + +/** Recorded Address (ECMA 167r3 4/7.1) */ +struct udf_lb_addr_s +{ + udf_Uint32_t lba; + udf_Uint16_t partitionReferenceNum; +} GNUC_PACKED; + +typedef struct udf_lb_addr_s udf_lb_addr_t; + +/** Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */ +struct udf_short_ad_s +{ + udf_Uint32_t len; + udf_Uint32_t pos; +} GNUC_PACKED; + +typedef struct udf_short_ad_s udf_short_ad_t; + +/** Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */ +struct udf_long_ad_s +{ + udf_Uint32_t len; + udf_lb_addr_t loc; + udf_Uint8_t imp_use[6]; +} GNUC_PACKED; + +typedef struct udf_long_ad_s udf_long_ad_t; + +/** Logical Volume Descriptor (ECMA 167r3 3/10.6) */ +struct logical_vol_desc_s +{ + udf_tag_t tag; + udf_Uint32_t seq_num; + udf_charspec_t desc_charset; + udf_dstring logvol_id[128]; + udf_Uint32_t logical_blocksize; + udf_regid_t domain_id; + union { + udf_long_ad_t fsd_loc; + udf_Uint8_t logvol_content_use[16]; + } lvd_use; + udf_Uint8_t logvol_contents_use[16]; + udf_Uint32_t maptable_len; + udf_Uint32_t i_partition_maps; + udf_regid_t imp_id; + udf_Uint8_t imp_use[128]; + udf_extent_ad_t integrity_seq_ext; + udf_Uint8_t partition_maps[0]; +} GNUC_PACKED; + +typedef struct logical_vol_desc_s logical_vol_desc_t; + +/** Generic Partition Map (ECMA 167r3 3/10.7.1) */ +struct generic_partition_map +{ + udf_Uint8_t partition_map_type; + udf_Uint8_t partition_map_length; + udf_Uint8_t partition_mapping[0]; +} GNUC_PACKED; + +/** Partition Map Type (ECMA 167r3 3/10.7.1.1) */ +#define GP_PARTITION_MAP_TYPE_UNDEF 0x00 +#define GP_PARTIITON_MAP_TYPE_1 0x01 +#define GP_PARTITION_MAP_TYPE_2 0x02 + +/** Type 1 Partition Map (ECMA 167r3 3/10.7.2) */ +struct generic_partition_map1 +{ + udf_Uint8_t partition_map_type; + udf_Uint8_t partition_map_length; + udf_Uint16_t vol_seq_num; + udf_Uint16_t i_partition; +} GNUC_PACKED; + +/** Type 2 Partition Map (ECMA 167r3 3/10.7.3) */ +struct generic_partition_map2 +{ + udf_Uint8_t partition_map_type; + udf_Uint8_t partition_map_length; + udf_Uint8_t partition_id[62]; +} GNUC_PACKED; + +/** Unallocated Space Descriptor (ECMA 167r3 3/10.8) */ +struct unalloc_space_desc_s +{ + udf_tag_t tag; + udf_Uint32_t vol_desc_seq_num; + udf_Uint32_t i_alloc_descs; + udf_extent_ad_t allocDescs[0]; +} GNUC_PACKED; + +/** Terminating Descriptor (ECMA 167r3 3/10.9) */ +struct terminating_desc_s +{ + udf_tag_t tag; + udf_Uint8_t reserved[496]; +} GNUC_PACKED; + +/** Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) */ +struct logvol_integrity_desc_s +{ + udf_tag_t tag; + udf_timestamp_t recording_time; + udf_Uint32_t integrity_type; + udf_extent_ad_t next_integrity_ext; + udf_Uint8_t logvol_contents_use[32]; + udf_Uint32_t i_partitions; + udf_Uint32_t imp_use_len; + udf_Uint32_t freespace_table[0]; + udf_Uint32_t size_table[0]; + udf_Uint8_t imp_use[0]; +} GNUC_PACKED; + +/** Integrity Type (ECMA 167r3 3/10.10.3) */ +#define LVID_INTEGRITY_TYPE_OPEN 0x00000000 +#define LVID_INTEGRITY_TYPE_CLOSE 0x00000001 + +/** Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */ +struct udf_ext_ad_s +{ + udf_Uint32_t len; + udf_Uint32_t recorded_len; + udf_Uint32_t information_len; + udf_lb_addr_t ext_loc; +} GNUC_PACKED; + +typedef struct udf_ext_ad_s udf_ext_ad_t; + +/** Descriptor Tag (ECMA 167r3 4/7.2 - See 3/7.2) */ + +/** Tag Identifier (ECMA 167r3 4/7.2.1) */ + +/** File Set Descriptor (ECMA 167r3 4/14.1) */ +struct udf_fsd_s +{ + udf_tag_t tag; + udf_timestamp_t recording_time; + udf_Uint16_t interchange_lvl; + udf_Uint16_t maxInterchange_lvl; + udf_Uint32_t charset_list; + udf_Uint32_t max_charset_list; + udf_Uint32_t fileset_num; + udf_Uint32_t udf_fsd_num; + udf_charspec_t logical_vol_id_charset; + udf_dstring logical_vol_id[128]; + udf_charspec_t fileset_charset; + udf_dstring fileSet_id[32]; + udf_dstring copyright_file_id[32]; + udf_dstring abstract_file_id[32]; + udf_long_ad_t root_icb; + udf_regid_t domain_id; + udf_long_ad_t next_ext; + udf_long_ad_t stream_directory_ICB; + udf_Uint8_t reserved[32]; +} GNUC_PACKED; + +typedef struct udf_fsd_s udf_fsd_t; + +/** Partition Header Descriptor (ECMA 167r3 4/14.3) */ +struct partition_header_desc_s +{ + udf_short_ad_t unalloc_space_table; + udf_short_ad_t unalloc_space_bitmap; + udf_short_ad_t partition_integrity_table; + udf_short_ad_t freed_space_table; + udf_short_ad_t freed_space_bitmap; + udf_Uint8_t reserved[88]; +} GNUC_PACKED; + +typedef struct partition_header_desc_s partition_header_desc_t; + +/** File Identifier Descriptor (ECMA 167r3 4/14.4) */ +struct udf_fileid_desc_s +{ + udf_tag_t tag; + udf_Uint16_t file_version_num; + udf_Uint8_t file_characteristics; + udf_Uint8_t i_file_id; + udf_long_ad_t icb; + udf_Uint16_t i_imp_use; + udf_Uint8_t imp_use[0]; + udf_Uint8_t file_id[0]; + udf_Uint8_t padding[0]; +} GNUC_PACKED; + +typedef struct udf_fileid_desc_s udf_fileid_desc_t; + +/** File Characteristics (ECMA 167r3 4/14.4.3) + + Imagine the below enumeration values are \#defines to be used in a + bitmask rather than distinct values of an enum. +*/ +typedef enum { + UDF_FILE_HIDDEN = (1 << 0), + UDF_FILE_DIRECTORY = (1 << 1), + UDF_FILE_DELETED = (1 << 2), + UDF_FILE_PARENT = (1 << 3), + UDF_FILE_METADATA = (1 << 4) +} file_characteristics_t; + +/** Allocation Ext Descriptor (ECMA 167r3 4/14.5) */ +struct allocExtDesc +{ + udf_tag_t tag; + udf_Uint32_t previous_alloc_ext_loc; + udf_Uint32_t i_alloc_descs; +} GNUC_PACKED; + +/** ICB Tag (ECMA 167r3 4/14.6) */ +struct udf_icbtag_s +{ + udf_Uint32_t prev_num_dirs; + udf_Uint16_t strat_type; + udf_Uint16_t strat_param; + udf_Uint16_t max_num_entries; + udf_Uint8_t reserved; + udf_Uint8_t file_type; + udf_lb_addr_t parent_ICB; + udf_Uint16_t flags; +} GNUC_PACKED; + +typedef struct udf_icbtag_s udf_icbtag_t; + +#define UDF_ICB_TAG_FLAGS_SETUID 0x40 +#define UDF_ICB_TAG_FLAGS_SETGID 0x80 +#define UDF_ICB_TAG_FLAGS_STICKY 0x100 + +/** Strategy Type (ECMA 167r3 4/14.6.2) which helpfully points + largely to 4/A.x */ +#define ICBTAG_STRATEGY_TYPE_UNDEF 0x0000 +#define ICBTAG_STRATEGY_TYPE_1 0x0001 /**< 4/A.2 Direct entries Uint16 */ +#define ICBTAG_STRATEGY_TYPE_2 0x0002 /**< 4/A.3 List of ICB direct entries */ +#define ICBTAG_STRATEGY_TYPE_3 0x0003 /**< 4/A.4 */ +#define ICBTAG_STRATEGY_TYPE_4 0x0004 /**< 4/A.5 Hierarchy having one + single ICB with one direct entry. + This is what's most often used. + */ + +/** File Type (ECMA 167r3 4/14.6.6) + + Imagine the below enum values as \#define'd values rather than + distinct values of an enum. +*/ +typedef enum { + ICBTAG_FILE_TYPE_UNDEF = 0x00, + ICBTAG_FILE_TYPE_USE = 0x01, + ICBTAG_FILE_TYPE_PIE = 0x02, + ICBTAG_FILE_TYPE_IE = 0x03, + ICBTAG_FILE_TYPE_DIRECTORY = 0x04, + ICBTAG_FILE_TYPE_REGULAR = 0x05, + ICBTAG_FILE_TYPE_BLOCK = 0x06, + ICBTAG_FILE_TYPE_CHAR = 0x07, + ICBTAG_FILE_TYPE_EA = 0x08, + ICBTAG_FILE_TYPE_FIFO = 0x09, + ICBTAG_FILE_TYPE_SOCKET = 0x0A, + ICBTAG_FILE_TYPE_TE = 0x0B, + ICBTAG_FILE_TYPE_SYMLINK = 0x0C, + ICBTAG_FILE_TYPE_STREAMDIR = 0x0D +} icbtag_file_type_enum_t; + +/** Flags (ECMA 167r3 4/14.6.8) */ +typedef enum { + ICBTAG_FLAG_AD_MASK = 0x0007, /**< "&" this to get below address + flags */ + ICBTAG_FLAG_AD_SHORT = 0x0000, /**< The allocation descriptor + field is filled with + short_ad's. If the + offset is beyond the + current extent, look for + the next extent. */ + ICBTAG_FLAG_AD_LONG = 0x0001, /**< The allocation descriptor + field is filled with + long_ad's If the offset + is beyond the current + extent, look for the next + extent. */ + ICBTAG_FLAG_AD_EXTENDED = 0x0002, + ICBTAG_FLAG_AD_IN_ICB = 0x0003, /**< This type means that the + file *data* is stored in + the allocation descriptor + field of the file entry. */ + ICBTAG_FLAG_SORTED = 0x0008, + ICBTAG_FLAG_NONRELOCATABLE = 0x0010, + ICBTAG_FLAG_ARCHIVE = 0x0020, + ICBTAG_FLAG_SETUID = 0x0040, + ICBTAG_FLAG_SETGID = 0x0080, + ICBTAG_FLAG_STICKY = 0x0100, + ICBTAG_FLAG_CONTIGUOUS = 0x0200, + ICBTAG_FLAG_SYSTEM = 0x0400, + ICBTAG_FLAG_TRANSFORMED = 0x0800, + ICBTAG_FLAG_MULTIVERSIONS = 0x1000, + ICBTAG_FLAG_STREAM = 0x2000 +} icbtag_flag_enum_t; + +/** Indirect Entry (ECMA 167r3 4/14.7) */ +struct indirect_entry_s +{ + udf_tag_t tag; + udf_icbtag_t icb_tag; + udf_long_ad_t indirect_ICB; +} GNUC_PACKED; + +/** Terminal Entry (ECMA 167r3 4/14.8) */ +struct terminal_entry_s +{ + udf_tag_t tag; + udf_icbtag_t icb_tag; +} GNUC_PACKED; + +/** File Entry (ECMA 167r3 4/14.9) */ +struct udf_file_entry_s +{ + udf_tag_t tag; + udf_icbtag_t icb_tag; /**< 4/14.9.2 */ + udf_Uint32_t uid; /**< 4/14.9.3 */ + udf_Uint32_t gid; /**< 4/14.9.4 */ + udf_Uint32_t permissions; /**< 4/14.9.5 */ + udf_Uint16_t link_count; /**< 4/14.9.6 */ + udf_Uint8_t rec_format; /**< 4/14.9.7 */ + udf_Uint8_t rec_disp_attr; /**< 4/14.9.8 */ + udf_Uint32_t rec_len; /**< 4/14.9.9 */ + udf_Uint64_t info_len; /**< 4/14.9.10 */ + udf_Uint64_t logblks_recorded; /**< 4/14.9.11 */ + udf_timestamp_t access_time; /**< 4/14.9.12 - last access to + any stream of file prior to + recording file entry */ + udf_timestamp_t modification_time; /**< 4/14.9.13 - last access to + modification to any stream of + file */ + udf_timestamp_t attribute_time; + udf_Uint32_t checkpoint; + udf_long_ad_t ext_attr_ICB; + udf_regid_t imp_id; + udf_Uint64_t unique_ID; + udf_Uint32_t i_extended_attr; + udf_Uint32_t i_alloc_descs; + udf_Uint8_t ext_attr[0]; + udf_Uint8_t alloc_descs[0]; +} GNUC_PACKED; + +typedef struct udf_file_entry_s udf_file_entry_t; + +#define UDF_FENTRY_SIZE 176 +#define UDF_FENTRY_PERM_USER_MASK 0x07 +#define UDF_FENTRY_PERM_GRP_MASK 0xE0 +#define UDF_FENTRY_PERM_OWNER_MASK 0x1C00 + +/** Permissions (ECMA 167r3 4/14.9.5) */ +#define FE_PERM_O_EXEC 0x00000001U +#define FE_PERM_O_WRITE 0x00000002U +#define FE_PERM_O_READ 0x00000004U +#define FE_PERM_O_CHATTR 0x00000008U +#define FE_PERM_O_DELETE 0x00000010U +#define FE_PERM_G_EXEC 0x00000020U +#define FE_PERM_G_WRITE 0x00000040U +#define FE_PERM_G_READ 0x00000080U +#define FE_PERM_G_CHATTR 0x00000100U +#define FE_PERM_G_DELETE 0x00000200U +#define FE_PERM_U_EXEC 0x00000400U +#define FE_PERM_U_WRITE 0x00000800U +#define FE_PERM_U_READ 0x00001000U +#define FE_PERM_U_CHATTR 0x00002000U +#define FE_PERM_U_DELETE 0x00004000U + +/** Record Format (ECMA 167r3 4/14.9.7) */ +#define FE_RECORD_FMT_UNDEF 0x00 +#define FE_RECORD_FMT_FIXED_PAD 0x01 +#define FE_RECORD_FMT_FIXED 0x02 +#define FE_RECORD_FMT_VARIABLE8 0x03 +#define FE_RECORD_FMT_VARIABLE16 0x04 +#define FE_RECORD_FMT_VARIABLE16_MSB 0x05 +#define FE_RECORD_FMT_VARIABLE32 0x06 +#define FE_RECORD_FMT_PRINT 0x07 +#define FE_RECORD_FMT_LF 0x08 +#define FE_RECORD_FMT_CR 0x09 +#define FE_RECORD_FMT_CRLF 0x0A +#define FE_RECORD_FMT_LFCR 0x0B + +/** Record Display Attributes (ECMA 167r3 4/14.9.8) */ +#define FE_RECORD_DISPLAY_ATTR_UNDEF 0x00 +#define FE_RECORD_DISPLAY_ATTR_1 0x01 +#define FE_RECORD_DISPLAY_ATTR_2 0x02 +#define FE_RECORD_DISPLAY_ATTR_3 0x03 + +/** Extended Attribute Header Descriptor (ECMA 167r3 4/14.10.1) */ +struct extended_attr_header_desc_s +{ + udf_tag_t tag; + udf_Uint32_t imp_attr_location; + udf_Uint32_t app_attr_location; +} GNUC_PACKED; + +/** Generic Format (ECMA 167r3 4/14.10.2) */ +struct generic_format_s +{ + udf_Uint32_t attr_type; + udf_Uint8_t attr_subtype; + udf_Uint8_t reserved[3]; + udf_Uint32_t attrLength; + udf_Uint8_t attrData[0]; +} GNUC_PACKED; + +/** Character Set Information (ECMA 167r3 4/14.10.3) */ +struct charSet_info_s +{ + udf_Uint32_t attr_type; + udf_Uint8_t attr_subtype; + udf_Uint8_t reserved[3]; + udf_Uint32_t attrLength; + udf_Uint32_t escapeSeqLength; + udf_Uint8_t charSetType; + udf_Uint8_t escapeSeq[0]; +} GNUC_PACKED; + +/* Alternate Permissions (ECMA 167r3 4/14.10.4) */ +struct alt_perms_s +{ + udf_Uint32_t attr_type; + udf_Uint8_t attr_subtype; + udf_Uint8_t reserved[3]; + udf_Uint32_t attrLength; + udf_Uint16_t owner_id; + udf_Uint16_t group_id; + udf_Uint16_t permission; +} GNUC_PACKED; + +/** File Times Extended Attribute (ECMA 167r3 4/14.10.5) */ +struct filetimes_ext_attr_s +{ + udf_Uint32_t attr_type; + udf_Uint8_t attr_subtype; + udf_Uint8_t reserved[3]; + udf_Uint32_t attrLength; + udf_Uint32_t dataLength; + udf_Uint32_t fileTimeExistence; + udf_Uint8_t fileTimes; +} GNUC_PACKED; + +/** FileTimeExistence (ECMA 167r3 4/14.10.5.6) */ +#define FTE_CREATION 0x00000001 +#define FTE_DELETION 0x00000004 +#define FTE_EFFECTIVE 0x00000008 +#define FTE_BACKUP 0x00000002 + +/** Information Times Extended Attribute (ECMA 167r3 4/14.10.6) */ +struct infoTimesExtAttr +{ + udf_Uint32_t attr_type; + udf_Uint8_t attr_subtype; + udf_Uint8_t reserved[3]; + udf_Uint32_t attrLength; + udf_Uint32_t dataLength; + udf_Uint32_t infoTimeExistence; + udf_Uint8_t infoTimes[0]; +} GNUC_PACKED; + +/** Device Specification (ECMA 167r3 4/14.10.7) */ +struct deviceSpec +{ + udf_Uint32_t attr_type; + udf_Uint8_t attr_subtype; + udf_Uint8_t reserved[3]; + udf_Uint32_t attrLength; + udf_Uint32_t imp_useLength; + udf_Uint32_t majorDevice_id; + udf_Uint32_t minorDevice_id; + udf_Uint8_t imp_use[0]; +} GNUC_PACKED; + +/** Implementation Use Extended Attr (ECMA 167r3 4/14.10.8) */ +struct impUseExtAttr +{ + udf_Uint32_t attr_type; + udf_Uint8_t attr_subtype; + udf_Uint8_t reserved[3]; + udf_Uint32_t attrLength; + udf_Uint32_t imp_useLength; + udf_regid_t imp_id; + udf_Uint8_t imp_use[0]; +} GNUC_PACKED; + +/** Application Use Extended Attribute (ECMA 167r3 4/14.10.9) */ +struct appUseExtAttr +{ + udf_Uint32_t attr_type; + udf_Uint8_t attr_subtype; + udf_Uint8_t reserved[3]; + udf_Uint32_t attrLength; + udf_Uint32_t appUseLength; + udf_regid_t app_id; + udf_Uint8_t appUse[0]; +} GNUC_PACKED; + +#define EXTATTR_CHAR_SET 1 +#define EXTATTR_ALT_PERMS 3 +#define EXTATTR_FILE_TIMES 5 +#define EXTATTR_INFO_TIMES 6 +#define EXTATTR_DEV_SPEC 12 +#define EXTATTR_IMP_USE 2048 +#define EXTATTR_APP_USE 65536 + + +/** Unallocated Space Entry (ECMA 167r3 4/14.11) */ +struct unallocSpaceEntry +{ + udf_tag_t tag; + udf_icbtag_t icb_tag; + udf_Uint32_t lengthAllocDescs; + udf_Uint8_t allocDescs[0]; +} GNUC_PACKED; + +/** Space Bitmap Descriptor (ECMA 167r3 4/14.12) */ +struct spaceBitmapDesc +{ + udf_tag_t tag; + udf_Uint32_t i_bits; + udf_Uint32_t i_bytes; + udf_Uint8_t bitmap[0]; +} GNUC_PACKED; + +/** Partition Integrity Entry (ECMA 167r3 4/14.13) */ +struct partitionIntegrityEntry +{ + udf_tag_t tag; + udf_icbtag_t icb_tag; + udf_timestamp_t recording_time; + udf_Uint8_t integrityType; + udf_Uint8_t reserved[175]; + udf_regid_t imp_id; + udf_Uint8_t imp_use[256]; +} GNUC_PACKED; + +/** Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */ + +/** Extent Length (ECMA 167r3 4/14.14.1.1) */ +#define EXT_RECORDED_ALLOCATED 0x00000000 +#define EXT_NOT_RECORDED_ALLOCATED 0x40000000 +#define EXT_NOT_RECORDED_NOT_ALLOCATED 0x80000000 +#define EXT_NEXT_EXTENT_ALLOCDECS 0xC0000000 + +/** Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */ + +/** Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */ + +/** Logical Volume Header Descriptor (ECMA 167r3 4/14.15) */ +struct logical_vol_header_desc_s +{ + udf_Uint64_t uniqueID; + udf_Uint8_t reserved[24]; +} GNUC_PACKED; + +typedef struct logical_vol_header_desc_s logical_vol_header_desc_t; + +/** Path Component (ECMA 167r3 4/14.16.1) */ +struct pathComponent +{ + udf_Uint8_t component_type; + udf_Uint8_t lengthComponent_id; + udf_Uint16_t componentFileVersionNum; + udf_dstring component_id[0]; +} GNUC_PACKED; + +/** File Entry (ECMA 167r3 4/14.17) */ +struct extended_file_entry +{ + udf_tag_t tag; /**< 4/14.17.1 - id = 266 */ + udf_icbtag_t icb_tag; /**< 4/14.17.2 & 4/14.9.2 */ + udf_Uint32_t uid; /**< 4/14.17.3 & 4/14.9.3 */ + udf_Uint32_t gid; /**< 4/14.17.4 & 4/14.9.4 */ + udf_Uint32_t permissions; /**< 4/14.17.5 & 4/14.9.5 */ + udf_Uint16_t link_count; /**< 4/14.17.6 & 4/14.9.6 */ + udf_Uint8_t rec_format; /**< 4/14.17.7 & 4/14.9.7 */ + udf_Uint8_t rec_display_attr; /**< 4/14.17.8 & 4/14.9.8 */ + udf_Uint32_t record_len; /**< 4/14.17.9 & 4/14.9.9 */ + udf_Uint64_t info_len; /**< 4/14.17.10 & 4/14.9.10 */ + udf_Uint64_t object_size; /**< 4/14.17.11 */ + udf_Uint64_t logblks_recorded; /**< 4/14.17.12 & 4/14.9.11 */ + udf_timestamp_t access_time; /**< 4/14.17.13 & 4/14.9.12 - last + access to any stream of file */ + udf_timestamp_t modification_time; /**< 4/14.17.14 & 4/14.9.13 - last + modification to any stream of + file*/ + udf_timestamp_t create_time; /**< 4/14.17.15 */ + udf_timestamp_t attribute_time; /**< 4/14.17.16 & 4/14.9.14 - + most recent create or modify + time */ + udf_Uint32_t checkpoint; + udf_Uint32_t reserved; /**< #00 bytes */ + udf_long_ad_t ext_attr_ICB; + udf_long_ad_t stream_directory_ICB; + udf_regid_t imp_id; + udf_Uint64_t unique_ID; + udf_Uint32_t length_extended_attr; + udf_Uint32_t length_alloc_descs; + udf_Uint8_t ext_attr[0]; + udf_Uint8_t alloc_descs[0]; +} GNUC_PACKED; + +PRAGMA_END_PACKED + +/** The below variables are trickery to force the above enum symbol + values to be recorded in debug symbol tables. They are used to + allow one refer to the enumeration value names in the typedefs + above in a debugger and in debugger expressions. +*/ +extern tag_id_t debug_tagid; +extern file_characteristics_t debug_file_characteristics; +extern icbtag_file_type_enum_t debug_icbtag_file_type_enum; +extern icbtag_flag_enum_t debug_flag_enum; +extern ecma_167_enum1_t debug_ecma_167_enum1; +extern ecma_167_timezone_enum_t debug_ecma_167_timezone_enum; + +#endif /* _ECMA_167_H */ diff --git a/include/cdio/iso9660.h b/include/cdio/iso9660.h new file mode 100644 index 00000000..a5311c8f --- /dev/null +++ b/include/cdio/iso9660.h @@ -0,0 +1,1116 @@ +/* + $Id: iso9660.h,v 1.102 2008/07/16 00:28:54 rocky Exp $ + + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 + Rocky Bernstein <rocky@gnu.org> + Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org> + + See also iso9660.h by Eric Youngdale (1993). + + Copyright 1993 Yggdrasil Computing, Incorporated + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ +/*! + * \file iso9660.h + * + * \brief The top-level interface header for libiso9660: the ISO-9660 + * filesystem library; applications include this. + * + * See also the ISO-9660 specification. The freely available European + * equivalant standard is called ECMA-119. +*/ + + +#ifndef __CDIO_ISO9660_H__ +#define __CDIO_ISO9660_H__ + +#include <time.h> + +#include <cdio/cdio.h> +#include <cdio/ds.h> +#include <cdio/posix.h> + +/** \brief ISO 9660 Integer and Character types + +These are described in the section 7 of the ISO 9660 (or ECMA 119) +specification. +*/ + +typedef uint8_t iso711_t; /*! See section 7.1.1 */ +typedef int8_t iso712_t; /*! See section 7.1.2 */ +typedef uint16_t iso721_t; /*! See section 7.2.1 */ +typedef uint16_t iso722_t; /*! See section 7.2.2 */ +typedef uint32_t iso723_t; /*! See section 7.2.3 */ +typedef uint32_t iso731_t; /*! See section 7.3.1 */ +typedef uint32_t iso732_t; /*! See section 7.3.2 */ +typedef uint64_t iso733_t; /*! See section 7.3.3 */ + +typedef char achar_t; /*! See section 7.4.1 */ +typedef char dchar_t; /*! See section 7.4.1 */ + +#ifndef EMPTY_ARRAY_SIZE +#define EMPTY_ARRAY_SIZE 0 +#endif + +#include <cdio/types.h> +#include <cdio/xa.h> + +#ifdef ISODCL +#undef ISODCL +#endif +/* This part borrowed from the bsd386 isofs */ +#define ISODCL(from, to) ((to) - (from) + 1) + +#define MIN_TRACK_SIZE 4*75 +#define MIN_ISO_SIZE MIN_TRACK_SIZE + +/*! The below isn't really an enumeration one would really use in a + program; things are done this way so that in a debugger one can to + refer to the enumeration value names such as in a debugger + expression and get something. With the more common a \#define + mechanism, the name/value assocation is lost at run time. + */ +extern enum iso_enum1_s { + ISO_PVD_SECTOR = 16, /**< Sector of Primary Volume Descriptor. */ + ISO_EVD_SECTOR = 17, /**< Sector of End Volume Descriptor. */ + LEN_ISONAME = 31, /**< Size in bytes of the filename + portion + null byte. */ + ISO_MAX_SYSTEM_ID = 32, /**< Maximum number of characters in a system + id. */ + MAX_ISONAME = 37, /**< Size in bytes of the filename + portion + null byte. */ + ISO_MAX_PREPARER_ID = 128, /**< Maximum number of characters in a + preparer id. */ + MAX_ISOPATHNAME = 255, /**< Maximum number of characters in the + entire ISO 9660 filename. */ + ISO_BLOCKSIZE = 2048 /**< Number of bytes in an ISO 9660 block. */ + +} iso_enums1; + +/*! An enumeration for some of the ISO_* \#defines below. This isn't + really an enumeration one would really use in a program it is here + to be helpful in debuggers where wants just to refer to the + ISO_*_ names and get something. + */ + +/*! ISO 9660 directory flags. */ +extern enum iso_flag_enum_s { + ISO_FILE = 0, /**< Not really a flag... */ + ISO_EXISTENCE = 1, /**< Do not make existence known (hidden) */ + ISO_DIRECTORY = 2, /**< This file is a directory */ + ISO_ASSOCIATED = 4, /**< This file is an associated file */ + ISO_RECORD = 8, /**< Record format in extended attr. != 0 */ + ISO_PROTECTION = 16, /**< No read/execute perm. in ext. attr. */ + ISO_DRESERVED1 = 32, /**<, Reserved bit 5 */ + ISO_DRESERVED2 = 64, /**<, Reserved bit 6 */ + ISO_MULTIEXTENT = 128, /**< Not final entry of a mult. ext. file */ +} iso_flag_enums; + +/*! Volume descriptor types */ +extern enum iso_vd_enum_s { + ISO_VD_BOOT_RECORD = 0, /**< CD is bootable */ + ISO_VD_PRIMARY = 1, /**< Is in any ISO-9660 */ + ISO_VD_SUPPLEMENTARY = 2, /**< Used by Joliet, for example */ + ISO_VD_PARITION = 3, /**< Indicates a partition of a CD */ + ISO_VD_END = 255 +} iso_vd_enums; + + +/*! + An ISO filename is: + <em>abcd</em>.<em>eee</em> -> + <em>filename</em>.<em>ext</em>;<em>version#</em> + + For ISO-9660 Level 1, the maximum needed string length is: + +@code + 30 chars (filename + ext) + + 2 chars ('.' + ';') + + 5 chars (strlen("32767")) + + 1 null byte + ================================ + = 38 chars +@endcode + +*/ + +/*! \brief Maximum number of characters in a publisher id. */ +#define ISO_MAX_PUBLISHER_ID 128 + +/*! \brief Maximum number of characters in an application id. */ +#define ISO_MAX_APPLICATION_ID 128 + +/*! \brief Maximum number of characters in a volume id. */ +#define ISO_MAX_VOLUME_ID 32 + +/*! \brief Maximum number of characters in a volume-set id. */ +#define ISO_MAX_VOLUMESET_ID 128 + +/*! String inside frame which identifies an ISO 9660 filesystem. This + string is the "id" field of an iso9660_pvd_t or an iso9660_svd_t. +*/ +extern const char ISO_STANDARD_ID[sizeof("CD001")-1]; + +#define ISO_STANDARD_ID "CD001" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef enum strncpy_pad_check { + ISO9660_NOCHECK = 0, + ISO9660_7BIT, + ISO9660_ACHARS, + ISO9660_DCHARS +} strncpy_pad_check_t; + +PRAGMA_BEGIN_PACKED + +/*! + \brief ISO-9660 shorter-format time structure. See ECMA 9.1.5. + + @see iso9660_dtime + */ +struct iso9660_dtime_s { + iso711_t dt_year; /**< Number of years since 1900 */ + iso711_t dt_month; /**< Has value in range 1..12. Note starts + at 1, not 0 like a tm struct. */ + iso711_t dt_day; /**< Day of the month from 1 to 31 */ + iso711_t dt_hour; /**< Hour of the day from 0 to 23 */ + iso711_t dt_minute; /**< Minute of the hour from 0 to 59 */ + iso711_t dt_second; /**< Second of the minute from 0 to 59 */ + iso712_t dt_gmtoff; /**< GMT values -48 .. + 52 in 15 minute + intervals */ +} GNUC_PACKED; + +typedef struct iso9660_dtime_s iso9660_dtime_t; + +/*! + \brief ISO-9660 longer-format time structure. + + Section 8.4.26.1 of ECMA 119. All values are encoded as character + arrays, eg. '1', '9', '5', '5' for the year 1955 (no null terminated + byte). + + @see iso9660_ltime + */ +struct iso9660_ltime_s { + char lt_year [ISODCL( 1, 4)]; /**< Add 1900 to value + for the Julian + year */ + char lt_month [ISODCL( 5, 6)]; /**< Has value in range + 1..12. Note starts + at 1, not 0 like a + tm struct. */ + char lt_day [ISODCL( 7, 8)]; /**< Day of month: 1..31 */ + char lt_hour [ISODCL( 9, 10)]; /**< hour: 0..23 */ + char lt_minute [ISODCL( 11, 12)]; /**< minute: 0..59 */ + char lt_second [ISODCL( 13, 14)]; /**< second: 0..59 */ + char lt_hsecond [ISODCL( 15, 16)]; /**< The value is in + units of 1/100's of + a second */ + iso712_t lt_gmtoff; /**< Offset from Greenwich Mean Time in number + of 15 min intervals from -48 (West) to +52 + (East) recorded according to 7.1.2 numerical + value */ +} GNUC_PACKED; + +typedef struct iso9660_ltime_s iso9660_ltime_t; +typedef struct iso9660_dir_s iso9660_dir_t; +typedef struct iso9660_stat_s iso9660_stat_t; + +#include <cdio/rock.h> + +/*! \brief Format of an ISO-9660 directory record + + Section 9.1 of ECMA 119. + + This structure may have an odd length depending on how many + characters there are in the filename! Some compilers (e.g. on + Sun3/mc68020) pad the structures to an even length. For this reason, + we cannot use sizeof (struct iso_path_table) or sizeof (struct + iso_directory_record) to compute on disk sizes. Instead, we use + offsetof(..., name) and add the name size. See mkisofs.h of the + cdrtools package. + + @see iso9660_stat +*/ +struct iso9660_dir_s { + iso711_t length; /*! Length of Directory record (9.1.1) */ + iso711_t xa_length; /*! XA length if XA is used. Otherwise + zero. (9.1.2) */ + iso733_t extent; /*! LBA of first local block allocated + to the extent */ + iso733_t size; /*! data length of File Section. This + does not include the length of + any XA Records. (9.1.2) */ + iso9660_dtime_t recording_time; /*! Recording date and time (9.1.3) */ + uint8_t file_flags; /*! If no XA then zero. If a directory, + then bits 2,3 and 7 are zero. + (9.1.6) */ + iso711_t file_unit_size; /*! File Unit size for the File + Section if the File Section + is recorded in interleaved + mode. Otherwise zero. (9.1.7) */ + iso711_t interleave_gap; /*! Interleave Gap size for the + File Section if the File + Section is interleaved. Otherwise + zero. (9.1.8) */ + iso723_t volume_sequence_number; /*! Ordinal number of the volume + in the Volume Set on which + the Extent described by this + Directory Record is + recorded. (9.1.9) */ + iso711_t filename_len; /*! number of bytes in filename field */ + char filename[EMPTY_ARRAY_SIZE]; +} GNUC_PACKED; + +/*! + \brief ISO-9660 Primary Volume Descriptor. + */ +struct iso9660_pvd_s { + iso711_t type; /**< ISO_VD_PRIMARY - 1 */ + char id[5]; /**< ISO_STANDARD_ID "CD001" + */ + iso711_t version; /**< value 1 for ECMA 119 */ + char unused1[1]; /**< unused - value 0 */ + achar_t system_id[ISO_MAX_SYSTEM_ID]; /**< each char is an achar */ + dchar_t volume_id[ISO_MAX_VOLUME_ID]; /**< each char is a dchar */ + uint8_t unused2[8]; /**< unused - value 0 */ + iso733_t volume_space_size; /**< total number of + sectors */ + uint8_t unused3[32]; /**< unused - value 0 */ + iso723_t volume_set_size; /**< often 1 */ + iso723_t volume_sequence_number; /**< often 1 */ + iso723_t logical_block_size; /**< sector size, e.g. 2048 */ + iso733_t path_table_size; /**< bytes in path table */ + iso731_t type_l_path_table; /**< first sector of L Path + Table */ + iso731_t opt_type_l_path_table; /**< first sector of optional + L Path Table */ + iso732_t type_m_path_table; /**< first sector of M Path + table */ + iso732_t opt_type_m_path_table; /**< first sector of optional + M Path table */ + iso9660_dir_t root_directory_record; /**< See 8.4.18 and + section 9.1 of + ISO 9660 spec. */ + char root_directory_filename; /**< Is '\\0' or root + directory. Also pads previous + field to 34 bytes */ + dchar_t volume_set_id[ISO_MAX_VOLUMESET_ID]; /**< Volume Set of + which the volume is + a member. See + section 8.4.19 */ + achar_t publisher_id[ISO_MAX_PUBLISHER_ID]; /**< Publisher of + volume. If the first + character is '_' 0x5F, + the remaining bytes + specify a file + containing the user. + If all bytes are " " + (0x20) no publisher + is specified. See + section 8.4.20 of + ECMA 119 */ + achar_t preparer_id[ISO_MAX_PREPARER_ID]; /**< preparer of + volume. If the first + character is '_' 0x5F, + the remaining bytes + specify a file + containing the user. + If all bytes are " " + (0x20) no preparer + is specified. + See section 8.4.21 + of ECMA 119 */ + achar_t application_id[ISO_MAX_APPLICATION_ID]; /**< application + use to create the + volume. If the first + character is '_' 0x5F, + the remaining bytes + specify a file + containing the user. + If all bytes are " " + (0x20) no application + is specified. + See section of 8.4.22 + of ECMA 119 */ + dchar_t copyright_file_id[37]; /**< Name of file for + copyright info. If + all bytes are " " + (0x20), then no file + is identified. See + section 8.4.23 of ECMA 119 + 9660 spec. */ + dchar_t abstract_file_id[37]; /**< See section 8.4.24 of + ECMA 119. */ + dchar_t bibliographic_file_id[37]; /**< See section 7.5 of + ISO 9660 spec. */ + iso9660_ltime_t creation_date; /**< date and time of volume + creation. See section 8.4.26.1 + of the ISO 9660 spec. */ + iso9660_ltime_t modification_date; /**< date and time of the most + recent modification. + See section 8.4.27 of the + ISO 9660 spec. */ + iso9660_ltime_t expiration_date; /**< date and time when volume + expires. See section 8.4.28 + of the ISO 9660 spec. */ + iso9660_ltime_t effective_date; /**< date and time when volume + is effective. See section + 8.4.29 of the ISO 9660 + spec. */ + iso711_t file_structure_version; /**< value 1 for ECMA 119 */ + uint8_t unused4[1]; /**< unused - value 0 */ + char application_data[512]; /**< Application can put + whatever it wants here. */ + uint8_t unused5[653]; /**< Unused - value 0 */ +} GNUC_PACKED; + +typedef struct iso9660_pvd_s iso9660_pvd_t; + +/*! + \brief ISO-9660 Supplementary Volume Descriptor. + + This is used for Joliet Extentions and is almost the same as the + the primary descriptor but two unused fields, "unused1" and "unused3 + become "flags and "escape_sequences" respectively. +*/ +struct iso9660_svd_s { + iso711_t type; /**< ISO_VD_SUPPLEMENTARY - 2 + */ + char id[5]; /**< ISO_STANDARD_ID "CD001" + */ + iso711_t version; /**< value 1 */ + char flags; /**< Section 8.5.3 */ + achar_t system_id[ISO_MAX_SYSTEM_ID]; /**< Section 8.5.4; each char + is an achar */ + dchar_t volume_id[ISO_MAX_VOLUME_ID]; /**< Section 8.5.5; each char + is a dchar */ + char unused2[8]; + iso733_t volume_space_size; /**< total number of + sectors */ + char escape_sequences[32]; /**< Section 8.5.6 */ + iso723_t volume_set_size; /**< often 1 */ + iso723_t volume_sequence_number; /**< often 1 */ + iso723_t logical_block_size; /**< sector size, e.g. 2048 */ + iso733_t path_table_size; /**< 8.5.7; bytes in path + table */ + iso731_t type_l_path_table; /**< 8.5.8; first sector of + little-endian path table */ + iso731_t opt_type_l_path_table; /**< 8.5.9; first sector of + optional little-endian + path table */ + iso732_t type_m_path_table; /**< 8.5.10; first sector of + big-endian path table */ + iso732_t opt_type_m_path_table; /**< 8.5.11; first sector of + optional big-endian path + table */ + iso9660_dir_t root_directory_record; /**< See section 8.5.12 and + 9.1 of ISO 9660 spec. */ + char root_directory_filename; /**< Is '\\0' or root + directory. Also pads previous + field to 34 bytes */ + dchar_t volume_set_id[ISO_MAX_VOLUMESET_ID]; /**< 8.5.13; + dchars */ + achar_t publisher_id[ISO_MAX_PUBLISHER_ID]; /**< + Publisher of volume. + If the first char- + aracter is '_' 0x5F, + the remaining bytes + specify a file + containing the user. + If all bytes are " " + (0x20) no publisher + is specified. See + section 8.5.14 of + ECMA 119 */ + achar_t preparer_id[ISO_MAX_PREPARER_ID]; /**< + Data preparer of + volume. If the first + character is '_' 0x5F, + the remaining bytes + specify a file + containing the user. + If all bytes are " " + (0x20) no preparer + is specified. + See section 8.5.15 + of ECMA 119 */ + achar_t application_id[ISO_MAX_APPLICATION_ID]; /**< application + use to create the + volume. If the first + character is '_' 0x5F, + the remaining bytes + specify a file + containing the user. + If all bytes are " " + (0x20) no application + is specified. + See section of 8.5.16 + of ECMA 119 */ + dchar_t copyright_file_id[37]; /**< Name of file for + copyright info. If + all bytes are " " + (0x20), then no file + is identified. See + section 8.5.17 of ECMA 119 + 9660 spec. */ + dchar_t abstract_file_id[37]; /**< See section 8.5.18 of + ECMA 119. */ + dchar_t bibliographic_file_id[37]; /**< See section 8.5.19 of + ECMA 119. */ + iso9660_ltime_t creation_date; /**< date and time of volume + creation. See section 8.4.26.1 + of the ECMA 119 spec. */ + iso9660_ltime_t modification_date; /**< date and time of the most + recent modification. + See section 8.4.27 of the + ECMA 119 spec. */ + iso9660_ltime_t expiration_date; /**< date and time when volume + expires. See section 8.4.28 + of the ECMA 119 spec. */ + iso9660_ltime_t effective_date; /**< date and time when volume + is effective. See section + 8.4.29 of the ECMA 119 + spec. */ + iso711_t file_structure_version; /**< value 1 for ECMA 119 */ + uint8_t unused4[1]; /**< unused - value 0 */ + char application_data[512]; /**< 8.5.20 Application can put + whatever it wants here. */ + uint8_t unused5[653]; /**< Unused - value 0 */ +} GNUC_PACKED; + +typedef struct iso9660_svd_s iso9660_svd_t; + +PRAGMA_END_PACKED + +/*! \brief Unix stat-like version of iso9660_dir + + The iso9660_stat structure is not part of the ISO-9660 + specification. We use it for our to communicate information + in a C-library friendly way, e.g struct tm time structures and + a C-style filename string. + + @see iso9660_dir +*/ +struct iso9660_stat_s { /* big endian!! */ + + iso_rock_statbuf_t rr; /**< Rock Ridge-specific fields */ + + struct tm tm; /**< time on entry - FIXME merge with + one of entries above, like ctime? */ + lsn_t lsn; /**< start logical sector number */ + uint32_t size; /**< total size in bytes */ + uint32_t secsize; /**< number of sectors allocated */ + iso9660_xa_t xa; /**< XA attributes */ + enum { _STAT_FILE = 1, _STAT_DIR = 2 } type; + bool b_xa; + char filename[EMPTY_ARRAY_SIZE]; /**< filename */ +}; + +/** A mask used in iso9660_ifs_read_vd which allows what kinds + of extensions we allow, eg. Joliet, Rock Ridge, etc. */ +typedef uint8_t iso_extension_mask_t; + +/*! An enumeration for some of the ISO_EXTENSION_* \#defines below. This isn't + really an enumeration one would really use in a program it is here + to be helpful in debuggers where wants just to refer to the + ISO_EXTENSION_*_ names and get something. + */ +extern enum iso_extension_enum_s { + ISO_EXTENSION_JOLIET_LEVEL1 = 0x01, + ISO_EXTENSION_JOLIET_LEVEL2 = 0x02, + ISO_EXTENSION_JOLIET_LEVEL3 = 0x04, + ISO_EXTENSION_ROCK_RIDGE = 0x08, + ISO_EXTENSION_HIGH_SIERRA = 0x10 +} iso_extension_enums; + + +#define ISO_EXTENSION_ALL 0xFF +#define ISO_EXTENSION_NONE 0x00 +#define ISO_EXTENSION_JOLIET \ + (ISO_EXTENSION_JOLIET_LEVEL1 | \ + ISO_EXTENSION_JOLIET_LEVEL2 | \ + ISO_EXTENSION_JOLIET_LEVEL3 ) + + +/** This is an opaque structure. */ +typedef struct _iso9660_s iso9660_t; + + /*! Close previously opened ISO 9660 image and free resources + associated with the image. Call this when done using using an ISO + 9660 image. + + @return true is unconditionally returned. If there was an error + false would be returned. + */ + bool iso9660_close (iso9660_t * p_iso); + + + /*! + Open an ISO 9660 image for reading. Maybe in the future we will have + a mode. NULL is returned on error. + */ + iso9660_t *iso9660_open (const char *psz_path /*flags, mode */); + + /*! + Open an ISO 9660 image for reading allowing various ISO 9660 + extensions. Maybe in the future we will have a mode. NULL is + returned on error. + + @see iso9660_open_fuzzy + */ + iso9660_t *iso9660_open_ext (const char *psz_path, + iso_extension_mask_t iso_extension_mask); + + /*! Open an ISO 9660 image for "fuzzy" reading. This means that we + will try to guess various internal offset based on internal + checks. This may be useful when trying to read an ISO 9660 image + contained in a file format that libiso9660 doesn't know natively + (or knows imperfectly.) + + Some tolerence allowed for positioning the ISO 9660 image. We scan + for STANDARD_ID and use that to set the eventual offset to adjust + by (as long as that is <= i_fuzz). + + Maybe in the future we will have a mode. NULL is returned on error. + + @see iso9660_open, @see iso9660_fuzzy_ext + */ + iso9660_t *iso9660_open_fuzzy (const char *psz_path /*flags, mode */, + uint16_t i_fuzz); + + /*! + Open an ISO 9660 image for reading with some tolerence for positioning + of the ISO9660 image. We scan for ISO_STANDARD_ID and use that to set + the eventual offset to adjust by (as long as that is <= i_fuzz). + + Maybe in the future we will have a mode. NULL is returned on error. + + @see iso9660_open_ext @see iso9660_open_fuzzy + */ + iso9660_t *iso9660_open_fuzzy_ext (const char *psz_path, + iso_extension_mask_t iso_extension_mask, + uint16_t i_fuzz + /*flags, mode */); + + /*! + Read the Super block of an ISO 9660 image but determine framesize + and datastart and a possible additional offset. Generally here we are + not reading an ISO 9660 image but a CD-Image which contains an ISO 9660 + filesystem. + */ + bool iso9660_ifs_fuzzy_read_superblock (iso9660_t *p_iso, + iso_extension_mask_t iso_extension_mask, + uint16_t i_fuzz); + + /*! + Seek to a position and then read i_size blocks. + + @param p_iso the ISO-9660 file image to get data from + + @param ptr place to put returned data. It should be able to store + a least i_size bytes + + @param start location to start reading from + + @param i_size number of blocks to read. Each block is ISO_BLOCKSIZE bytes + long. + + @return number of bytes (not blocks) read + + */ + long int iso9660_iso_seek_read (const iso9660_t *p_iso, /*out*/ void *ptr, + lsn_t start, long int i_size); + + /*! + Read the Primary Volume Descriptor for a CD. + True is returned if read, and false if there was an error. + */ + bool iso9660_fs_read_pvd ( const CdIo_t *p_cdio, + /*out*/ iso9660_pvd_t *p_pvd ); + + /*! + Read the Primary Volume Descriptor for an ISO 9660 image. + True is returned if read, and false if there was an error. + */ + bool iso9660_ifs_read_pvd (const iso9660_t *p_iso, + /*out*/ iso9660_pvd_t *p_pvd); + +/*! + Read the Super block of an ISO 9660 image. This is the + Primary Volume Descriptor (PVD) and perhaps a Supplemental Volume + Descriptor if (Joliet) extensions are acceptable. +*/ + bool iso9660_fs_read_superblock (CdIo_t *p_cdio, + iso_extension_mask_t iso_extension_mask); + + /*! + Read the Super block of an ISO 9660 image. This is the + Primary Volume Descriptor (PVD) and perhaps a Supplemental Volume + Descriptor if (Joliet) extensions are acceptable. + */ + bool iso9660_ifs_read_superblock (iso9660_t *p_iso, + iso_extension_mask_t iso_extension_mask); + + +/*==================================================== + Time conversion + ====================================================*/ +/*! + Set time in format used in ISO 9660 directory index record + from a Unix time structure. */ + void iso9660_set_dtime (const struct tm *tm, + /*out*/ iso9660_dtime_t *idr_date); + + + /*! + Set "long" time in format used in ISO 9660 primary volume descriptor + from a Unix time structure. */ + void iso9660_set_ltime (const struct tm *_tm, + /*out*/ iso9660_ltime_t *p_pvd_date); + + /*! + Get Unix time structure from format use in an ISO 9660 directory index + record. Even though tm_wday and tm_yday fields are not explicitly in + idr_date, they are calculated from the other fields. + + If tm is to reflect the localtime, set "b_localtime" true, otherwise + tm will reported in GMT. + */ + bool iso9660_get_dtime (const iso9660_dtime_t *idr_date, bool b_localtime, + /*out*/ struct tm *tm); + + + /*! + Get "long" time in format used in ISO 9660 primary volume descriptor + from a Unix time structure. + */ + bool iso9660_get_ltime (const iso9660_ltime_t *p_ldate, + /*out*/ struct tm *p_tm); + + /*==================================================== + Character Classification and String Manipulation + ====================================================*/ + /*! + Return true if c is a DCHAR - a character that can appear in an an + ISO-9600 level 1 directory name. These are the ASCII capital + letters A-Z, the digits 0-9 and an underscore. + */ + bool iso9660_is_dchar (int c); + + /*! + Return true if c is an ACHAR - + These are the DCHAR's plus some ASCII symbols including the space + symbol. + */ + bool iso9660_is_achar (int c); + + /*! + Convert an ISO-9660 file name which is in the format usually stored + in a ISO 9660 directory entry into what's usually listed as the + file name in a listing. Lowercase name, and remove trailing ;1's + or .;1's and turn the other ;'s into version numbers. + + @param psz_oldname the ISO-9660 filename to be translated. + @param psz_newname returned string. The caller allocates this and + it should be at least the size of psz_oldname. + @return length of the translated string is returned. + */ + int iso9660_name_translate(const char *psz_oldname, + /*out*/ char *psz_newname); + + /*! + Convert an ISO-9660 file name which is in the format usually stored + in a ISO 9660 directory entry into what's usually listed as the + file name in a listing. Lowercase name if no Joliet Extension + interpretation. Remove trailing ;1's or .;1's and turn the other + ;'s into version numbers. + + @param psz_oldname the ISO-9660 filename to be translated. + @param psz_newname returned string. The caller allocates this and + it should be at least the size of psz_oldname. + @param i_joliet_level 0 if not using Joliet Extension. Otherwise the + Joliet level. + @return length of the translated string is returned. It will be no greater + than the length of psz_oldname. + */ + int iso9660_name_translate_ext(const char *psz_oldname, char *psz_newname, + uint8_t i_joliet_level); + + /*! + Pad string src with spaces to size len and copy this to dst. If + len is less than the length of src, dst will be truncated to the + first len characters of src. + + src can also be scanned to see if it contains only ACHARs, DCHARs, + 7-bit ASCII chars depending on the enumeration _check. + + In addition to getting changed, dst is the return value. + Note: this string might not be NULL terminated. + */ + char *iso9660_strncpy_pad(char dst[], const char src[], size_t len, + enum strncpy_pad_check _check); + + /*===================================================================== + File and Directory Names + ======================================================================*/ + + /*! + Check that psz_path is a valid ISO-9660 directory name. + + A valid directory name should not start out with a slash (/), + dot (.) or null byte, should be less than 37 characters long, + have no more than 8 characters in a directory component + which is separated by a /, and consist of only DCHARs. + + True is returned if psz_path is valid. + */ + bool iso9660_dirname_valid_p (const char psz_path[]); + + /*! + Take psz_path and a version number and turn that into a ISO-9660 + pathname. (That's just the pathname followd by ";" and the version + number. For example, mydir/file.ext -> MYDIR/FILE.EXT;1 for version + 1. The resulting ISO-9660 pathname is returned. + */ + char *iso9660_pathname_isofy (const char psz_path[], uint16_t i_version); + + /*! + Check that psz_path is a valid ISO-9660 pathname. + + A valid pathname contains a valid directory name, if one appears and + the filename portion should be no more than 8 characters for the + file prefix and 3 characters in the extension (or portion after a + dot). There should be exactly one dot somewhere in the filename + portion and the filename should be composed of only DCHARs. + + True is returned if psz_path is valid. + */ + bool iso9660_pathname_valid_p (const char psz_path[]); + +/*===================================================================== + directory tree +======================================================================*/ + +void +iso9660_dir_init_new (void *dir, uint32_t self, uint32_t ssize, + uint32_t parent, uint32_t psize, + const time_t *dir_time); + +void +iso9660_dir_init_new_su (void *dir, uint32_t self, uint32_t ssize, + const void *ssu_data, unsigned int ssu_size, + uint32_t parent, uint32_t psize, + const void *psu_data, unsigned int psu_size, + const time_t *dir_time); + +void +iso9660_dir_add_entry_su (void *dir, const char filename[], uint32_t extent, + uint32_t size, uint8_t file_flags, + const void *su_data, + unsigned int su_size, const time_t *entry_time); + +unsigned int +iso9660_dir_calc_record_size (unsigned int namelen, unsigned int su_len); + +/*! + Given a directory pointer, find the filesystem entry that contains + lsn and return information about it. + + @return stat_t of entry if we found lsn, or NULL otherwise. + Caller must free return value. + */ +#define iso9660_fs_find_lsn iso9660_find_fs_lsn +iso9660_stat_t *iso9660_fs_find_lsn(CdIo_t *p_cdio, lsn_t i_lsn); + + +/*! + Given a directory pointer, find the filesystem entry that contains + lsn and return information about it. + + @return stat_t of entry if we found lsn, or NULL otherwise. + Caller must free return value. + */ +iso9660_stat_t *iso9660_fs_find_lsn_with_path(CdIo_t *p_cdio, lsn_t i_lsn, + /*out*/ char **ppsz_path); + +/*! + Given a directory pointer, find the filesystem entry that contains + lsn and return information about it. + + @return stat_t of entry if we found lsn, or NULL otherwise. + Caller must free return value. + */ +iso9660_stat_t *iso9660_ifs_find_lsn(iso9660_t *p_iso, lsn_t i_lsn); + + +/*! + Given a directory pointer, find the filesystem entry that contains + lsn and return information about it. + + @param p_iso pointer to iso_t + @param i_lsn LSN to find + @param ppsz_path full path of lsn filename. On entry *ppsz_path should be + NULL. On return it will be allocated an point to the full path of the + file at lsn or NULL if the lsn is not found. You should deallocate + *ppsz_path when you are done using it. + + @return stat_t of entry if we found lsn, or NULL otherwise. + Caller must free return value. + */ +iso9660_stat_t *iso9660_ifs_find_lsn_with_path(iso9660_t *p_iso, + lsn_t i_lsn, + /*out*/ char **ppsz_path); + + +/*! + Return file status for psz_path. NULL is returned on error. + + @param p_cdio the CD object to read from + + @param psz_path filename path to look up and get information about + + @return ISO 9660 file information + + Important note: + + You make get different results looking up "/" versus "/." and the + latter may give more complete information. "/" will take information + from the PVD only, whereas "/." will force a directory read of "/" and + find "." and in that Rock-Ridge information might be found which fills + in more stat information. Ideally iso9660_fs_stat should be fixed. + Patches anyone? + */ +iso9660_stat_t *iso9660_fs_stat (CdIo_t *p_cdio, const char psz_path[]); + + +/*! + Return file status for path name psz_path. NULL is returned on error. + pathname version numbers in the ISO 9660 name are dropped, i.e. ;1 + is removed and if level 1 ISO-9660 names are lowercased. + + b_mode2 is historical. It is not used. + */ +iso9660_stat_t *iso9660_fs_stat_translate (CdIo_t *p_cdio, + const char psz_path[], + bool b_mode2); + +/*! + Return file status for pathname. NULL is returned on error. + */ +iso9660_stat_t *iso9660_ifs_stat (iso9660_t *p_iso, const char psz_path[]); + + +/*! Return file status for path name psz_path. NULL is returned on + error. pathname version numbers in the ISO 9660 name are dropped, + i.e. ;1 is removed and if level 1 ISO-9660 names are lowercased. + */ +iso9660_stat_t *iso9660_ifs_stat_translate (iso9660_t *p_iso, + const char psz_path[]); + +/*! Read psz_path (a directory) and return a list of iso9660_stat_t + pointers for the files inside that directory. The caller must free the + returned result. + + b_mode2 is historical. It is not used. +*/ +CdioList_t * iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[], + bool b_mode2); + +/*! Read psz_path (a directory) and return a list of iso9660_stat_t + pointers for the files inside that directory. The caller must free + the returned result. +*/ +CdioList_t * iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[]); + +/*! + Return the PVD's application ID. + NULL is returned if there is some problem in getting this. +*/ +char * iso9660_get_application_id(iso9660_pvd_t *p_pvd); + +/*! + Get the application ID. psz_app_id is set to NULL if there + is some problem in getting this and false is returned. +*/ +bool iso9660_ifs_get_application_id(iso9660_t *p_iso, + /*out*/ cdio_utf8_t **p_psz_app_id); + +/*! + Return the Joliet level recognized for p_iso. +*/ +uint8_t iso9660_ifs_get_joliet_level(iso9660_t *p_iso); + +uint8_t iso9660_get_dir_len(const iso9660_dir_t *p_idr); + +#if FIXME +uint8_t iso9660_get_dir_size(const iso9660_dir_t *p_idr); + +lsn_t iso9660_get_dir_extent(const iso9660_dir_t *p_idr); +#endif + + /*! + Return the directory name stored in the iso9660_dir_t + + A string is allocated: the caller must deallocate. This routine + can return NULL if memory allocation fails. + */ + char * iso9660_dir_to_name (const iso9660_dir_t *p_iso9660_dir); + + /*! + Returns a POSIX mode for a given p_iso_dirent. + */ + mode_t iso9660_get_posix_filemode(const iso9660_stat_t *p_iso_dirent); + + /*! + Return a string containing the preparer id with trailing + blanks removed. + */ + char *iso9660_get_preparer_id(const iso9660_pvd_t *p_pvd); + + /*! + Get the preparer ID. psz_preparer_id is set to NULL if there + is some problem in getting this and false is returned. + */ + bool iso9660_ifs_get_preparer_id(iso9660_t *p_iso, + /*out*/ cdio_utf8_t **p_psz_preparer_id); + + /*! + Return a string containing the PVD's publisher id with trailing + blanks removed. + */ + char *iso9660_get_publisher_id(const iso9660_pvd_t *p_pvd); + + /*! + Get the publisher ID. psz_publisher_id is set to NULL if there + is some problem in getting this and false is returned. + */ + bool iso9660_ifs_get_publisher_id(iso9660_t *p_iso, + /*out*/ cdio_utf8_t **p_psz_publisher_id); + + uint8_t iso9660_get_pvd_type(const iso9660_pvd_t *p_pvd); + + const char * iso9660_get_pvd_id(const iso9660_pvd_t *p_pvd); + + int iso9660_get_pvd_space_size(const iso9660_pvd_t *p_pvd); + + int iso9660_get_pvd_block_size(const iso9660_pvd_t *p_pvd) ; + + /*! Return the primary volume id version number (of pvd). + If there is an error 0 is returned. + */ + int iso9660_get_pvd_version(const iso9660_pvd_t *pvd) ; + + /*! + Return a string containing the PVD's system id with trailing + blanks removed. + */ + char *iso9660_get_system_id(const iso9660_pvd_t *p_pvd); + + /*! + Get the system ID. psz_system_id is set to NULL if there + is some problem in getting this and false is returned. + */ + bool iso9660_ifs_get_system_id(iso9660_t *p_iso, + /*out*/ cdio_utf8_t **p_psz_system_id); + + + /*! Return the LSN of the root directory for pvd. + If there is an error CDIO_INVALID_LSN is returned. + */ + lsn_t iso9660_get_root_lsn(const iso9660_pvd_t *p_pvd); + + /*! + Get the volume ID in the PVD. psz_volume_id is set to NULL if there + is some problem in getting this and false is returned. + */ + char *iso9660_get_volume_id(const iso9660_pvd_t *p_pvd); + + /*! + Get the volume ID in the PVD. psz_volume_id is set to NULL if there + is some problem in getting this and false is returned. + */ + bool iso9660_ifs_get_volume_id(iso9660_t *p_iso, + /*out*/ cdio_utf8_t **p_psz_volume_id); + + /*! + Return the volumeset ID in the PVD. + NULL is returned if there is some problem in getting this. + */ + char *iso9660_get_volumeset_id(const iso9660_pvd_t *p_pvd); + + /*! + Get the volumeset ID. psz_systemset_id is set to NULL if there + is some problem in getting this and false is returned. + */ + bool iso9660_ifs_get_volumeset_id(iso9660_t *p_iso, + /*out*/ cdio_utf8_t **p_psz_volumeset_id); + + /* pathtable */ + + /*! Zero's out pathable. Do this first. */ + void iso9660_pathtable_init (void *pt); + + unsigned int iso9660_pathtable_get_size (const void *pt); + + uint16_t iso9660_pathtable_l_add_entry (void *pt, const char name[], + uint32_t extent, uint16_t parent); + + uint16_t iso9660_pathtable_m_add_entry (void *pt, const char name[], + uint32_t extent, uint16_t parent); + + /**===================================================================== + Volume Descriptors + ======================================================================*/ + + void iso9660_set_pvd (void *pd, const char volume_id[], + const char application_id[], + const char publisher_id[], const char preparer_id[], + uint32_t iso_size, const void *root_dir, + uint32_t path_table_l_extent, + uint32_t path_table_m_extent, + uint32_t path_table_size, const time_t *pvd_time); + + void iso9660_set_evd (void *pd); + + /*! + Return true if ISO 9660 image has extended attrributes (XA). + */ + bool iso9660_ifs_is_xa (const iso9660_t * p_iso); + + +#ifndef DO_NOT_WANT_COMPATIBILITY +/** For compatibility with < 0.77 */ +#define iso9660_isdchar iso9660_is_dchar +#define iso9660_isachar iso9660_is_achar +#endif /*DO_NOT_WANT_COMPATIBILITY*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#undef ISODCL +#endif /* __CDIO_ISO9660_H__ */ + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/cdio/logging.h b/include/cdio/logging.h new file mode 100644 index 00000000..988d11c5 --- /dev/null +++ b/include/cdio/logging.h @@ -0,0 +1,136 @@ +/* + $Id: logging.h,v 1.11 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2003, 2004, 2008 Rocky Bernstein <rocky@gnu.org> + Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** \file logging.h + * \brief Header to control logging and level of detail of output. + * + */ + +#ifndef __LOGGING_H__ +#define __LOGGING_H__ + +#include <cdio/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The different log levels supported. + */ +typedef enum { + CDIO_LOG_DEBUG = 1, /**< Debug-level messages - helps debug what's up. */ + CDIO_LOG_INFO, /**< Informational - indicates perhaps something of + interest. */ + CDIO_LOG_WARN, /**< Warning conditions - something that looks funny. */ + CDIO_LOG_ERROR, /**< Error conditions - may terminate program. */ + CDIO_LOG_ASSERT /**< Critical conditions - may abort program. */ +} cdio_log_level_t; + +/** + * The place to save the preference concerning how much verbosity + * is desired. This is used by the internal default log handler, but + * it could be use by applications which provide their own log handler. + */ +extern cdio_log_level_t cdio_loglevel_default; + +/** + * This type defines the signature of a log handler. For every + * message being logged, the handler will receive the log level and + * the message string. + * + * @see cdio_log_set_handler + * @see cdio_log_level_t + * + * @param level The log level. + * @param message The log message. + */ +typedef void (*cdio_log_handler_t) (cdio_log_level_t level, + const char message[]); + +/** + * Set a custom log handler for libcdio. The return value is the log + * handler being replaced. If the provided parameter is NULL, then + * the handler will be reset to the default handler. + * + * @see cdio_log_handler_t + * + * @param new_handler The new log handler. + * @return The previous log handler. + */ +cdio_log_handler_t cdio_log_set_handler (cdio_log_handler_t new_handler); + +/** + * Handle an message with the given log level. + * + * @see cdio_debug + * @see cdio_info + * @see cdio_warn + * @see cdio_error + + * @param level The log level. + * @param format printf-style format string + * @param ... remaining arguments needed by format string + */ +void cdio_log (cdio_log_level_t level, + const char format[], ...) GNUC_PRINTF(2, 3); + +/** + * Handle a debugging message. + * + * @see cdio_log for a more generic routine + */ +void cdio_debug (const char format[], ...) GNUC_PRINTF(1,2); + +/** + * Handle an informative message. + * + * @see cdio_log for a more generic routine + */ +void cdio_info (const char format[], ...) GNUC_PRINTF(1,2); + +/** + * Handle a warning message. + * + * @see cdio_log for a more generic routine + */ +void cdio_warn (const char format[], ...) GNUC_PRINTF(1,2); + +/** + * Handle an error message. Execution is terminated. + * + * @see cdio_log for a more generic routine. + */ +void cdio_error (const char format[], ...) GNUC_PRINTF(1,2); + +#ifdef __cplusplus +} +#endif + +#endif /* __LOGGING_H__ */ + + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/cdio/mmc.h b/include/cdio/mmc.h new file mode 100644 index 00000000..c7a4eeaf --- /dev/null +++ b/include/cdio/mmc.h @@ -0,0 +1,907 @@ +/* + $Id: mmc.h,v 1.32 2008/05/09 06:13:32 edsdead Exp $ + + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 + Rocky Bernstein <rocky@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** + * \file mmc.h + * + * \brief Common definitions for MMC (Multimedia Commands). Applications + * include this for direct MMC access. +*/ + +#ifndef __CDIO_MMC_H__ +#define __CDIO_MMC_H__ + +#include <cdio/cdio.h> +#include <cdio/types.h> +#include <cdio/dvd.h> +#include <cdio/audio.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /** Set this to the maximum value in milliseconds that we will + wait on an MMC command. */ + extern uint32_t mmc_timeout_ms; + + /** The default timeout (non-read) is 6 seconds. */ +#define MMC_TIMEOUT_DEFAULT 6000 + + /** Set this to the maximum value in milliseconds that we will + wait on an MMC read command. */ + extern uint32_t mmc_read_timeout_ms; + + /** The default read timeout is 3 minutes. */ +#define MMC_READ_TIMEOUT_DEFAULT 3*60*1000 + + + /** \brief The opcode-portion (generic packet commands) of an MMC command. + + In general, those opcodes that end in 6 take a 6-byte command + descriptor, those that end in 10 take a 10-byte + descriptor and those that in in 12 take a 12-byte descriptor. + + (Not that you need to know that, but it seems to be a + big deal in the MMC specification.) + + */ + typedef enum { + CDIO_MMC_GPCMD_INQUIRY = 0x12, /**< Request drive + information. */ + CDIO_MMC_GPCMD_MODE_SELECT_6 = 0x15, /**< Select medium + (6 bytes). */ + CDIO_MMC_GPCMD_MODE_SENSE_6 = 0x1a, /**< Get medium or device + information. Should be issued + before MODE SELECT to get + mode support or save current + settings. (6 bytes). */ + CDIO_MMC_GPCMD_START_STOP = 0x1b, /**< Enable/disable Disc + operations. (6 bytes). */ + CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL = 0x1e, /**< Enable/disable Disc + removal. (6 bytes). */ + + /** Group 2 Commands (CDB's here are 10-bytes) + */ + CDIO_MMC_GPCMD_READ_10 = 0x28, /**< Read data from drive + (10 bytes). */ + CDIO_MMC_GPCMD_READ_SUBCHANNEL = 0x42, /**< Read Sub-Channel data. + (10 bytes). */ + CDIO_MMC_GPCMD_READ_TOC = 0x43, /**< READ TOC/PMA/ATIP. + (10 bytes). */ + CDIO_MMC_GPCMD_READ_HEADER = 0x44, + CDIO_MMC_GPCMD_PLAY_AUDIO_10 = 0x45, /**< Begin audio playing at + current position + (10 bytes). */ + CDIO_MMC_GPCMD_GET_CONFIGURATION = 0x46, /**< Get drive Capabilities + (10 bytes) */ + CDIO_MMC_GPCMD_PLAY_AUDIO_MSF = 0x47, /**< Begin audio playing at + specified MSF (10 + bytes). */ + CDIO_MMC_GPCMD_PLAY_AUDIO_TI = 0x48, + CDIO_MMC_GPCMD_PLAY_TRACK_REL_10 = 0x49, /**< Play audio at the track + relative LBA. (10 bytes). + Doesn't seem to be part + of MMC standards but is + handled by Plextor drives. + */ + + CDIO_MMC_GPCMD_GET_EVENT_STATUS = 0x4a, /**< Report events and + Status. */ + CDIO_MMC_GPCMD_PAUSE_RESUME = 0x4b, /**< Stop or restart audio + playback. (10 bytes). + Used with a PLAY command. */ + + CDIO_MMC_GPCMD_READ_DISC_INFO = 0x51, /**< Get CD information. + (10 bytes). */ + CDIO_MMC_GPCMD_MODE_SELECT_10 = 0x55, /**< Select medium + (10-bytes). */ + CDIO_MMC_GPCMD_MODE_SENSE_10 = 0x5a, /**< Get medium or device + information. Should be issued + before MODE SELECT to get + mode support or save current + settings. (6 bytes). */ + + /** Group 5 Commands (CDB's here are 12-bytes) + */ + CDIO_MMC_GPCMD_PLAY_AUDIO_12 = 0xa5, /**< Begin audio playing at + current position + (12 bytes) */ + CDIO_MMC_GPCMD_LOAD_UNLOAD = 0xa6, /**< Load/unload a Disc + (12 bytes) */ + CDIO_MMC_GPCMD_READ_12 = 0xa8, /**< Read data from drive + (12 bytes). */ + CDIO_MMC_GPCMD_PLAY_TRACK_REL_12 = 0xa9, /**< Play audio at the track + relative LBA. (12 bytes). + Doesn't seem to be part + of MMC standards but is + handled by Plextor drives. + */ + CDIO_MMC_GPCMD_READ_DVD_STRUCTURE = 0xad, /**< Get DVD structure info + from media (12 bytes). */ + CDIO_MMC_GPCMD_READ_MSF = 0xb9, /**< Read almost any field + of a CD sector at specified + MSF. (12 bytes). */ + CDIO_MMC_GPCMD_SET_SPEED = 0xbb, /**< Set drive speed + (12 bytes). This is listed + as optional in ATAPI 2.6, + but is (curiously) + missing from Mt. Fuji, + Table 57. It is mentioned + in Mt. Fuji Table 377 as an + MMC command for SCSI + devices though... Most + ATAPI drives support it. */ + CDIO_MMC_GPCMD_READ_CD = 0xbe, /**< Read almost any field + of a CD sector at current + location. (12 bytes). */ + /** Vendor-unique Commands + */ + CDIO_MMC_GPCMD_CD_PLAYBACK_STATUS = 0xc4 /**< SONY unique = command */, + CDIO_MMC_GPCMD_PLAYBACK_CONTROL = 0xc9 /**< SONY unique = command */, + CDIO_MMC_GPCMD_READ_CDDA = 0xd8 /**< Vendor unique = command */, + CDIO_MMC_GPCMD_READ_CDXA = 0xdb /**< Vendor unique = command */, + CDIO_MMC_GPCMD_READ_ALL_SUBCODES = 0xdf /**< Vendor unique = command */ + } cdio_mmc_gpcmd_t; + + + /** Read Subchannel states */ + typedef enum { + CDIO_MMC_READ_SUB_ST_INVALID = 0x00, /**< audio status not supported */ + CDIO_MMC_READ_SUB_ST_PLAY = 0x11, /**< audio play operation in + progress */ + CDIO_MMC_READ_SUB_ST_PAUSED = 0x12, /**< audio play operation paused */ + CDIO_MMC_READ_SUB_ST_COMPLETED = 0x13, /**< audio play successfully + completed */ + CDIO_MMC_READ_SUB_ST_ERROR = 0x14, /**< audio play stopped due to + error */ + CDIO_MMC_READ_SUB_ST_NO_STATUS = 0x15, /**< no current audio status to + return */ + } cdio_mmc_read_sub_state_t; + + /** Level values that can go into READ_CD */ + typedef enum { + CDIO_MMC_READ_TYPE_ANY = 0, /**< All types */ + CDIO_MMC_READ_TYPE_CDDA = 1, /**< Only CD-DA sectors */ + CDIO_MMC_READ_TYPE_MODE1 = 2, /**< mode1 sectors (user data = 2048) */ + CDIO_MMC_READ_TYPE_MODE2 = 3, /**< mode2 sectors form1 or form2 */ + CDIO_MMC_READ_TYPE_M2F1 = 4, /**< mode2 sectors form1 */ + CDIO_MMC_READ_TYPE_M2F2 = 5 /**< mode2 sectors form2 */ + } cdio_mmc_read_cd_type_t; + + /** Format values for READ_TOC */ + typedef enum { + CDIO_MMC_READTOC_FMT_TOC = 0, + CDIO_MMC_READTOC_FMT_SESSION = 1, + CDIO_MMC_READTOC_FMT_FULTOC = 2, + CDIO_MMC_READTOC_FMT_PMA = 3, /**< Q subcode data */ + CDIO_MMC_READTOC_FMT_ATIP = 4, /**< includes media type */ + CDIO_MMC_READTOC_FMT_CDTEXT = 5 /**< CD-TEXT info */ + } cdio_mmc_readtoc_t; + +/** Page codes for MODE SENSE and MODE SET. */ + typedef enum { + CDIO_MMC_R_W_ERROR_PAGE = 0x01, + CDIO_MMC_WRITE_PARMS_PAGE = 0x05, + CDIO_MMC_CDR_PARMS_PAGE = 0x0d, + CDIO_MMC_AUDIO_CTL_PAGE = 0x0e, + CDIO_MMC_POWER_PAGE = 0x1a, + CDIO_MMC_FAULT_FAIL_PAGE = 0x1c, + CDIO_MMC_TO_PROTECT_PAGE = 0x1d, + CDIO_MMC_CAPABILITIES_PAGE = 0x2a, + CDIO_MMC_ALL_PAGES = 0x3f, + } cdio_mmc_mode_page_t; + + +PRAGMA_BEGIN_PACKED + struct mmc_audio_volume_entry_s + { + uint8_t selection; /* Only the lower 4 bits are used. */ + uint8_t volume; + } GNUC_PACKED; + + typedef struct mmc_audio_volume_entry_s mmc_audio_volume_entry_t; + + /** This struct is used by cdio_audio_get_volume and cdio_audio_set_volume */ + struct mmc_audio_volume_s + { + mmc_audio_volume_entry_t port[4]; + } GNUC_PACKED; + + typedef struct mmc_audio_volume_s mmc_audio_volume_t; + +PRAGMA_END_PACKED + + +/** Return type codes for GET_CONFIGURATION. */ +typedef enum { + CDIO_MMC_GET_CONF_ALL_FEATURES = 0, /**< all features without regard + to currency. */ + CDIO_MMC_GET_CONF_CURRENT_FEATURES = 1, /**< features which are currently + in effect (e.g. based on + medium inserted). */ + CDIO_MMC_GET_CONF_NAMED_FEATURE = 2 /**< just the feature named in + the GET_CONFIGURATION cdb. */ +} cdio_mmc_get_conf_t; + + +/** FEATURE codes used in GET CONFIGURATION. */ + +typedef enum { + CDIO_MMC_FEATURE_PROFILE_LIST = 0x000, /**< Profile List Feature */ + CDIO_MMC_FEATURE_CORE = 0x001, + CDIO_MMC_FEATURE_MORPHING = 0x002, /**< Report/prevent operational + changes */ + CDIO_MMC_FEATURE_REMOVABLE_MEDIUM = 0x003, /**< Removable Medium Feature */ + CDIO_MMC_FEATURE_WRITE_PROTECT = 0x004, /**< Write Protect Feature */ + CDIO_MMC_FEATURE_RANDOM_READABLE = 0x010, /**< Random Readable Feature */ + CDIO_MMC_FEATURE_MULTI_READ = 0x01D, /**< Multi-Read Feature */ + CDIO_MMC_FEATURE_CD_READ = 0x01E, /**< CD Read Feature */ + CDIO_MMC_FEATURE_DVD_READ = 0x01F, /**< DVD Read Feature */ + CDIO_MMC_FEATURE_RANDOM_WRITABLE = 0x020, /**< Random Writable Feature */ + CDIO_MMC_FEATURE_INCR_WRITE = 0x021, /**< Incremental Streaming + Writable Feature */ + CDIO_MMC_FEATURE_SECTOR_ERASE = 0x022, /**< Sector Erasable Feature */ + CDIO_MMC_FEATURE_FORMATABLE = 0x023, /**< Formattable Feature */ + CDIO_MMC_FEATURE_DEFECT_MGMT = 0x024, /**< Management Ability of the + Logical Unit/media system to + provide an apparently + defect-free space.*/ + CDIO_MMC_FEATURE_WRITE_ONCE = 0x025, /**< Write Once + Feature */ + CDIO_MMC_FEATURE_RESTRICT_OVERW = 0x026, /**< Restricted Overwrite + Feature */ + CDIO_MMC_FEATURE_CD_RW_CAV = 0x027, /**< CD-RW CAV Write Feature */ + CDIO_MMC_FEATURE_MRW = 0x028, /**< MRW Feature */ + CDIO_MMC_FEATURE_ENHANCED_DEFECT = 0x029, /**< Enhanced Defect Reporting */ + CDIO_MMC_FEATURE_DVD_PRW = 0x02A, /**< DVD+RW Feature */ + CDIO_MMC_FEATURE_DVD_PR = 0x02B, /**< DVD+R Feature */ + CDIO_MMC_FEATURE_RIGID_RES_OVERW = 0x02C, /**< Rigid Restricted Overwrite */ + CDIO_MMC_FEATURE_CD_TAO = 0x02D, /**< CD Track at Once */ + CDIO_MMC_FEATURE_CD_SAO = 0x02E, /**< CD Mastering (Session at + Once) */ + CDIO_MMC_FEATURE_DVD_R_RW_WRITE = 0x02F, /**< DVD-R/RW Write */ + CDIO_MMC_FEATURE_CD_RW_MEDIA_WRITE= 0x037, /**< CD-RW Media Write Support */ + CDIO_MMC_FEATURE_DVD_PR_2_LAYER = 0x03B, /**< DVD+R Double Layer */ + CDIO_MMC_FEATURE_POWER_MGMT = 0x100, /**< Initiator and device directed + power management */ + CDIO_MMC_FEATURE_CDDA_EXT_PLAY = 0x103, /**< Ability to play audio CDs + via the Logical Unit's own + analog output */ + CDIO_MMC_FEATURE_MCODE_UPGRADE = 0x104, /* Ability for the device to + accept new microcode via + the interface */ + CDIO_MMC_FEATURE_TIME_OUT = 0x105, /**< Ability to respond to all + commands within a specific + time */ + CDIO_MMC_FEATURE_DVD_CSS = 0x106, /**< Ability to perform DVD + CSS/CPPM authentication and + RPC */ + CDIO_MMC_FEATURE_RT_STREAMING = 0x107, /**< Ability to read and write + using Initiator requested + performance parameters */ + CDIO_MMC_FEATURE_LU_SN = 0x108, /**< The Logical Unit has a unique + identifier. */ + CDIO_MMC_FEATURE_FIRMWARE_DATE = 0x1FF, /**< Firmware creation date + report */ +} cdio_mmc_feature_t; + +/** Profile profile codes used in GET_CONFIGURATION - PROFILE LIST. */ +typedef enum { + CDIO_MMC_FEATURE_PROF_NON_REMOVABLE = 0x0001, /**< Re-writable disk, capable + of changing behavior */ + CDIO_MMC_FEATURE_PROF_REMOVABLE = 0x0002, /**< disk Re-writable; with + removable media */ + CDIO_MMC_FEATURE_PROF_MO_ERASABLE = 0x0003, /**< Erasable Magneto-Optical + disk with sector erase + capability */ + CDIO_MMC_FEATURE_PROF_MO_WRITE_ONCE = 0x0004, /**< Write Once Magneto-Optical + write once */ + CDIO_MMC_FEATURE_PROF_AS_MO = 0x0005, /**< Advance Storage + Magneto-Optical */ + CDIO_MMC_FEATURE_PROF_CD_ROM = 0x0008, /**< Read only Compact Disc + capable */ + CDIO_MMC_FEATURE_PROF_CD_R = 0x0009, /**< Write once Compact Disc + capable */ + CDIO_MMC_FEATURE_PROF_CD_RW = 0x000A, /**< CD-RW Re-writable + Compact Disc capable */ + CDIO_MMC_FEATURE_PROF_DVD_ROM = 0x0010, /**< Read only DVD */ + CDIO_MMC_FEATURE_PROF_DVD_R_SEQ = 0x0011, /**< Re-recordable DVD using + Sequential recording */ + CDIO_MMC_FEATURE_PROF_DVD_RAM = 0x0012, /**< Re-writable DVD */ + CDIO_MMC_FEATURE_PROF_DVD_RW_RO = 0x0013, /**< Re-recordable DVD using + Restricted Overwrite */ + CDIO_MMC_FEATURE_PROF_DVD_RW_SEQ = 0x0014, /**< Re-recordable DVD using + Sequential recording */ + CDIO_MMC_FEATURE_PROF_DVD_PRW = 0x001A, /**< DVD+RW - DVD ReWritable */ + CDIO_MMC_FEATURE_PROF_DVD_PR = 0x001B, /**< DVD+R - DVD Recordable */ + CDIO_MMC_FEATURE_PROF_DDCD_ROM = 0x0020, /**< Read only DDCD */ + CDIO_MMC_FEATURE_PROF_DDCD_R = 0x0021, /**< DDCD-R Write only DDCD */ + CDIO_MMC_FEATURE_PROF_DDCD_RW = 0x0022, /**< Re-Write only DDCD */ + CDIO_MMC_FEATURE_PROF_DVD_PR2 = 0x002B, /**< DVD+R - DVD Recordable + double layer */ + CDIO_MMC_FEATURE_PROF_NON_CONFORM = 0xFFFF, /**< The Logical Unit does not + conform to any Profile. */ +} cdio_mmc_feature_profile_t; + +typedef enum { + CDIO_MMC_FEATURE_INTERFACE_UNSPECIFIED = 0, + CDIO_MMC_FEATURE_INTERFACE_SCSI = 1, + CDIO_MMC_FEATURE_INTERFACE_ATAPI = 2, + CDIO_MMC_FEATURE_INTERFACE_IEEE_1394 = 3, + CDIO_MMC_FEATURE_INTERFACE_IEEE_1394A = 4, + CDIO_MMC_FEATURE_INTERFACE_FIBRE_CH = 5 +} cdio_mmc_feature_interface_t; + + +/** The largest Command Descriptor Block (CDB) size. + The possible sizes are 6, 10, and 12 bytes. + */ +#define MAX_CDB_LEN 12 + +/** \brief A Command Descriptor Block (CDB) used in sending MMC + commands. + */ +typedef struct mmc_cdb_s { + uint8_t field[MAX_CDB_LEN]; +} mmc_cdb_t; + + /** \brief Format of header block in data returned from an MMC + GET_CONFIGURATION command. + */ + typedef struct mmc_feature_list_header_s { + unsigned char length_msb; + unsigned char length_1sb; + unsigned char length_2sb; + unsigned char length_lsb; + unsigned char reserved1; + unsigned char reserved2; + unsigned char profile_msb; + unsigned char profile_lsb; + } cdio_mmc_feature_list_header_t; + + /** An enumeration indicating whether an MMC command is sending + data or getting data. + */ + typedef enum mmc_direction_s { + SCSI_MMC_DATA_READ, + SCSI_MMC_DATA_WRITE + } cdio_mmc_direction_t; + + typedef struct mmc_subchannel_s + { + uint8_t reserved; + uint8_t audio_status; + uint16_t data_length; /**< Really ISO 9660 7.2.2 */ + uint8_t format; + uint8_t address: 4; + uint8_t control: 4; + uint8_t track; + uint8_t index; + uint8_t abs_addr[4]; + uint8_t rel_addr[4]; + } cdio_mmc_subchannel_t; + +#define CDIO_MMC_SET_COMMAND(cdb, command) \ + cdb[0] = command + +#define CDIO_MMC_SET_READ_TYPE(cdb, sector_type) \ + cdb[1] = (sector_type << 2) + +#define CDIO_MMC_GETPOS_LEN16(p, pos) \ + (p[pos]<<8) + p[pos+1] + +#define CDIO_MMC_GET_LEN16(p) \ + (p[0]<<8) + p[1] + +#define CDIO_MMC_GET_LEN32(p) \ + (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3]; + +#define CDIO_MMC_SET_LEN16(cdb, pos, len) \ + cdb[pos ] = (len >> 8) & 0xff; \ + cdb[pos+1] = (len ) & 0xff + +#define CDIO_MMC_SET_READ_LBA(cdb, lba) \ + cdb[2] = (lba >> 24) & 0xff; \ + cdb[3] = (lba >> 16) & 0xff; \ + cdb[4] = (lba >> 8) & 0xff; \ + cdb[5] = (lba ) & 0xff + +#define CDIO_MMC_SET_START_TRACK(cdb, command) \ + cdb[6] = command + +#define CDIO_MMC_SET_READ_LENGTH24(cdb, len) \ + cdb[6] = (len >> 16) & 0xff; \ + cdb[7] = (len >> 8) & 0xff; \ + cdb[8] = (len ) & 0xff + +#define CDIO_MMC_SET_READ_LENGTH16(cdb, len) \ + CDIO_MMC_SET_LEN16(cdb, 7, len) + +#define CDIO_MMC_SET_READ_LENGTH8(cdb, len) \ + cdb[8] = (len ) & 0xff + +#define CDIO_MMC_MCSB_ALL_HEADERS 0xf + +#define CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb, val) \ + cdb[9] = val << 3; + +/** + Read Audio Subchannel information + + @param p_cdio the CD object to be acted upon. + @param p_subchannel place for returned subchannel information +*/ +driver_return_code_t +mmc_audio_read_subchannel (CdIo_t *p_cdio, + /*out*/ cdio_subchannel_t *p_subchannel); + + /** + Return a string containing the name of the audio state as returned from + the Q_SUBCHANNEL. + */ + const char *mmc_audio_state2str( uint8_t i_audio_state ); + + /** + Eject using MMC commands. If CD-ROM is "locked" we'll unlock it. + Command is not "immediate" -- we'll wait for the command to complete. + For a more general (and lower-level) routine, @see mmc_start_stop_media. + */ + driver_return_code_t mmc_eject_media( const CdIo_t *p_cdio ); + + /** + Return a string containing the name of the given feature + */ + const char *mmc_feature2str( int i_feature ); + + /** + Return a string containing the name of the given feature + */ + const char *mmc_feature_profile2str( int i_feature_profile ); + + /** + Return the length in bytes of the Command Descriptor + Buffer (CDB) for a given MMC command. The length will be + either 6, 10, or 12. + */ + uint8_t mmc_get_cmd_len(uint8_t mmc_cmd); + + /** + Get the block size used in read requests, via MMC. + @return the blocksize if > 0; error if <= 0 + */ + int mmc_get_blocksize ( CdIo_t *p_cdio ); + + /** + * Close tray using a MMC START STOP command. + */ + driver_return_code_t mmc_close_tray( CdIo_t *p_cdio ); + + /** + Get the lsn of the end of the CD + + @return the lsn. On error return CDIO_INVALID_LSN. + */ + lsn_t mmc_get_disc_last_lsn( const CdIo_t *p_cdio ); + + /** + Return the discmode as reported by the MMC Read (FULL) TOC + command. + + Information was obtained from Section 5.1.13 (Read TOC/PMA/ATIP) + pages 56-62 from the MMC draft specification, revision 10a + at http://www.t10.org/ftp/t10/drafts/mmc/mmc-r10a.pdf See + especially tables 72, 73 and 75. + */ + discmode_t mmc_get_discmode( const CdIo_t *p_cdio ); + + + /** + Get drive capabilities for a device. + @return the drive capabilities. + */ + void mmc_get_drive_cap ( CdIo_t *p_cdio, + /*out*/ cdio_drive_read_cap_t *p_read_cap, + /*out*/ cdio_drive_write_cap_t *p_write_cap, + /*out*/ cdio_drive_misc_cap_t *p_misc_cap); + + typedef enum { + CDIO_MMC_LEVEL_WEIRD, + CDIO_MMC_LEVEL_1, + CDIO_MMC_LEVEL_2, + CDIO_MMC_LEVEL_3, + CDIO_MMC_LEVEL_NONE + } cdio_mmc_level_t; + + /** + Get the MMC level supported by the device. + */ + cdio_mmc_level_t mmc_get_drive_mmc_cap(CdIo_t *p_cdio); + + + /** + Get the DVD type associated with cd object. + + @return the DVD discmode. + */ + discmode_t mmc_get_dvd_struct_physical ( const CdIo_t *p_cdio, + cdio_dvd_struct_t *s); + + /*! + Return results of media status + @param p_cdio the CD object to be acted upon. + @param out_buf media status code from operation + @return DRIVER_OP_SUCCESS (0) if we got the status. + return codes are the same as driver_return_code_t + */ + int mmc_get_event_status(const CdIo_t *p_cdio, uint8_t out_buf[2]); + + /*! + Find out if media tray is open or closed. + @param p_cdio the CD object to be acted upon. + @return 1 if media is open, 0 if closed. Error + return codes are the same as driver_return_code_t + */ + int mmc_get_tray_status ( const CdIo_t *p_cdio ); + + /** + Get the CD-ROM hardware info via an MMC INQUIRY command. + + @return true if we were able to get hardware info, false if we had + an error. + */ + bool mmc_get_hwinfo ( const CdIo_t *p_cdio, + /* out*/ cdio_hwinfo_t *p_hw_info ); + + + /** + Find out if media has changed since the last call. + @param p_cdio the CD object to be acted upon. + @return 1 if media has changed since last call, 0 if not. Error + return codes are the same as driver_return_code_t + */ + int mmc_get_media_changed(const CdIo_t *p_cdio); + + /** + Get the media catalog number (MCN) from the CD via MMC. + + @return the media catalog number r NULL if there is none or we + don't have the ability to get it. + + Note: string is malloc'd so caller has to free() the returned + string when done with it. + + */ + char * mmc_get_mcn ( const CdIo_t *p_cdio ); + + /** Get the output port volumes and port selections used on AUDIO PLAY + commands via a MMC MODE SENSE command using the CD Audio Control + Page. + */ + driver_return_code_t mmc_audio_get_volume (CdIo_t *p_cdio, /*out*/ + mmc_audio_volume_t *p_volume); + + /** + Report if CD-ROM has a praticular kind of interface (ATAPI, SCSCI, ...) + Is it possible for an interface to have serveral? If not this + routine could probably return the single mmc_feature_interface_t. + @return true if we have the interface and false if not. + */ + bool_3way_t mmc_have_interface( CdIo_t *p_cdio, + cdio_mmc_feature_interface_t e_interface ); + + /** Run a MODE_SENSE command (6- or 10-byte version) + and put the results in p_buf + @return DRIVER_OP_SUCCESS if we ran the command ok. + */ + int mmc_mode_sense( CdIo_t *p_cdio, /*out*/ void *p_buf, int i_size, + int page); + + + /** Run a MODE_SENSE command (10-byte version) + and put the results in p_buf + @return DRIVER_OP_SUCCESS if we ran the command ok. + */ + int mmc_mode_sense_10( CdIo_t *p_cdio, /*out*/ void *p_buf, int i_size, + int page); + + /** Run a MODE_SENSE command (6-byte version) + and put the results in p_buf + @return DRIVER_OP_SUCCESS if we ran the command ok. + */ + int mmc_mode_sense_6( CdIo_t *p_cdio, /*out*/ void *p_buf, int i_size, + int page); + + /** Issue a MMC READ_CD command. + + @param p_cdio object to read from + + @param p_buf Place to store data. The caller should ensure that + p_buf can hold at least i_blocksize * i_blocks bytes. + + @param i_lsn sector to read + + @param expected_sector_type restricts reading to a specific CD + sector type. Only 3 bits with values 1-5 are used: + 0 all sector types + 1 CD-DA sectors only + 2 Mode 1 sectors only + 3 Mode 2 formless sectors only. Note in contrast to all other + values an MMC CD-ROM is not required to support this mode. + 4 Mode 2 Form 1 sectors only + 5 Mode 2 Form 2 sectors only + + @param b_digital_audio_play Control error concealment when the + data being read is CD-DA. If the data being read is not CD-DA, + this parameter is ignored. If the data being read is CD-DA and + DAP is false zero, then the user data returned should not be + modified by flaw obscuring mechanisms such as audio data mute and + interpolate. If the data being read is CD-DA and DAP is true, + then the user data returned should be modified by flaw obscuring + mechanisms such as audio data mute and interpolate. + + b_sync_header return the sync header (which will probably have + the same value as CDIO_SECTOR_SYNC_HEADER of size + CDIO_CD_SYNC_SIZE). + + @param header_codes Header Codes refer to the sector header and + the sub-header that is present in mode 2 formed sectors: + + 0 No header information is returned. + 1 The 4-byte sector header of data sectors is be returned, + 2 The 8-byte sector sub-header of mode 2 formed sectors is + returned. + 3 Both sector header and sub-header (12 bytes) is returned. + The Header preceeds the rest of the bytes (e.g. user-data bytes) + that might get returned. + + @param b_user_data Return user data if true. + + For CD-DA, the User Data is CDIO_CD_FRAMESIZE_RAW bytes. + + For Mode 1, The User Data is ISO_BLOCKSIZE bytes beginning at + offset CDIO_CD_HEADER_SIZE+CDIO_CD_SUBHEADER_SIZE. + + For Mode 2 formless, The User Data is M2RAW_SECTOR_SIZE bytes + beginning at offset CDIO_CD_HEADER_SIZE+CDIO_CD_SUBHEADER_SIZE. + + For data Mode 2, form 1, User Data is ISO_BLOCKSIZE bytes beginning at + offset CDIO_CD_XA_SYNC_HEADER. + + For data Mode 2, form 2, User Data is 2 324 bytes beginning at + offset CDIO_CD_XA_SYNC_HEADER. + + @param b_sync + + @param b_edc_ecc true if we return EDC/ECC error detection/correction bits. + + The presence and size of EDC redundancy or ECC parity is defined + according to sector type: + + CD-DA sectors have neither EDC redundancy nor ECC parity. + + Data Mode 1 sectors have 288 bytes of EDC redundancy, Pad, and + ECC parity beginning at offset 2064. + + Data Mode 2 formless sectors have neither EDC redundancy nor ECC + parity + + Data Mode 2 form 1 sectors have 280 bytes of EDC redundancy and + ECC parity beginning at offset 2072 + + Data Mode 2 form 2 sectors optionally have 4 bytes of EDC + redundancy beginning at offset 2348. + + + @param c2_error_information If true associate a bit with each + sector for C2 error The resulting bit field is ordered exactly as + the main channel bytes. Each 8-bit boundary defines a byte of + flag bits. + + @param subchannel_selection subchannel-selection bits + + 0 No Sub-channel data shall be returned. (0 bytes) + 1 RAW P-W Sub-channel data shall be returned. (96 byte) + 2 Formatted Q sub-channel data shall be transferred (16 bytes) + 3 Reserved + 4 Corrected and de-interleaved R-W sub-channel (96 bytes) + 5-7 Reserved + + @param i_blocksize size of the a block expected to be returned + + @param i_blocks number of blocks expected to be returned. + + */ + driver_return_code_t + mmc_read_cd ( const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, + int expected_sector_type, bool b_digital_audio_play, + bool b_sync, uint8_t header_codes, bool b_user_data, + bool b_edc_ecc, uint8_t c2_error_information, + uint8_t subchannel_selection, uint16_t i_blocksize, + uint32_t i_blocks ); + + /** Read just the user data part of some sort of data sector (via + mmc_read_cd). + + @param p_cdio object to read from + + @param p_buf place to read data into. The caller should make sure + this location can store at least CDIO_CD_FRAMESIZE, + M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE depending on + the kind of sector getting read. If you don't know + whether you have a Mode 1/2, Form 1/ Form 2/Formless + sector best to reserve space for the maximum, + M2RAW_SECTOR_SIZE. + + @param i_lsn sector to read + @param i_blocksize size of each block + @param i_blocks number of blocks to read + + */ + driver_return_code_t mmc_read_data_sectors ( CdIo_t *p_cdio, void *p_buf, + lsn_t i_lsn, + uint16_t i_blocksize, + uint32_t i_blocks ); + + /** Read sectors using SCSI-MMC GPCMD_READ_CD. + Can read only up to 25 blocks. + */ + driver_return_code_t mmc_read_sectors ( const CdIo_t *p_cdio, void *p_buf, + lsn_t i_lsn, int read_sector_type, + uint32_t i_blocks); + + /** + Run a Multimedia command (MMC). + + @param p_cdio CD structure set by cdio_open(). + @param i_timeout_ms time in milliseconds we will wait for the command + to complete. + @param p_cdb CDB bytes. All values that are needed should be set + on input. We'll figure out what the right CDB length + should be. + @param e_direction direction the transfer is to go. + @param i_buf Size of buffer + @param p_buf Buffer for data, both sending and receiving. + + @return 0 if command completed successfully. + */ + driver_return_code_t + mmc_run_cmd( const CdIo_t *p_cdio, unsigned int i_timeout_ms, + const mmc_cdb_t *p_cdb, + cdio_mmc_direction_t e_direction, unsigned int i_buf, + /*in/out*/ void *p_buf ); + + /** + Run a Multimedia command (MMC) specifying the CDB length. + The motivation here is for example ot use in is an undocumented + debug command for LG drives (namely E7), whose length is being + miscalculated by mmc_get_cmd_len(); it doesn't follow the usual + code number to length conventions. Patch supplied by SukkoPera. + + @param p_cdio CD structure set by cdio_open(). + @param i_timeout_ms time in milliseconds we will wait for the command + to complete. + @param p_cdb CDB bytes. All values that are needed should be set + on input. + @param i_cdb number of CDB bytes. + @param e_direction direction the transfer is to go. + @param i_buf Size of buffer + @param p_buf Buffer for data, both sending and receiving. + + @return 0 if command completed successfully. + */ + driver_return_code_t + mmc_run_cmd_len( const CdIo_t *p_cdio, unsigned int i_timeout_ms, + const mmc_cdb_t *p_cdb, unsigned int i_cdb, + cdio_mmc_direction_t e_direction, unsigned int i_buf, + /*in/out*/ void *p_buf ); + + /** + Set the block size for subsequest read requests, via MMC. + */ + driver_return_code_t mmc_set_blocksize ( const CdIo_t *p_cdio, + uint16_t i_blocksize); + + /** + Set the drive speed in CD-ROM speed units. + + @param p_cdio CD structure set by cdio_open(). + @param i_drive_speed speed in CD-ROM speed units. Note this + not Kbs as would be used in the MMC spec or + in mmc_set_speed(). To convert CD-ROM speed units + to Kbs, multiply the number by 176 (for raw data) + and by 150 (for filesystem data). On many CD-ROM + drives, specifying a value too large will result + in using the fastest speed. + + @return the drive speed if greater than 0. -1 if we had an error. is -2 + returned if this is not implemented for the current driver. + + @see cdio_set_speed and mmc_set_speed + */ + driver_return_code_t mmc_set_drive_speed( const CdIo_t *p_cdio, + int i_drive_speed ); + + /** + Set the drive speed in K bytes per second. + + @param p_cdio CD structure set by cdio_open(). + @param i_Kbs_speed speed in K bytes per second. Note this is + not in standard CD-ROM speed units, e.g. + 1x, 4x, 16x as it is in cdio_set_speed. + To convert CD-ROM speed units to Kbs, + multiply the number by 176 (for raw data) + and by 150 (for filesystem data). + Also note that ATAPI specs say that a value + less than 176 will result in an error. + On many CD-ROM drives, + specifying a value too large will result in using + the fastest speed. + + @return the drive speed if greater than 0. -1 if we had an error. is -2 + returned if this is not implemented for the current driver. + + @see cdio_set_speed and mmc_set_drive_speed + */ + driver_return_code_t mmc_set_speed( const CdIo_t *p_cdio, + int i_Kbs_speed ); + + /** + Load or Unload media using a MMC START STOP command. + + @param p_cdio the CD object to be acted upon. + @param b_eject eject if true and close tray if false + @param b_immediate wait or don't wait for operation to complete + @param power_condition Set CD-ROM to idle/standby/sleep. If nonzero + eject/load is ignored, so set to 0 if you want to eject or load. + + @see mmc_eject_media or mmc_close_tray + */ + driver_return_code_t + mmc_start_stop_media(const CdIo_t *p_cdio, bool b_eject, bool b_immediate, + uint8_t power_condition); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/** The below variables are trickery to force the above enum symbol + values to be recorded in debug symbol tables. They are used to + allow one to refer to the enumeration value names in the typedefs + above in a debugger and debugger expressions +*/ +extern cdio_mmc_feature_t debug_cdio_mmc_feature; +extern cdio_mmc_feature_interface_t debug_cdio_mmc_feature_interface; +extern cdio_mmc_feature_profile_t debug_cdio_mmc_feature_profile; +extern cdio_mmc_get_conf_t debug_cdio_mmc_get_conf; +extern cdio_mmc_gpcmd_t debug_cdio_mmc_gpcmd; +extern cdio_mmc_read_sub_state_t debug_cdio_mmc_read_sub_state; +extern cdio_mmc_read_cd_type_t debug_cdio_mmc_read_cd_type; +extern cdio_mmc_readtoc_t debug_cdio_mmc_readtoc; +extern cdio_mmc_mode_page_t debug_cdio_mmc_mode_page; + +#endif /* __MMC_H__ */ + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/cdio/paranoia.h b/include/cdio/paranoia.h new file mode 100644 index 00000000..02b50002 --- /dev/null +++ b/include/cdio/paranoia.h @@ -0,0 +1,202 @@ +/* + $Id: paranoia.h,v 1.15 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2004, 2005, 2006, 2007, 2008 Rocky Bernstein <rocky@gnu.org> + Copyright (C) 1998 Monty xiphmont@mit.edu + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** \file paranoia.h + * + * \brief The top-level header for libcdda_paranoia: a device- and OS- + * independent library for reading CD-DA with error tolerance and + * repair. Applications include this for paranoia access. + */ + +#ifndef _CDIO_PARANOIA_H_ +#define _CDIO_PARANOIA_H_ + +#include <cdio/cdda.h> + +/*! Paranoia likes to work with 16-bit numbers rather than + (possibly byte-swapped) bytes. So there are this many + 16-bit numbers block (frame, or sector) read. +*/ +#define CD_FRAMEWORDS (CDIO_CD_FRAMESIZE_RAW/2) + +/** + Flags used in paranoia_modeset. + + The enumeration type one probably wouldn't really use in a program. + It is here instead of defines to give symbolic names that can be + helpful in debuggers where wants just to say refer to + PARANOIA_MODE_DISABLE and get the correct value. +*/ + +typedef enum { + PARANOIA_MODE_DISABLE = 0x00, /**< No fixups */ + PARANOIA_MODE_VERIFY = 0x01, /**< Verify data integrety in overlap area*/ + PARANOIA_MODE_FRAGMENT = 0x02, /**< unsupported */ + PARANOIA_MODE_OVERLAP = 0x04, /**< Perform overlapped reads */ + PARANOIA_MODE_SCRATCH = 0x08, /**< unsupported */ + PARANOIA_MODE_REPAIR = 0x10, /**< unsupported */ + PARANOIA_MODE_NEVERSKIP = 0x20, /**< Do not skip failed reads (retry + maxretries) */ + PARANOIA_MODE_FULL = 0xff, /**< Maximum paranoia - all of the above + (except disable) */ +} paranoia_mode_t; + + +/** + Flags set in a callback. + + The enumeration type one probably wouldn't really use in a program. + It is here instead of defines to give symbolic names that can be + helpful in debuggers where wants just to say refer to + PARANOIA_CB_READ and get the correct value. +*/ +typedef enum { + PARANOIA_CB_READ, /**< Read off adjust ??? */ + PARANOIA_CB_VERIFY, /**< Verifying jitter */ + PARANOIA_CB_FIXUP_EDGE, /**< Fixed edge jitter */ + PARANOIA_CB_FIXUP_ATOM, /**< Fixed atom jitter */ + PARANOIA_CB_SCRATCH, /**< Unsupported */ + PARANOIA_CB_REPAIR, /**< Unsupported */ + PARANOIA_CB_SKIP, /**< Skip exhausted retry */ + PARANOIA_CB_DRIFT, /**< Skip exhausted retry */ + PARANOIA_CB_BACKOFF, /**< Unsupported */ + PARANOIA_CB_OVERLAP, /**< Dynamic overlap adjust */ + PARANOIA_CB_FIXUP_DROPPED, /**< Fixed dropped bytes */ + PARANOIA_CB_FIXUP_DUPED, /**< Fixed duplicate bytes */ + PARANOIA_CB_READERR /**< Hard read error */ +} paranoia_cb_mode_t; + + extern const char *paranoia_cb_mode2str[]; + +#ifdef __cplusplus +extern "C" { +#endif + + /*! + Get and initialize a new cdrom_paranoia object from cdrom_drive. + Run this before calling any of the other paranoia routines below. + + @return new cdrom_paranoia object Call paranoia_free() when you are + done with it + */ + extern cdrom_paranoia_t *cdio_paranoia_init(cdrom_drive_t *d); + + /*! + Free any resources associated with p. + + @param p paranoia object to for which resources are to be freed. + + @see paranoia_init. + */ + extern void cdio_paranoia_free(cdrom_paranoia_t *p); + + /*! + Set the kind of repair you want to on for reading. + The modes are listed above + + @param p paranoia type + @param mode_flags paranoia mode flags built from values in + paranoia_mode_t, e.g. + PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP + */ + extern void cdio_paranoia_modeset(cdrom_paranoia_t *p, int mode_flags); + + /*! + reposition reading offset. + + @param p paranoia type + @param seek byte offset to seek to + @param whence like corresponding parameter in libc's lseek, e.g. + SEEK_SET or SEEK_END. + */ + extern lsn_t cdio_paranoia_seek(cdrom_paranoia_t *p, off_t seek, int whence); + + /*! + Reads the next sector of audio data and returns a pointer to a full + sector of verified samples. + + @param p paranoia object. + + @param callback callback routine which gets called with the status + on each read. + + @return the audio data read, CDIO_CD_FRAMESIZE_RAW (2352) + bytes. This data is not to be freed by the caller. It will persist + only until the next call to paranoia_read() for this p. + */ + extern int16_t *cdio_paranoia_read(cdrom_paranoia_t *p, + void(*callback)(long int, + paranoia_cb_mode_t)); + + /*! The same as cdio_paranoia_read but the number of retries is set. + @param p paranoia object. + + @param callback callback routine which gets called with the status + on each read. + + @param max_retries number of times to try re-reading a block before + failing. + + @return the block of CDIO_FRAMEIZE_RAW bytes (or + CDIO_FRAMESIZE_RAW / 2 16-bit integers). Unless byte-swapping has + been turned off the 16-bit integers Endian independent order. + + @see cdio_paranoia_read. + + */ + extern int16_t *cdio_paranoia_read_limited(cdrom_paranoia_t *p, + void(*callback)(long int, + paranoia_cb_mode_t), + int max_retries); + + +/*! a temporary hack */ + extern void cdio_paranoia_overlapset(cdrom_paranoia_t *p,long overlap); + + extern void cdio_paranoia_set_range(cdrom_paranoia_t *p, long int start, + long int end); + +#ifndef DO_NOT_WANT_PARANOIA_COMPATIBILITY +/** For compatibility with good ol' paranoia */ +#define cdrom_paranoia cdrom_paranoia_t +#define paranoia_init cdio_paranoia_init +#define paranoia_free cdio_paranoia_free +#define paranoia_modeset cdio_paranoia_modeset +#define paranoia_seek cdio_paranoia_seek +#define paranoia_read cdio_paranoia_read +#define paranoia_read_limited cdio_paranoia_read_limited +#define paranoia_overlapset cdio_paranoia_overlapset +#define paranoia_set_range cdio_paranoia_set_range +#endif /*DO_NOT_WANT_PARANOIA_COMPATIBILITY*/ + +#ifdef __cplusplus +} +#endif + +/** The below variables are trickery to force the above enum symbol + values to be recorded in debug symbol tables. They are used to + allow one to refer to the enumeration value names in the typedefs + above in a debugger and debugger expressions +*/ + +extern paranoia_mode_t debug_paranoia_mode; +extern paranoia_cb_mode_t debug_paranoia_cb_mode; + +#endif /*_CDIO_PARANOIA_H_*/ diff --git a/include/cdio/posix.h b/include/cdio/posix.h new file mode 100644 index 00000000..89e0ad37 --- /dev/null +++ b/include/cdio/posix.h @@ -0,0 +1,43 @@ +/* + $Id: posix.h,v 1.2 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2005, 2008 Rocky Bernstein <rocky@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ +/*! + * \file posix.h + * + * \brief various POSIX definitions. +*/ + +#ifndef __CDIO_POSIX_H__ +#define __CDIO_POSIX_H__ + +typedef uint32_t posix_mode_t; +typedef uint32_t posix_nlink_t; +typedef uint32_t posix_uid_t; +typedef uint32_t posix_gid_t; +typedef uint16_t unicode16_t; + +#endif /* __CDIO_POSIX_H__ */ + + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/cdio/read.h b/include/cdio/read.h new file mode 100644 index 00000000..81e5148a --- /dev/null +++ b/include/cdio/read.h @@ -0,0 +1,235 @@ +/* + $Id: read.h,v 1.15 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2005, 2006, 2007, 2008 Rocky Bernstein <rocky@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** \file read.h + * + * \brief The top-level header for sector (block, frame)-related + * libcdio calls. + */ + +#ifndef __CDIO_READ_H__ +#define __CDIO_READ_H__ + +#ifndef EXTERNAL_LIBCDIO_CONFIG_H +#define EXTERNAL_LIBCDIO_CONFIG_H +/* Need for HAVE_SYS_TYPES_H */ +#include <cdio/cdio_config.h> +#endif + +#ifdef HAVE_SYS_TYPES_H +/* Some systems need this for off_t and ssize. */ +#include <sys/types.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /** All the different ways a block/sector can be read. */ + typedef enum { + CDIO_READ_MODE_AUDIO, /**< CD-DA, audio, Red Book */ + CDIO_READ_MODE_M1F1, /**< Mode 1 Form 1 */ + CDIO_READ_MODE_M1F2, /**< Mode 1 Form 2 */ + CDIO_READ_MODE_M2F1, /**< Mode 2 Form 1 */ + CDIO_READ_MODE_M2F2 /**< Mode 2 Form 2 */ + } cdio_read_mode_t; + + /*! + Reposition read offset + Similar to (if not the same as) libc's fseek() + + @param p_cdio object which gets adjusted + @param offset amount to seek + @param whence like corresponding parameter in libc's fseek, e.g. + SEEK_SET or SEEK_END. + @return (off_t) -1 on error. + */ + + off_t cdio_lseek(const CdIo_t *p_cdio, off_t offset, int whence); + + /*! Reads into buf the next size bytes. Similar to (if not the + same as) libc's read(). This is a "cooked" read, or one handled by + the OS. It probably won't work on audio data. For that use + cdio_read_audio_sector(s). + + @param p_cdio object to read from + @param p_buf place to read data into. The caller should make sure + this location can store at least i_size bytes. + @param i_size number of bytes to read + + @return (ssize_t) -1 on error. + */ + ssize_t cdio_read(const CdIo_t *p_cdio, void *p_buf, size_t i_size); + + /*! + Read an audio sector + + @param p_cdio object to read from + @param p_buf place to read data into. The caller should make sure + this location can store at least CDIO_FRAMESIZE_RAW + bytes. + @param i_lsn sector to read + */ + driver_return_code_t cdio_read_audio_sector (const CdIo_t *p_cdio, + void *p_buf, lsn_t i_lsn); + + /*! + Reads audio sectors + + @param p_cdio object to read from + @param p_buf place to read data into. The caller should make sure + this location can store at least CDIO_FRAMESIZE_RAW + * i_blocks bytes. + @param i_lsn sector to read + @param i_blocks number of sectors to read + */ + driver_return_code_t cdio_read_audio_sectors (const CdIo_t *p_cdio, + void *p_buf, lsn_t i_lsn, + uint32_t i_blocks); + + /*! + Read data sectors + + @param p_cdio object to read from + @param p_buf place to read data into. The caller should make sure + this location can store at least ISO_BLOCKSIZE, + M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE depending + on the kind of sector getting read. If you don't + know whether you have a Mode 1/2, Form 1/ Form 2/Formless + sector best to reserve space for the maximum, + M2RAW_SECTOR_SIZE. + @param i_lsn sector to read + @param i_blocksize size of block. Should be either CDIO_CD_FRAMESIZE, + M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE. See comment above under p_buf. + + @param i_blocks number of blocks to read + */ + driver_return_code_t cdio_read_data_sectors ( const CdIo_t *p_cdio, + void *p_buf, lsn_t i_lsn, + uint16_t i_blocksize, + uint32_t i_blocks ); + /*! + Reads a mode 1 sector + + @param p_cdio object to read from + @param p_buf place to read data into. + @param i_lsn sector to read + @param b_form2 true for reading mode 1 form 2 sectors or false for + mode 1 form 1 sectors. + */ + driver_return_code_t cdio_read_mode1_sector (const CdIo_t *p_cdio, + void *p_buf, lsn_t i_lsn, + bool b_form2); + /*! + Reads mode 1 sectors + + @param p_cdio object to read from + @param p_buf place to read data into + @param i_lsn sector to read + @param b_form2 true for reading mode 1 form 2 sectors or false for + mode 1 form 1 sectors. + @param i_blocks number of sectors to read + */ + driver_return_code_t cdio_read_mode1_sectors (const CdIo_t *p_cdio, + void *p_buf, lsn_t i_lsn, + bool b_form2, + uint32_t i_blocks); + /*! + Reads a mode 2 sector + + @param p_cdio object to read from + @param p_buf place to read data into. The caller should make sure + this location can store at least + M2RAW_SECTOR_SIZE (for form 1) or CDIO_CD_FRAMESIZE (for + form 2) bytes. + @param i_lsn sector to read + @param b_form2 true for reading mode 2 form 2 sectors or false for + mode 2 form 1 sectors. + + @return 0 if no error, nonzero otherwise. + */ + driver_return_code_t cdio_read_mode2_sector (const CdIo_t *p_cdio, + void *p_buf, lsn_t i_lsn, + bool b_form2); + + /** The special case of reading a single block is a common one so we + provide a routine for that as a convenience. + */ + driver_return_code_t cdio_read_sector(const CdIo_t *p_cdio, void *p_buf, + lsn_t i_lsn, + cdio_read_mode_t read_mode); + /*! + Reads mode 2 sectors + + @param p_cdio object to read from + @param p_buf place to read data into. The caller should make sure + this location can store at least + M2RAW_SECTOR_SIZE (for form 1) or CDIO_CD_FRAMESIZE (for + form 2) * i_blocks bytes. + @param i_lsn sector to read + @param b_form2 true for reading mode2 form 2 sectors or false for + mode 2 form 1 sectors. + @param i_blocks number of sectors to read + + @return 0 if no error, nonzero otherwise. + */ + driver_return_code_t cdio_read_mode2_sectors (const CdIo_t *p_cdio, + void *p_buf, lsn_t i_lsn, + bool b_form2, + uint32_t i_blocks); + + /*! + Reads a number of sectors (AKA blocks). + + @param p_cdio cdio object + @param p_buf place to read data into. The caller should make sure + this location is large enough. See below for size information. + @param read_mode the kind of "mode" to use in reading. + @param i_lsn sector to read + @param i_blocks number of sectors to read + @return DRIVER_OP_SUCCESS (0) if no error, other (negative) enumerations + are returned on error. + + If read_mode is CDIO_MODE_AUDIO, + *p_buf should hold at least CDIO_FRAMESIZE_RAW * i_blocks bytes. + + If read_mode is CDIO_MODE_DATA, + *p_buf should hold at least i_blocks times either ISO_BLOCKSIZE, + M1RAW_SECTOR_SIZE or M2F2_SECTOR_SIZE depending on the kind of + sector getting read. If you don't know whether you have a Mode 1/2, + Form 1/ Form 2/Formless sector best to reserve space for the maximum + which is M2RAW_SECTOR_SIZE. + + If read_mode is CDIO_MODE_M2F1, + *p_buf should hold at least M2RAW_SECTOR_SIZE * i_blocks bytes. + + If read_mode is CDIO_MODE_M2F2, + *p_buf should hold at least CDIO_CD_FRAMESIZE * i_blocks bytes. + + */ + driver_return_code_t cdio_read_sectors(const CdIo_t *p_cdio, void *p_buf, + lsn_t i_lsn, + cdio_read_mode_t read_mode, + uint32_t i_blocks); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CDIO_TRACK_H__ */ diff --git a/include/cdio/rock.h b/include/cdio/rock.h new file mode 100644 index 00000000..57003276 --- /dev/null +++ b/include/cdio/rock.h @@ -0,0 +1,396 @@ +/* + $Id: rock.h,v 1.15 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2005, 2006 2008 Rocky Bernstein <rocky@panix.com> + + See also rock.c by Eric Youngdale (1993) from GNU/Linux + This is Copyright 1993 Yggdrasil Computing, Incorporated + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ +/*! + \file rock.h + \brief Things related to the Rock Ridge Interchange Protocol (RRIP) + + Applications will probably not include this directly but via + the iso9660.h header. +*/ + + +#ifndef __CDIO_ROCK_H__ +#define __CDIO_ROCK_H__ + +#include <cdio/types.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* MSYS 1.0.10 with MinGW 3.4.2 (and perhaps others) don't have + S_ISSOCK() or S_ISLNK() macros, so we'll roll our own. */ +#if !defined(HAVE_S_ISSOCK) && !defined(S_ISSOCK) +#define S_ISSOCK(st_mode) ((((st_mode)) & 0170000) == (0140000)) +#endif + +#if !defined(HAVE_S_ISLNK) && !defined(S_ISLNK) +#define S_ISLNK(st_mode) ((((st_mode)) & 0170000) == (0010000)) +#endif + +/*! An enumeration for some of the ISO_ROCK_* \#defines below. This isn't + really an enumeration one would really use in a program it is to + be helpful in debuggers where wants just to refer to the ISO_ROCK_* + names and get something. +*/ +extern enum iso_rock_enums { + ISO_ROCK_IRUSR = 000400, /**< read permission (owner) */ + ISO_ROCK_IWUSR = 000200, /**< write permission (owner) */ + ISO_ROCK_IXUSR = 000100, /**< execute permission (owner) */ + ISO_ROCK_IRGRP = 000040, /**< read permission (group) */ + ISO_ROCK_IWGRP = 000020, /**< write permission (group) */ + ISO_ROCK_IXGRP = 000010, /**< execute permission (group) */ + ISO_ROCK_IROTH = 000004, /**< read permission (other) */ + ISO_ROCK_IWOTH = 000002, /**< write permission (other) */ + ISO_ROCK_IXOTH = 000001, /**< execute permission (other) */ + + ISO_ROCK_ISUID = 004000, /**< set user ID on execution */ + ISO_ROCK_ISGID = 002000, /**< set group ID on execution */ + ISO_ROCK_ISVTX = 001000, /**< save swapped text even after use */ + + ISO_ROCK_ISSOCK = 0140000, /**< socket */ + ISO_ROCK_ISLNK = 0120000, /**< symbolic link */ + ISO_ROCK_ISREG = 0100000, /**< regular */ + ISO_ROCK_ISBLK = 060000, /**< block special */ + ISO_ROCK_ISCHR = 020000, /**< character special */ + ISO_ROCK_ISDIR = 040000, /**< directory */ + ISO_ROCK_ISFIFO = 010000 /**< pipe or FIFO */ +} iso_rock_enums; + +#define ISO_ROCK_IRUSR 000400 /** read permission (owner) */ +#define ISO_ROCK_IWUSR 000200 /** write permission (owner) */ +#define ISO_ROCK_IXUSR 000100 /** execute permission (owner) */ +#define ISO_ROCK_IRGRP 000040 /** read permission (group) */ +#define ISO_ROCK_IWGRP 000020 /** write permission (group) */ +#define ISO_ROCK_IXGRP 000010 /** execute permission (group) */ +#define ISO_ROCK_IROTH 000004 /** read permission (other) */ +#define ISO_ROCK_IWOTH 000002 /** write permission (other) */ +#define ISO_ROCK_IXOTH 000001 /** execute permission (other) */ + +#define ISO_ROCK_ISUID 004000 /** set user ID on execution */ +#define ISO_ROCK_ISGID 002000 /** set group ID on execution */ +#define ISO_ROCK_ISVTX 001000 /** save swapped text even after use */ + +#define ISO_ROCK_ISSOCK 0140000 /** socket */ +#define ISO_ROCK_ISLNK 0120000 /** symbolic link */ +#define ISO_ROCK_ISREG 0100000 /** regular */ +#define ISO_ROCK_ISBLK 060000 /** block special */ +#define ISO_ROCK_ISCHR 020000 /** character special */ +#define ISO_ROCK_ISDIR 040000 /** directory */ +#define ISO_ROCK_ISFIFO 010000 /** pipe or FIFO */ + +/** Enforced file locking (shared w/set group ID) */ +#define ISO_ROCK_ENFMT ISO_ROCK_ISGID + +PRAGMA_BEGIN_PACKED + +/*! The next two structs are used by the system-use-sharing protocol + (SUSP), in which the Rock Ridge extensions are embedded. It is + quite possible that other extensions are present on the disk, and + this is fine as long as they all use SUSP. */ + +/*! system-use-sharing protocol */ +typedef struct iso_su_sp_s{ + unsigned char magic[2]; + uint8_t skip; +} GNUC_PACKED iso_su_sp_t; + +/*! system-use extension record */ +typedef struct iso_su_er_s { + iso711_t len_id; /**< Identifier length. Value 10?. */ + unsigned char len_des; + unsigned char len_src; + iso711_t ext_ver; /**< Extension version. Value 1? */ + char data[EMPTY_ARRAY_SIZE]; +} GNUC_PACKED iso_su_er_t; + +typedef struct iso_su_ce_s { + char extent[8]; + char offset[8]; + char size[8]; +} iso_su_ce_t; + +/*! POSIX file attributes, PX. See Rock Ridge Section 4.1.2 */ +typedef struct iso_rock_px_s { + iso733_t st_mode; /*! file mode permissions; same as st_mode + of POSIX:5.6.1 */ + iso733_t st_nlinks; /*! number of links to file; same as st_nlinks + of POSIX:5.6.1 */ + iso733_t st_uid; /*! user id owner of file; same as st_uid + of POSIX:5.6.1 */ + iso733_t st_gid; /*! group id of file; same as st_gid of + of POSIX:5.6.1 */ +} GNUC_PACKED iso_rock_px_t ; + +/*! POSIX device number, PN. A PN is mandatory if the file type + recorded in the "PX" File Mode field for a Directory Record + indicates a character or block device (ISO_ROCK_ISCHR | + ISO_ROCK_ISBLK). This entry is ignored for other (non-Direcotry) + file types. No more than one "PN" is recorded in the System Use Area + of a Directory Record. + + See Rock Ridge Section 4.1.2 */ +typedef struct iso_rock_pn_s { + iso733_t dev_high; /**< high-order 32 bits of the 64 bit device number. + 7.2.3 encoded */ + iso733_t dev_low; /**< low-order 32 bits of the 64 bit device number. + 7.2.3 encoded */ +} GNUC_PACKED iso_rock_pn_t ; + +/*! These are the bits and their meanings for flags in the SL structure. */ +typedef enum { + ISO_ROCK_SL_CONTINUE = 1, + ISO_ROCK_SL_CURRENT = 2, + ISO_ROCK_SL_PARENT = 4, + ISO_ROCK_SL_ROOT = 8 +} iso_rock_sl_flag_t; + +#define ISO_ROCK_SL_CONTINUE 1 +#define ISO_ROCK_SL_CURRENT 2 +#define ISO_ROCK_SL_PARENT 4 +#define ISO_ROCK_SL_ROOT 8 + +typedef struct iso_rock_sl_part_s { + uint8_t flags; + uint8_t len; + char text[EMPTY_ARRAY_SIZE]; +} GNUC_PACKED iso_rock_sl_part_t ; + +/*! Symbolic link. See Rock Ridge Section 4.1.3 */ +typedef struct iso_rock_sl_s { + unsigned char flags; + iso_rock_sl_part_t link; +} GNUC_PACKED iso_rock_sl_t ; + +/*! Alternate name. See Rock Ridge Section 4.1.4 */ + +/*! These are the bits and their meanings for flags in the NM structure. */ +typedef enum { + ISO_ROCK_NM_CONTINUE = 1, + ISO_ROCK_NM_CURRENT = 2, + ISO_ROCK_NM_PARENT = 4, +} iso_rock_nm_flag_t; + +#define ISO_ROCK_NM_CONTINUE 1 +#define ISO_ROCK_NM_CURRENT 2 +#define ISO_ROCK_NM_PARENT 4 + + +typedef struct iso_rock_nm_s { + unsigned char flags; + char name[EMPTY_ARRAY_SIZE]; +} GNUC_PACKED iso_rock_nm_t ; + +/*! Child link. See Section 4.1.5.1 */ +typedef struct iso_rock_cl_s { + char location[1]; +} GNUC_PACKED iso_rock_cl_t ; + +/*! Parent link. See Section 4.1.5.2 */ +typedef struct iso_rock_pl_s { + char location[1]; +} GNUC_PACKED iso_rock_pl_t ; + +/*! These are the bits and their meanings for flags in the TF structure. */ +typedef enum { + ISO_ROCK_TF_CREATE = 1, + ISO_ROCK_TF_MODIFY = 2, + ISO_ROCK_TF_ACCESS = 4, + ISO_ROCK_TF_ATTRIBUTES = 8, + ISO_ROCK_TF_BACKUP = 16, + ISO_ROCK_TF_EXPIRATION = 32, + ISO_ROCK_TF_EFFECTIVE = 64, + ISO_ROCK_TF_LONG_FORM = 128 +} iso_rock_tf_flag_t; + +/* These are the bits and their meanings for flags in the TF structure. */ +#define ISO_ROCK_TF_CREATE 1 +#define ISO_ROCK_TF_MODIFY 2 +#define ISO_ROCK_TF_ACCESS 4 +#define ISO_ROCK_TF_ATTRIBUTES 8 +#define ISO_ROCK_TF_BACKUP 16 +#define ISO_ROCK_TF_EXPIRATION 32 +#define ISO_ROCK_TF_EFFECTIVE 64 +#define ISO_ROCK_TF_LONG_FORM 128 + +/*! Time stamp(s) for a file. See Rock Ridge Section 4.1.6 */ +typedef struct iso_rock_tf_s { + uint8_t flags; /**< See ISO_ROCK_TF_* bits above. */ + uint8_t time_bytes[EMPTY_ARRAY_SIZE]; /**< A homogenious array of + iso9660_ltime_t or + iso9660_dtime_t entries + depending on flags & + ISO_ROCK_TF_LONG_FORM. Lacking + a better method, we store + this as an array of bytes + and a cast to the + appropriate type will have + to be made before + extraction. */ +} GNUC_PACKED iso_rock_tf_t ; + +/*! File data in sparse format. See Rock Ridge Section 4.1.7 */ +typedef struct iso_rock_sf_s { + iso733_t virtual_size_high; /**< high-order 32 bits of virtual size */ + iso733_t virtual_size_low; /**< low-order 32 bits of virtual size */ + uint8_t table_depth; +} GNUC_PACKED iso_rock_sf_t ; + +typedef struct iso_extension_record_s { + char signature[2]; /**< signature word; either 'SP', 'CE', 'ER', 'RR', + 'PX', 'PN', 'SL', 'NM', 'CL', 'PL', 'TF', or + 'ZF' */ + iso711_t len; /**< length of system-user area - 44 for PX + 20 for PN, 5+strlen(text) for SL, 21 for + SF, etc. */ + iso711_t version; /**< version number - value 1 */ + union { + iso_su_sp_t SP; /**< system-use-sharing protocol - not + strictly part of Rock Ridge */ + iso_su_er_t ER; /**< system-use extension packet - not + strictly part of Rock Ridge */ + iso_su_ce_t CE; /**< system-use - strictly part of Rock Ridge */ + iso_rock_px_t PX; /**< Rock Ridge POSIX file attributes */ + iso_rock_pn_t PN; /**< Rock Ridge POSIX device number */ + iso_rock_sl_t SL; /**< Rock Ridge symbolic link */ + iso_rock_nm_t NM; /**< Rock Ridge alternate name */ + iso_rock_cl_t CL; /**< Rock Ridge child link */ + iso_rock_pl_t PL; /**< Rock Ridge parent link */ + iso_rock_tf_t TF; /**< Rock Ridge timestamp(s) for a file */ + } u; +} GNUC_PACKED iso_extension_record_t; + +typedef struct iso_rock_time_s { + bool b_used; /**< If true, field has been set and is valid. + Otherwise remaning fields are meaningless. */ + bool b_longdate; /**< If true date format is a iso9660_ltime_t. + Otherwise date is iso9660_dtime_t */ + union + { + iso9660_ltime_t ltime; + iso9660_dtime_t dtime; + } t; +} GNUC_PACKED iso_rock_time_t; + +typedef struct iso_rock_statbuf_s { + bool_3way_t b3_rock; /**< has Rock Ridge extension. + If "yep", then the fields + are used. + */ + posix_mode_t st_mode; /**< protection */ + posix_nlink_t st_nlinks; /**< number of hard links */ + posix_uid_t st_uid; /**< user ID of owner */ + posix_gid_t st_gid; /**< group ID of owner */ + uint8_t s_rock_offset; + int i_symlink; /**< size of psz_symlink */ + int i_symlink_max; /**< max allocated to psz_symlink */ + char *psz_symlink; /**< if symbolic link, name + of pointed to file. */ + iso_rock_time_t create; /**< create time See ISO 9660:9.5.4. */ + iso_rock_time_t modify; /**< time of last modification + ISO 9660:9.5.5. st_mtime field of + POSIX:5.6.1. */ + iso_rock_time_t access; /**< time of last file access st_atime + field of POSIX:5.6.1. */ + iso_rock_time_t attributes; /**< time of last attribute change. + st_ctime field of POSIX:5.6.1. */ + iso_rock_time_t backup; /**< time of last backup. */ + iso_rock_time_t expiration; /**< time of expiration; See ISO + 9660:9.5.6. */ + iso_rock_time_t effective; /**< Effective time; See ISO 9660:9.5.7. + */ + uint32_t i_rdev; /**< the upper 16-bits is major device + number, the lower 16-bits is the + minor device number */ + +} iso_rock_statbuf_t; + +PRAGMA_END_PACKED + +/*! return length of name field; 0: not found, -1: to be ignored */ +int get_rock_ridge_filename(iso9660_dir_t * de, /*out*/ char * retname, + /*out*/ iso9660_stat_t *p_stat); + + int parse_rock_ridge_stat(iso9660_dir_t *de, /*out*/ iso9660_stat_t *p_stat); + + /*! + Returns POSIX mode bitstring for a given file. + */ + mode_t + iso9660_get_posix_filemode_from_rock(const iso_rock_statbuf_t *rr); + +/*! + Returns a string which interpreting the POSIX mode st_mode. + For example: + \verbatim + drwxrws--- + -rw---Sr-- + lrwxrwxrwx + \endverbatim + + A description of the characters in the string follows + The 1st character is either "d" if the entry is a directory, "l" is + a symbolic link or "-" if neither. + + The 2nd to 4th characters refer to permissions for a user while the + the 5th to 7th characters refer to permissions for a group while, and + the 8th to 10h characters refer to permissions for everyone. + + In each of these triplets the first character (2, 5, 8) is "r" if + the entry is allowed to be read. + + The second character of a triplet (3, 6, 9) is "w" if the entry is + allowed to be written. + + The third character of a triplet (4, 7, 10) is "x" if the entry is + executable but not user (for character 4) or group (for characters + 6) settable and "s" if the item has the corresponding user/group set. + + For a directory having an executable property on ("x" or "s") means + the directory is allowed to be listed or "searched". If the execute + property is not allowed for a group or user but the corresponding + group/user is set "S" indicates this. If none of these properties + holds the "-" indicates this. +*/ +const char *iso9660_get_rock_attr_str(posix_mode_t st_mode); + +/** These variables are not used, but are defined to facilatate debugging + by letting us use enumerations values (which also correspond to + \#define's inside a debugged program. + */ +extern iso_rock_nm_flag_t iso_rock_nm_flag; +extern iso_rock_sl_flag_t iso_rock_sl_flag; +extern iso_rock_tf_flag_t iso_rock_tf_flag; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __ISO_ROCK_H__ */ + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/cdio/sector.h b/include/cdio/sector.h new file mode 100644 index 00000000..6e308338 --- /dev/null +++ b/include/cdio/sector.h @@ -0,0 +1,286 @@ +/* + $Id: sector.h,v 1.38 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2003, 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org> + Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ +/*! + \file sector.h + \brief Things related to CD-ROM layout: tracks, sector sizes, MSFs, LBAs. + + A CD-ROM physical sector size is 2048, 2052, 2056, 2324, 2332, 2336, + 2340, or 2352 bytes long. + + Sector types of the standard CD-ROM data formats: + +\verbatim + format sector type user data size (bytes) + ----------------------------------------------------------------------------- + 1 (Red Book) CD-DA 2352 (CDIO_CD_FRAMESIZE_RAW) + 2 (Yellow Book) Mode1 Form1 2048 (CDIO_CD_FRAMESIZE) + 3 (Yellow Book) Mode1 Form2 2336 (M2RAW_SECTOR_SIZE) + 4 (Green Book) Mode2 Form1 2048 (CDIO_CD_FRAMESIZE) + 5 (Green Book) Mode2 Form2 2328 (2324+4 spare bytes) + + + The layout of the standard CD-ROM data formats: + ----------------------------------------------------------------------------- + - audio (red): | audio_sample_bytes | + | 2352 | + + - data (yellow, mode1): | sync - head - data - EDC - zero - ECC | + | 12 - 4 - 2048 - 4 - 8 - 276 | + + - data (yellow, mode2): | sync - head - data | + | 12 - 4 - 2336 | + + - XA data (green, mode2 form1): | sync - head - sub - data - EDC - ECC | + | 12 - 4 - 8 - 2048 - 4 - 276 | + + - XA data (green, mode2 form2): | sync - head - sub - data - Spare | + | 12 - 4 - 8 - 2324 - 4 | +\endverbatim + + +*/ + +#ifndef _CDIO_SECTOR_H_ +#define _CDIO_SECTOR_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include <cdio/types.h> + + /*! Information that can be obtained through a Read Subchannel + command. + */ +#define CDIO_SUBCHANNEL_SUBQ_DATA 0 +#define CDIO_SUBCHANNEL_CURRENT_POSITION 1 +#define CDIO_SUBCHANNEL_MEDIA_CATALOG 2 +#define CDIO_SUBCHANNEL_TRACK_ISRC 3 + + /*! track flags + * Q Sub-channel Control Field (4.2.3.3) + */ + typedef enum { + NONE = 0x00, /* no flags set */ + PRE_EMPHASIS = 0x01, /* audio track recorded with pre-emphasis */ + COPY_PERMITTED = 0x02, /* digital copy permitted */ + DATA = 0x04, /* data track */ + FOUR_CHANNEL_AUDIO = 0x08, /* 4 audio channels */ + SCMS = 0x10 /* SCMS (5.29.2.7) */ + } flag_t; + +#define CDIO_PREGAP_SECTORS 150 +#define CDIO_POSTGAP_SECTORS 150 + + /*! An enumeration for some of the CDIO_CD \#defines below. This isn't + really an enumeration one would really use in a program it is to + be helpful in debuggers where wants just to refer to the CDIO_CD_ + names and get something. + */ + extern enum cdio_cd_enums { + CDIO_CD_MINS = 74, /**< max. minutes per CD, not really + a limit */ + CDIO_CD_SECS_PER_MIN = 60, /**< seconds per minute */ + CDIO_CD_FRAMES_PER_SEC = 75, /**< frames per second */ + CDIO_CD_SYNC_SIZE = 12, /**< 12 sync bytes per raw data + frame */ + CDIO_CD_CHUNK_SIZE = 24, /**< lowest-level "data bytes + piece" */ + CDIO_CD_NUM_OF_CHUNKS = 98, /**< chunks per frame */ + CDIO_CD_FRAMESIZE_SUB = 96, /**< subchannel data "frame" size */ + CDIO_CD_HEADER_SIZE = 4, /**< header (address) bytes per raw + frame */ + CDIO_CD_SUBHEADER_SIZE = 8, /**< subheader bytes per raw XA data + frame */ + CDIO_CD_ECC_SIZE = 276, /**< bytes ECC per most raw data + frame types */ + CDIO_CD_FRAMESIZE = 2048, /**< bytes per frame, "cooked" + mode */ + CDIO_CD_FRAMESIZE_RAW = 2352, /**< bytes per frame, "raw" mode */ + CDIO_CD_FRAMESIZE_RAWER = 2646, /**< The maximum possible + returned */ + CDIO_CD_FRAMESIZE_RAW1 = 2340, + CDIO_CD_FRAMESIZE_RAW0 = 2336, + CDIO_CD_MAX_SESSIONS = 99, + CDIO_CD_MIN_SESSION_NO = 1, /**<, Smallest CD session number */ + CDIO_CD_MAX_LSN = 450150, /**< Largest LSN in a CD */ + CDIO_CD_MIN_LSN = -450150, /**< Smallest LSN in a CD */ + } cdio_cd_enums; + + /*! + Some generally useful CD-ROM information -- mostly based on the above. + This is from linux.h - not to slight other OS's. This was the first + place I came across such useful stuff. + */ +#define CDIO_CD_MINS 74 /**< max. minutes per CD, not really + a limit */ +#define CDIO_CD_SECS_PER_MIN 60 /**< seconds per minute */ +#define CDIO_CD_FRAMES_PER_SEC 75 /**< frames per second */ +#define CDIO_CD_SYNC_SIZE 12 /**< 12 sync bytes per raw data frame */ +#define CDIO_CD_CHUNK_SIZE 24 /**< lowest-level "data bytes piece" */ +#define CDIO_CD_NUM_OF_CHUNKS 98 /**< chunks per frame */ +#define CDIO_CD_FRAMESIZE_SUB 96 /**< subchannel data "frame" size */ +#define CDIO_CD_HEADER_SIZE 4 /**< header (address) bytes per raw + data frame */ +#define CDIO_CD_SUBHEADER_SIZE 8 /**< subheader bytes per raw XA data + frame */ +#define CDIO_CD_EDC_SIZE 4 /**< bytes EDC per most raw data + frame types */ +#define CDIO_CD_M1F1_ZERO_SIZE 8 /**< bytes zero per yellow book mode + 1 frame */ +#define CDIO_CD_ECC_SIZE 276 /**< bytes ECC per most raw data frame + types */ +#define CDIO_CD_FRAMESIZE 2048 /**< bytes per frame, "cooked" mode */ +#define CDIO_CD_FRAMESIZE_RAW 2352 /**< bytes per frame, "raw" mode */ +#define CDIO_CD_FRAMESIZE_RAWER 2646 /**< The maximum possible returned + bytes */ +#define CDIO_CD_FRAMESIZE_RAW1 (CDIO_CD_CD_FRAMESIZE_RAW-CDIO_CD_SYNC_SIZE) /*2340*/ +#define CDIO_CD_FRAMESIZE_RAW0 (CDIO_CD_FRAMESIZE_RAW-CDIO_CD_SYNC_SIZE-CDIO_CD_HEADER_SIZE) /*2336*/ + + /*! "before data" part of raw XA (green, mode2) frame */ +#define CDIO_CD_XA_HEADER (CDIO_CD_HEADER_SIZE+CDIO_CD_SUBHEADER_SIZE) + + /*! "after data" part of raw XA (green, mode2 form1) frame */ +#define CDIO_CD_XA_TAIL (CDIO_CD_EDC_SIZE+CDIO_CD_ECC_SIZE) + + /*! "before data" sync bytes + header of XA (green, mode2) frame */ +#define CDIO_CD_XA_SYNC_HEADER (CDIO_CD_SYNC_SIZE+CDIO_CD_XA_HEADER) + + /*! String of bytes used to identify the beginning of a Mode 1 or + Mode 2 sector. */ + extern const uint8_t CDIO_SECTOR_SYNC_HEADER[CDIO_CD_SYNC_SIZE]; + /**< + {0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}; + */ + + /*! An enumeration for some of the M2*_SECTOR_SIZE \#defines + below. This isn't really an enumeration one would really use in a + program it is to be helpful in debuggers where wants just to refer + to the M2*_SECTOR_SIZE names and get something. + */ + extern enum m2_sector_enums { + M2F2_SECTOR_SIZE = 2324, + M2SUB_SECTOR_SIZE = 2332, + M2RAW_SECTOR_SIZE = 2336 + } m2_sector_enums; + +#define M2F2_SECTOR_SIZE 2324 +#define M2SUB_SECTOR_SIZE 2332 +#define M2RAW_SECTOR_SIZE 2336 + + /*! Largest CD session number */ +#define CDIO_CD_MAX_SESSIONS 99 + /*! Smallest CD session number */ +#define CDIO_CD_MIN_SESSION_NO 1 + + /*! Largest LSN in a CD */ +#define CDIO_CD_MAX_LSN 450150 + /*! Smallest LSN in a CD */ +#define CDIO_CD_MIN_LSN -450150 + + +#define CDIO_CD_FRAMES_PER_MIN \ + (CDIO_CD_FRAMES_PER_SEC*CDIO_CD_SECS_PER_MIN) + +#define CDIO_CD_74MIN_SECTORS (UINT32_C(74)*CDIO_CD_FRAMES_PER_MIN) +#define CDIO_CD_80MIN_SECTORS (UINT32_C(80)*CDIO_CD_FRAMES_PER_MIN) +#define CDIO_CD_90MIN_SECTORS (UINT32_C(90)*CDIO_CD_FRAMES_PER_MIN) + +#define CDIO_CD_MAX_SECTORS \ + (UINT32_C(100)*CDIO_CD_FRAMES_PER_MIN-CDIO_PREGAP_SECTORS) + +#define msf_t_SIZEOF 3 + + /*! + Convert an LBA into a string representation of the MSF. + \warning cdio_lba_to_msf_str returns new allocated string */ + char *cdio_lba_to_msf_str (lba_t i_lba); + + /*! + Convert an MSF into a string representation of the MSF. + \warning cdio_msf_to_msf_str returns new allocated string */ + char *cdio_msf_to_str (const msf_t *p_msf); + + /*! + Convert an LBA into the corresponding LSN. + */ + lba_t cdio_lba_to_lsn (lba_t i_lba); + + /*! + Convert an LBA into the corresponding MSF. + */ + void cdio_lba_to_msf(lba_t i_lba, msf_t *p_msf); + + /*! + Convert an LSN into the corresponding LBA. + CDIO_INVALID_LBA is returned if there is an error. + */ + lba_t cdio_lsn_to_lba (lsn_t i_lsn); + + /*! + Convert an LSN into the corresponding MSF. + */ + void cdio_lsn_to_msf (lsn_t i_lsn, msf_t *p_msf); + + /*! + Convert a MSF into the corresponding LBA. + CDIO_INVALID_LBA is returned if there is an error. + */ + lba_t cdio_msf_to_lba (const msf_t *p_msf); + + /*! + Convert a MSF into the corresponding LSN. + CDIO_INVALID_LSN is returned if there is an error. + */ + lsn_t cdio_msf_to_lsn (const msf_t *p_msf); + + /*! + Convert a MSF - broken out as 3 integer components into the + corresponding LBA. + CDIO_INVALID_LBA is returned if there is an error. + */ + lba_t cdio_msf3_to_lba (unsigned int minutes, unsigned int seconds, + unsigned int frames); + + /*! + Convert a string of the form MM:SS:FF into the corresponding LBA. + CDIO_INVALID_LBA is returned if there is an error. + */ + lba_t cdio_mmssff_to_lba (const char *psz_mmssff); + +#ifdef __cplusplus + } +#endif + +#ifndef DO_NOT_WANT_PARANOIA_COMPATIBILITY +/** For compatibility with good ol' paranoia */ +#define CD_FRAMESIZE_RAW CDIO_CD_FRAMESIZE_RAW +#endif /*DO_NOT_WANT_PARANOIA_COMPATIBILITY*/ + +#endif /* _CDIO_SECTOR_H_ */ + + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/cdio/track.h b/include/cdio/track.h new file mode 100644 index 00000000..9deb942b --- /dev/null +++ b/include/cdio/track.h @@ -0,0 +1,269 @@ +/* + $Id: track.h,v 1.14 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** \file track.h + * \brief The top-level header for track-related libcdio calls. + */ +#ifndef __CDIO_TRACK_H__ +#define __CDIO_TRACK_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /*! Printable tags for track_format_t enumeration. */ + extern const char *track_format2str[6]; + + typedef enum { + TRACK_FORMAT_AUDIO, /**< Audio track, e.g. CD-DA */ + TRACK_FORMAT_CDI, /**< CD-i. How this is different from DATA below? */ + TRACK_FORMAT_XA, /**< Mode2 of some sort */ + TRACK_FORMAT_DATA, /**< Mode1 of some sort */ + TRACK_FORMAT_PSX, /**< Playstation CD. Like audio but only 2336 bytes + * of user data. + */ + TRACK_FORMAT_ERROR /**< Dunno what is, or some other error. */ + } track_format_t; + + typedef enum { + CDIO_TRACK_FLAG_FALSE, + CDIO_TRACK_FLAG_TRUE, + CDIO_TRACK_FLAG_ERROR, + CDIO_TRACK_FLAG_UNKNOWN + } track_flag_t; + + /*! \brief Structure containing attributes associated with a track */ + typedef struct { + track_flag_t preemphasis; /**< Linear preemphasis on an audio track */ + track_flag_t copy_permit; /**< Whether copying is permitted */ + int channels; /**< Number of audio channels, 2, 4. -2 if not + implemented or -1 for error. + */ + } track_flags_t; + + /*! The leadout track is always 0xAA, regardless of # of tracks on + disc, or what value may be used internally. For example although + OS X uses a different value for the lead-out track internally than + given below, programmers should use CDIO_CDROM_LEADOUT_TRACK and + not worry about this. + */ + + /*! An enumeration for some of the CDIO_CDROM_* \#defines below. This + isn't really an enumeration one would really use in a program; it + is to be helpful in debuggers where wants just to refer to the + CDIO_CDROM_* names and get something. + */ + extern enum cdio_track_enums { + CDIO_CDROM_LBA = 0x01, /**< "logical block": first frame is #0 */ + CDIO_CDROM_MSF = 0x02, /**< "minute-second-frame": binary, not + BCD here! */ + CDIO_CDROM_DATA_TRACK = 0x04, + CDIO_CDROM_CDI_TRACK = 0x10, + CDIO_CDROM_XA_TRACK = 0x20, + CDIO_CD_MAX_TRACKS = 99, /**< Largest CD track number */ + CDIO_CDROM_LEADOUT_TRACK = 0xAA, /**< Lead-out track number */ + CDIO_INVALID_TRACK = 0xFF, /**< Constant for invalid track number */ + + } cdio_track_enums; + +#define CDIO_CD_MIN_TRACK_NO 1 /**< Smallest CD track number */ + + /*! track modes (Table 350) + reference: MMC-3 draft revsion - 10g + */ + typedef enum { + AUDIO, /**< 2352 byte block length */ + MODE1, /**< 2048 byte block length */ + MODE1_RAW, /**< 2352 byte block length */ + MODE2, /**< 2336 byte block length */ + MODE2_FORM1, /**< 2048 byte block length */ + MODE2_FORM2, /**< 2324 byte block length */ + MODE2_FORM_MIX, /**< 2336 byte block length */ + MODE2_RAW /**< 2352 byte block length */ + } trackmode_t; + + /*! + Get CD-Text information for a CdIo_t object. + + @param p_cdio the CD object that may contain CD-Text information. + @param i_track track for which we are requesting CD-Text information. + @return the CD-Text object or NULL if obj is NULL + or CD-Text information does not exist. + + If i_track is 0 or CDIO_CDROM_LEADOUT_TRACK the track returned + is the information assocated with the CD. + */ + cdtext_t *cdio_get_cdtext (CdIo_t *p_cdio, track_t i_track); + + /*! + Get the number of the first track. + + @return the track number or CDIO_INVALID_TRACK + on error. + */ + track_t cdio_get_first_track_num(const CdIo_t *p_cdio); + + /*! + Return the last track number. + CDIO_INVALID_TRACK is returned on error. + */ + track_t cdio_get_last_track_num (const CdIo_t *p_cdio); + + + /*! Find the track which contains lsn. + CDIO_INVALID_TRACK is returned if the lsn outside of the CD or + if there was some error. + + If the lsn is before the pregap of the first track 0 is returned. + Otherwise we return the track that spans the lsn. + */ + track_t cdio_get_track(const CdIo_t *p_cdio, lsn_t lsn); + + /*! Return number of channels in track: 2 or 4; -2 if not + implemented or -1 for error. + Not meaningful if track is not an audio track. + */ + int cdio_get_track_channels(const CdIo_t *p_cdio, track_t i_track); + + /*! Return copy protection status on a track. Is this meaningful + if not an audio track? + */ + track_flag_t cdio_get_track_copy_permit(const CdIo_t *p_cdio, + track_t i_track); + + /*! + Get the format (audio, mode2, mode1) of track. + */ + track_format_t cdio_get_track_format(const CdIo_t *p_cdio, track_t i_track); + + /*! + Return true if we have XA data (green, mode2 form1) or + XA data (green, mode2 form2). That is track begins: + sync - header - subheader + 12 4 - 8 + + FIXME: there's gotta be a better design for this and get_track_format? + */ + bool cdio_get_track_green(const CdIo_t *p_cdio, track_t i_track); + + /*! + Return the ending LSN for track number + i_track in cdio. CDIO_INVALID_LSN is returned on error. + */ + lsn_t cdio_get_track_last_lsn(const CdIo_t *p_cdio, track_t i_track); + + /*! + Get the starting LBA for track number + i_track in p_cdio. Track numbers usually start at something + greater than 0, usually 1. + + The "leadout" track is specified either by + using i_track CDIO_CDROM_LEADOUT_TRACK or the total tracks+1. + + @param p_cdio object to get information from + @param i_track the track number we want the LSN for + @return the starting LBA or CDIO_INVALID_LBA on error. + */ + lba_t cdio_get_track_lba(const CdIo_t *p_cdio, track_t i_track); + + /*! + Return the starting LSN for track number + i_track in p_cdio. Track numbers usually start at something + greater than 0, usually 1. + + The "leadout" track is specified either by + using i_track CDIO_CDROM_LEADOUT_TRACK or the total tracks+1. + + @param p_cdio object to get information from + @param i_track the track number we want the LSN for + @return the starting LSN or CDIO_INVALID_LSN on error. + */ + lsn_t cdio_get_track_lsn(const CdIo_t *p_cdio, track_t i_track); + + /*! + Return the starting LBA for the pregap for track number + i_track in p_cdio. Track numbers usually start at something + greater than 0, usually 1. + + @param p_cdio object to get information from + @param i_track the track number we want the LBA for + @return the starting LBA or CDIO_INVALID_LBA on error. + */ + lba_t cdio_get_track_pregap_lba(const CdIo_t *p_cdio, track_t i_track); + + /*! + Return the starting LSN for the pregap for track number + i_track in p_cdio. Track numbers usually start at something + greater than 0, usually 1. + + @param p_cdio object to get information from + @param i_track the track number we want the LSN for + @return the starting LSN or CDIO_INVALID_LSN on error. + */ + lsn_t cdio_get_track_pregap_lsn(const CdIo_t *p_cdio, track_t i_track); + + /*! + Get the International Standard Recording Code (ISRC) for track number + i_track in p_cdio. Track numbers usually start at something + greater than 0, usually 1. + + @return the International Standard Recording Code (ISRC) or NULL + if there is none or we don't have the ability to get it. + + Note: string is malloc'd so caller has to free() the returned + string when done with it. + + */ + char * cdio_get_track_isrc (const CdIo_t *p_cdio, track_t i_track); + + /*! + Return the starting MSF (minutes/secs/frames) for track number + i_track in p_cdio. Track numbers usually start at something + greater than 0, usually 1. + + The "leadout" track is specified either by + using i_track CDIO_CDROM_LEADOUT_TRACK or the total tracks+1. + + @return true if things worked or false if there is no track entry. + */ + bool cdio_get_track_msf(const CdIo_t *p_cdio, track_t i_track, + /*out*/ msf_t *msf); + + /*! Get linear preemphasis status on an audio track + This is not meaningful if not an audio track? + */ + track_flag_t cdio_get_track_preemphasis(const CdIo_t *p_cdio, + track_t i_track); + + /*! + Get the number of sectors between this track an the next. This + includes any pregap sectors before the start of the next track. + Track numbers usually start at something + greater than 0, usually 1. + + @return the number of sectors or 0 if there is an error. + */ + unsigned int cdio_get_track_sec_count(const CdIo_t *p_cdio, track_t i_track); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CDIO_TRACK_H__ */ + diff --git a/include/cdio/types.h b/include/cdio/types.h new file mode 100644 index 00000000..347bf5a7 --- /dev/null +++ b/include/cdio/types.h @@ -0,0 +1,327 @@ +/* + $Id: types.h,v 1.37 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008 + Rocky Bernstein <rocky@gnu.org> + Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** \file types.h + * \brief Common type definitions used pervasively in libcdio. + */ + + +#ifndef __CDIO_TYPES_H__ +#define __CDIO_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef EXTERNAL_LIBCDIO_CONFIG_H +#define EXTERNAL_LIBCDIO_CONFIG_H +#include <cdio/cdio_config.h> +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + + /* provide some C99 definitions */ + +#if defined(HAVE_SYS_TYPES_H) +#include <sys/types.h> +#endif + +#if defined(HAVE_STDINT_H) +# include <stdint.h> +#elif defined(HAVE_INTTYPES_H) +# include <inttypes.h> +#elif defined(AMIGA) || defined(__linux__) + typedef u_int8_t uint8_t; + typedef u_int16_t uint16_t; + typedef u_int32_t uint32_t; + typedef u_int64_t uint64_t; +#else + /* warning ISO/IEC 9899:1999 <stdint.h> was missing and even <inttypes.h> */ + /* fixme */ +#endif /* HAVE_STDINT_H */ + +typedef uint8_t ubyte; + + /* default HP/UX macros are broken */ +#if defined(__hpux__) +# undef UINT16_C +# undef UINT32_C +# undef UINT64_C +# undef INT64_C +#endif + + /* if it's still not defined, take a good guess... should work for + most 32bit and 64bit archs */ + +#ifndef UINT16_C +# define UINT16_C(c) c ## U +#endif + +#ifndef UINT32_C +# if defined (SIZEOF_INT) && SIZEOF_INT == 4 +# define UINT32_C(c) c ## U +# elif defined (SIZEOF_LONG) && SIZEOF_LONG == 4 +# define UINT32_C(c) c ## UL +# else +# define UINT32_C(c) c ## U +# endif +#endif + +#ifndef UINT64_C +# if defined (SIZEOF_LONG) && SIZEOF_LONG == 8 +# define UINT64_C(c) c ## UL +# elif defined (SIZEOF_INT) && SIZEOF_INT == 8 +# define UINT64_C(c) c ## U +# else +# define UINT64_C(c) c ## ULL +# endif +#endif + +#ifndef INT64_C +# if defined (SIZEOF_LONG) && SIZEOF_LONG == 8 +# define INT64_C(c) c ## L +# elif defined (SIZEOF_INT) && SIZEOF_INT == 8 +# define INT64_C(c) c +# else +# define INT64_C(c) c ## LL +# endif +#endif + +#ifndef __cplusplus +# if defined(HAVE_STDBOOL_H) +# include <stdbool.h> +# else + /* ISO/IEC 9899:1999 <stdbool.h> missing -- enabling workaround */ + +# define false 0 +# define true 1 +# define bool uint8_t +# endif /*HAVE_STDBOOL_H*/ +#endif /*C++*/ + + /* some GCC optimizations -- gcc 2.5+ */ + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +#define GNUC_PRINTF( format_idx, arg_idx ) \ + __attribute__((format (printf, format_idx, arg_idx))) +#define GNUC_SCANF( format_idx, arg_idx ) \ + __attribute__((format (scanf, format_idx, arg_idx))) +#define GNUC_FORMAT( arg_idx ) \ + __attribute__((format_arg (arg_idx))) +#define GNUC_NORETURN \ + __attribute__((noreturn)) +#define GNUC_CONST \ + __attribute__((const)) +#define GNUC_UNUSED \ + __attribute__((unused)) +#define GNUC_PACKED \ + __attribute__((packed)) +#else /* !__GNUC__ */ +#define GNUC_PRINTF( format_idx, arg_idx ) +#define GNUC_SCANF( format_idx, arg_idx ) +#define GNUC_FORMAT( arg_idx ) +#define GNUC_NORETURN +#define GNUC_CONST +#define GNUC_UNUSED +#define GNUC_PACKED +#endif /* !__GNUC__ */ + +#if defined(__GNUC__) + /* for GCC we try to use GNUC_PACKED */ +# define PRAGMA_BEGIN_PACKED +# define PRAGMA_END_PACKED +#elif defined(HAVE_ISOC99_PRAGMA) + /* should work with most EDG-frontend based compilers */ +# define PRAGMA_BEGIN_PACKED _Pragma("pack(1)") +# define PRAGMA_END_PACKED _Pragma("pack()") +#else /* neither gcc nor _Pragma() available... */ + /* ...so let's be naive and hope the regression testsuite is run... */ +# define PRAGMA_BEGIN_PACKED +# define PRAGMA_END_PACKED +#endif + + /* + * user directed static branch prediction gcc 2.96+ + */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 95) +# define GNUC_LIKELY(x) __builtin_expect((x),true) +# define GNUC_UNLIKELY(x) __builtin_expect((x),false) +#else +# define GNUC_LIKELY(x) (x) +# define GNUC_UNLIKELY(x) (x) +#endif + +#ifndef NULL +# define NULL ((void*) 0) +#endif + + /* our own offsetof()-like macro */ +#define __cd_offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) + + /*! + \brief MSF (minute/second/frame) structure + + One CD-ROMs addressing scheme especially used in audio formats + (Red Book) is an address by minute, sector and frame which + BCD-encoded in three bytes. An alternative format is an lba_t. + + Note: the fields in this structure are BCD encoded. Use + cdio_to_bcd8() or cdio_from_bcd8() to convert an integer into or + out of this format. The format specifier %x (not %d) can be used + if you need to format or print values in this structure. + + @see lba_t + */ + PRAGMA_BEGIN_PACKED + struct msf_s { + uint8_t m, s, f; /* BCD encoded! */ + } GNUC_PACKED; + PRAGMA_END_PACKED + + typedef struct msf_s msf_t; + +#define msf_t_SIZEOF 3 + + /*! + \brief UTF-8 char definition + + Type to denote UTF-8 strings. + */ + + typedef char cdio_utf8_t; + + typedef enum { + nope = 0, + yep = 1, + dunno = 2 + } bool_3way_t; + + /* type used for bit-fields in structs (1 <= bits <= 8) */ +#if defined(__GNUC__) + /* this is strict ISO C99 which allows only 'unsigned int', 'signed + int' and '_Bool' explicitly as bit-field type */ + typedef unsigned int bitfield_t; +#else + /* other compilers might increase alignment requirements to match the + 'unsigned int' type -- fixme: find out how unalignment accesses can + be pragma'ed on non-gcc compilers */ + typedef uint8_t bitfield_t; +#endif + + /*! The type of a Logical Block Address. We allow for an lba to be + negative to be consistent with an lba, although I'm not sure this + this is possible. + + */ + typedef int32_t lba_t; + + /*! The type of a Logical Sector Number. Note that an lba can be negative + and the MMC3 specs allow for a conversion of a negative lba. + + @see msf_t + */ + typedef int32_t lsn_t; + + /* Address in either MSF or logical format */ + union cdio_cdrom_addr + { + msf_t msf; + lba_t lba; + }; + + /*! The type of a track number 0..99. */ + typedef uint8_t track_t; + + /*! The type of a session number 0..99. */ + typedef uint8_t session_t; + + /*! + Constant for invalid session number + */ +#define CDIO_INVALID_SESSION 0xFF + + /*! + Constant for invalid LBA. It is 151 less than the most negative + LBA -45150. This provide slack for the 150-frame offset in + LBA to LSN 150 conversions + */ +#define CDIO_INVALID_LBA -45301 + + /*! + Constant for invalid LSN + */ +#define CDIO_INVALID_LSN CDIO_INVALID_LBA + + /*! + Number of ASCII bytes in a media catalog number (MCN). + */ +#define CDIO_MCN_SIZE 13 + + /*! + Type to hold ASCII bytes in a media catalog number (MCN). + We include an extra 0 byte so these can be used as C strings. + */ + typedef char cdio_mcn_t[CDIO_MCN_SIZE+1]; + + + /*! + Number of ASCII bytes in International Standard Recording Codes (ISRC) + */ +#define CDIO_ISRC_SIZE 12 + + /*! + Type to hold ASCII bytes in a media catalog number (MCN). + We include an extra 0 byte so these can be used as C strings. + */ + typedef char cdio_isrc_t[CDIO_ISRC_SIZE+1]; + + typedef int cdio_fs_anal_t; + + /*! + track flags + Q Sub-channel Control Field (4.2.3.3) + */ + typedef enum { + CDIO_TRACK_FLAG_NONE = 0x00, /**< no flags set */ + CDIO_TRACK_FLAG_PRE_EMPHASIS = 0x01, /**< audio track recorded with + pre-emphasis */ + CDIO_TRACK_FLAG_COPY_PERMITTED = 0x02, /**< digital copy permitted */ + CDIO_TRACK_FLAG_DATA = 0x04, /**< data track */ + CDIO_TRACK_FLAG_FOUR_CHANNEL_AUDIO = 0x08, /**< 4 audio channels */ + CDIO_TRACK_FLAG_SCMS = 0x10 /**< SCMS (5.29.2.7) */ +} cdio_track_flag; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CDIO_TYPES_H__ */ + + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/cdio/udf.h b/include/cdio/udf.h new file mode 100644 index 00000000..e35d74d1 --- /dev/null +++ b/include/cdio/udf.h @@ -0,0 +1,171 @@ +/* + $Id: udf.h,v 1.22 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/*! + * \file udf.h + * + * \brief The top-level interface header for libudf: UDF filesystem + * library; applications include this. + * +*/ + +#ifndef UDF_H +#define UDF_H + +#include <cdio/cdio.h> +#include <cdio/ecma_167.h> +#include <cdio/posix.h> + +typedef uint16_t partition_num_t; + +/** Opaque structures. */ +typedef struct udf_s udf_t; +typedef struct udf_file_s udf_file_t; +typedef struct udf_dirent_s udf_dirent_t; + +/** + Imagine the below a \#define'd value rather than distinct values of + an enum. +*/ +typedef enum { + UDF_BLOCKSIZE = 2048 +} udf_enum1_t; + +/** This variable is trickery to force the above enum symbol value to + be recorded in debug symbol tables. It is used to allow one refer + to above enumeration values in a debugger and debugger + expressions */ +extern udf_enum1_t debug_udf_enum1; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /*! + Close UDF and free resources associated with p_udf. + */ + bool udf_close (udf_t *p_udf); + + /*! + Seek to a position i_start and then read i_blocks. Number of + blocks read is returned. One normally expects the return to be + equal to i_blocks. + */ + + driver_return_code_t udf_read_sectors (const udf_t *p_udf, void *ptr, + lsn_t i_start, long int i_blocks); + + /*! + Open an UDF for reading. Maybe in the future we will have + a mode. NULL is returned on error. + + Caller must free result - use udf_close for that. + */ + udf_t *udf_open (const char *psz_path); + + /*! + Return the partition number of the the opened udf handle. -1 + Is returned if we have an error. + */ + int16_t udf_get_part_number(const udf_t *p_udf); + + /*! + Get the root in p_udf. If b_any_partition is false then + the root must be in the given partition. + NULL is returned if the partition is not found or a root is not found or + there is on error. + + Caller must free result - use udf_file_free for that. + */ + udf_dirent_t *udf_get_root (udf_t *p_udf, bool b_any_partition, + partition_num_t i_partition); + + /** + * Gets the Volume Identifier string, in 8bit unicode (latin-1) + * psz_volid, place to put the string + * i_volid_size, size of the buffer volid points to + * returns the size of buffer needed for all data + */ + int udf_get_volume_id(udf_t *p_udf, /*out*/ char *psz_volid, + unsigned int i_volid); + + /** + * Gets the Volume Set Identifier, as a 128-byte dstring (not decoded) + * WARNING This is not a null terminated string + * volsetid, place to put the data + * volsetid_size, size of the buffer volsetid points to + * the buffer should be >=128 bytes to store the whole volumesetidentifier + * returns the size of the available volsetid information (128) + * or 0 on error + */ + int udf_get_volumeset_id(udf_t *p_udf, /*out*/ uint8_t *volsetid, + unsigned int i_volsetid); + + /*! + Return a file pointer matching pzz_name. + */ + udf_dirent_t *udf_fopen(udf_dirent_t *p_udf_root, const char *psz_name); + + /*! udf_mode_string - fill in string PSZ_STR with an ls-style ASCII + representation of the i_mode. PSZ_STR is returned. + + 10 characters are stored in PSZ_STR; a terminating null byte is added. + The characters stored in PSZ_STR are: + + 0 File type. 'd' for directory, 'c' for character + special, 'b' for block special, 'm' for multiplex, + 'l' for symbolic link, 's' for socket, 'p' for fifo, + '-' for regular, '?' for any other file type + + 1 'r' if the owner may read, '-' otherwise. + + 2 'w' if the owner may write, '-' otherwise. + + 3 'x' if the owner may execute, 's' if the file is + set-user-id, '-' otherwise. + 'S' if the file is set-user-id, but the execute + bit isn't set. + + 4 'r' if group members may read, '-' otherwise. + + 5 'w' if group members may write, '-' otherwise. + + 6 'x' if group members may execute, 's' if the file is + set-group-id, '-' otherwise. + 'S' if it is set-group-id but not executable. + + 7 'r' if any user may read, '-' otherwise. + + 8 'w' if any user may write, '-' otherwise. + + 9 'x' if any user may execute, 't' if the file is "sticky" + (will be retained in swap space after execution), '-' + otherwise. + 'T' if the file is sticky but not executable. */ + + char *udf_mode_string (mode_t i_mode, char *psz_str); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include <cdio/udf_time.h> +#include <cdio/udf_file.h> + +#endif /*UDF_H*/ diff --git a/include/cdio/udf_file.h b/include/cdio/udf_file.h new file mode 100644 index 00000000..0b8fe99e --- /dev/null +++ b/include/cdio/udf_file.h @@ -0,0 +1,117 @@ +/* + $Id: udf_file.h,v 1.12 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/** + * \file udf_file.h + * + * \brief Routines involving UDF file operations + * +*/ + +#ifndef UDF_FILE_H +#define UDF_FILE_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /** + Return the file id descriptor of the given file. + */ + bool udf_get_fileid_descriptor(const udf_dirent_t *p_udf_dirent, + /*out*/ udf_fileid_desc_t *p_udf_fid); + + /** + Return the name of the file + */ + const char *udf_get_filename(const udf_dirent_t *p_udf_dirent); + + /** + Return the name of the file + */ + bool udf_get_file_entry(const udf_dirent_t *p_udf_dirent, + /*out*/ udf_file_entry_t *p_udf_fe); + + /** + Return the number of hard links of the file. Return 0 if error. + */ + uint16_t udf_get_link_count(const udf_dirent_t *p_udf_dirent); + + /** + Return the file length the file. Return 2147483647L if error. + */ + uint64_t udf_get_file_length(const udf_dirent_t *p_udf_dirent); + + /** + Returns a POSIX mode for a given p_udf_dirent. + */ + mode_t udf_get_posix_filemode(const udf_dirent_t *p_udf_dirent); + + /** + Return the next subdirectory. + */ + udf_dirent_t *udf_opendir(const udf_dirent_t *p_udf_dirent); + + /** + Attempts to read up to count bytes from UDF directory entry + p_udf_dirent into the buffer starting at buf. buf should be a + multiple of UDF_BLOCKSIZE bytes. Reading continues after the + point at which we last read or from the beginning the first time. + + If count is zero, read() returns zero and has no other results. If + count is greater than SSIZE_MAX, the result is unspecified. + + If there is an error, cast the result to driver_return_code_t for + the specific error code. + */ + /** + Attempts to read up to count bytes from file descriptor fd into + the buffer starting at buf. + + If count is zero, read() returns zero and has no other results. If + count is greater than SSIZE_MAX, the result is unspecified. + */ + ssize_t udf_read_block(const udf_dirent_t *p_udf_dirent, + void * buf, size_t count); + + /** + Advances p_udf_direct to the the next directory entry in the + pointed to by p_udf_dir. It also returns this as the value. NULL + is returned on reaching the end-of-file or if an error. Also + p_udf_dirent is free'd. If the end of is not reached the caller + must call udf_dirent_free() with p_udf_dirent when done with it to + release resources. + */ + udf_dirent_t *udf_readdir(udf_dirent_t *p_udf_dirent); + + /** + free free resources associated with p_udf_dirent. + */ + bool udf_dirent_free(udf_dirent_t *p_udf_dirent); + + /** + Return true if the file is a directory. + */ + bool udf_is_dir(const udf_dirent_t *p_udf_dirent); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /*UDF_FILE_H*/ diff --git a/include/cdio/udf_time.h b/include/cdio/udf_time.h new file mode 100644 index 00000000..791fcdd9 --- /dev/null +++ b/include/cdio/udf_time.h @@ -0,0 +1,80 @@ +/* + $Id: udf_time.h,v 1.5 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2005, 2008 Rocky Bernstein <rocky@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +/*! + * \file udf_time.h + * + * \brief UDF time conversion and access files. + * +*/ + +#ifndef UDF_TIME_H +#define UDF_TIME_H + +#include <time.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /*! + Return the access time of the file. + */ + time_t udf_get_access_time(const udf_dirent_t *p_udf_dirent); + + /*! + Return the attribute (most recent create or access) time of the file + */ + time_t udf_get_attribute_time(const udf_dirent_t *p_udf_dirent); + + /*! + Return the modification time of the file. + */ + time_t udf_get_modification_time(const udf_dirent_t *p_udf_dirent); + + /*! + Return the access timestamp of the file + */ + udf_timestamp_t *udf_get_access_timestamp(const udf_dirent_t *p_udf_dirent); + + /*! + Return the modification timestamp of the file + */ + udf_timestamp_t *udf_get_modification_timestamp(const udf_dirent_t + *p_udf_dirent); + + /*! + Return the attr timestamp of the file + */ + udf_timestamp_t *udf_get_attr_timestamp(const udf_dirent_t *p_udf_dirent); + + /*! + Convert a UDF timestamp to a time_t. If microseconds are desired, + use dest_usec. The return value is the same as dest. */ + time_t *udf_stamp_to_time(time_t *dest, long int *dest_usec, + const udf_timestamp_t src); + + udf_timestamp_t *udf_timespec_to_stamp(const struct timespec ts, + udf_timestamp_t *dest); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /*UDF_TIME_H*/ diff --git a/include/cdio/utf8.h b/include/cdio/utf8.h new file mode 100644 index 00000000..236105e9 --- /dev/null +++ b/include/cdio/utf8.h @@ -0,0 +1,92 @@ +/* + $Id: utf8.h,v 1.2 2008/03/25 15:59:09 karl Exp $ + + Copyright (C) 2008 Rocky Bernstein <rocky@gnu.org> + Copyright (C) 2006 Burkhard Plaum <plaum@ipf.uni-stuttgart.de> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ +/* UTF-8 support */ + + +#include <cdio/types.h> + +/** \brief Opaque characterset converter + */ + +typedef struct cdio_charset_coverter_s cdio_charset_coverter_t; + +/** \brief Create a charset converter + * \param src_charset Source charset + * \param dst_charset Destination charset + * \returns A newly allocated charset converter + */ + +cdio_charset_coverter_t * +cdio_charset_converter_create(const char * src_charset, + const char * dst_charset); + +/** \brief Destroy a characterset converter + * \param cnv A characterset converter + */ + +void cdio_charset_converter_destroy(cdio_charset_coverter_t*cnv); + +/** \brief Convert a string from one character set to another + * \param cnv A charset converter + * \param src Source string + * \param src_len Length of source string + * \param dst Returns destination string + * \param dst_len If non NULL, returns the length of the destination string + * \returns true if conversion was sucessful, false else. + * + * The destination string must be freed by the caller with free(). + * If you pass -1 for src_len, strlen() will be used. + */ + +bool cdio_charset_convert(cdio_charset_coverter_t*cnv, + char * src, int src_len, + char ** dst, int * dst_len); + +/** \brief Convert a string from UTF-8 to another charset + * \param src Source string (0 terminated) + * \param dst Returns destination string + * \param dst_len If non NULL, returns the length of the destination string + * \param dst_charset The characterset to convert to + * \returns true if conversion was sucessful, false else. + * + * This is a convenience function, which creates a charset converter, + * converts one string and destroys the charset converter. + */ + + +bool cdio_charset_from_utf8(cdio_utf8_t * src, char ** dst, + int * dst_len, const char * dst_charset); + +/** \brief Convert a string from another charset to UTF-8 + * \param src Source string + * \param src_len Length of the source string + * \param dst Returns destination string (0 terminated) + * \param src_charset The characterset to convert from + * \returns true if conversion was sucessful, false else. + * + * This is a convenience function, which creates a charset converter, + * converts one string and destroys the charset converter. If you pass -1 + * for src_len, strlen() will be used. + */ + + +bool cdio_charset_to_utf8(char *src, size_t src_len, cdio_utf8_t **dst, + const char * src_charset); + diff --git a/include/cdio/util.h b/include/cdio/util.h new file mode 100644 index 00000000..81557dc7 --- /dev/null +++ b/include/cdio/util.h @@ -0,0 +1,117 @@ +/* + $Id: util.h,v 1.12 2008/03/25 15:59:10 karl Exp $ + + Copyright (C) 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org> + Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org> + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __CDIO_UTIL_H__ +#define __CDIO_UTIL_H__ + +/*! + \file util.h + \brief Miscellaneous utility functions. + + Warning: this will probably get removed/replaced by using glib.h +*/ +#include <stdlib.h> + +#undef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +#undef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#undef IN +#define IN(x, low, high) ((x) >= (low) && (x) <= (high)) + +#undef CLAMP +#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) + +static inline uint32_t +_cdio_len2blocks (uint32_t i_len, uint16_t i_blocksize) +{ + uint32_t i_blocks; + + i_blocks = i_len / (uint32_t) i_blocksize; + if (i_len % i_blocksize) + i_blocks++; + + return i_blocks; +} + +/* round up to next block boundary */ +static inline unsigned +_cdio_ceil2block (unsigned offset, uint16_t i_blocksize) +{ + return _cdio_len2blocks (offset, i_blocksize) * i_blocksize; +} + +static inline unsigned int +_cdio_ofs_add (unsigned offset, unsigned length, uint16_t i_blocksize) +{ + if (i_blocksize - (offset % i_blocksize) < length) + offset = _cdio_ceil2block (offset, i_blocksize); + + offset += length; + + return offset; +} + +static inline const char * +_cdio_bool_str (bool b) +{ + return b ? "yes" : "no"; +} + +#ifdef __cplusplus +extern "C" { +#endif + +void * +_cdio_memdup (const void *mem, size_t count); + +char * +_cdio_strdup_upper (const char str[]); + +void +_cdio_strfreev(char **strv); + +size_t +_cdio_strlenv(char **str_array); + +char ** +_cdio_strsplit(const char str[], char delim); + +uint8_t cdio_to_bcd8(uint8_t n); +uint8_t cdio_from_bcd8(uint8_t p); + +void cdio_follow_symlink (const char * src, char * dst); + +#ifdef __cplusplus +} +#endif + +#endif /* __CDIO_UTIL_H__ */ + + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/cdio/version.h b/include/cdio/version.h new file mode 100644 index 00000000..8eb564dc --- /dev/null +++ b/include/cdio/version.h @@ -0,0 +1,12 @@ +/* $Id: version.h.in,v 1.6 2005/01/29 20:54:20 rocky Exp $ */ +/** \file version.h + * + * \brief A file containing the libcdio package version + * number (82) and OS build name. + */ + +/*! CDIO_VERSION can as a string in programs to show what version is used. */ +#define CDIO_VERSION "0.82 i686-pc-linux-gnu" + +/*! LIBCDIO_VERSION_NUM can be used for testing in the C preprocessor */ +#define LIBCDIO_VERSION_NUM 82 diff --git a/include/cdio/version.h.in b/include/cdio/version.h.in new file mode 100644 index 00000000..17d199e7 --- /dev/null +++ b/include/cdio/version.h.in @@ -0,0 +1,12 @@ +/* $Id: version.h.in,v 1.6 2005/01/29 20:54:20 rocky Exp $ */ +/** \file version.h + * + * \brief A file containing the libcdio package version + * number (@LIBCDIO_VERSION_NUM@) and OS build name. + */ + +/*! CDIO_VERSION can as a string in programs to show what version is used. */ +#define CDIO_VERSION "@VERSION@ @build@" + +/*! LIBCDIO_VERSION_NUM can be used for testing in the C preprocessor */ +#define LIBCDIO_VERSION_NUM @LIBCDIO_VERSION_NUM@ diff --git a/include/cdio/xa.h b/include/cdio/xa.h new file mode 100644 index 00000000..13b21c8f --- /dev/null +++ b/include/cdio/xa.h @@ -0,0 +1,179 @@ +/* + $Id: xa.h,v 1.19 2008/03/25 15:59:10 karl Exp $ + + Copyright (C) 2003, 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org> + Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org> + + See also iso9660.h by Eric Youngdale (1993) and in cdrtools. These are + + Copyright 1993 Yggdrasil Computing, Incorporated + Copyright (c) 1999,2000 J. Schilling + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ +/*! + \file xa.h + \brief Things related to the ISO-9660 XA (Extended Attributes) format + + Applications will probably not include this directly but via + the iso9660.h header. +*/ + + +#ifndef __CDIO_XA_H__ +#define __CDIO_XA_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /*! An enumeration for some of the XA_* \#defines below. This isn't + really an enumeration one would really use in a program it is to + be helpful in debuggers where wants just to refer to the XA_* + names and get something. + */ + typedef enum { + ISO_XA_MARKER_OFFSET = 1024, + XA_PERM_RSYS = 0x0001, /**< System Group Read */ + XA_PERM_XSYS = 0x0004, /**< System Group Execute */ + + XA_PERM_RUSR = 0x0010, /**< User (owner) Read */ + XA_PERM_XUSR = 0x0040, /**< User (owner) Execute */ + + XA_PERM_RGRP = 0x0100, /**< Group Read */ + XA_PERM_XGRP = 0x0400, /**< Group Execute */ + + XA_PERM_ROTH = 0x1000, /**< Other (world) Read */ + XA_PERM_XOTH = 0x4000, /**< Other (world) Execute */ + + XA_ATTR_MODE2FORM1 = (1 << 11), + XA_ATTR_MODE2FORM2 = (1 << 12), + XA_ATTR_INTERLEAVED = (1 << 13), + XA_ATTR_CDDA = (1 << 14), + XA_ATTR_DIRECTORY = (1 << 15), + + XA_PERM_ALL_READ = (XA_PERM_RUSR | XA_PERM_RSYS | XA_PERM_RGRP), + XA_PERM_ALL_EXEC = (XA_PERM_XUSR | XA_PERM_XSYS | XA_PERM_XGRP), + XA_PERM_ALL_ALL = (XA_PERM_ALL_READ | XA_PERM_ALL_EXEC), + + XA_FORM1_DIR = (XA_ATTR_DIRECTORY | XA_ATTR_MODE2FORM1 | XA_PERM_ALL_ALL), + XA_FORM1_FILE = (XA_ATTR_MODE2FORM1 | XA_PERM_ALL_ALL), + XA_FORM2_FILE = (XA_ATTR_MODE2FORM2 | XA_PERM_ALL_ALL) + } xa_misc_enum_t; + +extern const char ISO_XA_MARKER_STRING[sizeof("CD-XA001")-1]; + +#define ISO_XA_MARKER_STRING "CD-XA001" + +/*! \brief "Extended Architecture" according to the Philips Yellow Book. + +CD-ROM EXtended Architecture is a modification to the CD-ROM +specification that defines two new types of sectors. CD-ROM XA was +developed jointly by Sony, Philips, and Microsoft, and announced in +August 1988. Its specifications were published in an extension to the +Yellow Book. CD-i, Photo CD, Video CD and CD-EXTRA have all +subsequently been based on CD-ROM XA. + +CD-XA defines another way of formatting sectors on a CD-ROM, including +headers in the sectors that describe the type (audio, video, data) and +some additional info (markers, resolution in case of a video or audio +sector, file numbers, etc). + +The data written on a CD-XA is consistent with and can be in ISO-9660 +file system format and therefore be readable by ISO-9660 file system +translators. But also a CD-I player can also read CD-XA discs even if +its own `Green Book' file system only resembles ISO 9660 and isn't +fully compatible. + + Note structure is big-endian. +*/ +typedef struct iso9660_xa_s +{ + uint16_t group_id; /**< 0 */ + uint16_t user_id; /**< 0 */ + uint16_t attributes; /**< XA_ATTR_ */ + char signature[2]; /**< { 'X', 'A' } */ + uint8_t filenum; /**< file number, see also XA subheader */ + uint8_t reserved[5]; /**< zero */ +} GNUC_PACKED iso9660_xa_t; + + + /*! + Returns POSIX mode bitstring for a given file. + */ + posix_mode_t iso9660_get_posix_filemode_from_xa(uint16_t i_perms); + +/*! + Returns a string interpreting the extended attribute xa_attr. + For example: + \verbatim + d---1xrxrxr + ---2--r-r-r + -a--1xrxrxr + \endverbatim + + A description of the characters in the string follows. + The 1st character is either "d" if the entry is a directory, or "-" if not + The 2nd character is either "a" if the entry is CDDA (audio), or "-" if not + The 3rd character is either "i" if the entry is interleaved, or "-" if not + The 4th character is either "2" if the entry is mode2 form2 or "-" if not + The 5th character is either "1" if the entry is mode2 form1 or "-" if not + Note that an entry will either be in mode2 form1 or mode form2. That + is you will either see "2-" or "-1" in the 4th & 5th positions. + + The 6th and 7th characters refer to permissions for a user while the + the 8th and 9th characters refer to permissions for a group while, and + the 10th and 11th characters refer to permissions for everyone. + + In each of these pairs the first character (6, 8, 10) is "x" if the + entry is executable. For a directory this means the directory is + allowed to be listed or "searched". + The second character of a pair (7, 9, 11) is "r" if the entry is allowed + to be read. +*/ +const char * +iso9660_get_xa_attr_str (uint16_t xa_attr); + +/*! + Allocates and initalizes a new iso9600_xa_t variable and returns + it. The caller should free the returned result. + + @see iso9660_xa +*/ +iso9660_xa_t * +iso9660_xa_init (iso9660_xa_t *_xa, uint16_t uid, uint16_t gid, uint16_t attr, + uint8_t filenum); + +#ifdef __cplusplus +} + +/** The below variables are trickery to force the above enum symbol + values to be recorded in debug symbol tables. They are used to + allow one to refer to the enumeration value names in the typedefs + above in a debugger and debugger expressions. +*/ +extern xa_misc_enum_t debugger_xa_misc_enum; + + +#endif /* __cplusplus */ + +#endif /* __CDIO_XA_H__ */ + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/curl/Makefile.am b/include/curl/Makefile.am new file mode 100644 index 00000000..a3b44438 --- /dev/null +++ b/include/curl/Makefile.am @@ -0,0 +1,25 @@ +pkginclude_HEADERS = \ + curl.h curlver.h easy.h mprintf.h stdcheaders.h types.h multi.h \ + typecheck-gcc.h curlbuild.h curlrules.h + +pkgincludedir= $(includedir)/curl + +# curlbuild.h does not exist in the git tree. When the original libcurl +# source code distribution archive file is created, curlbuild.h.dist is +# renamed to curlbuild.h and included in the tarball so that it can be +# used directly on non-configure systems. +# +# The distributed curlbuild.h will be overwritten on configure systems +# when the configure script runs, with one that is suitable and specific +# to the library being configured and built. +# +# curlbuild.h.in is the distributed template file from which the configure +# script creates curlbuild.h at library configuration time, overwiting the +# one included in the distribution archive. +# +# curlbuild.h.dist is not included in the source code distribution archive. + +EXTRA_DIST = curlbuild.h.in + +DISTCLEANFILES = curlbuild.h + diff --git a/include/curl/curl.h b/include/curl/curl.h new file mode 100644 index 00000000..cb9d0fbf --- /dev/null +++ b/include/curl/curl.h @@ -0,0 +1,2119 @@ +#ifndef __CURL_CURL_H +#define __CURL_CURL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * If you have libcurl problems, all docs and details are found here: + * http://curl.haxx.se/libcurl/ + * + * curl-library mailing list subscription and unsubscription web interface: + * http://cool.haxx.se/mailman/listinfo/curl-library/ + */ + +#include "curlver.h" /* libcurl version defines */ +#include "curlbuild.h" /* libcurl build definitions */ +#include "curlrules.h" /* libcurl rules enforcement */ + +/* + * Define WIN32 when build target is Win32 API + */ + +#if (defined(_WIN32) || defined(__WIN32__)) && \ + !defined(WIN32) && !defined(__SYMBIAN32__) +#define WIN32 +#endif + +#include <stdio.h> +#include <limits.h> + +#if defined(__FreeBSD__) && (__FreeBSD__ >= 2) +/* Needed for __FreeBSD_version symbol definition */ +#include <osreldate.h> +#endif + +/* The include stuff here below is mainly for time_t! */ +#include <sys/types.h> +#include <time.h> + +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \ + !defined(__CYGWIN__) || defined(__MINGW32__) +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H)) +/* The check above prevents the winsock2 inclusion if winsock.h already was + included, since they can't co-exist without problems */ +#include <winsock2.h> +#include <ws2tcpip.h> +#endif +#else + +/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish + libc5-based Linux systems. Only include it on system that are known to + require it! */ +#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ + defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ + defined(ANDROID) || \ + (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) +#include <sys/select.h> +#endif + +#ifndef _WIN32_WCE +#include <sys/socket.h> +#endif +#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) +#include <sys/time.h> +#endif +#include <sys/types.h> +#endif + +#ifdef __BEOS__ +#include <support/SupportDefs.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void CURL; + +/* + * Decorate exportable functions for Win32 and Symbian OS DLL linking. + * This avoids using a .def file for building libcurl.dll. + */ +#if (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)) && \ + !defined(CURL_STATICLIB) +#if defined(BUILDING_LIBCURL) +#define CURL_EXTERN __declspec(dllexport) +#else +#define CURL_EXTERN __declspec(dllimport) +#endif +#else + +#ifdef CURL_HIDDEN_SYMBOLS +/* + * This definition is used to make external definitions visible in the + * shared library when symbols are hidden by default. It makes no + * difference when compiling applications whether this is set or not, + * only when compiling the library. + */ +#define CURL_EXTERN CURL_EXTERN_SYMBOL +#else +#define CURL_EXTERN +#endif +#endif + +#ifndef curl_socket_typedef +/* socket typedef */ +#ifdef WIN32 +typedef SOCKET curl_socket_t; +#define CURL_SOCKET_BAD INVALID_SOCKET +#else +typedef int curl_socket_t; +#define CURL_SOCKET_BAD -1 +#endif +#define curl_socket_typedef +#endif /* curl_socket_typedef */ + +struct curl_httppost { + struct curl_httppost *next; /* next entry in the list */ + char *name; /* pointer to allocated name */ + long namelength; /* length of name length */ + char *contents; /* pointer to allocated data contents */ + long contentslength; /* length of contents field */ + char *buffer; /* pointer to allocated buffer contents */ + long bufferlength; /* length of buffer field */ + char *contenttype; /* Content-Type */ + struct curl_slist* contentheader; /* list of extra headers for this form */ + struct curl_httppost *more; /* if one field name has more than one + file, this link should link to following + files */ + long flags; /* as defined below */ +#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */ +#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */ +#define HTTPPOST_PTRNAME (1<<2) /* name is only stored pointer + do not free in formfree */ +#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer + do not free in formfree */ +#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */ +#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */ +#define HTTPPOST_CALLBACK (1<<6) /* upload file contents by using the + regular read callback to get the data + and pass the given pointer as custom + pointer */ + + char *showfilename; /* The file name to show. If not set, the + actual file name will be used (if this + is a file part) */ + void *userp; /* custom pointer used for + HTTPPOST_CALLBACK posts */ +}; + +typedef int (*curl_progress_callback)(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); + +#ifndef CURL_MAX_WRITE_SIZE + /* Tests have proven that 20K is a very bad buffer size for uploads on + Windows, while 16K for some odd reason performed a lot better. + We do the ifndef check to allow this value to easier be changed at build + time for those who feel adventurous. The practical minimum is about + 400 bytes since libcurl uses a buffer of this size as a scratch area + (unrelated to network send operations). */ +#define CURL_MAX_WRITE_SIZE 16384 +#endif + +#ifndef CURL_MAX_HTTP_HEADER +/* The only reason to have a max limit for this is to avoid the risk of a bad + server feeding libcurl with a never-ending header that will cause reallocs + infinitely */ +#define CURL_MAX_HTTP_HEADER (100*1024) +#endif + + +/* This is a magic return code for the write callback that, when returned, + will signal libcurl to pause receiving on the current transfer. */ +#define CURL_WRITEFUNC_PAUSE 0x10000001 +typedef size_t (*curl_write_callback)(char *buffer, + size_t size, + size_t nitems, + void *outstream); + + + +/* enumeration of file types */ +typedef enum { + CURLFILETYPE_FILE = 0, + CURLFILETYPE_DIRECTORY, + CURLFILETYPE_SYMLINK, + CURLFILETYPE_DEVICE_BLOCK, + CURLFILETYPE_DEVICE_CHAR, + CURLFILETYPE_NAMEDPIPE, + CURLFILETYPE_SOCKET, + CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ + + CURLFILETYPE_UNKNOWN /* should never occur */ +} curlfiletype; + +#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) +#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) +#define CURLFINFOFLAG_KNOWN_TIME (1<<2) +#define CURLFINFOFLAG_KNOWN_PERM (1<<3) +#define CURLFINFOFLAG_KNOWN_UID (1<<4) +#define CURLFINFOFLAG_KNOWN_GID (1<<5) +#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) +#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) + +/* Content of this structure depends on information which is known and is + achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man + page for callbacks returning this structure -- some fields are mandatory, + some others are optional. The FLAG field has special meaning. */ +struct curl_fileinfo { + char *filename; + curlfiletype filetype; + time_t time; + unsigned int perm; + int uid; + int gid; + curl_off_t size; + long int hardlinks; + + struct { + /* If some of these fields is not NULL, it is a pointer to b_data. */ + char *time; + char *perm; + char *user; + char *group; + char *target; /* pointer to the target filename of a symlink */ + } strings; + + unsigned int flags; + + /* used internally */ + char * b_data; + size_t b_size; + size_t b_used; +}; + +/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ +#define CURL_CHUNK_BGN_FUNC_OK 0 +#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ +#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ + +/* if splitting of data transfer is enabled, this callback is called before + download of an individual chunk started. Note that parameter "remains" works + only for FTP wildcard downloading (for now), otherwise is not used */ +typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, + void *ptr, + int remains); + +/* return codes for CURLOPT_CHUNK_END_FUNCTION */ +#define CURL_CHUNK_END_FUNC_OK 0 +#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ + +/* If splitting of data transfer is enabled this callback is called after + download of an individual chunk finished. + Note! After this callback was set then it have to be called FOR ALL chunks. + Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. + This is the reason why we don't need "transfer_info" parameter in this + callback and we are not interested in "remains" parameter too. */ +typedef long (*curl_chunk_end_callback)(void *ptr); + +/* return codes for FNMATCHFUNCTION */ +#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ +#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ +#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ + +/* callback type for wildcard downloading pattern matching. If the + string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ +typedef int (*curl_fnmatch_callback)(void *ptr, + const char *pattern, + const char *string); + +/* These are the return codes for the seek callbacks */ +#define CURL_SEEKFUNC_OK 0 +#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ +#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so + libcurl might try other means instead */ +typedef int (*curl_seek_callback)(void *instream, + curl_off_t offset, + int origin); /* 'whence' */ + +/* This is a return code for the read callback that, when returned, will + signal libcurl to immediately abort the current transfer. */ +#define CURL_READFUNC_ABORT 0x10000000 +/* This is a return code for the read callback that, when returned, will + signal libcurl to pause sending data on the current transfer. */ +#define CURL_READFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_read_callback)(char *buffer, + size_t size, + size_t nitems, + void *instream); + +typedef enum { + CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ + CURLSOCKTYPE_LAST /* never use */ +} curlsocktype; + +typedef int (*curl_sockopt_callback)(void *clientp, + curl_socket_t curlfd, + curlsocktype purpose); + +struct curl_sockaddr { + int family; + int socktype; + int protocol; + unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it + turned really ugly and painful on the systems that + lack this type */ + struct sockaddr addr; +}; + +typedef curl_socket_t +(*curl_opensocket_callback)(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address); + +typedef enum { + CURLIOE_OK, /* I/O operation successful */ + CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ + CURLIOE_FAILRESTART, /* failed to restart the read */ + CURLIOE_LAST /* never use */ +} curlioerr; + +typedef enum { + CURLIOCMD_NOP, /* no operation */ + CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ + CURLIOCMD_LAST /* never use */ +} curliocmd; + +typedef curlioerr (*curl_ioctl_callback)(CURL *handle, + int cmd, + void *clientp); + +/* + * The following typedef's are signatures of malloc, free, realloc, strdup and + * calloc respectively. Function pointers of these types can be passed to the + * curl_global_init_mem() function to set user defined memory management + * callback routines. + */ +typedef void *(*curl_malloc_callback)(size_t size); +typedef void (*curl_free_callback)(void *ptr); +typedef void *(*curl_realloc_callback)(void *ptr, size_t size); +typedef char *(*curl_strdup_callback)(const char *str); +typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); + +/* the kind of data that is passed to information_callback*/ +typedef enum { + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN, /* 1 */ + CURLINFO_HEADER_OUT, /* 2 */ + CURLINFO_DATA_IN, /* 3 */ + CURLINFO_DATA_OUT, /* 4 */ + CURLINFO_SSL_DATA_IN, /* 5 */ + CURLINFO_SSL_DATA_OUT, /* 6 */ + CURLINFO_END +} curl_infotype; + +typedef int (*curl_debug_callback) + (CURL *handle, /* the handle/transfer this concerns */ + curl_infotype type, /* what kind of data */ + char *data, /* points to the data */ + size_t size, /* size of the data pointed to */ + void *userptr); /* whatever the user please */ + +/* All possible error codes from all sorts of curl functions. Future versions + may return other values, stay prepared. + + Always add new return codes last. Never *EVER* remove any. The return + codes must remain the same! + */ + +typedef enum { + CURLE_OK = 0, + CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ + CURLE_FAILED_INIT, /* 2 */ + CURLE_URL_MALFORMAT, /* 3 */ + CURLE_OBSOLETE4, /* 4 - NOT USED */ + CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ + CURLE_COULDNT_RESOLVE_HOST, /* 6 */ + CURLE_COULDNT_CONNECT, /* 7 */ + CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server + due to lack of access - when login fails + this is not returned. */ + CURLE_OBSOLETE10, /* 10 - NOT USED */ + CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ + CURLE_OBSOLETE12, /* 12 - NOT USED */ + CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ + CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ + CURLE_FTP_CANT_GET_HOST, /* 15 */ + CURLE_OBSOLETE16, /* 16 - NOT USED */ + CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ + CURLE_PARTIAL_FILE, /* 18 */ + CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ + CURLE_OBSOLETE20, /* 20 - NOT USED */ + CURLE_QUOTE_ERROR, /* 21 - quote command failure */ + CURLE_HTTP_RETURNED_ERROR, /* 22 */ + CURLE_WRITE_ERROR, /* 23 */ + CURLE_OBSOLETE24, /* 24 - NOT USED */ + CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ + CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ + CURLE_OUT_OF_MEMORY, /* 27 */ + /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error + instead of a memory allocation error if CURL_DOES_CONVERSIONS + is defined + */ + CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ + CURLE_OBSOLETE29, /* 29 - NOT USED */ + CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ + CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ + CURLE_OBSOLETE32, /* 32 - NOT USED */ + CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ + CURLE_HTTP_POST_ERROR, /* 34 */ + CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ + CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ + CURLE_FILE_COULDNT_READ_FILE, /* 37 */ + CURLE_LDAP_CANNOT_BIND, /* 38 */ + CURLE_LDAP_SEARCH_FAILED, /* 39 */ + CURLE_OBSOLETE40, /* 40 - NOT USED */ + CURLE_FUNCTION_NOT_FOUND, /* 41 */ + CURLE_ABORTED_BY_CALLBACK, /* 42 */ + CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ + CURLE_OBSOLETE44, /* 44 - NOT USED */ + CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ + CURLE_OBSOLETE46, /* 46 - NOT USED */ + CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */ + CURLE_UNKNOWN_TELNET_OPTION, /* 48 - User specified an unknown option */ + CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */ + CURLE_OBSOLETE50, /* 50 - NOT USED */ + CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint + wasn't verified fine */ + CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ + CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ + CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as + default */ + CURLE_SEND_ERROR, /* 55 - failed sending network data */ + CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ + CURLE_OBSOLETE57, /* 57 - NOT IN USE */ + CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ + CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ + CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ + CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized transfer encoding */ + CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ + CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ + CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ + CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind + that failed */ + CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ + CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not + accepted and we failed to login */ + CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ + CURLE_TFTP_PERM, /* 69 - permission problem on server */ + CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ + CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ + CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ + CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ + CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ + CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_CONV_REQD, /* 76 - caller must register conversion + callbacks using curl_easy_setopt options + CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOPT_CONV_TO_NETWORK_FUNCTION, and + CURLOPT_CONV_FROM_UTF8_FUNCTION */ + CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing + or wrong format */ + CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ + CURLE_SSH, /* 79 - error from the SSH layer, somewhat + generic so the error message will be of + interest when this has happened */ + + CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL + connection */ + CURLE_AGAIN, /* 81 - socket is not ready for send/recv, + wait till it's ready and try again (Added + in 7.18.2) */ + CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or + wrong format (Added in 7.19.0) */ + CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in + 7.19.0) */ + CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ + CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ + CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Identifiers */ + CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ + CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ + + CURL_LAST /* never use! */ +} CURLcode; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ + +/* The following were added in 7.17.1 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION + +/* The following were added in 7.17.0 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* noone should be using this! */ +#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 +#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 +#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 +#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 +#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 +#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 +#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 +#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 +#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 +#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 +#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 +#define CURLE_URL_MALFORMAT_USER CURLE_OBSOLETE4 + +#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED +#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE +#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR +#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL +#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS +#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR +#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED + +/* The following were added earlier */ + +#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT + +#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR +#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED +#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED + +#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE +#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME + +/* This was the error code 50 in 7.7.3 and a few earlier versions, this + is no longer used by libcurl but is instead #defined here only to not + make programs break */ +#define CURLE_ALREADY_COMPLETE 99999 + +#endif /*!CURL_NO_OLDIES*/ + +/* This prototype applies to all conversion callbacks */ +typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); + +typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ + void *ssl_ctx, /* actually an + OpenSSL SSL_CTX */ + void *userptr); + +typedef enum { + CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use + CONNECT HTTP/1.1 */ + CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT + HTTP/1.0 */ + CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already + in 7.10 */ + CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ + CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ + CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the + host name rather than the IP address. added + in 7.18.0 */ +} curl_proxytype; /* this enum was added in 7.10 */ + +#define CURLAUTH_NONE 0 /* nothing */ +#define CURLAUTH_BASIC (1<<0) /* Basic (default) */ +#define CURLAUTH_DIGEST (1<<1) /* Digest */ +#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */ +#define CURLAUTH_NTLM (1<<3) /* NTLM */ +#define CURLAUTH_DIGEST_IE (1<<4) /* Digest with IE flavour */ +#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) /* all fine types set */ +#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) + +#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ +#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ +#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ +#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ +#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ +#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY + +#define CURL_ERROR_SIZE 256 + +struct curl_khkey { + const char *key; /* points to a zero-terminated string encoded with base64 + if len is zero, otherwise to the "raw" data */ + size_t len; + enum type { + CURLKHTYPE_UNKNOWN, + CURLKHTYPE_RSA1, + CURLKHTYPE_RSA, + CURLKHTYPE_DSS + } keytype; +}; + +/* this is the set of return values expected from the curl_sshkeycallback + callback */ +enum curl_khstat { + CURLKHSTAT_FINE_ADD_TO_FILE, + CURLKHSTAT_FINE, + CURLKHSTAT_REJECT, /* reject the connection, return an error */ + CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so + this causes a CURLE_DEFER error but otherwise the + connection will be left intact etc */ + CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ +}; + +/* this is the set of status codes pass in to the callback */ +enum curl_khmatch { + CURLKHMATCH_OK, /* match */ + CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ + CURLKHMATCH_MISSING, /* no matching host/key found */ + CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ +}; + +typedef int + (*curl_sshkeycallback) (CURL *easy, /* easy handle */ + const struct curl_khkey *knownkey, /* known */ + const struct curl_khkey *foundkey, /* found */ + enum curl_khmatch, /* libcurl's view on the keys */ + void *clientp); /* custom pointer passed from app */ + +/* parameter for the CURLOPT_USE_SSL option */ +typedef enum { + CURLUSESSL_NONE, /* do not attempt to use SSL */ + CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ + CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ + CURLUSESSL_ALL, /* SSL for all communication or fail */ + CURLUSESSL_LAST /* not an option, never use */ +} curl_usessl; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2009 */ + +#define CURLFTPSSL_NONE CURLUSESSL_NONE +#define CURLFTPSSL_TRY CURLUSESSL_TRY +#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL +#define CURLFTPSSL_ALL CURLUSESSL_ALL +#define CURLFTPSSL_LAST CURLUSESSL_LAST +#define curl_ftpssl curl_usessl +#endif /*!CURL_NO_OLDIES*/ + +/* parameter for the CURLOPT_FTP_SSL_CCC option */ +typedef enum { + CURLFTPSSL_CCC_NONE, /* do not send CCC */ + CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ + CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ + CURLFTPSSL_CCC_LAST /* not an option, never use */ +} curl_ftpccc; + +/* parameter for the CURLOPT_FTPSSLAUTH option */ +typedef enum { + CURLFTPAUTH_DEFAULT, /* let libcurl decide */ + CURLFTPAUTH_SSL, /* use "AUTH SSL" */ + CURLFTPAUTH_TLS, /* use "AUTH TLS" */ + CURLFTPAUTH_LAST /* not an option, never use */ +} curl_ftpauth; + +/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ +typedef enum { + CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ + CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD + again if MKD succeeded, for SFTP this does + similar magic */ + CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD + again even if MKD failed! */ + CURLFTP_CREATE_DIR_LAST /* not an option, never use */ +} curl_ftpcreatedir; + +/* parameter for the CURLOPT_FTP_FILEMETHOD option */ +typedef enum { + CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ + CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ + CURLFTPMETHOD_NOCWD, /* no CWD at all */ + CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ + CURLFTPMETHOD_LAST /* not an option, never use */ +} curl_ftpmethod; + +/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ +#define CURLPROTO_HTTP (1<<0) +#define CURLPROTO_HTTPS (1<<1) +#define CURLPROTO_FTP (1<<2) +#define CURLPROTO_FTPS (1<<3) +#define CURLPROTO_SCP (1<<4) +#define CURLPROTO_SFTP (1<<5) +#define CURLPROTO_TELNET (1<<6) +#define CURLPROTO_LDAP (1<<7) +#define CURLPROTO_LDAPS (1<<8) +#define CURLPROTO_DICT (1<<9) +#define CURLPROTO_FILE (1<<10) +#define CURLPROTO_TFTP (1<<11) +#define CURLPROTO_IMAP (1<<12) +#define CURLPROTO_IMAPS (1<<13) +#define CURLPROTO_POP3 (1<<14) +#define CURLPROTO_POP3S (1<<15) +#define CURLPROTO_SMTP (1<<16) +#define CURLPROTO_SMTPS (1<<17) +#define CURLPROTO_RTSP (1<<18) +#define CURLPROTO_RTMP (1<<19) +#define CURLPROTO_RTMPT (1<<20) +#define CURLPROTO_RTMPE (1<<21) +#define CURLPROTO_RTMPTE (1<<22) +#define CURLPROTO_RTMPS (1<<23) +#define CURLPROTO_RTMPTS (1<<24) +#define CURLPROTO_GOPHER (1<<25) +#define CURLPROTO_ALL (~0) /* enable everything */ + +/* long may be 32 or 64 bits, but we should never depend on anything else + but 32 */ +#define CURLOPTTYPE_LONG 0 +#define CURLOPTTYPE_OBJECTPOINT 10000 +#define CURLOPTTYPE_FUNCTIONPOINT 20000 +#define CURLOPTTYPE_OFF_T 30000 + +/* name is uppercase CURLOPT_<name>, + type is one of the defined CURLOPTTYPE_<type> + number is unique identifier */ +#ifdef CINIT +#undef CINIT +#endif + +#ifdef CURL_ISOCPP +#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLOPT_/**/name = type + number +#endif + +/* + * This macro-mania below setups the CURLOPT_[what] enum, to be used with + * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] + * word. + */ + +typedef enum { + /* This is the FILE * or void * the regular output should be written to. */ + CINIT(FILE, OBJECTPOINT, 1), + + /* The full URL to get/put */ + CINIT(URL, OBJECTPOINT, 2), + + /* Port number to connect to, if other than default. */ + CINIT(PORT, LONG, 3), + + /* Name of proxy to use. */ + CINIT(PROXY, OBJECTPOINT, 4), + + /* "name:password" to use when fetching. */ + CINIT(USERPWD, OBJECTPOINT, 5), + + /* "name:password" to use with proxy. */ + CINIT(PROXYUSERPWD, OBJECTPOINT, 6), + + /* Range to get, specified as an ASCII string. */ + CINIT(RANGE, OBJECTPOINT, 7), + + /* not used */ + + /* Specified file stream to upload from (use as input): */ + CINIT(INFILE, OBJECTPOINT, 9), + + /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE + * bytes big. If this is not used, error messages go to stderr instead: */ + CINIT(ERRORBUFFER, OBJECTPOINT, 10), + + /* Function that will be called to store the output (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), + + /* Function that will be called to read the input (instead of fread). The + * parameters will use fread() syntax, make sure to follow them. */ + CINIT(READFUNCTION, FUNCTIONPOINT, 12), + + /* Time-out the read operation after this amount of seconds */ + CINIT(TIMEOUT, LONG, 13), + + /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about + * how large the file being sent really is. That allows better error + * checking and better verifies that the upload was successful. -1 means + * unknown size. + * + * For large file support, there is also a _LARGE version of the key + * which takes an off_t type, allowing platforms with larger off_t + * sizes to handle larger files. See below for INFILESIZE_LARGE. + */ + CINIT(INFILESIZE, LONG, 14), + + /* POST static input fields. */ + CINIT(POSTFIELDS, OBJECTPOINT, 15), + + /* Set the referrer page (needed by some CGIs) */ + CINIT(REFERER, OBJECTPOINT, 16), + + /* Set the FTP PORT string (interface name, named or numerical IP address) + Use i.e '-' to use default address. */ + CINIT(FTPPORT, OBJECTPOINT, 17), + + /* Set the User-Agent string (examined by some CGIs) */ + CINIT(USERAGENT, OBJECTPOINT, 18), + + /* If the download receives less than "low speed limit" bytes/second + * during "low speed time" seconds, the operations is aborted. + * You could i.e if you have a pretty high speed connection, abort if + * it is less than 2000 bytes/sec during 20 seconds. + */ + + /* Set the "low speed limit" */ + CINIT(LOW_SPEED_LIMIT, LONG, 19), + + /* Set the "low speed time" */ + CINIT(LOW_SPEED_TIME, LONG, 20), + + /* Set the continuation offset. + * + * Note there is also a _LARGE version of this key which uses + * off_t types, allowing for large file offsets on platforms which + * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. + */ + CINIT(RESUME_FROM, LONG, 21), + + /* Set cookie in request: */ + CINIT(COOKIE, OBJECTPOINT, 22), + + /* This points to a linked list of headers, struct curl_slist kind */ + CINIT(HTTPHEADER, OBJECTPOINT, 23), + + /* This points to a linked list of post entries, struct curl_httppost */ + CINIT(HTTPPOST, OBJECTPOINT, 24), + + /* name of the file keeping your private SSL-certificate */ + CINIT(SSLCERT, OBJECTPOINT, 25), + + /* password for the SSL or SSH private key */ + CINIT(KEYPASSWD, OBJECTPOINT, 26), + + /* send TYPE parameter? */ + CINIT(CRLF, LONG, 27), + + /* send linked-list of QUOTE commands */ + CINIT(QUOTE, OBJECTPOINT, 28), + + /* send FILE * or void * to store headers to, if you use a callback it + is simply passed to the callback unmodified */ + CINIT(WRITEHEADER, OBJECTPOINT, 29), + + /* point to a file to read the initial cookies from, also enables + "cookie awareness" */ + CINIT(COOKIEFILE, OBJECTPOINT, 31), + + /* What version to specifically try to use. + See CURL_SSLVERSION defines below. */ + CINIT(SSLVERSION, LONG, 32), + + /* What kind of HTTP time condition to use, see defines */ + CINIT(TIMECONDITION, LONG, 33), + + /* Time to use with the above condition. Specified in number of seconds + since 1 Jan 1970 */ + CINIT(TIMEVALUE, LONG, 34), + + /* 35 = OBSOLETE */ + + /* Custom request, for customizing the get command like + HTTP: DELETE, TRACE and others + FTP: to use a different list command + */ + CINIT(CUSTOMREQUEST, OBJECTPOINT, 36), + + /* HTTP request, for odd commands like DELETE, TRACE and others */ + CINIT(STDERR, OBJECTPOINT, 37), + + /* 38 is not used */ + + /* send linked-list of post-transfer QUOTE commands */ + CINIT(POSTQUOTE, OBJECTPOINT, 39), + + /* Pass a pointer to string of the output using full variable-replacement + as described elsewhere. */ + CINIT(WRITEINFO, OBJECTPOINT, 40), + + CINIT(VERBOSE, LONG, 41), /* talk a lot */ + CINIT(HEADER, LONG, 42), /* throw the header out too */ + CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ + CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ + CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */ + CINIT(UPLOAD, LONG, 46), /* this is an upload */ + CINIT(POST, LONG, 47), /* HTTP POST method */ + CINIT(DIRLISTONLY, LONG, 48), /* return bare names when listing directories */ + + CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ + + /* Specify whether to read the user+password from the .netrc or the URL. + * This must be one of the CURL_NETRC_* enums below. */ + CINIT(NETRC, LONG, 51), + + CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ + + CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ + CINIT(PUT, LONG, 54), /* HTTP PUT */ + + /* 55 = OBSOLETE */ + + /* Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_progress_callback + * prototype defines. */ + CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), + + /* Data passed to the progress callback */ + CINIT(PROGRESSDATA, OBJECTPOINT, 57), + + /* We want the referrer field set automatically when following locations */ + CINIT(AUTOREFERER, LONG, 58), + + /* Port of the proxy, can be set in the proxy string as well with: + "[host]:[port]" */ + CINIT(PROXYPORT, LONG, 59), + + /* size of the POST input data, if strlen() is not good to use */ + CINIT(POSTFIELDSIZE, LONG, 60), + + /* tunnel non-http operations through a HTTP proxy */ + CINIT(HTTPPROXYTUNNEL, LONG, 61), + + /* Set the interface string to use as outgoing network interface */ + CINIT(INTERFACE, OBJECTPOINT, 62), + + /* Set the krb4/5 security level, this also enables krb4/5 awareness. This + * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string + * is set but doesn't match one of these, 'private' will be used. */ + CINIT(KRBLEVEL, OBJECTPOINT, 63), + + /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ + CINIT(SSL_VERIFYPEER, LONG, 64), + + /* The CApath or CAfile used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAINFO, OBJECTPOINT, 65), + + /* 66 = OBSOLETE */ + /* 67 = OBSOLETE */ + + /* Maximum number of http redirects to follow */ + CINIT(MAXREDIRS, LONG, 68), + + /* Pass a long set to 1 to get the date of the requested document (if + possible)! Pass a zero to shut it off. */ + CINIT(FILETIME, LONG, 69), + + /* This points to a linked list of telnet options */ + CINIT(TELNETOPTIONS, OBJECTPOINT, 70), + + /* Max amount of cached alive connections */ + CINIT(MAXCONNECTS, LONG, 71), + + /* What policy to use when closing connections when the cache is filled + up */ + CINIT(CLOSEPOLICY, LONG, 72), + + /* 73 = OBSOLETE */ + + /* Set to explicitly use a new connection for the upcoming transfer. + Do not use this unless you're absolutely sure of this, as it makes the + operation slower and is less friendly for the network. */ + CINIT(FRESH_CONNECT, LONG, 74), + + /* Set to explicitly forbid the upcoming transfer's connection to be re-used + when done. Do not use this unless you're absolutely sure of this, as it + makes the operation slower and is less friendly for the network. */ + CINIT(FORBID_REUSE, LONG, 75), + + /* Set to a file name that contains random data for libcurl to use to + seed the random engine when doing SSL connects. */ + CINIT(RANDOM_FILE, OBJECTPOINT, 76), + + /* Set to the Entropy Gathering Daemon socket pathname */ + CINIT(EGDSOCKET, OBJECTPOINT, 77), + + /* Time-out connect operations after this amount of seconds, if connects + are OK within this time, then fine... This only aborts the connect + phase. [Only works on unix-style/SIGALRM operating systems] */ + CINIT(CONNECTTIMEOUT, LONG, 78), + + /* Function that will be called to store headers (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), + + /* Set this to force the HTTP request to get back to GET. Only really usable + if POST, PUT or a custom request have been used first. + */ + CINIT(HTTPGET, LONG, 80), + + /* Set if we should verify the Common name from the peer certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches the + * provided hostname. */ + CINIT(SSL_VERIFYHOST, LONG, 81), + + /* Specify which file name to write all known cookies in after completed + operation. Set file name to "-" (dash) to make it go to stdout. */ + CINIT(COOKIEJAR, OBJECTPOINT, 82), + + /* Specify which SSL ciphers to use */ + CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83), + + /* Specify which HTTP version to use! This must be set to one of the + CURL_HTTP_VERSION* enums set below. */ + CINIT(HTTP_VERSION, LONG, 84), + + /* Specifically switch on or off the FTP engine's use of the EPSV command. By + default, that one will always be attempted before the more traditional + PASV command. */ + CINIT(FTP_USE_EPSV, LONG, 85), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ + CINIT(SSLCERTTYPE, OBJECTPOINT, 86), + + /* name of the file keeping your private SSL-key */ + CINIT(SSLKEY, OBJECTPOINT, 87), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ + CINIT(SSLKEYTYPE, OBJECTPOINT, 88), + + /* crypto engine for the SSL-sub system */ + CINIT(SSLENGINE, OBJECTPOINT, 89), + + /* set the crypto engine for the SSL-sub system as default + the param has no meaning... + */ + CINIT(SSLENGINE_DEFAULT, LONG, 90), + + /* Non-zero value means to use the global dns cache */ + CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* To become OBSOLETE soon */ + + /* DNS cache timeout */ + CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + + /* send linked-list of pre-transfer QUOTE commands */ + CINIT(PREQUOTE, OBJECTPOINT, 93), + + /* set the debug function */ + CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + + /* set the data for the debug function */ + CINIT(DEBUGDATA, OBJECTPOINT, 95), + + /* mark this as start of a cookie session */ + CINIT(COOKIESESSION, LONG, 96), + + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAPATH, OBJECTPOINT, 97), + + /* Instruct libcurl to use a smaller receive buffer */ + CINIT(BUFFERSIZE, LONG, 98), + + /* Instruct libcurl to not use any signal/alarm handlers, even when using + timeouts. This option is useful for multi-threaded applications. + See libcurl-the-guide for more background information. */ + CINIT(NOSIGNAL, LONG, 99), + + /* Provide a CURLShare for mutexing non-ts data */ + CINIT(SHARE, OBJECTPOINT, 100), + + /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), + CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */ + CINIT(PROXYTYPE, LONG, 101), + + /* Set the Accept-Encoding string. Use this to tell a server you would like + the response to be compressed. */ + CINIT(ENCODING, OBJECTPOINT, 102), + + /* Set pointer to private data */ + CINIT(PRIVATE, OBJECTPOINT, 103), + + /* Set aliases for HTTP 200 in the HTTP Response header */ + CINIT(HTTP200ALIASES, OBJECTPOINT, 104), + + /* Continue to send authentication (user+password) when following locations, + even when hostname changed. This can potentially send off the name + and password to whatever host the server decides. */ + CINIT(UNRESTRICTED_AUTH, LONG, 105), + + /* Specifically switch on or off the FTP engine's use of the EPRT command ( it + also disables the LPRT attempt). By default, those ones will always be + attempted before the good old traditional PORT command. */ + CINIT(FTP_USE_EPRT, LONG, 106), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_USERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(HTTPAUTH, LONG, 107), + + /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx + in second argument. The function must be matching the + curl_ssl_ctx_callback proto. */ + CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), + + /* Set the userdata for the ssl context callback function's third + argument */ + CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), + + /* FTP Option that causes missing dirs to be created on the remote server. + In 7.19.4 we introduced the convenience enums for this option using the + CURLFTP_CREATE_DIR prefix. + */ + CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(PROXYAUTH, LONG, 111), + + /* FTP option that changes the timeout, in seconds, associated with + getting a response. This is different from transfer timeout time and + essentially places a demand on the FTP server to acknowledge commands + in a timely manner. */ + CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), +#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT + + /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to + tell libcurl to resolve names to those IP versions only. This only has + affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ + CINIT(IPRESOLVE, LONG, 113), + + /* Set this option to limit the size of a file that will be downloaded from + an HTTP or FTP server. + + Note there is also _LARGE version which adds large file support for + platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ + CINIT(MAXFILESIZE, LONG, 114), + + /* See the comment for INFILESIZE above, but in short, specifies + * the size of the file being uploaded. -1 means unknown. + */ + CINIT(INFILESIZE_LARGE, OFF_T, 115), + + /* Sets the continuation offset. There is also a LONG version of this; + * look above for RESUME_FROM. + */ + CINIT(RESUME_FROM_LARGE, OFF_T, 116), + + /* Sets the maximum size of data that will be downloaded from + * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. + */ + CINIT(MAXFILESIZE_LARGE, OFF_T, 117), + + /* Set this option to the file name of your .netrc file you want libcurl + to parse (using the CURLOPT_NETRC option). If not set, libcurl will do + a poor attempt to find the user's home directory and check for a .netrc + file in there. */ + CINIT(NETRC_FILE, OBJECTPOINT, 118), + + /* Enable SSL/TLS for FTP, pick one of: + CURLFTPSSL_TRY - try using SSL, proceed anyway otherwise + CURLFTPSSL_CONTROL - SSL for the control connection or fail + CURLFTPSSL_ALL - SSL for all communication or fail + */ + CINIT(USE_SSL, LONG, 119), + + /* The _LARGE version of the standard POSTFIELDSIZE option */ + CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), + + /* Enable/disable the TCP Nagle algorithm */ + CINIT(TCP_NODELAY, LONG, 121), + + /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 123 OBSOLETE. Gone in 7.16.0 */ + /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 127 OBSOLETE. Gone in 7.16.0 */ + /* 128 OBSOLETE. Gone in 7.16.0 */ + + /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option + can be used to change libcurl's default action which is to first try + "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK + response has been received. + + Available parameters are: + CURLFTPAUTH_DEFAULT - let libcurl decide + CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS + CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL + */ + CINIT(FTPSSLAUTH, LONG, 129), + + CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), + CINIT(IOCTLDATA, OBJECTPOINT, 131), + + /* 132 OBSOLETE. Gone in 7.16.0 */ + /* 133 OBSOLETE. Gone in 7.16.0 */ + + /* zero terminated string for pass on to the FTP server when asked for + "account" info */ + CINIT(FTP_ACCOUNT, OBJECTPOINT, 134), + + /* feed cookies into cookie engine */ + CINIT(COOKIELIST, OBJECTPOINT, 135), + + /* ignore Content-Length */ + CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), + + /* Set to non-zero to skip the IP address received in a 227 PASV FTP server + response. Typically used for FTP-SSL purposes but is not restricted to + that. libcurl will then instead use the same IP address it used for the + control connection. */ + CINIT(FTP_SKIP_PASV_IP, LONG, 137), + + /* Select "file method" to use when doing FTP, see the curl_ftpmethod + above. */ + CINIT(FTP_FILEMETHOD, LONG, 138), + + /* Local port number to bind the socket to */ + CINIT(LOCALPORT, LONG, 139), + + /* Number of ports to try, including the first one set with LOCALPORT. + Thus, setting it to 1 will make no additional attempts but the first. + */ + CINIT(LOCALPORTRANGE, LONG, 140), + + /* no transfer, set up connection and let application use the socket by + extracting it with CURLINFO_LASTSOCKET */ + CINIT(CONNECT_ONLY, LONG, 141), + + /* Function that will be called to convert from the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + + /* Function that will be called to convert to the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + + /* Function that will be called to convert from UTF8 + (instead of using the iconv calls in libcurl) + Note that this is used only for SSL certificate processing */ + CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + + /* if the connection proceeds too quickly then need to slow it down */ + /* limit-rate: maximum number of bytes per second to send or receive */ + CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), + CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), + + /* Pointer to command string to send if USER/PASS fails. */ + CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147), + + /* callback function for setting socket options */ + CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), + CINIT(SOCKOPTDATA, OBJECTPOINT, 149), + + /* set to 0 to disable session ID re-use for this transfer, default is + enabled (== 1) */ + CINIT(SSL_SESSIONID_CACHE, LONG, 150), + + /* allowed SSH authentication methods */ + CINIT(SSH_AUTH_TYPES, LONG, 151), + + /* Used by scp/sftp to do public/private key authentication */ + CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152), + CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153), + + /* Send CCC (Clear Command Channel) after authentication */ + CINIT(FTP_SSL_CCC, LONG, 154), + + /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ + CINIT(TIMEOUT_MS, LONG, 155), + CINIT(CONNECTTIMEOUT_MS, LONG, 156), + + /* set to zero to disable the libcurl's decoding and thus pass the raw body + data to the application even when it is encoded/compressed */ + CINIT(HTTP_TRANSFER_DECODING, LONG, 157), + CINIT(HTTP_CONTENT_DECODING, LONG, 158), + + /* Permission used when creating new files and directories on the remote + server for protocols that support it, SFTP/SCP/FILE */ + CINIT(NEW_FILE_PERMS, LONG, 159), + CINIT(NEW_DIRECTORY_PERMS, LONG, 160), + + /* Set the behaviour of POST when redirecting. Values must be set to one + of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ + CINIT(POSTREDIR, LONG, 161), + + /* used by scp/sftp to verify the host's public key */ + CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162), + + /* Callback function for opening socket (instead of socket(2)). Optionally, + callback is able change the address or refuse to connect returning + CURL_SOCKET_BAD. The callback should have type + curl_opensocket_callback */ + CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), + CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), + + /* POST volatile input fields. */ + CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), + + /* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy */ + CINIT(PROXY_TRANSFER_MODE, LONG, 166), + + /* Callback function for seeking in the input stream */ + CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), + CINIT(SEEKDATA, OBJECTPOINT, 168), + + /* CRL file */ + CINIT(CRLFILE, OBJECTPOINT, 169), + + /* Issuer certificate */ + CINIT(ISSUERCERT, OBJECTPOINT, 170), + + /* (IPv6) Address scope */ + CINIT(ADDRESS_SCOPE, LONG, 171), + + /* Collect certificate chain info and allow it to get retrievable with + CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only + working with OpenSSL-powered builds. */ + CINIT(CERTINFO, LONG, 172), + + /* "name" and "pwd" to use when fetching. */ + CINIT(USERNAME, OBJECTPOINT, 173), + CINIT(PASSWORD, OBJECTPOINT, 174), + + /* "name" and "pwd" to use with Proxy when fetching. */ + CINIT(PROXYUSERNAME, OBJECTPOINT, 175), + CINIT(PROXYPASSWORD, OBJECTPOINT, 176), + + /* Comma separated list of hostnames defining no-proxy zones. These should + match both hostnames directly, and hostnames within a domain. For + example, local.com will match local.com and www.local.com, but NOT + notlocal.com or www.notlocal.com. For compatibility with other + implementations of this, .local.com will be considered to be the same as + local.com. A single * is the only valid wildcard, and effectively + disables the use of proxy. */ + CINIT(NOPROXY, OBJECTPOINT, 177), + + /* block size for TFTP transfers */ + CINIT(TFTP_BLKSIZE, LONG, 178), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_SERVICE, OBJECTPOINT, 179), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), + + /* set the bitmask for the protocols that are allowed to be used for the + transfer, which thus helps the app which takes URLs from users or other + external inputs and want to restrict what protocol(s) to deal + with. Defaults to CURLPROTO_ALL. */ + CINIT(PROTOCOLS, LONG, 181), + + /* set the bitmask for the protocols that libcurl is allowed to follow to, + as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs + to be set in both bitmasks to be allowed to get redirected to. Defaults + to all protocols except FILE and SCP. */ + CINIT(REDIR_PROTOCOLS, LONG, 182), + + /* set the SSH knownhost file name to use */ + CINIT(SSH_KNOWNHOSTS, OBJECTPOINT, 183), + + /* set the SSH host key callback, must point to a curl_sshkeycallback + function */ + CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), + + /* set the SSH host key callback custom pointer */ + CINIT(SSH_KEYDATA, OBJECTPOINT, 185), + + /* set the SMTP mail originator */ + CINIT(MAIL_FROM, OBJECTPOINT, 186), + + /* set the SMTP mail receiver(s) */ + CINIT(MAIL_RCPT, OBJECTPOINT, 187), + + /* FTP: send PRET before PASV */ + CINIT(FTP_USE_PRET, LONG, 188), + + /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ + CINIT(RTSP_REQUEST, LONG, 189), + + /* The RTSP session identifier */ + CINIT(RTSP_SESSION_ID, OBJECTPOINT, 190), + + /* The RTSP stream URI */ + CINIT(RTSP_STREAM_URI, OBJECTPOINT, 191), + + /* The Transport: header to use in RTSP requests */ + CINIT(RTSP_TRANSPORT, OBJECTPOINT, 192), + + /* Manually initialize the client RTSP CSeq for this handle */ + CINIT(RTSP_CLIENT_CSEQ, LONG, 193), + + /* Manually initialize the server RTSP CSeq for this handle */ + CINIT(RTSP_SERVER_CSEQ, LONG, 194), + + /* The stream to pass to INTERLEAVEFUNCTION. */ + CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), + + /* Let the application define a custom write method for RTP data */ + CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), + + /* Turn on wildcard matching */ + CINIT(WILDCARDMATCH, LONG, 197), + + /* Directory matching callback called before downloading of an + individual file (chunk) started */ + CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), + + /* Directory matching callback called after the file (chunk) + was downloaded, or skipped */ + CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), + + /* Change match (fnmatch-like) callback for wildcard matching */ + CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), + + /* Let the application define custom chunk data pointer */ + CINIT(CHUNK_DATA, OBJECTPOINT, 201), + + /* FNMATCH_FUNCTION user pointer */ + CINIT(FNMATCH_DATA, OBJECTPOINT, 202), + + CURLOPT_LASTENTRY /* the last unused */ +} CURLoption; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2011 */ + +/* This was added in version 7.19.1 */ +#define CURLOPT_POST301 CURLOPT_POSTREDIR + +/* These are scheduled to disappear by 2009 */ + +/* The following were added in 7.17.0 */ +#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_FTPAPPEND CURLOPT_APPEND +#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY +#define CURLOPT_FTP_SSL CURLOPT_USE_SSL + +/* The following were added earlier */ + +#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL + +#else +/* This is set if CURL_NO_OLDIES is defined at compile-time */ +#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ +#endif + + + /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host + name resolves addresses using more than one IP protocol version, this + option might be handy to force libcurl to use a specific IP version. */ +#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP + versions that your system allows */ +#define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */ +#define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */ + + /* three convenient "aliases" that follow the name scheme better */ +#define CURLOPT_WRITEDATA CURLOPT_FILE +#define CURLOPT_READDATA CURLOPT_INFILE +#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER +#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER + + /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ +enum { + CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd + like the library to choose the best possible + for us! */ + CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ + CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ + + CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ +}; + +/* + * Public API enums for RTSP requests + */ +enum { + CURL_RTSPREQ_NONE, /* first in list */ + CURL_RTSPREQ_OPTIONS, + CURL_RTSPREQ_DESCRIBE, + CURL_RTSPREQ_ANNOUNCE, + CURL_RTSPREQ_SETUP, + CURL_RTSPREQ_PLAY, + CURL_RTSPREQ_PAUSE, + CURL_RTSPREQ_TEARDOWN, + CURL_RTSPREQ_GET_PARAMETER, + CURL_RTSPREQ_SET_PARAMETER, + CURL_RTSPREQ_RECORD, + CURL_RTSPREQ_RECEIVE, + CURL_RTSPREQ_LAST /* last in list */ +}; + + /* These enums are for use with the CURLOPT_NETRC option. */ +enum CURL_NETRC_OPTION { + CURL_NETRC_IGNORED, /* The .netrc will never be read. + * This is the default. */ + CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred + * to one in the .netrc. */ + CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. + * Unless one is set programmatically, the .netrc + * will be queried. */ + CURL_NETRC_LAST +}; + +enum { + CURL_SSLVERSION_DEFAULT, + CURL_SSLVERSION_TLSv1, + CURL_SSLVERSION_SSLv2, + CURL_SSLVERSION_SSLv3, + + CURL_SSLVERSION_LAST /* never use, keep last */ +}; + +/* symbols to use with CURLOPT_POSTREDIR. + CURL_REDIR_POST_301 and CURL_REDIR_POST_302 can be bitwise ORed so that + CURL_REDIR_POST_301 | CURL_REDIR_POST_302 == CURL_REDIR_POST_ALL */ + +#define CURL_REDIR_GET_ALL 0 +#define CURL_REDIR_POST_301 1 +#define CURL_REDIR_POST_302 2 +#define CURL_REDIR_POST_ALL (CURL_REDIR_POST_301|CURL_REDIR_POST_302) + +typedef enum { + CURL_TIMECOND_NONE, + + CURL_TIMECOND_IFMODSINCE, + CURL_TIMECOND_IFUNMODSINCE, + CURL_TIMECOND_LASTMOD, + + CURL_TIMECOND_LAST +} curl_TimeCond; + + +/* curl_strequal() and curl_strnequal() are subject for removal in a future + libcurl, see lib/README.curlx for details */ +CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2); +CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n); + +/* name is uppercase CURLFORM_<name> */ +#ifdef CFINIT +#undef CFINIT +#endif + +#ifdef CURL_ISOCPP +#define CFINIT(name) CURLFORM_ ## name +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define CFINIT(name) CURLFORM_/**/name +#endif + +typedef enum { + CFINIT(NOTHING), /********* the first one is unused ************/ + + /* */ + CFINIT(COPYNAME), + CFINIT(PTRNAME), + CFINIT(NAMELENGTH), + CFINIT(COPYCONTENTS), + CFINIT(PTRCONTENTS), + CFINIT(CONTENTSLENGTH), + CFINIT(FILECONTENT), + CFINIT(ARRAY), + CFINIT(OBSOLETE), + CFINIT(FILE), + + CFINIT(BUFFER), + CFINIT(BUFFERPTR), + CFINIT(BUFFERLENGTH), + + CFINIT(CONTENTTYPE), + CFINIT(CONTENTHEADER), + CFINIT(FILENAME), + CFINIT(END), + CFINIT(OBSOLETE2), + + CFINIT(STREAM), + + CURLFORM_LASTENTRY /* the last unused */ +} CURLformoption; + +#undef CFINIT /* done */ + +/* structure to be used as parameter for CURLFORM_ARRAY */ +struct curl_forms { + CURLformoption option; + const char *value; +}; + +/* use this for multipart formpost building */ +/* Returns code for curl_formadd() + * + * Returns: + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) + * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * + ***************************************************************************/ +typedef enum { + CURL_FORMADD_OK, /* first, no error */ + + CURL_FORMADD_MEMORY, + CURL_FORMADD_OPTION_TWICE, + CURL_FORMADD_NULL, + CURL_FORMADD_UNKNOWN_OPTION, + CURL_FORMADD_INCOMPLETE, + CURL_FORMADD_ILLEGAL_ARRAY, + CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ + + CURL_FORMADD_LAST /* last */ +} CURLFORMcode; + +/* + * NAME curl_formadd() + * + * DESCRIPTION + * + * Pretty advanced function for building multi-part formposts. Each invoke + * adds one part that together construct a full post. Then use + * CURLOPT_HTTPPOST to send it off to libcurl. + */ +CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...); + +/* + * callback function for curl_formget() + * The void *arg pointer will be the one passed as second argument to + * curl_formget(). + * The character buffer passed to it must not be freed. + * Should return the buffer length passed to it as the argument "len" on + * success. + */ +typedef size_t (*curl_formget_callback)(void *arg, const char *buf, size_t len); + +/* + * NAME curl_formget() + * + * DESCRIPTION + * + * Serialize a curl_httppost struct built with curl_formadd(). + * Accepts a void pointer as second argument which will be passed to + * the curl_formget_callback function. + * Returns 0 on success. + */ +CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append); +/* + * NAME curl_formfree() + * + * DESCRIPTION + * + * Free a multipart formpost previously built with curl_formadd(). + */ +CURL_EXTERN void curl_formfree(struct curl_httppost *form); + +/* + * NAME curl_getenv() + * + * DESCRIPTION + * + * Returns a malloc()'ed string that MUST be curl_free()ed after usage is + * complete. DEPRECATED - see lib/README.curlx + */ +CURL_EXTERN char *curl_getenv(const char *variable); + +/* + * NAME curl_version() + * + * DESCRIPTION + * + * Returns a static ascii string of the libcurl version. + */ +CURL_EXTERN char *curl_version(void); + +/* + * NAME curl_easy_escape() + * + * DESCRIPTION + * + * Escapes URL strings (converts all letters consider illegal in URLs to their + * %XX versions). This function returns a new allocated string or NULL if an + * error occurred. + */ +CURL_EXTERN char *curl_easy_escape(CURL *handle, + const char *string, + int length); + +/* the previous version: */ +CURL_EXTERN char *curl_escape(const char *string, + int length); + + +/* + * NAME curl_easy_unescape() + * + * DESCRIPTION + * + * Unescapes URL encoding in strings (converts all %XX codes to their 8bit + * versions). This function returns a new allocated string or NULL if an error + * occurred. + * Conversion Note: On non-ASCII platforms the ASCII %XX codes are + * converted into the host encoding. + */ +CURL_EXTERN char *curl_easy_unescape(CURL *handle, + const char *string, + int length, + int *outlength); + +/* the previous version */ +CURL_EXTERN char *curl_unescape(const char *string, + int length); + +/* + * NAME curl_free() + * + * DESCRIPTION + * + * Provided for de-allocation in the same translation unit that did the + * allocation. Added in libcurl 7.10 + */ +CURL_EXTERN void curl_free(void *p); + +/* + * NAME curl_global_init() + * + * DESCRIPTION + * + * curl_global_init() should be invoked exactly once for each application that + * uses libcurl and before any call of other libcurl functions. + * + * This function is not thread-safe! + */ +CURL_EXTERN CURLcode curl_global_init(long flags); + +/* + * NAME curl_global_init_mem() + * + * DESCRIPTION + * + * curl_global_init() or curl_global_init_mem() should be invoked exactly once + * for each application that uses libcurl. This function can be used to + * initialize libcurl and set user defined memory management callback + * functions. Users can implement memory management routines to check for + * memory leaks, check for mis-use of the curl library etc. User registered + * callback routines with be invoked by this library instead of the system + * memory management routines like malloc, free etc. + */ +CURL_EXTERN CURLcode curl_global_init_mem(long flags, + curl_malloc_callback m, + curl_free_callback f, + curl_realloc_callback r, + curl_strdup_callback s, + curl_calloc_callback c); + +/* + * NAME curl_global_cleanup() + * + * DESCRIPTION + * + * curl_global_cleanup() should be invoked exactly once for each application + * that uses libcurl + */ +CURL_EXTERN void curl_global_cleanup(void); + +/* linked-list structure for the CURLOPT_QUOTE option (and other) */ +struct curl_slist { + char *data; + struct curl_slist *next; +}; + +/* + * NAME curl_slist_append() + * + * DESCRIPTION + * + * Appends a string to a linked list. If no list exists, it will be created + * first. Returns the new list, after appending. + */ +CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, + const char *); + +/* + * NAME curl_slist_free_all() + * + * DESCRIPTION + * + * free a previously built curl_slist. + */ +CURL_EXTERN void curl_slist_free_all(struct curl_slist *); + +/* + * NAME curl_getdate() + * + * DESCRIPTION + * + * Returns the time, in seconds since 1 Jan 1970 of the time string given in + * the first argument. The time argument in the second parameter is unused + * and should be set to NULL. + */ +CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); + +/* info about the certificate chain, only for OpenSSL builds. Asked + for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ +struct curl_certinfo { + int num_of_certs; /* number of certificates with information */ + struct curl_slist **certinfo; /* for each index in this array, there's a + linked list with textual information in the + format "name: value" */ +}; + +#define CURLINFO_STRING 0x100000 +#define CURLINFO_LONG 0x200000 +#define CURLINFO_DOUBLE 0x300000 +#define CURLINFO_SLIST 0x400000 +#define CURLINFO_MASK 0x0fffff +#define CURLINFO_TYPEMASK 0xf00000 + +typedef enum { + CURLINFO_NONE, /* first, never use this */ + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, + CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, + CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, + CURLINFO_CERTINFO = CURLINFO_SLIST + 34, + CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, + CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, + CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, + CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, + CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, + CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, + CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, + CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + /* Fill in new entries below here! */ + + CURLINFO_LASTONE = 42 +} CURLINFO; + +/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as + CURLINFO_HTTP_CODE */ +#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE + +typedef enum { + CURLCLOSEPOLICY_NONE, /* first, never use this */ + + CURLCLOSEPOLICY_OLDEST, + CURLCLOSEPOLICY_LEAST_RECENTLY_USED, + CURLCLOSEPOLICY_LEAST_TRAFFIC, + CURLCLOSEPOLICY_SLOWEST, + CURLCLOSEPOLICY_CALLBACK, + + CURLCLOSEPOLICY_LAST /* last, never use this */ +} curl_closepolicy; + +#define CURL_GLOBAL_SSL (1<<0) +#define CURL_GLOBAL_WIN32 (1<<1) +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) +#define CURL_GLOBAL_NOTHING 0 +#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL + + +/***************************************************************************** + * Setup defines, protos etc for the sharing stuff. + */ + +/* Different data locks for a single share */ +typedef enum { + CURL_LOCK_DATA_NONE = 0, + /* CURL_LOCK_DATA_SHARE is used internally to say that + * the locking is just made to change the internal state of the share + * itself. + */ + CURL_LOCK_DATA_SHARE, + CURL_LOCK_DATA_COOKIE, + CURL_LOCK_DATA_DNS, + CURL_LOCK_DATA_SSL_SESSION, + CURL_LOCK_DATA_CONNECT, + CURL_LOCK_DATA_LAST +} curl_lock_data; + +/* Different lock access types */ +typedef enum { + CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ + CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ + CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ + CURL_LOCK_ACCESS_LAST /* never use */ +} curl_lock_access; + +typedef void (*curl_lock_function)(CURL *handle, + curl_lock_data data, + curl_lock_access locktype, + void *userptr); +typedef void (*curl_unlock_function)(CURL *handle, + curl_lock_data data, + void *userptr); + +typedef void CURLSH; + +typedef enum { + CURLSHE_OK, /* all is fine */ + CURLSHE_BAD_OPTION, /* 1 */ + CURLSHE_IN_USE, /* 2 */ + CURLSHE_INVALID, /* 3 */ + CURLSHE_NOMEM, /* out of memory */ + CURLSHE_LAST /* never use */ +} CURLSHcode; + +typedef enum { + CURLSHOPT_NONE, /* don't use */ + CURLSHOPT_SHARE, /* specify a data type to share */ + CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ + CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ + CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ + CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock + callback functions */ + CURLSHOPT_LAST /* never use */ +} CURLSHoption; + +CURL_EXTERN CURLSH *curl_share_init(void); +CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); +CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); + +/**************************************************************************** + * Structures for querying information about the curl library at runtime. + */ + +typedef enum { + CURLVERSION_FIRST, + CURLVERSION_SECOND, + CURLVERSION_THIRD, + CURLVERSION_FOURTH, + CURLVERSION_LAST /* never actually use this */ +} CURLversion; + +/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by + basically all programs ever that want to get version information. It is + meant to be a built-in version number for what kind of struct the caller + expects. If the struct ever changes, we redefine the NOW to another enum + from above. */ +#define CURLVERSION_NOW CURLVERSION_FOURTH + +typedef struct { + CURLversion age; /* age of the returned struct */ + const char *version; /* LIBCURL_VERSION */ + unsigned int version_num; /* LIBCURL_VERSION_NUM */ + const char *host; /* OS/host/cpu/machine when configured */ + int features; /* bitmask, see defines below */ + const char *ssl_version; /* human readable string */ + long ssl_version_num; /* not used anymore, always 0 */ + const char *libz_version; /* human readable string */ + /* protocols is terminated by an entry with a NULL protoname */ + const char * const *protocols; + + /* The fields below this were added in CURLVERSION_SECOND */ + const char *ares; + int ares_num; + + /* This field was added in CURLVERSION_THIRD */ + const char *libidn; + + /* These field were added in CURLVERSION_FOURTH */ + + /* Same as '_libiconv_version' if built with HAVE_ICONV */ + int iconv_ver_num; + + const char *libssh_version; /* human readable string */ + +} curl_version_info_data; + +#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ +#define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */ +#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ +#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ +#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ +#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */ +#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */ +#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */ +#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */ +#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */ +#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */ +#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */ +#define CURL_VERSION_CONV (1<<12) /* character conversions supported */ +#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */ + +/* + * NAME curl_version_info() + * + * DESCRIPTION + * + * This function returns a pointer to a static copy of the version info + * struct. See above. + */ +CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); + +/* + * NAME curl_easy_strerror() + * + * DESCRIPTION + * + * The curl_easy_strerror function may be used to turn a CURLcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_easy_strerror(CURLcode); + +/* + * NAME curl_share_strerror() + * + * DESCRIPTION + * + * The curl_share_strerror function may be used to turn a CURLSHcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_share_strerror(CURLSHcode); + +/* + * NAME curl_easy_pause() + * + * DESCRIPTION + * + * The curl_easy_pause function pauses or unpauses transfers. Select the new + * state by setting the bitmask, use the convenience defines below. + * + */ +CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); + +#define CURLPAUSE_RECV (1<<0) +#define CURLPAUSE_RECV_CONT (0) + +#define CURLPAUSE_SEND (1<<2) +#define CURLPAUSE_SEND_CONT (0) + +#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) +#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) + +#ifdef __cplusplus +} +#endif + +/* unfortunately, the easy.h and multi.h include files need options and info + stuff before they can be included! */ +#include "easy.h" /* nothing in curl is fun without the easy stuff */ +#include "multi.h" + +/* the typechecker doesn't work in C++ (yet) */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ + ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ + !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) +#include "typecheck-gcc.h" +#else +#if defined(__STDC__) && (__STDC__ >= 1) +/* This preprocessor magic that replaces a call with the exact same call is + only done to make sure application authors pass exactly three arguments + to these functions. */ +#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) +#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) +#endif /* __STDC__ >= 1 */ +#endif /* gcc >= 4.3 && !__cplusplus */ + +#endif /* __CURL_CURL_H */ diff --git a/include/curl/curlbuild.h b/include/curl/curlbuild.h new file mode 100644 index 00000000..81f4a285 --- /dev/null +++ b/include/curl/curlbuild.h @@ -0,0 +1,191 @@ +/* include/curl/curlbuild.h. Generated from curlbuild.h.in by configure. */ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/ + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.in or + * at file include/curl/curlbuild.h, this is due to the following reason: + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ +/* ================================================================ */ + +/* Configure process defines this to 1 when it finds out that system */ +/* header file ws2tcpip.h must be included by the external interface. */ +/* #undef CURL_PULL_WS2TCPIP_H */ +#ifdef CURL_PULL_WS2TCPIP_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include <windows.h> +# include <winsock2.h> +# include <ws2tcpip.h> +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/types.h must be included by the external interface. */ +#define CURL_PULL_SYS_TYPES_H 1 +#ifdef CURL_PULL_SYS_TYPES_H +# include <sys/types.h> +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file stdint.h must be included by the external interface. */ +#define CURL_PULL_STDINT_H 1 +#ifdef CURL_PULL_STDINT_H +# include <stdint.h> +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file inttypes.h must be included by the external interface. */ +#define CURL_PULL_INTTYPES_H 1 +#ifdef CURL_PULL_INTTYPES_H +# include <inttypes.h> +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/socket.h must be included by the external interface. */ +#define CURL_PULL_SYS_SOCKET_H 1 +#ifdef CURL_PULL_SYS_SOCKET_H +# include <sys/socket.h> +#endif + +/* The size of `long', as computed by sizeof. */ +#define CURL_SIZEOF_LONG 4 + +/* Integral data type used for curl_socklen_t. */ +#define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t + +/* The size of `curl_socklen_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* Data type definition of curl_socklen_t. */ +typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; + +/* Signed integral data type used for curl_off_t. */ +#define CURL_TYPEOF_CURL_OFF_T int64_t + +/* Data type definition of curl_off_t. */ +typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; + +/* curl_off_t formatting string directive without "%" conversion specifier. */ +#define CURL_FORMAT_CURL_OFF_T "lld" + +/* unsigned curl_off_t formatting string without "%" conversion specifier. */ +#define CURL_FORMAT_CURL_OFF_TU "llu" + +/* curl_off_t formatting string directive with "%" conversion specifier. */ +#define CURL_FORMAT_OFF_T "%lld" + +/* The size of `curl_off_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_OFF_T 8 + +/* curl_off_t constant suffix. */ +#define CURL_SUFFIX_CURL_OFF_T LL + +/* unsigned curl_off_t constant suffix. */ +#define CURL_SUFFIX_CURL_OFF_TU ULL + +#endif /* __CURL_CURLBUILD_H */ diff --git a/include/curl/curlbuild.h.cmake b/include/curl/curlbuild.h.cmake new file mode 100644 index 00000000..3aa772fc --- /dev/null +++ b/include/curl/curlbuild.h.cmake @@ -0,0 +1,180 @@ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/ + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.in or + * at file include/curl/curlbuild.h, this is due to the following reason: + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif +#ifdef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ +/* ================================================================ */ + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/types.h must be included by the external interface. */ +#cmakedefine CURL_PULL_SYS_TYPES_H ${CURL_PULL_SYS_TYPES_H} +#ifdef CURL_PULL_SYS_TYPES_H +# include <sys/types.h> +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file stdint.h must be included by the external interface. */ +#cmakedefine CURL_PULL_STDINT_H ${CURL_PULL_STDINT_H} +#ifdef CURL_PULL_STDINT_H +# include <stdint.h> +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file inttypes.h must be included by the external interface. */ +#cmakedefine CURL_PULL_INTTYPES_H ${CURL_PULL_INTTYPES_H} +#ifdef CURL_PULL_INTTYPES_H +# include <inttypes.h> +#endif + +/* The size of `long', as computed by sizeof. */ +#cmakedefine CURL_SIZEOF_LONG ${CURL_SIZEOF_LONG} + +/* Integral data type used for curl_socklen_t. */ +#cmakedefine CURL_TYPEOF_CURL_SOCKLEN_T ${CURL_TYPEOF_CURL_SOCKLEN_T} + +/* on windows socklen_t is in here */ +#ifdef _WIN32 +# include <winsock2.h> +# include <ws2tcpip.h> +#endif + +#ifdef HAVE_SYS_SOCKET_H +# include <sys/socket.h> +#endif + +/* Data type definition of curl_socklen_t. */ +typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; + +/* The size of `curl_socklen_t', as computed by sizeof. */ +#cmakedefine CURL_SIZEOF_CURL_SOCKLEN_T ${CURL_SIZEOF_CURL_SOCKLEN_T} + +/* Signed integral data type used for curl_off_t. */ +#cmakedefine CURL_TYPEOF_CURL_OFF_T ${CURL_TYPEOF_CURL_OFF_T} + +/* Data type definition of curl_off_t. */ +typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; + +/* curl_off_t formatting string directive without "%" conversion specifier. */ +#cmakedefine CURL_FORMAT_CURL_OFF_T "${CURL_FORMAT_CURL_OFF_T}" + +/* unsigned curl_off_t formatting string without "%" conversion specifier. */ +#cmakedefine CURL_FORMAT_CURL_OFF_TU "${CURL_FORMAT_CURL_OFF_TU}" + +/* curl_off_t formatting string directive with "%" conversion specifier. */ +#cmakedefine CURL_FORMAT_OFF_T "${CURL_FORMAT_OFF_T}" + +/* The size of `curl_off_t', as computed by sizeof. */ +#cmakedefine CURL_SIZEOF_CURL_OFF_T ${CURL_SIZEOF_CURL_OFF_T} + +/* curl_off_t constant suffix. */ +#cmakedefine CURL_SUFFIX_CURL_OFF_T ${CURL_SUFFIX_CURL_OFF_T} + +/* unsigned curl_off_t constant suffix. */ +#cmakedefine CURL_SUFFIX_CURL_OFF_TU ${CURL_SUFFIX_CURL_OFF_TU} + +#endif /* __CURL_CURLBUILD_H */ diff --git a/include/curl/curlbuild.h.in b/include/curl/curlbuild.h.in new file mode 100644 index 00000000..cb1de80a --- /dev/null +++ b/include/curl/curlbuild.h.in @@ -0,0 +1,190 @@ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/ + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.in or + * at file include/curl/curlbuild.h, this is due to the following reason: + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ +/* ================================================================ */ + +/* Configure process defines this to 1 when it finds out that system */ +/* header file ws2tcpip.h must be included by the external interface. */ +#undef CURL_PULL_WS2TCPIP_H +#ifdef CURL_PULL_WS2TCPIP_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include <windows.h> +# include <winsock2.h> +# include <ws2tcpip.h> +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/types.h must be included by the external interface. */ +#undef CURL_PULL_SYS_TYPES_H +#ifdef CURL_PULL_SYS_TYPES_H +# include <sys/types.h> +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file stdint.h must be included by the external interface. */ +#undef CURL_PULL_STDINT_H +#ifdef CURL_PULL_STDINT_H +# include <stdint.h> +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file inttypes.h must be included by the external interface. */ +#undef CURL_PULL_INTTYPES_H +#ifdef CURL_PULL_INTTYPES_H +# include <inttypes.h> +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/socket.h must be included by the external interface. */ +#undef CURL_PULL_SYS_SOCKET_H +#ifdef CURL_PULL_SYS_SOCKET_H +# include <sys/socket.h> +#endif + +/* The size of `long', as computed by sizeof. */ +#undef CURL_SIZEOF_LONG + +/* Integral data type used for curl_socklen_t. */ +#undef CURL_TYPEOF_CURL_SOCKLEN_T + +/* The size of `curl_socklen_t', as computed by sizeof. */ +#undef CURL_SIZEOF_CURL_SOCKLEN_T + +/* Data type definition of curl_socklen_t. */ +typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; + +/* Signed integral data type used for curl_off_t. */ +#undef CURL_TYPEOF_CURL_OFF_T + +/* Data type definition of curl_off_t. */ +typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; + +/* curl_off_t formatting string directive without "%" conversion specifier. */ +#undef CURL_FORMAT_CURL_OFF_T + +/* unsigned curl_off_t formatting string without "%" conversion specifier. */ +#undef CURL_FORMAT_CURL_OFF_TU + +/* curl_off_t formatting string directive with "%" conversion specifier. */ +#undef CURL_FORMAT_OFF_T + +/* The size of `curl_off_t', as computed by sizeof. */ +#undef CURL_SIZEOF_CURL_OFF_T + +/* curl_off_t constant suffix. */ +#undef CURL_SUFFIX_CURL_OFF_T + +/* unsigned curl_off_t constant suffix. */ +#undef CURL_SUFFIX_CURL_OFF_TU + +#endif /* __CURL_CURLBUILD_H */ diff --git a/include/curl/curlrules.h b/include/curl/curlrules.h new file mode 100644 index 00000000..8aad1df6 --- /dev/null +++ b/include/curl/curlrules.h @@ -0,0 +1,252 @@ +#ifndef __CURL_CURLRULES_H +#define __CURL_CURLRULES_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* COMPILE TIME SANITY CHECKS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * All checks done in this file are intentionally placed in a public + * header file which is pulled by curl/curl.h when an application is + * being built using an already built libcurl library. Additionally + * this file is also included and used when building the library. + * + * If compilation fails on this file it is certainly sure that the + * problem is elsewhere. It could be a problem in the curlbuild.h + * header file, or simply that you are using different compilation + * settings than those used to build the library. + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * Do not deactivate any check, these are done to make sure that the + * library is properly built and used. + * + * You can find further help on the libcurl development mailing list: + * http://cool.haxx.se/mailman/listinfo/curl-library/ + * + * NOTE 2 + * ------ + * + * Some of the following compile time checks are based on the fact + * that the dimension of a constant array can not be a negative one. + * In this way if the compile time verification fails, the compilation + * will fail issuing an error. The error description wording is compiler + * dependent but it will be quite similar to one of the following: + * + * "negative subscript or subscript is too large" + * "array must have at least one element" + * "-1 is an illegal array size" + * "size of array is negative" + * + * If you are building an application which tries to use an already + * built libcurl library and you are getting this kind of errors on + * this file, it is a clear indication that there is a mismatch between + * how the library was built and how you are trying to use it for your + * application. Your already compiled or binary library provider is the + * only one who can give you the details you need to properly use it. + */ + +/* + * Verify that some macros are actually defined. + */ + +#ifndef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing +#endif + +#ifndef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing +#endif + +/* + * Macros private to this header file. + */ + +#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1 + +#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 + +/* + * Verify that the size previously defined and expected for long + * is the same as the one reported by sizeof() at compile time. + */ + +typedef char + __curl_rule_01__ + [CurlchkszEQ(long, CURL_SIZEOF_LONG)]; + +/* + * Verify that the size previously defined and expected for + * curl_off_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_02__ + [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)]; + +/* + * Verify at compile time that the size of curl_off_t as reported + * by sizeof() is greater or equal than the one reported for long + * for the current compilation. + */ + +typedef char + __curl_rule_03__ + [CurlchkszGE(curl_off_t, long)]; + +/* + * Verify that the size previously defined and expected for + * curl_socklen_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_04__ + [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)]; + +/* + * Verify at compile time that the size of curl_socklen_t as reported + * by sizeof() is greater or equal than the one reported for int for + * the current compilation. + */ + +typedef char + __curl_rule_05__ + [CurlchkszGE(curl_socklen_t, int)]; + +/* ================================================================ */ +/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ +/* ================================================================ */ + +/* + * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow + * these to be visible and exported by the external libcurl interface API, + * while also making them visible to the library internals, simply including + * setup.h, without actually needing to include curl.h internally. + * If some day this section would grow big enough, all this should be moved + * to its own header file. + */ + +/* + * Figure out if we can use the ## preprocessor operator, which is supported + * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ + * or __cplusplus so we need to carefully check for them too. + */ + +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ + defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ + defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ + defined(__ILEC400__) + /* This compiler is believed to have an ISO compatible preprocessor */ +#define CURL_ISOCPP +#else + /* This compiler is believed NOT to have an ISO compatible preprocessor */ +#undef CURL_ISOCPP +#endif + +/* + * Macros for minimum-width signed and unsigned curl_off_t integer constants. + */ + +#ifdef CURL_ISOCPP +# define __CURL_OFF_T_C_HELPER2(Val,Suffix) Val ## Suffix +#else +# define __CURL_OFF_T_C_HELPER2(Val,Suffix) Val/**/Suffix +#endif +#define __CURL_OFF_T_C_HELPER1(Val,Suffix) __CURL_OFF_T_C_HELPER2(Val,Suffix) +#define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HELPER1(Val,CURL_SUFFIX_CURL_OFF_T) +#define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HELPER1(Val,CURL_SUFFIX_CURL_OFF_TU) + +/* + * Get rid of macros private to this header file. + */ + +#undef CurlchkszEQ +#undef CurlchkszGE + +/* + * Get rid of macros not intended to exist beyond this point. + */ + +#undef CURL_PULL_WS2TCPIP_H +#undef CURL_PULL_SYS_TYPES_H +#undef CURL_PULL_SYS_SOCKET_H +#undef CURL_PULL_STDINT_H +#undef CURL_PULL_INTTYPES_H + +#undef CURL_TYPEOF_CURL_SOCKLEN_T +#undef CURL_TYPEOF_CURL_OFF_T + +#ifdef CURL_NO_OLDIES +#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */ +#endif + +#endif /* __CURL_CURLRULES_H */ diff --git a/include/curl/curlver.h b/include/curl/curlver.h new file mode 100644 index 00000000..e345f56d --- /dev/null +++ b/include/curl/curlver.h @@ -0,0 +1,69 @@ +#ifndef __CURL_CURLVER_H +#define __CURL_CURLVER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This header file contains nothing but libcurl version info, generated by + a script at release-time. This was made its own header file in 7.11.2 */ + +/* This is the global package copyright */ +#define LIBCURL_COPYRIGHT "1996 - 2010 Daniel Stenberg, <daniel@haxx.se>." + +/* This is the version number of the libcurl package from which this header + file origins: */ +#define LIBCURL_VERSION "7.21.2" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBCURL_VERSION_MAJOR 7 +#define LIBCURL_VERSION_MINOR 21 +#define LIBCURL_VERSION_PATCH 2 + +/* This is the numeric version of the libcurl version number, meant for easier + parsing and comparions by programs. The LIBCURL_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. +*/ +#define LIBCURL_VERSION_NUM 0x071502 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in git, as the timestamp is properly set in the + * tarballs by the maketgz script. + * + * The format of the date should follow this template: + * + * "Mon Feb 12 11:35:33 UTC 2007" + */ +#define LIBCURL_TIMESTAMP "Tue Oct 12 22:03:31 UTC 2010" + +#endif /* __CURL_CURLVER_H */ diff --git a/include/curl/easy.h b/include/curl/easy.h new file mode 100644 index 00000000..1ddb4fe5 --- /dev/null +++ b/include/curl/easy.h @@ -0,0 +1,102 @@ +#ifndef __CURL_EASY_H +#define __CURL_EASY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN CURL *curl_easy_init(void); +CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); +CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); +CURL_EXTERN void curl_easy_cleanup(CURL *curl); + +/* + * NAME curl_easy_getinfo() + * + * DESCRIPTION + * + * Request internal information from the curl session with this function. The + * third argument MUST be a pointer to a long, a pointer to a char * or a + * pointer to a double (as the documentation describes elsewhere). The data + * pointed to will be filled in accordingly and can be relied upon only if the + * function returns CURLE_OK. This function is intended to get used *AFTER* a + * performed transfer, all results from this function are undefined until the + * transfer is completed. + */ +CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); + + +/* + * NAME curl_easy_duphandle() + * + * DESCRIPTION + * + * Creates a new curl session handle with the same options set for the handle + * passed in. Duplicating a handle could only be a matter of cloning data and + * options, internal state info and things like persistant connections cannot + * be transfered. It is useful in multithreaded applications when you can run + * curl_easy_duphandle() for each new thread to avoid a series of identical + * curl_easy_setopt() invokes in every thread. + */ +CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl); + +/* + * NAME curl_easy_reset() + * + * DESCRIPTION + * + * Re-initializes a CURL handle to the default values. This puts back the + * handle to the same state as it was in when it was just created. + * + * It does keep: live connections, the Session ID cache, the DNS cache and the + * cookies. + */ +CURL_EXTERN void curl_easy_reset(CURL *curl); + +/* + * NAME curl_easy_recv() + * + * DESCRIPTION + * + * Receives data from the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, + size_t *n); + +/* + * NAME curl_easy_send() + * + * DESCRIPTION + * + * Sends data over the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, + size_t buflen, size_t *n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/curl/mprintf.h b/include/curl/mprintf.h new file mode 100644 index 00000000..de7dd2f3 --- /dev/null +++ b/include/curl/mprintf.h @@ -0,0 +1,81 @@ +#ifndef __CURL_MPRINTF_H +#define __CURL_MPRINTF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include <stdarg.h> +#include <stdio.h> /* needed for FILE */ + +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN int curl_mprintf(const char *format, ...); +CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); +CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); +CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, + const char *format, ...); +CURL_EXTERN int curl_mvprintf(const char *format, va_list args); +CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); +CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); +CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, + const char *format, va_list args); +CURL_EXTERN char *curl_maprintf(const char *format, ...); +CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); + +#ifdef _MPRINTF_REPLACE +# undef printf +# undef fprintf +# undef sprintf +# undef vsprintf +# undef snprintf +# undef vprintf +# undef vfprintf +# undef vsnprintf +# undef aprintf +# undef vaprintf +# define printf curl_mprintf +# define fprintf curl_mfprintf +#ifdef CURLDEBUG +/* When built with CURLDEBUG we define away the sprintf() functions since we + don't want internal code to be using them */ +# define sprintf sprintf_was_used +# define vsprintf vsprintf_was_used +#else +# define sprintf curl_msprintf +# define vsprintf curl_mvsprintf +#endif +# define snprintf curl_msnprintf +# define vprintf curl_mvprintf +# define vfprintf curl_mvfprintf +# define vsnprintf curl_mvsnprintf +# define aprintf curl_maprintf +# define vaprintf curl_mvaprintf +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __CURL_MPRINTF_H */ diff --git a/include/curl/multi.h b/include/curl/multi.h new file mode 100644 index 00000000..f9656666 --- /dev/null +++ b/include/curl/multi.h @@ -0,0 +1,345 @@ +#ifndef __CURL_MULTI_H +#define __CURL_MULTI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + This is an "external" header file. Don't give away any internals here! + + GOALS + + o Enable a "pull" interface. The application that uses libcurl decides where + and when to ask libcurl to get/send data. + + o Enable multiple simultaneous transfers in the same thread without making it + complicated for the application. + + o Enable the application to select() on its own file descriptors and curl's + file descriptors simultaneous easily. + +*/ + +/* + * This header file should not really need to include "curl.h" since curl.h + * itself includes this file and we expect user applications to do #include + * <curl/curl.h> without the need for especially including multi.h. + * + * For some reason we added this include here at one point, and rather than to + * break existing (wrongly written) libcurl applications, we leave it as-is + * but with this warning attached. + */ +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void CURLM; + +typedef enum { + CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or + curl_multi_socket*() soon */ + CURLM_OK, + CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ + CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ + CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ + CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ + CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ + CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ + CURLM_LAST +} CURLMcode; + +/* just to make code nicer when using curl_multi_socket() you can now check + for CURLM_CALL_MULTI_SOCKET too in the same style it works for + curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ +#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM + +typedef enum { + CURLMSG_NONE, /* first, not used */ + CURLMSG_DONE, /* This easy handle has completed. 'result' contains + the CURLcode of the transfer */ + CURLMSG_LAST /* last, not used */ +} CURLMSG; + +struct CURLMsg { + CURLMSG msg; /* what this message means */ + CURL *easy_handle; /* the handle it concerns */ + union { + void *whatever; /* message-specific data */ + CURLcode result; /* return code for transfer */ + } data; +}; +typedef struct CURLMsg CURLMsg; + +/* + * Name: curl_multi_init() + * + * Desc: inititalize multi-style curl usage + * + * Returns: a new CURLM handle to use in all 'curl_multi' functions. + */ +CURL_EXTERN CURLM *curl_multi_init(void); + +/* + * Name: curl_multi_add_handle() + * + * Desc: add a standard curl handle to the multi stack + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_remove_handle() + * + * Desc: removes a curl handle from the multi stack again + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_fdset() + * + * Desc: Ask curl for its fd_set sets. The app can use these to select() or + * poll() on. We want curl_multi_perform() called as soon as one of + * them are ready. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *exc_fd_set, + int *max_fd); + + /* + * Name: curl_multi_perform() + * + * Desc: When the app thinks there's data available for curl it calls this + * function to read/write whatever there is right now. This returns + * as soon as the reads and writes are done. This function does not + * require that there actually is data available for reading or that + * data can be written, it can be called just in case. It returns + * the number of handles that still transfer data in the second + * argument's integer-pointer. + * + * Returns: CURLMcode type, general multi error code. *NOTE* that this only + * returns errors etc regarding the whole multi stack. There might + * still have occurred problems on invidual transfers even when this + * returns OK. + */ +CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, + int *running_handles); + + /* + * Name: curl_multi_cleanup() + * + * Desc: Cleans up and removes a whole multi stack. It does not free or + * touch any individual easy handles in any way. We need to define + * in what state those handles will be if this function is called + * in the middle of a transfer. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); + +/* + * Name: curl_multi_info_read() + * + * Desc: Ask the multi handle if there's any messages/informationals from + * the individual transfers. Messages include informationals such as + * error code from the transfer or just the fact that a transfer is + * completed. More details on these should be written down as well. + * + * Repeated calls to this function will return a new struct each + * time, until a special "end of msgs" struct is returned as a signal + * that there is no more to get at this point. + * + * The data the returned pointer points to will not survive calling + * curl_multi_cleanup(). + * + * The 'CURLMsg' struct is meant to be very simple and only contain + * very basic informations. If more involved information is wanted, + * we will provide the particular "transfer handle" in that struct + * and that should/could/would be used in subsequent + * curl_easy_getinfo() calls (or similar). The point being that we + * must never expose complex structs to applications, as then we'll + * undoubtably get backwards compatibility problems in the future. + * + * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out + * of structs. It also writes the number of messages left in the + * queue (after this read) in the integer the second argument points + * to. + */ +CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, + int *msgs_in_queue); + +/* + * Name: curl_multi_strerror() + * + * Desc: The curl_multi_strerror function may be used to turn a CURLMcode + * value into the equivalent human readable error string. This is + * useful for printing meaningful error messages. + * + * Returns: A pointer to a zero-terminated error message. + */ +CURL_EXTERN const char *curl_multi_strerror(CURLMcode); + +/* + * Name: curl_multi_socket() and + * curl_multi_socket_all() + * + * Desc: An alternative version of curl_multi_perform() that allows the + * application to pass in one of the file descriptors that have been + * detected to have "action" on them and let libcurl perform. + * See man page for details. + */ +#define CURL_POLL_NONE 0 +#define CURL_POLL_IN 1 +#define CURL_POLL_OUT 2 +#define CURL_POLL_INOUT 3 +#define CURL_POLL_REMOVE 4 + +#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD + +#define CURL_CSELECT_IN 0x01 +#define CURL_CSELECT_OUT 0x02 +#define CURL_CSELECT_ERR 0x04 + +typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int what, /* see above */ + void *userp, /* private callback + pointer */ + void *socketp); /* private socket + pointer */ +/* + * Name: curl_multi_timer_callback + * + * Desc: Called by libcurl whenever the library detects a change in the + * maximum number of milliseconds the app is allowed to wait before + * curl_multi_socket() or curl_multi_perform() must be called + * (to allow libcurl's timed events to take place). + * + * Returns: The callback should return zero. + */ +typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ + long timeout_ms, /* see above */ + void *userp); /* private callback + pointer */ + +CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, + curl_socket_t s, + int ev_bitmask, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, + int *running_handles); + +#ifndef CURL_ALLOW_OLD_MULTI_SOCKET +/* This macro below was added in 7.16.3 to push users who recompile to use + the new curl_multi_socket_action() instead of the old curl_multi_socket() +*/ +#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) +#endif + +/* + * Name: curl_multi_timeout() + * + * Desc: Returns the maximum number of milliseconds the app is allowed to + * wait before curl_multi_socket() or curl_multi_perform() must be + * called (to allow libcurl's timed events to take place). + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, + long *milliseconds); + +#undef CINIT /* re-using the same name as in curl.h */ + +#ifdef CURL_ISOCPP +#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLMOPT_/**/name = type + number +#endif + +typedef enum { + /* This is the socket callback function pointer */ + CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), + + /* This is the argument passed to the socket callback */ + CINIT(SOCKETDATA, OBJECTPOINT, 2), + + /* set to 1 to enable pipelining for this multi handle */ + CINIT(PIPELINING, LONG, 3), + + /* This is the timer callback function pointer */ + CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), + + /* This is the argument passed to the timer callback */ + CINIT(TIMERDATA, OBJECTPOINT, 5), + + /* maximum number of entries in the connection cache */ + CINIT(MAXCONNECTS, LONG, 6), + + CURLMOPT_LASTENTRY /* the last unused */ +} CURLMoption; + + +/* + * Name: curl_multi_setopt() + * + * Desc: Sets options for the multi handle. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, + CURLMoption option, ...); + + +/* + * Name: curl_multi_assign() + * + * Desc: This function sets an association in the multi handle between the + * given socket and a private pointer of the application. This is + * (only) useful for curl_multi_socket uses. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, + curl_socket_t sockfd, void *sockp); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif diff --git a/include/curl/stdcheaders.h b/include/curl/stdcheaders.h new file mode 100644 index 00000000..ad82ef63 --- /dev/null +++ b/include/curl/stdcheaders.h @@ -0,0 +1,33 @@ +#ifndef __STDC_HEADERS_H +#define __STDC_HEADERS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include <sys/types.h> + +size_t fread (void *, size_t, size_t, FILE *); +size_t fwrite (const void *, size_t, size_t, FILE *); + +int strcasecmp(const char *, const char *); +int strncasecmp(const char *, const char *, size_t); + +#endif /* __STDC_HEADERS_H */ diff --git a/include/curl/typecheck-gcc.h b/include/curl/typecheck-gcc.h new file mode 100644 index 00000000..e6f74a95 --- /dev/null +++ b/include/curl/typecheck-gcc.h @@ -0,0 +1,584 @@ +#ifndef __CURL_TYPECHECK_GCC_H +#define __CURL_TYPECHECK_GCC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* wraps curl_easy_setopt() with typechecking */ + +/* To add a new kind of warning, add an + * if(_curl_is_sometype_option(_curl_opt)) + * if(!_curl_is_sometype(value)) + * _curl_easy_setopt_err_sometype(); + * block and define _curl_is_sometype_option, _curl_is_sometype and + * _curl_easy_setopt_err_sometype below + * + * NOTE: We use two nested 'if' statements here instead of the && operator, in + * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x + * when compiling with -Wlogical-op. + * + * To add an option that uses the same type as an existing option, you'll just + * need to extend the appropriate _curl_*_option macro + */ +#define curl_easy_setopt(handle, option, value) \ +__extension__ ({ \ + __typeof__ (option) _curl_opt = option; \ + if (__builtin_constant_p(_curl_opt)) { \ + if (_curl_is_long_option(_curl_opt)) \ + if (!_curl_is_long(value)) \ + _curl_easy_setopt_err_long(); \ + if (_curl_is_off_t_option(_curl_opt)) \ + if (!_curl_is_off_t(value)) \ + _curl_easy_setopt_err_curl_off_t(); \ + if (_curl_is_string_option(_curl_opt)) \ + if (!_curl_is_string(value)) \ + _curl_easy_setopt_err_string(); \ + if (_curl_is_write_cb_option(_curl_opt)) \ + if (!_curl_is_write_cb(value)) \ + _curl_easy_setopt_err_write_callback(); \ + if ((_curl_opt) == CURLOPT_READFUNCTION) \ + if (!_curl_is_read_cb(value)) \ + _curl_easy_setopt_err_read_cb(); \ + if ((_curl_opt) == CURLOPT_IOCTLFUNCTION) \ + if (!_curl_is_ioctl_cb(value)) \ + _curl_easy_setopt_err_ioctl_cb(); \ + if ((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \ + if (!_curl_is_sockopt_cb(value)) \ + _curl_easy_setopt_err_sockopt_cb(); \ + if ((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \ + if (!_curl_is_opensocket_cb(value)) \ + _curl_easy_setopt_err_opensocket_cb(); \ + if ((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \ + if (!_curl_is_progress_cb(value)) \ + _curl_easy_setopt_err_progress_cb(); \ + if ((_curl_opt) == CURLOPT_DEBUGFUNCTION) \ + if (!_curl_is_debug_cb(value)) \ + _curl_easy_setopt_err_debug_cb(); \ + if ((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \ + if (!_curl_is_ssl_ctx_cb(value)) \ + _curl_easy_setopt_err_ssl_ctx_cb(); \ + if (_curl_is_conv_cb_option(_curl_opt)) \ + if (!_curl_is_conv_cb(value)) \ + _curl_easy_setopt_err_conv_cb(); \ + if ((_curl_opt) == CURLOPT_SEEKFUNCTION) \ + if (!_curl_is_seek_cb(value)) \ + _curl_easy_setopt_err_seek_cb(); \ + if (_curl_is_cb_data_option(_curl_opt)) \ + if (!_curl_is_cb_data(value)) \ + _curl_easy_setopt_err_cb_data(); \ + if ((_curl_opt) == CURLOPT_ERRORBUFFER) \ + if (!_curl_is_error_buffer(value)) \ + _curl_easy_setopt_err_error_buffer(); \ + if ((_curl_opt) == CURLOPT_STDERR) \ + if (!_curl_is_FILE(value)) \ + _curl_easy_setopt_err_FILE(); \ + if (_curl_is_postfields_option(_curl_opt)) \ + if (!_curl_is_postfields(value)) \ + _curl_easy_setopt_err_postfields(); \ + if ((_curl_opt) == CURLOPT_HTTPPOST) \ + if (!_curl_is_arr((value), struct curl_httppost)) \ + _curl_easy_setopt_err_curl_httpost(); \ + if (_curl_is_slist_option(_curl_opt)) \ + if (!_curl_is_arr((value), struct curl_slist)) \ + _curl_easy_setopt_err_curl_slist(); \ + if ((_curl_opt) == CURLOPT_SHARE) \ + if (!_curl_is_ptr((value), CURLSH)) \ + _curl_easy_setopt_err_CURLSH(); \ + } \ + curl_easy_setopt(handle, _curl_opt, value); \ +}) + +/* wraps curl_easy_getinfo() with typechecking */ +/* FIXME: don't allow const pointers */ +#define curl_easy_getinfo(handle, info, arg) \ +__extension__ ({ \ + __typeof__ (info) _curl_info = info; \ + if (__builtin_constant_p(_curl_info)) { \ + if (_curl_is_string_info(_curl_info)) \ + if (!_curl_is_arr((arg), char *)) \ + _curl_easy_getinfo_err_string(); \ + if (_curl_is_long_info(_curl_info)) \ + if (!_curl_is_arr((arg), long)) \ + _curl_easy_getinfo_err_long(); \ + if (_curl_is_double_info(_curl_info)) \ + if (!_curl_is_arr((arg), double)) \ + _curl_easy_getinfo_err_double(); \ + if (_curl_is_slist_info(_curl_info)) \ + if (!_curl_is_arr((arg), struct curl_slist *)) \ + _curl_easy_getinfo_err_curl_slist(); \ + } \ + curl_easy_getinfo(handle, _curl_info, arg); \ +}) + +/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(), + * for now just make sure that the functions are called with three + * arguments + */ +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) + + +/* the actual warnings, triggered by calling the _curl_easy_setopt_err* + * functions */ + +/* To define a new warning, use _CURL_WARNING(identifier, "message") */ +#define _CURL_WARNING(id, message) \ + static void __attribute__((warning(message))) __attribute__((unused)) \ + __attribute__((noinline)) id(void) { __asm__(""); } + +_CURL_WARNING(_curl_easy_setopt_err_long, + "curl_easy_setopt expects a long argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, + "curl_easy_setopt expects a curl_off_t argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_string, + "curl_easy_setopt expects a string (char* or char[]) argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_write_callback, + "curl_easy_setopt expects a curl_write_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_read_cb, + "curl_easy_setopt expects a curl_read_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, + "curl_easy_setopt expects a curl_ioctl_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, + "curl_easy_setopt expects a curl_sockopt_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, + "curl_easy_setopt expects a curl_opensocket_callback argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_progress_cb, + "curl_easy_setopt expects a curl_progress_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_debug_cb, + "curl_easy_setopt expects a curl_debug_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, + "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_conv_cb, + "curl_easy_setopt expects a curl_conv_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_seek_cb, + "curl_easy_setopt expects a curl_seek_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_cb_data, + "curl_easy_setopt expects a private data pointer as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_error_buffer, + "curl_easy_setopt expects a char buffer of CURL_ERROR_SIZE as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_FILE, + "curl_easy_setopt expects a FILE* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_postfields, + "curl_easy_setopt expects a void* or char* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, + "curl_easy_setopt expects a struct curl_httppost* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_slist, + "curl_easy_setopt expects a struct curl_slist* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_CURLSH, + "curl_easy_setopt expects a CURLSH* argument for this option") + +_CURL_WARNING(_curl_easy_getinfo_err_string, + "curl_easy_getinfo expects a pointer to char * for this info") +_CURL_WARNING(_curl_easy_getinfo_err_long, + "curl_easy_getinfo expects a pointer to long for this info") +_CURL_WARNING(_curl_easy_getinfo_err_double, + "curl_easy_getinfo expects a pointer to double for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, + "curl_easy_getinfo expects a pointer to struct curl_slist * for this info") + +/* groups of curl_easy_setops options that take the same type of argument */ + +/* To add a new option to one of the groups, just add + * (option) == CURLOPT_SOMETHING + * to the or-expression. If the option takes a long or curl_off_t, you don't + * have to do anything + */ + +/* evaluates to true if option takes a long argument */ +#define _curl_is_long_option(option) \ + (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) + +#define _curl_is_off_t_option(option) \ + ((option) > CURLOPTTYPE_OFF_T) + +/* evaluates to true if option takes a char* argument */ +#define _curl_is_string_option(option) \ + ((option) == CURLOPT_URL || \ + (option) == CURLOPT_PROXY || \ + (option) == CURLOPT_INTERFACE || \ + (option) == CURLOPT_NETRC_FILE || \ + (option) == CURLOPT_USERPWD || \ + (option) == CURLOPT_USERNAME || \ + (option) == CURLOPT_PASSWORD || \ + (option) == CURLOPT_PROXYUSERPWD || \ + (option) == CURLOPT_PROXYUSERNAME || \ + (option) == CURLOPT_PROXYPASSWORD || \ + (option) == CURLOPT_NOPROXY || \ + (option) == CURLOPT_ENCODING || \ + (option) == CURLOPT_REFERER || \ + (option) == CURLOPT_USERAGENT || \ + (option) == CURLOPT_COOKIE || \ + (option) == CURLOPT_COOKIEFILE || \ + (option) == CURLOPT_COOKIEJAR || \ + (option) == CURLOPT_COOKIELIST || \ + (option) == CURLOPT_FTPPORT || \ + (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ + (option) == CURLOPT_FTP_ACCOUNT || \ + (option) == CURLOPT_RANGE || \ + (option) == CURLOPT_CUSTOMREQUEST || \ + (option) == CURLOPT_SSLCERT || \ + (option) == CURLOPT_SSLCERTTYPE || \ + (option) == CURLOPT_SSLKEY || \ + (option) == CURLOPT_SSLKEYTYPE || \ + (option) == CURLOPT_KEYPASSWD || \ + (option) == CURLOPT_SSLENGINE || \ + (option) == CURLOPT_CAINFO || \ + (option) == CURLOPT_CAPATH || \ + (option) == CURLOPT_RANDOM_FILE || \ + (option) == CURLOPT_EGDSOCKET || \ + (option) == CURLOPT_SSL_CIPHER_LIST || \ + (option) == CURLOPT_KRBLEVEL || \ + (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ + (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ + (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ + (option) == CURLOPT_CRLFILE || \ + (option) == CURLOPT_ISSUERCERT || \ + (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ + (option) == CURLOPT_SSH_KNOWNHOSTS || \ + (option) == CURLOPT_MAIL_FROM || \ + (option) == CURLOPT_RTSP_SESSION_ID || \ + (option) == CURLOPT_RTSP_STREAM_URI || \ + (option) == CURLOPT_RTSP_TRANSPORT || \ + 0) + +/* evaluates to true if option takes a curl_write_callback argument */ +#define _curl_is_write_cb_option(option) \ + ((option) == CURLOPT_HEADERFUNCTION || \ + (option) == CURLOPT_WRITEFUNCTION) + +/* evaluates to true if option takes a curl_conv_callback argument */ +#define _curl_is_conv_cb_option(option) \ + ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) + +/* evaluates to true if option takes a data argument to pass to a callback */ +#define _curl_is_cb_data_option(option) \ + ((option) == CURLOPT_WRITEDATA || \ + (option) == CURLOPT_READDATA || \ + (option) == CURLOPT_IOCTLDATA || \ + (option) == CURLOPT_SOCKOPTDATA || \ + (option) == CURLOPT_OPENSOCKETDATA || \ + (option) == CURLOPT_PROGRESSDATA || \ + (option) == CURLOPT_WRITEHEADER || \ + (option) == CURLOPT_DEBUGDATA || \ + (option) == CURLOPT_SSL_CTX_DATA || \ + (option) == CURLOPT_SEEKDATA || \ + (option) == CURLOPT_PRIVATE || \ + (option) == CURLOPT_SSH_KEYDATA || \ + (option) == CURLOPT_INTERLEAVEDATA || \ + (option) == CURLOPT_CHUNK_DATA || \ + (option) == CURLOPT_FNMATCH_DATA || \ + 0) + +/* evaluates to true if option takes a POST data argument (void* or char*) */ +#define _curl_is_postfields_option(option) \ + ((option) == CURLOPT_POSTFIELDS || \ + (option) == CURLOPT_COPYPOSTFIELDS || \ + 0) + +/* evaluates to true if option takes a struct curl_slist * argument */ +#define _curl_is_slist_option(option) \ + ((option) == CURLOPT_HTTPHEADER || \ + (option) == CURLOPT_HTTP200ALIASES || \ + (option) == CURLOPT_QUOTE || \ + (option) == CURLOPT_POSTQUOTE || \ + (option) == CURLOPT_PREQUOTE || \ + (option) == CURLOPT_TELNETOPTIONS || \ + (option) == CURLOPT_MAIL_RCPT || \ + 0) + +/* groups of curl_easy_getinfo infos that take the same type of argument */ + +/* evaluates to true if info expects a pointer to char * argument */ +#define _curl_is_string_info(info) \ + (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) + +/* evaluates to true if info expects a pointer to long argument */ +#define _curl_is_long_info(info) \ + (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) + +/* evaluates to true if info expects a pointer to double argument */ +#define _curl_is_double_info(info) \ + (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) + +/* true if info expects a pointer to struct curl_slist * argument */ +#define _curl_is_slist_info(info) \ + (CURLINFO_SLIST < (info)) + + +/* typecheck helpers -- check whether given expression has requested type*/ + +/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, + * otherwise define a new macro. Search for __builtin_types_compatible_p + * in the GCC manual. + * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is + * the actual expression passed to the curl_easy_setopt macro. This + * means that you can only apply the sizeof and __typeof__ operators, no + * == or whatsoever. + */ + +/* XXX: should evaluate to true iff expr is a pointer */ +#define _curl_is_any_ptr(expr) \ + (sizeof(expr) == sizeof(void*)) + +/* evaluates to true if expr is NULL */ +/* XXX: must not evaluate expr, so this check is not accurate */ +#define _curl_is_NULL(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) + +/* evaluates to true if expr is type*, const type* or NULL */ +#define _curl_is_ptr(expr, type) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), type *) || \ + __builtin_types_compatible_p(__typeof__(expr), const type *)) + +/* evaluates to true if expr is one of type[], type*, NULL or const type* */ +#define _curl_is_arr(expr, type) \ + (_curl_is_ptr((expr), type) || \ + __builtin_types_compatible_p(__typeof__(expr), type [])) + +/* evaluates to true if expr is a string */ +#define _curl_is_string(expr) \ + (_curl_is_arr((expr), char) || \ + _curl_is_arr((expr), signed char) || \ + _curl_is_arr((expr), unsigned char)) + +/* evaluates to true if expr is a long (no matter the signedness) + * XXX: for now, int is also accepted (and therefore short and char, which + * are promoted to int when passed to a variadic function) */ +#define _curl_is_long(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), long) || \ + __builtin_types_compatible_p(__typeof__(expr), signed long) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ + __builtin_types_compatible_p(__typeof__(expr), int) || \ + __builtin_types_compatible_p(__typeof__(expr), signed int) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ + __builtin_types_compatible_p(__typeof__(expr), short) || \ + __builtin_types_compatible_p(__typeof__(expr), signed short) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ + __builtin_types_compatible_p(__typeof__(expr), char) || \ + __builtin_types_compatible_p(__typeof__(expr), signed char) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned char)) + +/* evaluates to true if expr is of type curl_off_t */ +#define _curl_is_off_t(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) + +/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ +/* XXX: also check size of an char[] array? */ +#define _curl_is_error_buffer(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), char *) || \ + __builtin_types_compatible_p(__typeof__(expr), char[])) + +/* evaluates to true if expr is of type (const) void* or (const) FILE* */ +#if 0 +#define _curl_is_cb_data(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_ptr((expr), FILE)) +#else /* be less strict */ +#define _curl_is_cb_data(expr) \ + _curl_is_any_ptr(expr) +#endif + +/* evaluates to true if expr is of type FILE* */ +#define _curl_is_FILE(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), FILE *)) + +/* evaluates to true if expr can be passed as POST data (void* or char*) */ +#define _curl_is_postfields(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_arr((expr), char)) + +/* FIXME: the whole callback checking is messy... + * The idea is to tolerate char vs. void and const vs. not const + * pointers in arguments at least + */ +/* helper: __builtin_types_compatible_p distinguishes between functions and + * function pointers, hide it */ +#define _curl_callback_compatible(func, type) \ + (__builtin_types_compatible_p(__typeof__(func), type) || \ + __builtin_types_compatible_p(__typeof__(func), type*)) + +/* evaluates to true if expr is of type curl_read_callback or "similar" */ +#define _curl_is_read_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \ + _curl_callback_compatible((expr), _curl_read_callback1) || \ + _curl_callback_compatible((expr), _curl_read_callback2) || \ + _curl_callback_compatible((expr), _curl_read_callback3) || \ + _curl_callback_compatible((expr), _curl_read_callback4) || \ + _curl_callback_compatible((expr), _curl_read_callback5) || \ + _curl_callback_compatible((expr), _curl_read_callback6)) +typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*); +typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*); +typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*); +typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*); +typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*); +typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*); + +/* evaluates to true if expr is of type curl_write_callback or "similar" */ +#define _curl_is_write_cb(expr) \ + (_curl_is_read_cb(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \ + _curl_callback_compatible((expr), _curl_write_callback1) || \ + _curl_callback_compatible((expr), _curl_write_callback2) || \ + _curl_callback_compatible((expr), _curl_write_callback3) || \ + _curl_callback_compatible((expr), _curl_write_callback4) || \ + _curl_callback_compatible((expr), _curl_write_callback5) || \ + _curl_callback_compatible((expr), _curl_write_callback6)) +typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*); +typedef size_t (_curl_write_callback2)(const char *, size_t, size_t, + const void*); +typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*); +typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*); +typedef size_t (_curl_write_callback5)(const void *, size_t, size_t, + const void*); +typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*); + +/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ +#define _curl_is_ioctl_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback4)) +typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*); +typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*); +typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*); +typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*); + +/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ +#define _curl_is_sockopt_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback2)) +typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); +typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t, + curlsocktype); + +/* evaluates to true if expr is of type curl_opensocket_callback or "similar" */ +#define _curl_is_opensocket_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\ + _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback4)) +typedef curl_socket_t (_curl_opensocket_callback1) + (void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback2) + (void *, curlsocktype, const struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback3) + (const void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback4) + (const void *, curlsocktype, const struct curl_sockaddr *); + +/* evaluates to true if expr is of type curl_progress_callback or "similar" */ +#define _curl_is_progress_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \ + _curl_callback_compatible((expr), _curl_progress_callback1) || \ + _curl_callback_compatible((expr), _curl_progress_callback2)) +typedef int (_curl_progress_callback1)(void *, + double, double, double, double); +typedef int (_curl_progress_callback2)(const void *, + double, double, double, double); + +/* evaluates to true if expr is of type curl_debug_callback or "similar" */ +#define _curl_is_debug_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \ + _curl_callback_compatible((expr), _curl_debug_callback1) || \ + _curl_callback_compatible((expr), _curl_debug_callback2) || \ + _curl_callback_compatible((expr), _curl_debug_callback3) || \ + _curl_callback_compatible((expr), _curl_debug_callback4)) +typedef int (_curl_debug_callback1) (CURL *, + curl_infotype, char *, size_t, void *); +typedef int (_curl_debug_callback2) (CURL *, + curl_infotype, char *, size_t, const void *); +typedef int (_curl_debug_callback3) (CURL *, + curl_infotype, const char *, size_t, void *); +typedef int (_curl_debug_callback4) (CURL *, + curl_infotype, const char *, size_t, const void *); + +/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ +/* this is getting even messier... */ +#define _curl_is_ssl_ctx_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) +typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *); +typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *); +typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *); +typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *); +#ifdef HEADER_SSL_H +/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX + * this will of course break if we're included before OpenSSL headers... + */ +typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); +typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); +typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); +typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, const void *); +#else +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; +#endif + +/* evaluates to true if expr is of type curl_conv_callback or "similar" */ +#define _curl_is_conv_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \ + _curl_callback_compatible((expr), _curl_conv_callback1) || \ + _curl_callback_compatible((expr), _curl_conv_callback2) || \ + _curl_callback_compatible((expr), _curl_conv_callback3) || \ + _curl_callback_compatible((expr), _curl_conv_callback4)) +typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); +typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); +typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); +typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); + +/* evaluates to true if expr is of type curl_seek_callback or "similar" */ +#define _curl_is_seek_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \ + _curl_callback_compatible((expr), _curl_seek_callback1) || \ + _curl_callback_compatible((expr), _curl_seek_callback2)) +typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); +typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); + + +#endif /* __CURL_TYPECHECK_GCC_H */ diff --git a/include/curl/types.h b/include/curl/types.h new file mode 100644 index 00000000..d37d6ae9 --- /dev/null +++ b/include/curl/types.h @@ -0,0 +1 @@ +/* not used */ diff --git a/include/dbus-1/dbus/dbus-address.h b/include/dbus-1/dbus/dbus-address.h new file mode 100644 index 00000000..e51ef0ae --- /dev/null +++ b/include/dbus-1/dbus/dbus-address.h @@ -0,0 +1,67 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-address.h Server address parser. + * + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_ADDRESS_H +#define DBUS_ADDRESS_H + +#include <dbus/dbus-types.h> +#include <dbus/dbus-errors.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusAddress + * @{ + */ + +/** Opaque type representing one of the semicolon-separated items in an address */ +typedef struct DBusAddressEntry DBusAddressEntry; + +DBUS_EXPORT +dbus_bool_t dbus_parse_address (const char *address, + DBusAddressEntry ***entry, + int *array_len, + DBusError *error); +DBUS_EXPORT +const char *dbus_address_entry_get_value (DBusAddressEntry *entry, + const char *key); +DBUS_EXPORT +const char *dbus_address_entry_get_method (DBusAddressEntry *entry); +DBUS_EXPORT +void dbus_address_entries_free (DBusAddressEntry **entries); + +DBUS_EXPORT +char* dbus_address_escape_value (const char *value); +DBUS_EXPORT +char* dbus_address_unescape_value (const char *value, + DBusError *error); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_ADDRESS_H */ + diff --git a/include/dbus-1/dbus/dbus-arch-deps.h b/include/dbus-1/dbus/dbus-arch-deps.h new file mode 100644 index 00000000..c8359c8c --- /dev/null +++ b/include/dbus-1/dbus/dbus-arch-deps.h @@ -0,0 +1,67 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-arch-deps.h Header with architecture/compiler specific information, installed to libdir + * + * Copyright (C) 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.0 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_ARCH_DEPS_H +#define DBUS_ARCH_DEPS_H + +#include <dbus/dbus-macros.h> + +DBUS_BEGIN_DECLS + +#if 1 +#define DBUS_HAVE_INT64 1 +_DBUS_GNUC_EXTENSION typedef long long dbus_int64_t; +_DBUS_GNUC_EXTENSION typedef unsigned long long dbus_uint64_t; + +#define DBUS_INT64_CONSTANT(val) (_DBUS_GNUC_EXTENSION (val##LL)) +#define DBUS_UINT64_CONSTANT(val) (_DBUS_GNUC_EXTENSION (val##ULL)) + +#else +#undef DBUS_HAVE_INT64 +#undef DBUS_INT64_CONSTANT +#undef DBUS_UINT64_CONSTANT +#endif + +typedef int dbus_int32_t; +typedef unsigned int dbus_uint32_t; + +typedef short dbus_int16_t; +typedef unsigned short dbus_uint16_t; + +/* This is not really arch-dependent, but it's not worth + * creating an additional generated header just for this + */ +#define DBUS_MAJOR_VERSION 1 +#define DBUS_MINOR_VERSION 4 +#define DBUS_MICRO_VERSION 0 + +#define DBUS_VERSION_STRING "1.4.0" + +#define DBUS_VERSION ((1 << 16) | (4 << 8) | (0)) + +DBUS_END_DECLS + +#endif /* DBUS_ARCH_DEPS_H */ diff --git a/include/dbus-1/dbus/dbus-auth-script.h b/include/dbus-1/dbus/dbus-auth-script.h new file mode 100644 index 00000000..39e6c7c4 --- /dev/null +++ b/include/dbus-1/dbus/dbus-auth-script.h @@ -0,0 +1,37 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-auth-script.h Test DBusAuth using a special script file (internal to D-Bus implementation) + * + * Copyright (C) 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_AUTH_SCRIPT_H +#define DBUS_AUTH_SCRIPT_H + +#include <dbus/dbus-memory.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-string.h> + +DBUS_BEGIN_DECLS + +dbus_bool_t _dbus_auth_script_run (const DBusString *filename); + +DBUS_END_DECLS + +#endif /* DBUS_AUTH_SCRIPT_H */ diff --git a/include/dbus-1/dbus/dbus-auth.h b/include/dbus-1/dbus/dbus-auth.h new file mode 100644 index 00000000..ae3f3647 --- /dev/null +++ b/include/dbus-1/dbus/dbus-auth.h @@ -0,0 +1,83 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-auth.h Authentication + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_AUTH_H +#define DBUS_AUTH_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-errors.h> +#include <dbus/dbus-string.h> +#include <dbus/dbus-sysdeps.h> + +DBUS_BEGIN_DECLS + +typedef struct DBusAuth DBusAuth; + +typedef enum +{ + DBUS_AUTH_STATE_WAITING_FOR_INPUT, + DBUS_AUTH_STATE_WAITING_FOR_MEMORY, + DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND, + DBUS_AUTH_STATE_NEED_DISCONNECT, + DBUS_AUTH_STATE_AUTHENTICATED +} DBusAuthState; + +DBusAuth* _dbus_auth_server_new (const DBusString *guid); +DBusAuth* _dbus_auth_client_new (void); +DBusAuth* _dbus_auth_ref (DBusAuth *auth); +void _dbus_auth_unref (DBusAuth *auth); +dbus_bool_t _dbus_auth_set_mechanisms (DBusAuth *auth, + const char **mechanisms); +DBusAuthState _dbus_auth_do_work (DBusAuth *auth); +dbus_bool_t _dbus_auth_get_bytes_to_send (DBusAuth *auth, + const DBusString **str); +void _dbus_auth_bytes_sent (DBusAuth *auth, + int bytes_sent); +void _dbus_auth_get_buffer (DBusAuth *auth, + DBusString **buffer); +void _dbus_auth_return_buffer (DBusAuth *auth, + DBusString *buffer, + int bytes_read); +void _dbus_auth_get_unused_bytes (DBusAuth *auth, + const DBusString **str); +void _dbus_auth_delete_unused_bytes (DBusAuth *auth); +dbus_bool_t _dbus_auth_needs_encoding (DBusAuth *auth); +dbus_bool_t _dbus_auth_encode_data (DBusAuth *auth, + const DBusString *plaintext, + DBusString *encoded); +dbus_bool_t _dbus_auth_needs_decoding (DBusAuth *auth); +dbus_bool_t _dbus_auth_decode_data (DBusAuth *auth, + const DBusString *encoded, + DBusString *plaintext); +dbus_bool_t _dbus_auth_set_credentials (DBusAuth *auth, + DBusCredentials *credentials); +DBusCredentials* _dbus_auth_get_identity (DBusAuth *auth); +dbus_bool_t _dbus_auth_set_context (DBusAuth *auth, + const DBusString *context); +const char* _dbus_auth_get_guid_from_server(DBusAuth *auth); + +void _dbus_auth_set_unix_fd_possible(DBusAuth *auth, dbus_bool_t b); +dbus_bool_t _dbus_auth_get_unix_fd_negotiated(DBusAuth *auth); + +DBUS_END_DECLS + +#endif /* DBUS_AUTH_H */ diff --git a/include/dbus-1/dbus/dbus-bus.h b/include/dbus-1/dbus/dbus-bus.h new file mode 100644 index 00000000..02a95711 --- /dev/null +++ b/include/dbus-1/dbus/dbus-bus.h @@ -0,0 +1,95 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-bus.h Convenience functions for communicating with the bus. + * + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_BUS_H +#define DBUS_BUS_H + +#include <dbus/dbus-connection.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusBus + * @{ + */ + +DBUS_EXPORT +DBusConnection *dbus_bus_get (DBusBusType type, + DBusError *error); +DBUS_EXPORT +DBusConnection *dbus_bus_get_private (DBusBusType type, + DBusError *error); + +DBUS_EXPORT +dbus_bool_t dbus_bus_register (DBusConnection *connection, + DBusError *error); +DBUS_EXPORT +dbus_bool_t dbus_bus_set_unique_name (DBusConnection *connection, + const char *unique_name); +DBUS_EXPORT +const char* dbus_bus_get_unique_name (DBusConnection *connection); +DBUS_EXPORT +unsigned long dbus_bus_get_unix_user (DBusConnection *connection, + const char *name, + DBusError *error); +DBUS_EXPORT +char* dbus_bus_get_id (DBusConnection *connection, + DBusError *error); +DBUS_EXPORT +int dbus_bus_request_name (DBusConnection *connection, + const char *name, + unsigned int flags, + DBusError *error); +DBUS_EXPORT +int dbus_bus_release_name (DBusConnection *connection, + const char *name, + DBusError *error); +DBUS_EXPORT +dbus_bool_t dbus_bus_name_has_owner (DBusConnection *connection, + const char *name, + DBusError *error); + +DBUS_EXPORT +dbus_bool_t dbus_bus_start_service_by_name (DBusConnection *connection, + const char *name, + dbus_uint32_t flags, + dbus_uint32_t *reply, + DBusError *error); + +DBUS_EXPORT +void dbus_bus_add_match (DBusConnection *connection, + const char *rule, + DBusError *error); +DBUS_EXPORT +void dbus_bus_remove_match (DBusConnection *connection, + const char *rule, + DBusError *error); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_BUS_H */ diff --git a/include/dbus-1/dbus/dbus-connection-internal.h b/include/dbus-1/dbus/dbus-connection-internal.h new file mode 100644 index 00000000..cdf3f59d --- /dev/null +++ b/include/dbus-1/dbus/dbus-connection-internal.h @@ -0,0 +1,121 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-connection-internal.h DBusConnection internal interfaces + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_CONNECTION_INTERNAL_H +#define DBUS_CONNECTION_INTERNAL_H + +#include <dbus/dbus-internals.h> +#include <dbus/dbus-connection.h> +#include <dbus/dbus-message.h> +#include <dbus/dbus-transport.h> +#include <dbus/dbus-resources.h> +#include <dbus/dbus-list.h> +#include <dbus/dbus-timeout.h> +#include <dbus/dbus-dataslot.h> + +DBUS_BEGIN_DECLS + +typedef enum +{ + DBUS_ITERATION_DO_WRITING = 1 << 0, /**< Write messages out. */ + DBUS_ITERATION_DO_READING = 1 << 1, /**< Read messages in. */ + DBUS_ITERATION_BLOCK = 1 << 2 /**< Block if nothing to do. */ +} DBusIterationFlags; + +/** default timeout value when waiting for a message reply, 25 seconds */ +#define _DBUS_DEFAULT_TIMEOUT_VALUE (25 * 1000) + +void _dbus_connection_lock (DBusConnection *connection); +void _dbus_connection_unlock (DBusConnection *connection); +DBusConnection * _dbus_connection_ref_unlocked (DBusConnection *connection); +void _dbus_connection_unref_unlocked (DBusConnection *connection); +dbus_bool_t _dbus_connection_queue_received_message (DBusConnection *connection, + DBusMessage *message); +void _dbus_connection_queue_received_message_link (DBusConnection *connection, + DBusList *link); +dbus_bool_t _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection); +DBusMessage* _dbus_connection_get_message_to_send (DBusConnection *connection); +void _dbus_connection_message_sent (DBusConnection *connection, + DBusMessage *message); +dbus_bool_t _dbus_connection_add_watch_unlocked (DBusConnection *connection, + DBusWatch *watch); +void _dbus_connection_remove_watch_unlocked (DBusConnection *connection, + DBusWatch *watch); +void _dbus_connection_toggle_watch_unlocked (DBusConnection *connection, + DBusWatch *watch, + dbus_bool_t enabled); +dbus_bool_t _dbus_connection_handle_watch (DBusWatch *watch, + unsigned int condition, + void *data); +dbus_bool_t _dbus_connection_add_timeout_unlocked (DBusConnection *connection, + DBusTimeout *timeout); +void _dbus_connection_remove_timeout_unlocked (DBusConnection *connection, + DBusTimeout *timeout); +void _dbus_connection_toggle_timeout_unlocked (DBusConnection *connection, + DBusTimeout *timeout, + dbus_bool_t enabled); +DBusConnection* _dbus_connection_new_for_transport (DBusTransport *transport); +void _dbus_connection_do_iteration_unlocked (DBusConnection *connection, + DBusPendingCall *pending, + unsigned int flags, + int timeout_milliseconds); +void _dbus_connection_close_possibly_shared (DBusConnection *connection); +void _dbus_connection_close_if_only_one_ref (DBusConnection *connection); + +DBusPendingCall* _dbus_pending_call_new (DBusConnection *connection, + int timeout_milliseconds, + DBusTimeoutHandler timeout_handler); +void _dbus_pending_call_notify (DBusPendingCall *pending); +void _dbus_connection_remove_pending_call (DBusConnection *connection, + DBusPendingCall *pending); +void _dbus_connection_block_pending_call (DBusPendingCall *pending); +void _dbus_pending_call_complete_and_unlock (DBusPendingCall *pending, + DBusMessage *message); +dbus_bool_t _dbus_connection_send_and_unlock (DBusConnection *connection, + DBusMessage *message, + dbus_uint32_t *client_serial); + +void _dbus_connection_queue_synthesized_message_link (DBusConnection *connection, + DBusList *link); +void _dbus_connection_test_get_locks (DBusConnection *conn, + DBusMutex **mutex_loc, + DBusMutex **dispatch_mutex_loc, + DBusMutex **io_path_mutex_loc, + DBusCondVar **dispatch_cond_loc, + DBusCondVar **io_path_cond_loc); + +/* This _dbus_bus_* stuff doesn't really belong here, but dbus-bus-internal.h seems + * silly for one function + */ +/** + * @addtogroup DBusBusInternals + * @{ + */ + +void _dbus_bus_notify_shared_connection_disconnected_unlocked (DBusConnection *connection); + +/** @} */ + + +DBUS_END_DECLS + +#endif /* DBUS_CONNECTION_INTERNAL_H */ diff --git a/include/dbus-1/dbus/dbus-connection.h b/include/dbus-1/dbus/dbus-connection.h new file mode 100644 index 00000000..3e2a7d8d --- /dev/null +++ b/include/dbus-1/dbus/dbus-connection.h @@ -0,0 +1,495 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-connection.h DBusConnection object + * + * Copyright (C) 2002, 2003 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_CONNECTION_H +#define DBUS_CONNECTION_H + +#include <dbus/dbus-errors.h> +#include <dbus/dbus-memory.h> +#include <dbus/dbus-message.h> +#include <dbus/dbus-shared.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusConnection + * @{ + */ + +/* documented in dbus-watch.c */ +typedef struct DBusWatch DBusWatch; +/* documented in dbus-timeout.c */ +typedef struct DBusTimeout DBusTimeout; +/** Opaque type representing preallocated resources so a message can be sent without further memory allocation. */ +typedef struct DBusPreallocatedSend DBusPreallocatedSend; +/** Opaque type representing a method call that has not yet received a reply. */ +typedef struct DBusPendingCall DBusPendingCall; +/** Opaque type representing a connection to a remote application and associated incoming/outgoing message queues. */ +typedef struct DBusConnection DBusConnection; +/** Set of functions that must be implemented to handle messages sent to a particular object path. */ +typedef struct DBusObjectPathVTable DBusObjectPathVTable; + +/** + * Indicates the status of a #DBusWatch. + */ +typedef enum +{ + DBUS_WATCH_READABLE = 1 << 0, /**< As in POLLIN */ + DBUS_WATCH_WRITABLE = 1 << 1, /**< As in POLLOUT */ + DBUS_WATCH_ERROR = 1 << 2, /**< As in POLLERR (can't watch for + * this, but can be present in + * current state passed to + * dbus_watch_handle()). + */ + DBUS_WATCH_HANGUP = 1 << 3 /**< As in POLLHUP (can't watch for + * it, but can be present in current + * state passed to + * dbus_watch_handle()). + */ +} DBusWatchFlags; + +/** + * Indicates the status of incoming data on a #DBusConnection. This determines whether + * dbus_connection_dispatch() needs to be called. + */ +typedef enum +{ + DBUS_DISPATCH_DATA_REMAINS, /**< There is more data to potentially convert to messages. */ + DBUS_DISPATCH_COMPLETE, /**< All currently available data has been processed. */ + DBUS_DISPATCH_NEED_MEMORY /**< More memory is needed to continue. */ +} DBusDispatchStatus; + +/** Called when libdbus needs a new watch to be monitored by the main + * loop. Returns #FALSE if it lacks enough memory to add the + * watch. Set by dbus_connection_set_watch_functions() or + * dbus_server_set_watch_functions(). + */ +typedef dbus_bool_t (* DBusAddWatchFunction) (DBusWatch *watch, + void *data); +/** Called when dbus_watch_get_enabled() may return a different value + * than it did before. Set by dbus_connection_set_watch_functions() + * or dbus_server_set_watch_functions(). + */ +typedef void (* DBusWatchToggledFunction) (DBusWatch *watch, + void *data); +/** Called when libdbus no longer needs a watch to be monitored by the + * main loop. Set by dbus_connection_set_watch_functions() or + * dbus_server_set_watch_functions(). + */ +typedef void (* DBusRemoveWatchFunction) (DBusWatch *watch, + void *data); +/** Called when libdbus needs a new timeout to be monitored by the main + * loop. Returns #FALSE if it lacks enough memory to add the + * watch. Set by dbus_connection_set_timeout_functions() or + * dbus_server_set_timeout_functions(). + */ +typedef dbus_bool_t (* DBusAddTimeoutFunction) (DBusTimeout *timeout, + void *data); +/** Called when dbus_timeout_get_enabled() may return a different + * value than it did before. + * Set by dbus_connection_set_timeout_functions() or + * dbus_server_set_timeout_functions(). + */ +typedef void (* DBusTimeoutToggledFunction) (DBusTimeout *timeout, + void *data); +/** Called when libdbus no longer needs a timeout to be monitored by the + * main loop. Set by dbus_connection_set_timeout_functions() or + * dbus_server_set_timeout_functions(). + */ +typedef void (* DBusRemoveTimeoutFunction) (DBusTimeout *timeout, + void *data); +/** Called when the return value of dbus_connection_get_dispatch_status() + * may have changed. Set with dbus_connection_set_dispatch_status_function(). + */ +typedef void (* DBusDispatchStatusFunction) (DBusConnection *connection, + DBusDispatchStatus new_status, + void *data); +/** + * Called when the main loop's thread should be notified that there's now work + * to do. Set with dbus_connection_set_wakeup_main_function(). + */ +typedef void (* DBusWakeupMainFunction) (void *data); + +/** + * Called during authentication to check whether the given UNIX user + * ID is allowed to connect, if the client tried to auth as a UNIX + * user ID. Normally on Windows this would never happen. Set with + * dbus_connection_set_unix_user_function(). + */ +typedef dbus_bool_t (* DBusAllowUnixUserFunction) (DBusConnection *connection, + unsigned long uid, + void *data); + +/** + * Called during authentication to check whether the given Windows user + * ID is allowed to connect, if the client tried to auth as a Windows + * user ID. Normally on UNIX this would never happen. Set with + * dbus_connection_set_windows_user_function(). + */ +typedef dbus_bool_t (* DBusAllowWindowsUserFunction) (DBusConnection *connection, + const char *user_sid, + void *data); + + +/** + * Called when a pending call now has a reply available. Set with + * dbus_pending_call_set_notify(). + */ +typedef void (* DBusPendingCallNotifyFunction) (DBusPendingCall *pending, + void *user_data); + +/** + * Called when a message needs to be handled. The result indicates whether or + * not more handlers should be run. Set with dbus_connection_add_filter(). + */ +typedef DBusHandlerResult (* DBusHandleMessageFunction) (DBusConnection *connection, + DBusMessage *message, + void *user_data); +DBUS_EXPORT +DBusConnection* dbus_connection_open (const char *address, + DBusError *error); +DBUS_EXPORT +DBusConnection* dbus_connection_open_private (const char *address, + DBusError *error); +DBUS_EXPORT +DBusConnection* dbus_connection_ref (DBusConnection *connection); +DBUS_EXPORT +void dbus_connection_unref (DBusConnection *connection); +DBUS_EXPORT +void dbus_connection_close (DBusConnection *connection); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_is_connected (DBusConnection *connection); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_is_authenticated (DBusConnection *connection); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_is_anonymous (DBusConnection *connection); +DBUS_EXPORT +char* dbus_connection_get_server_id (DBusConnection *connection); +DBUS_EXPORT +dbus_bool_t dbus_connection_can_send_type (DBusConnection *connection, + int type); + +DBUS_EXPORT +void dbus_connection_set_exit_on_disconnect (DBusConnection *connection, + dbus_bool_t exit_on_disconnect); +DBUS_EXPORT +void dbus_connection_flush (DBusConnection *connection); +DBUS_EXPORT +dbus_bool_t dbus_connection_read_write_dispatch (DBusConnection *connection, + int timeout_milliseconds); +DBUS_EXPORT +dbus_bool_t dbus_connection_read_write (DBusConnection *connection, + int timeout_milliseconds); +DBUS_EXPORT +DBusMessage* dbus_connection_borrow_message (DBusConnection *connection); +DBUS_EXPORT +void dbus_connection_return_message (DBusConnection *connection, + DBusMessage *message); +DBUS_EXPORT +void dbus_connection_steal_borrowed_message (DBusConnection *connection, + DBusMessage *message); +DBUS_EXPORT +DBusMessage* dbus_connection_pop_message (DBusConnection *connection); +DBUS_EXPORT +DBusDispatchStatus dbus_connection_get_dispatch_status (DBusConnection *connection); +DBUS_EXPORT +DBusDispatchStatus dbus_connection_dispatch (DBusConnection *connection); +DBUS_EXPORT +dbus_bool_t dbus_connection_has_messages_to_send (DBusConnection *connection); +DBUS_EXPORT +dbus_bool_t dbus_connection_send (DBusConnection *connection, + DBusMessage *message, + dbus_uint32_t *client_serial); +DBUS_EXPORT +dbus_bool_t dbus_connection_send_with_reply (DBusConnection *connection, + DBusMessage *message, + DBusPendingCall **pending_return, + int timeout_milliseconds); +DBUS_EXPORT +DBusMessage * dbus_connection_send_with_reply_and_block (DBusConnection *connection, + DBusMessage *message, + int timeout_milliseconds, + DBusError *error); +DBUS_EXPORT +dbus_bool_t dbus_connection_set_watch_functions (DBusConnection *connection, + DBusAddWatchFunction add_function, + DBusRemoveWatchFunction remove_function, + DBusWatchToggledFunction toggled_function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_connection_set_timeout_functions (DBusConnection *connection, + DBusAddTimeoutFunction add_function, + DBusRemoveTimeoutFunction remove_function, + DBusTimeoutToggledFunction toggled_function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +void dbus_connection_set_wakeup_main_function (DBusConnection *connection, + DBusWakeupMainFunction wakeup_main_function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +void dbus_connection_set_dispatch_status_function (DBusConnection *connection, + DBusDispatchStatusFunction function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_unix_user (DBusConnection *connection, + unsigned long *uid); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_unix_process_id (DBusConnection *connection, + unsigned long *pid); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_adt_audit_session_data (DBusConnection *connection, + void **data, + dbus_int32_t *data_size); +DBUS_EXPORT +void dbus_connection_set_unix_user_function (DBusConnection *connection, + DBusAllowUnixUserFunction function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_windows_user (DBusConnection *connection, + char **windows_sid_p); +DBUS_EXPORT +void dbus_connection_set_windows_user_function (DBusConnection *connection, + DBusAllowWindowsUserFunction function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +void dbus_connection_set_allow_anonymous (DBusConnection *connection, + dbus_bool_t value); +DBUS_EXPORT +void dbus_connection_set_route_peer_messages (DBusConnection *connection, + dbus_bool_t value); + + +/* Filters */ + +DBUS_EXPORT +dbus_bool_t dbus_connection_add_filter (DBusConnection *connection, + DBusHandleMessageFunction function, + void *user_data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +void dbus_connection_remove_filter (DBusConnection *connection, + DBusHandleMessageFunction function, + void *user_data); + + +/* Other */ +DBUS_EXPORT +dbus_bool_t dbus_connection_allocate_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +void dbus_connection_free_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +dbus_bool_t dbus_connection_set_data (DBusConnection *connection, + dbus_int32_t slot, + void *data, + DBusFreeFunction free_data_func); +DBUS_EXPORT +void* dbus_connection_get_data (DBusConnection *connection, + dbus_int32_t slot); + +DBUS_EXPORT +void dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe); + +DBUS_EXPORT +void dbus_connection_set_max_message_size (DBusConnection *connection, + long size); +DBUS_EXPORT +long dbus_connection_get_max_message_size (DBusConnection *connection); +DBUS_EXPORT +void dbus_connection_set_max_received_size (DBusConnection *connection, + long size); +DBUS_EXPORT +long dbus_connection_get_max_received_size (DBusConnection *connection); + +DBUS_EXPORT +void dbus_connection_set_max_message_unix_fds (DBusConnection *connection, + long n); +DBUS_EXPORT +long dbus_connection_get_max_message_unix_fds (DBusConnection *connection); +DBUS_EXPORT +void dbus_connection_set_max_received_unix_fds(DBusConnection *connection, + long n); +DBUS_EXPORT +long dbus_connection_get_max_received_unix_fds(DBusConnection *connection); + +DBUS_EXPORT +long dbus_connection_get_outgoing_size (DBusConnection *connection); +DBUS_EXPORT +long dbus_connection_get_outgoing_unix_fds (DBusConnection *connection); + +DBUS_EXPORT +DBusPreallocatedSend* dbus_connection_preallocate_send (DBusConnection *connection); +DBUS_EXPORT +void dbus_connection_free_preallocated_send (DBusConnection *connection, + DBusPreallocatedSend *preallocated); +DBUS_EXPORT +void dbus_connection_send_preallocated (DBusConnection *connection, + DBusPreallocatedSend *preallocated, + DBusMessage *message, + dbus_uint32_t *client_serial); + + +/* Object tree functionality */ + +/** + * Called when a #DBusObjectPathVTable is unregistered (or its connection is freed). + * Found in #DBusObjectPathVTable. + */ +typedef void (* DBusObjectPathUnregisterFunction) (DBusConnection *connection, + void *user_data); +/** + * Called when a message is sent to a registered object path. Found in + * #DBusObjectPathVTable which is registered with dbus_connection_register_object_path() + * or dbus_connection_register_fallback(). + */ +typedef DBusHandlerResult (* DBusObjectPathMessageFunction) (DBusConnection *connection, + DBusMessage *message, + void *user_data); + +/** + * Virtual table that must be implemented to handle a portion of the + * object path hierarchy. Attach the vtable to a particular path using + * dbus_connection_register_object_path() or + * dbus_connection_register_fallback(). + */ +struct DBusObjectPathVTable +{ + DBusObjectPathUnregisterFunction unregister_function; /**< Function to unregister this handler */ + DBusObjectPathMessageFunction message_function; /**< Function to handle messages */ + + void (* dbus_internal_pad1) (void *); /**< Reserved for future expansion */ + void (* dbus_internal_pad2) (void *); /**< Reserved for future expansion */ + void (* dbus_internal_pad3) (void *); /**< Reserved for future expansion */ + void (* dbus_internal_pad4) (void *); /**< Reserved for future expansion */ +}; + +DBUS_EXPORT +dbus_bool_t dbus_connection_try_register_object_path (DBusConnection *connection, + const char *path, + const DBusObjectPathVTable *vtable, + void *user_data, + DBusError *error); + +DBUS_EXPORT +dbus_bool_t dbus_connection_register_object_path (DBusConnection *connection, + const char *path, + const DBusObjectPathVTable *vtable, + void *user_data); + +DBUS_EXPORT +dbus_bool_t dbus_connection_try_register_fallback (DBusConnection *connection, + const char *path, + const DBusObjectPathVTable *vtable, + void *user_data, + DBusError *error); + +DBUS_EXPORT +dbus_bool_t dbus_connection_register_fallback (DBusConnection *connection, + const char *path, + const DBusObjectPathVTable *vtable, + void *user_data); +DBUS_EXPORT +dbus_bool_t dbus_connection_unregister_object_path (DBusConnection *connection, + const char *path); + +DBUS_EXPORT +dbus_bool_t dbus_connection_get_object_path_data (DBusConnection *connection, + const char *path, + void **data_p); + +DBUS_EXPORT +dbus_bool_t dbus_connection_list_registered (DBusConnection *connection, + const char *parent_path, + char ***child_entries); + +DBUS_EXPORT +dbus_bool_t dbus_connection_get_unix_fd (DBusConnection *connection, + int *fd); +DBUS_EXPORT +dbus_bool_t dbus_connection_get_socket (DBusConnection *connection, + int *fd); + +/** @} */ + + +/** + * @addtogroup DBusWatch + * @{ + */ + +#ifndef DBUS_DISABLE_DEPRECATED +DBUS_EXPORT +DBUS_DEPRECATED int dbus_watch_get_fd (DBusWatch *watch); +#endif + +DBUS_EXPORT +int dbus_watch_get_unix_fd (DBusWatch *watch); +DBUS_EXPORT +int dbus_watch_get_socket (DBusWatch *watch); +DBUS_EXPORT +unsigned int dbus_watch_get_flags (DBusWatch *watch); +DBUS_EXPORT +void* dbus_watch_get_data (DBusWatch *watch); +DBUS_EXPORT +void dbus_watch_set_data (DBusWatch *watch, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_watch_handle (DBusWatch *watch, + unsigned int flags); +DBUS_EXPORT +dbus_bool_t dbus_watch_get_enabled (DBusWatch *watch); + +/** @} */ + +/** + * @addtogroup DBusTimeout + * @{ + */ + +DBUS_EXPORT +int dbus_timeout_get_interval (DBusTimeout *timeout); +DBUS_EXPORT +void* dbus_timeout_get_data (DBusTimeout *timeout); +DBUS_EXPORT +void dbus_timeout_set_data (DBusTimeout *timeout, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_timeout_handle (DBusTimeout *timeout); +DBUS_EXPORT +dbus_bool_t dbus_timeout_get_enabled (DBusTimeout *timeout); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_CONNECTION_H */ diff --git a/include/dbus-1/dbus/dbus-credentials.h b/include/dbus-1/dbus/dbus-credentials.h new file mode 100644 index 00000000..ef6124fd --- /dev/null +++ b/include/dbus-1/dbus/dbus-credentials.h @@ -0,0 +1,79 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-credentials.h Credentials provable through authentication + * + * Copyright (C) 2007 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_CREDENTIALS_H +#define DBUS_CREDENTIALS_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-errors.h> +#include <dbus/dbus-string.h> +#include <dbus/dbus-sysdeps.h> + +DBUS_BEGIN_DECLS + +typedef enum { + DBUS_CREDENTIAL_UNIX_PROCESS_ID, + DBUS_CREDENTIAL_UNIX_USER_ID, + DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID, + DBUS_CREDENTIAL_WINDOWS_SID +} DBusCredentialType; + +DBusCredentials* _dbus_credentials_new_from_current_process (void); +DBusCredentials* _dbus_credentials_new (void); +void _dbus_credentials_ref (DBusCredentials *credentials); +void _dbus_credentials_unref (DBusCredentials *credentials); +dbus_bool_t _dbus_credentials_add_unix_pid (DBusCredentials *credentials, + dbus_pid_t pid); +dbus_bool_t _dbus_credentials_add_unix_uid (DBusCredentials *credentials, + dbus_uid_t uid); +dbus_bool_t _dbus_credentials_add_windows_sid (DBusCredentials *credentials, + const char *windows_sid); +dbus_bool_t _dbus_credentials_add_adt_audit_data (DBusCredentials *credentials, + void *audit_data, + dbus_int32_t size); +dbus_bool_t _dbus_credentials_include (DBusCredentials *credentials, + DBusCredentialType type); +dbus_pid_t _dbus_credentials_get_unix_pid (DBusCredentials *credentials); +dbus_uid_t _dbus_credentials_get_unix_uid (DBusCredentials *credentials); +const char* _dbus_credentials_get_windows_sid (DBusCredentials *credentials); +void * _dbus_credentials_get_adt_audit_data (DBusCredentials *credentials); +dbus_int32_t _dbus_credentials_get_adt_audit_data_size (DBusCredentials *credentials); +dbus_bool_t _dbus_credentials_are_superset (DBusCredentials *credentials, + DBusCredentials *possible_subset); +dbus_bool_t _dbus_credentials_are_empty (DBusCredentials *credentials); +dbus_bool_t _dbus_credentials_are_anonymous (DBusCredentials *credentials); +dbus_bool_t _dbus_credentials_add_credentials (DBusCredentials *credentials, + DBusCredentials *other_credentials); +/* must silently allow 'which' to not exist */ +dbus_bool_t _dbus_credentials_add_credential (DBusCredentials *credentials, + DBusCredentialType which, + DBusCredentials *other_credentials); +void _dbus_credentials_clear (DBusCredentials *credentials); +DBusCredentials* _dbus_credentials_copy (DBusCredentials *credentials); +dbus_bool_t _dbus_credentials_same_user (DBusCredentials *credentials, + DBusCredentials *other_credentials); +dbus_bool_t _dbus_credentials_to_string_append (DBusCredentials *credentials, + DBusString *string); + +DBUS_END_DECLS + +#endif /* DBUS_CREDENTIALS_H */ diff --git a/include/dbus-1/dbus/dbus-dataslot.h b/include/dbus-1/dbus/dbus-dataslot.h new file mode 100644 index 00000000..2e706f72 --- /dev/null +++ b/include/dbus-1/dbus/dbus-dataslot.h @@ -0,0 +1,96 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-dataslot.h storing data on objects + * + * Copyright (C) 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_DATASLOT_H +#define DBUS_DATASLOT_H + +#include <dbus/dbus-internals.h> + +DBUS_BEGIN_DECLS + +typedef struct DBusDataSlotAllocator DBusDataSlotAllocator; +typedef struct DBusDataSlotList DBusDataSlotList; + +/** Opaque typedef for DBusDataSlot */ +typedef struct DBusDataSlot DBusDataSlot; +/** DBusDataSlot is used to store application data on the connection */ +struct DBusDataSlot +{ + void *data; /**< The application data */ + DBusFreeFunction free_data_func; /**< Free the application data */ +}; + +typedef struct DBusAllocatedSlot DBusAllocatedSlot; + +/** An allocated slot for storing data + */ +struct DBusAllocatedSlot +{ + dbus_int32_t slot_id; /**< ID of this slot */ + int refcount; /**< Number of uses of the slot */ +}; + +/** + * An allocator that tracks a set of slot IDs. + */ +struct DBusDataSlotAllocator +{ + DBusAllocatedSlot *allocated_slots; /**< Allocated slots */ + int n_allocated_slots; /**< number of slots malloc'd */ + int n_used_slots; /**< number of slots used */ + DBusMutex **lock_loc; /**< location of thread lock */ +}; + +/** + * Data structure that stores the actual user data set at a given + * slot. + */ +struct DBusDataSlotList +{ + DBusDataSlot *slots; /**< Data slots */ + int n_slots; /**< Slots we have storage for in data_slots */ +}; + +dbus_bool_t _dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator); +dbus_bool_t _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator, + DBusMutex **mutex_loc, + int *slot_id_p); +void _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator, + int *slot_id_p); +void _dbus_data_slot_list_init (DBusDataSlotList *list); +dbus_bool_t _dbus_data_slot_list_set (DBusDataSlotAllocator *allocator, + DBusDataSlotList *list, + int slot, + void *data, + DBusFreeFunction free_data_func, + DBusFreeFunction *old_free_func, + void **old_data); +void* _dbus_data_slot_list_get (DBusDataSlotAllocator *allocator, + DBusDataSlotList *list, + int slot); +void _dbus_data_slot_list_clear (DBusDataSlotList *list); +void _dbus_data_slot_list_free (DBusDataSlotList *list); + + +DBUS_END_DECLS + +#endif /* DBUS_DATASLOT_H */ diff --git a/include/dbus-1/dbus/dbus-errors.h b/include/dbus-1/dbus/dbus-errors.h new file mode 100644 index 00000000..e63139a0 --- /dev/null +++ b/include/dbus-1/dbus/dbus-errors.h @@ -0,0 +1,90 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-errors.h Error reporting + * + * Copyright (C) 2002 Red Hat Inc. + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_ERROR_H +#define DBUS_ERROR_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-protocol.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusErrors + * @{ + */ + +/** Mostly-opaque type representing an error that occurred */ +typedef struct DBusError DBusError; + +/** + * Object representing an exception. + */ +struct DBusError +{ + const char *name; /**< public error name field */ + const char *message; /**< public error message field */ + + unsigned int dummy1 : 1; /**< placeholder */ + unsigned int dummy2 : 1; /**< placeholder */ + unsigned int dummy3 : 1; /**< placeholder */ + unsigned int dummy4 : 1; /**< placeholder */ + unsigned int dummy5 : 1; /**< placeholder */ + + void *padding1; /**< placeholder */ +}; + +#define DBUS_ERROR_INIT { NULL, NULL, TRUE, 0, 0, 0, 0, NULL } + +DBUS_EXPORT +void dbus_error_init (DBusError *error); +DBUS_EXPORT +void dbus_error_free (DBusError *error); +DBUS_EXPORT +void dbus_set_error (DBusError *error, + const char *name, + const char *message, + ...); +DBUS_EXPORT +void dbus_set_error_const (DBusError *error, + const char *name, + const char *message); +DBUS_EXPORT +void dbus_move_error (DBusError *src, + DBusError *dest); +DBUS_EXPORT +dbus_bool_t dbus_error_has_name (const DBusError *error, + const char *name); +DBUS_EXPORT +dbus_bool_t dbus_error_is_set (const DBusError *error); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_ERROR_H */ diff --git a/include/dbus-1/dbus/dbus-file.h b/include/dbus-1/dbus/dbus-file.h new file mode 100644 index 00000000..24837f47 --- /dev/null +++ b/include/dbus-1/dbus/dbus-file.h @@ -0,0 +1,63 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-file.h dbus file related stuff (internal to D-Bus implementation) + * + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_FILE_H +#define DBUS_FILE_H + +//#include <dbus/dbus-types.h> +#include <dbus/dbus-string.h> +#include <dbus/dbus-errors.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusFile + * @{ + */ + +/** + * File interface + */ +dbus_bool_t _dbus_file_exists (const char *file); +dbus_bool_t _dbus_file_get_contents (DBusString *str, + const DBusString *filename, + DBusError *error); +dbus_bool_t _dbus_string_save_to_file (const DBusString *str, + const DBusString *filename, + dbus_bool_t world_readable, + DBusError *error); + +dbus_bool_t _dbus_make_file_world_readable (const DBusString *filename, + DBusError *error); + +dbus_bool_t _dbus_create_file_exclusively (const DBusString *filename, + DBusError *error); +dbus_bool_t _dbus_delete_file (const DBusString *filename, + DBusError *error); + +/** @} */ + +DBUS_END_DECLS + +#endif diff --git a/include/dbus-1/dbus/dbus-hash.h b/include/dbus-1/dbus/dbus-hash.h new file mode 100644 index 00000000..d1ca246c --- /dev/null +++ b/include/dbus-1/dbus/dbus-hash.h @@ -0,0 +1,151 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-hash.h Generic hash table utility (internal to D-Bus implementation) + * + * Copyright (C) 2002 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_HASH_H +#define DBUS_HASH_H + +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif + +#ifdef HAVE_INTTYPES_H +#include <inttypes.h> +#endif + +#include <dbus/dbus-memory.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-sysdeps.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusHashTable + * @{ + */ + +/** Hash iterator object. The iterator is on the stack, but its real + * fields are hidden privately. + */ +struct DBusHashIter +{ + void *dummy1; /**< Do not use. */ + void *dummy2; /**< Do not use. */ + void *dummy3; /**< Do not use. */ + void *dummy4; /**< Do not use. */ + int dummy5; /**< Do not use. */ + int dummy6; /**< Do not use. */ +}; + +typedef struct DBusHashTable DBusHashTable; +typedef struct DBusHashIter DBusHashIter; + +/* Allowing an arbitrary function as with GLib + * would be nicer for a public API, but for + * an internal API this saves typing, we can add + * more whenever we feel like it. + */ +typedef enum +{ + DBUS_HASH_STRING, /**< Hash keys are strings. */ + DBUS_HASH_TWO_STRINGS, /**< Hash key is two strings in one memory block, i.e. foo\\0bar\\0 */ + DBUS_HASH_INT, /**< Hash keys are integers. */ + DBUS_HASH_POINTER, /**< Hash keys are pointers. */ + DBUS_HASH_UINTPTR /**< Hash keys are integer capable to hold a pointer. */ +} DBusHashType; + +DBusHashTable* _dbus_hash_table_new (DBusHashType type, + DBusFreeFunction key_free_function, + DBusFreeFunction value_free_function); +DBusHashTable* _dbus_hash_table_ref (DBusHashTable *table); +void _dbus_hash_table_unref (DBusHashTable *table); +void _dbus_hash_table_remove_all (DBusHashTable *table); +void _dbus_hash_iter_init (DBusHashTable *table, + DBusHashIter *iter); +dbus_bool_t _dbus_hash_iter_next (DBusHashIter *iter); +void _dbus_hash_iter_remove_entry (DBusHashIter *iter); +void* _dbus_hash_iter_get_value (DBusHashIter *iter); +void _dbus_hash_iter_set_value (DBusHashIter *iter, + void *value); +int _dbus_hash_iter_get_int_key (DBusHashIter *iter); +const char* _dbus_hash_iter_get_string_key (DBusHashIter *iter); +const char* _dbus_hash_iter_get_two_strings_key (DBusHashIter *iter); +uintptr_t _dbus_hash_iter_get_uintptr_key (DBusHashIter *iter); +dbus_bool_t _dbus_hash_iter_lookup (DBusHashTable *table, + void *key, + dbus_bool_t create_if_not_found, + DBusHashIter *iter); +void* _dbus_hash_table_lookup_string (DBusHashTable *table, + const char *key); +void* _dbus_hash_table_lookup_two_strings (DBusHashTable *table, + const char *key); +void* _dbus_hash_table_lookup_int (DBusHashTable *table, + int key); +void* _dbus_hash_table_lookup_pointer (DBusHashTable *table, + void *key); +void* _dbus_hash_table_lookup_uintptr (DBusHashTable *table, + uintptr_t key); +dbus_bool_t _dbus_hash_table_remove_string (DBusHashTable *table, + const char *key); +dbus_bool_t _dbus_hash_table_remove_two_strings (DBusHashTable *table, + const char *key); +dbus_bool_t _dbus_hash_table_remove_int (DBusHashTable *table, + int key); +dbus_bool_t _dbus_hash_table_remove_pointer (DBusHashTable *table, + void *key); +dbus_bool_t _dbus_hash_table_remove_uintptr (DBusHashTable *table, + uintptr_t key); +dbus_bool_t _dbus_hash_table_insert_string (DBusHashTable *table, + char *key, + void *value); +dbus_bool_t _dbus_hash_table_insert_two_strings (DBusHashTable *table, + char *key, + void *value); +dbus_bool_t _dbus_hash_table_insert_int (DBusHashTable *table, + int key, + void *value); +dbus_bool_t _dbus_hash_table_insert_pointer (DBusHashTable *table, + void *key, + void *value); +dbus_bool_t _dbus_hash_table_insert_uintptr (DBusHashTable *table, + uintptr_t key, + void *value); +int _dbus_hash_table_get_n_entries (DBusHashTable *table); + +/* Preallocation */ + +/** A preallocated hash entry */ +typedef struct DBusPreallocatedHash DBusPreallocatedHash; + +DBusPreallocatedHash *_dbus_hash_table_preallocate_entry (DBusHashTable *table); +void _dbus_hash_table_free_preallocated_entry (DBusHashTable *table, + DBusPreallocatedHash *preallocated); +void _dbus_hash_table_insert_string_preallocated (DBusHashTable *table, + DBusPreallocatedHash *preallocated, + char *key, + void *value); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_HASH_H */ diff --git a/include/dbus-1/dbus/dbus-internals.h b/include/dbus-1/dbus/dbus-internals.h new file mode 100644 index 00000000..dcef7d7f --- /dev/null +++ b/include/dbus-1/dbus/dbus-internals.h @@ -0,0 +1,367 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-internals.h random utility stuff (internal to D-Bus implementation) + * + * Copyright (C) 2002, 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifdef DBUS_INSIDE_DBUS_H +#error "You can't include dbus-internals.h in the public header dbus.h" +#endif + +#ifndef DBUS_INTERNALS_H +#define DBUS_INTERNALS_H + +#include <dbus/dbus-memory.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-errors.h> +#include <dbus/dbus-sysdeps.h> +#include <dbus/dbus-threads-internal.h> + +DBUS_BEGIN_DECLS + +#ifndef DBUS_SESSION_BUS_DEFAULT_ADDRESS +#define DBUS_SESSION_BUS_DEFAULT_ADDRESS "autolaunch:" +#endif + +void _dbus_warn (const char *format, + ...) _DBUS_GNUC_PRINTF (1, 2); + +void _dbus_warn_check_failed (const char *format, + ...) _DBUS_GNUC_PRINTF (1, 2); + + +#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#define _DBUS_FUNCTION_NAME __func__ +#elif defined(__GNUC__) || defined(_MSC_VER) +#define _DBUS_FUNCTION_NAME __FUNCTION__ +#else +#define _DBUS_FUNCTION_NAME "unknown function" +#endif + +/* + * (code from GLib) + * + * The _DBUS_LIKELY and _DBUS_UNLIKELY macros let the programmer give hints to + * the compiler about the expected result of an expression. Some compilers + * can use this information for optimizations. + * + * The _DBUS_BOOLEAN_EXPR macro is intended to trigger a gcc warning when + * putting assignments in the macro arg + */ +#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) +#define _DBUS_BOOLEAN_EXPR(expr) \ + __extension__ ({ \ + int _dbus_boolean_var_; \ + if (expr) \ + _dbus_boolean_var_ = 1; \ + else \ + _dbus_boolean_var_ = 0; \ + _dbus_boolean_var_; \ +}) +#define _DBUS_LIKELY(expr) (__builtin_expect (_DBUS_BOOLEAN_EXPR(expr), 1)) +#define _DBUS_UNLIKELY(expr) (__builtin_expect (_DBUS_BOOLEAN_EXPR(expr), 0)) +#else +#define _DBUS_LIKELY(expr) (expr) +#define _DBUS_UNLIKELY(expr) (expr) +#endif + +#ifdef DBUS_ENABLE_VERBOSE_MODE + +/* + at least gnu cc and msvc compiler are known to + have support for variable macro argument lists + add other compilers is required +*/ +#if defined(__GNUC__) || defined(_MSC_VER) +#define DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS +#endif + +#ifdef DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS +void _dbus_verbose_real (const char *file, const int line, const char *function, + const char *format,...) _DBUS_GNUC_PRINTF (4, 5); +# define _dbus_verbose(fmt,...) _dbus_verbose_real( __FILE__,__LINE__,__FUNCTION__,fmt, ## __VA_ARGS__) +#else +void _dbus_verbose_real (const char *format, + ...) _DBUS_GNUC_PRINTF (1, 2); +# define _dbus_verbose _dbus_verbose_real +#endif +void _dbus_verbose_reset_real (void); +dbus_bool_t _dbus_is_verbose_real (void); + +# define _dbus_verbose_reset _dbus_verbose_reset_real +# define _dbus_is_verbose _dbus_is_verbose_real +#else +# ifdef HAVE_ISO_VARARGS +# define _dbus_verbose(...) +# elif defined (HAVE_GNUC_VARARGS) +# define _dbus_verbose(format...) +# else +static void _dbus_verbose(const char * x,...) {;} +# endif +# define _dbus_verbose_reset() +# define _dbus_is_verbose() FALSE +#endif /* !DBUS_ENABLE_VERBOSE_MODE */ + +const char* _dbus_strerror (int error_number); + +#ifdef DBUS_DISABLE_ASSERT +#define _dbus_assert(condition) +#else +void _dbus_real_assert (dbus_bool_t condition, + const char *condition_text, + const char *file, + int line, + const char *func); +#define _dbus_assert(condition) \ + _dbus_real_assert ((condition) != 0, #condition, __FILE__, __LINE__, _DBUS_FUNCTION_NAME) +#endif /* !DBUS_DISABLE_ASSERT */ + +#ifdef DBUS_DISABLE_ASSERT +#define _dbus_assert_not_reached(explanation) +#else +void _dbus_real_assert_not_reached (const char *explanation, + const char *file, + int line) _DBUS_GNUC_NORETURN; +#define _dbus_assert_not_reached(explanation) \ + _dbus_real_assert_not_reached (explanation, __FILE__, __LINE__) +#endif /* !DBUS_DISABLE_ASSERT */ + +#ifdef DBUS_DISABLE_CHECKS +#define _dbus_return_if_fail(condition) +#define _dbus_return_val_if_fail(condition, val) +#else + +extern const char *_dbus_return_if_fail_warning_format; + +#define _dbus_return_if_fail(condition) do { \ + _dbus_assert ((*(const char*)_DBUS_FUNCTION_NAME) != '_'); \ + if (!(condition)) { \ + _dbus_warn_check_failed (_dbus_return_if_fail_warning_format, \ + _DBUS_FUNCTION_NAME, #condition, __FILE__, __LINE__); \ + return; \ + } } while (0) + +#define _dbus_return_val_if_fail(condition, val) do { \ + _dbus_assert ((*(const char*)_DBUS_FUNCTION_NAME) != '_'); \ + if (!(condition)) { \ + _dbus_warn_check_failed (_dbus_return_if_fail_warning_format, \ + _DBUS_FUNCTION_NAME, #condition, __FILE__, __LINE__); \ + return (val); \ + } } while (0) + +#endif /* !DBUS_DISABLE_ASSERT */ + +#define _DBUS_N_ELEMENTS(array) ((int) (sizeof ((array)) / sizeof ((array)[0]))) + +#define _DBUS_POINTER_TO_INT(pointer) ((intptr_t)(pointer)) +#define _DBUS_INT_TO_POINTER(integer) ((void*)((intptr_t)(integer))) + +#define _DBUS_ZERO(object) (memset (&(object), '\0', sizeof ((object)))) + +#define _DBUS_STRUCT_OFFSET(struct_type, member) \ + ((intptr_t) ((unsigned char*) &((struct_type*) 0)->member)) + +#ifdef DBUS_DISABLE_CHECKS +/* this is an assert and not an error, but in the typical --disable-checks case (you're trying + * to really minimize code size), disabling these assertions makes sense. + */ +#define _DBUS_ASSERT_ERROR_IS_SET(error) +#define _DBUS_ASSERT_ERROR_IS_CLEAR(error) +#else +#define _DBUS_ASSERT_ERROR_IS_SET(error) _dbus_assert ((error) == NULL || dbus_error_is_set ((error))) +#define _DBUS_ASSERT_ERROR_IS_CLEAR(error) _dbus_assert ((error) == NULL || !dbus_error_is_set ((error))) +#endif + +#define _dbus_return_if_error_is_set(error) _dbus_return_if_fail ((error) == NULL || !dbus_error_is_set ((error))) +#define _dbus_return_val_if_error_is_set(error, val) _dbus_return_val_if_fail ((error) == NULL || !dbus_error_is_set ((error)), (val)) + +/* This alignment thing is from ORBit2 */ +/* Align a value upward to a boundary, expressed as a number of bytes. + * E.g. align to an 8-byte boundary with argument of 8. + */ + +/* + * (this + boundary - 1) + * & + * ~(boundary - 1) + */ + +#define _DBUS_ALIGN_VALUE(this, boundary) \ + (( ((uintptr_t)(this)) + (((uintptr_t)(boundary)) -1)) & (~(((uintptr_t)(boundary))-1))) + +#define _DBUS_ALIGN_ADDRESS(this, boundary) \ + ((void*)_DBUS_ALIGN_VALUE(this, boundary)) + + +char* _dbus_strdup (const char *str); +void* _dbus_memdup (const void *mem, + size_t n_bytes); +dbus_bool_t _dbus_string_array_contains (const char **array, + const char *str); +char** _dbus_dup_string_array (const char **array); + +#define _DBUS_INT16_MIN ((dbus_int16_t) 0x8000) +#define _DBUS_INT16_MAX ((dbus_int16_t) 0x7fff) +#define _DBUS_UINT16_MAX ((dbus_uint16_t)0xffff) +#define _DBUS_INT32_MIN ((dbus_int32_t) 0x80000000) +#define _DBUS_INT32_MAX ((dbus_int32_t) 0x7fffffff) +#define _DBUS_UINT32_MAX ((dbus_uint32_t)0xffffffff) +/* using 32-bit here is sort of bogus */ +#define _DBUS_INT_MIN _DBUS_INT32_MIN +#define _DBUS_INT_MAX _DBUS_INT32_MAX +#define _DBUS_UINT_MAX _DBUS_UINT32_MAX +#ifdef DBUS_HAVE_INT64 +#define _DBUS_INT64_MAX DBUS_INT64_CONSTANT (0x7fffffffffffffff) +#define _DBUS_UINT64_MAX DBUS_UINT64_CONSTANT (0xffffffffffffffff) +#endif +#define _DBUS_ONE_KILOBYTE 1024 +#define _DBUS_ONE_MEGABYTE 1024 * _DBUS_ONE_KILOBYTE +#define _DBUS_ONE_HOUR_IN_MILLISECONDS (1000 * 60 * 60) +#define _DBUS_USEC_PER_SECOND (1000000) + +#undef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +#undef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#undef ABS +#define ABS(a) (((a) < 0) ? -(a) : (a)) + +#define _DBUS_ISASCII(c) ((c) != '\0' && (((c) & ~0x7f) == 0)) + +typedef void (* DBusForeachFunction) (void *element, + void *data); + +dbus_bool_t _dbus_set_fd_nonblocking (int fd, + DBusError *error); + +void _dbus_verbose_bytes (const unsigned char *data, + int len, + int offset); +void _dbus_verbose_bytes_of_string (const DBusString *str, + int start, + int len); + +const char* _dbus_header_field_to_string (int header_field); + +extern const char *_dbus_no_memory_message; +#define _DBUS_SET_OOM(error) dbus_set_error_const ((error), DBUS_ERROR_NO_MEMORY, _dbus_no_memory_message) + +#ifdef DBUS_BUILD_TESTS +/* Memory debugging */ +void _dbus_set_fail_alloc_counter (int until_next_fail); +int _dbus_get_fail_alloc_counter (void); +void _dbus_set_fail_alloc_failures (int failures_per_failure); +int _dbus_get_fail_alloc_failures (void); +dbus_bool_t _dbus_decrement_fail_alloc_counter (void); +dbus_bool_t _dbus_disable_mem_pools (void); +int _dbus_get_malloc_blocks_outstanding (void); + +typedef dbus_bool_t (* DBusTestMemoryFunction) (void *data); +dbus_bool_t _dbus_test_oom_handling (const char *description, + DBusTestMemoryFunction func, + void *data); +#else +#define _dbus_set_fail_alloc_counter(n) +#define _dbus_get_fail_alloc_counter _DBUS_INT_MAX + +/* These are constant expressions so that blocks + * they protect should be optimized away + */ +#define _dbus_decrement_fail_alloc_counter() (FALSE) +#define _dbus_disable_mem_pools() (FALSE) +#define _dbus_get_malloc_blocks_outstanding (0) +#endif /* !DBUS_BUILD_TESTS */ + +typedef void (* DBusShutdownFunction) (void *data); +dbus_bool_t _dbus_register_shutdown_func (DBusShutdownFunction function, + void *data); + +extern int _dbus_current_generation; + +/* Thread initializers */ +#define _DBUS_LOCK_NAME(name) _dbus_lock_##name +#define _DBUS_DECLARE_GLOBAL_LOCK(name) extern DBusMutex *_dbus_lock_##name +#define _DBUS_DEFINE_GLOBAL_LOCK(name) DBusMutex *_dbus_lock_##name +#define _DBUS_LOCK(name) _dbus_mutex_lock (_dbus_lock_##name) +#define _DBUS_UNLOCK(name) _dbus_mutex_unlock (_dbus_lock_##name) + +/* 1-5 */ +_DBUS_DECLARE_GLOBAL_LOCK (list); +_DBUS_DECLARE_GLOBAL_LOCK (connection_slots); +_DBUS_DECLARE_GLOBAL_LOCK (pending_call_slots); +_DBUS_DECLARE_GLOBAL_LOCK (server_slots); +_DBUS_DECLARE_GLOBAL_LOCK (message_slots); +/* 5-10 */ +_DBUS_DECLARE_GLOBAL_LOCK (bus); +_DBUS_DECLARE_GLOBAL_LOCK (bus_datas); +_DBUS_DECLARE_GLOBAL_LOCK (shutdown_funcs); +_DBUS_DECLARE_GLOBAL_LOCK (system_users); +_DBUS_DECLARE_GLOBAL_LOCK (message_cache); +/* 10-14 */ +_DBUS_DECLARE_GLOBAL_LOCK (shared_connections); +_DBUS_DECLARE_GLOBAL_LOCK (win_fds); +_DBUS_DECLARE_GLOBAL_LOCK (sid_atom_cache); +_DBUS_DECLARE_GLOBAL_LOCK (machine_uuid); + +#if !DBUS_USE_SYNC +_DBUS_DECLARE_GLOBAL_LOCK (atomic); +#define _DBUS_N_GLOBAL_LOCKS (15) +#else +#define _DBUS_N_GLOBAL_LOCKS (14) +#endif + +dbus_bool_t _dbus_threads_init_debug (void); + +dbus_bool_t _dbus_address_append_escaped (DBusString *escaped, + const DBusString *unescaped); + +void _dbus_set_bad_address (DBusError *error, + const char *address_problem_type, + const char *address_problem_field, + const char *address_problem_other); + +#define DBUS_UUID_LENGTH_BYTES 16 +#define DBUS_UUID_LENGTH_WORDS (DBUS_UUID_LENGTH_BYTES / 4) +#define DBUS_UUID_LENGTH_HEX (DBUS_UUID_LENGTH_BYTES * 2) + +/** + * A globally unique ID ; we have one for each DBusServer, and also one for each + * machine with libdbus installed on it. + */ +union DBusGUID +{ + dbus_uint32_t as_uint32s[DBUS_UUID_LENGTH_WORDS]; /**< guid as four uint32 values */ + char as_bytes[DBUS_UUID_LENGTH_BYTES]; /**< guid as 16 single-byte values */ +}; + +void _dbus_generate_uuid (DBusGUID *uuid); +dbus_bool_t _dbus_uuid_encode (const DBusGUID *uuid, + DBusString *encoded); +dbus_bool_t _dbus_read_uuid_file (const DBusString *filename, + DBusGUID *uuid, + dbus_bool_t create_if_not_found, + DBusError *error); + +dbus_bool_t _dbus_get_local_machine_uuid_encoded (DBusString *uuid_str); + +DBUS_END_DECLS + +#endif /* DBUS_INTERNALS_H */ diff --git a/include/dbus-1/dbus/dbus-keyring.h b/include/dbus-1/dbus/dbus-keyring.h new file mode 100644 index 00000000..200e31bc --- /dev/null +++ b/include/dbus-1/dbus/dbus-keyring.h @@ -0,0 +1,52 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-keyring.h Store secret cookies in your homedir + * + * Copyright (C) 2003 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_KEYRING_H +#define DBUS_KEYRING_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-errors.h> +#include <dbus/dbus-string.h> +#include <dbus/dbus-credentials.h> + +DBUS_BEGIN_DECLS + +typedef struct DBusKeyring DBusKeyring; + +DBusKeyring* _dbus_keyring_new_for_credentials (DBusCredentials *credentials, + const DBusString *context, + DBusError *error); +DBusKeyring* _dbus_keyring_ref (DBusKeyring *keyring); +void _dbus_keyring_unref (DBusKeyring *keyring); +dbus_bool_t _dbus_keyring_validate_context (const DBusString *context); +int _dbus_keyring_get_best_key (DBusKeyring *keyring, + DBusError *error); +dbus_bool_t _dbus_keyring_is_for_credentials (DBusKeyring *keyring, + DBusCredentials *credentials); +dbus_bool_t _dbus_keyring_get_hex_key (DBusKeyring *keyring, + int key_id, + DBusString *hex_key); + + +DBUS_END_DECLS + +#endif /* DBUS_KEYRING_H */ diff --git a/include/dbus-1/dbus/dbus-list.h b/include/dbus-1/dbus/dbus-list.h new file mode 100644 index 00000000..663ad257 --- /dev/null +++ b/include/dbus-1/dbus/dbus-list.h @@ -0,0 +1,98 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-list.h Generic linked list utility (internal to D-Bus implementation) + * + * Copyright (C) 2002, 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_LIST_H +#define DBUS_LIST_H + +#include <dbus/dbus-internals.h> +#include <dbus/dbus-memory.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-sysdeps.h> + +DBUS_BEGIN_DECLS + +struct DBusList +{ + DBusList *prev; /**< Previous list node. */ + DBusList *next; /**< Next list node. */ + void *data; /**< Data stored at this element. */ +}; +dbus_bool_t _dbus_list_append (DBusList **list, + void *data); +dbus_bool_t _dbus_list_prepend (DBusList **list, + void *data); +dbus_bool_t _dbus_list_insert_before (DBusList **list, + DBusList *before_this_link, + void *data); +dbus_bool_t _dbus_list_insert_after (DBusList **list, + DBusList *after_this_link, + void *data); +void _dbus_list_insert_before_link (DBusList **list, + DBusList *before_this_link, + DBusList *link); +void _dbus_list_insert_after_link (DBusList **list, + DBusList *after_this_link, + DBusList *link); +dbus_bool_t _dbus_list_remove (DBusList **list, + void *data); +dbus_bool_t _dbus_list_remove_last (DBusList **list, + void *data); +void _dbus_list_remove_link (DBusList **list, + DBusList *link); +DBusList* _dbus_list_find_last (DBusList **list, + void *data); +void _dbus_list_clear (DBusList **list); +DBusList* _dbus_list_get_first_link (DBusList **list); +DBusList* _dbus_list_get_last_link (DBusList **list); +void* _dbus_list_get_last (DBusList **list); +void* _dbus_list_get_first (DBusList **list); +void* _dbus_list_pop_first (DBusList **list); +void* _dbus_list_pop_last (DBusList **list); +DBusList* _dbus_list_pop_first_link (DBusList **list); +DBusList* _dbus_list_pop_last_link (DBusList **list); +dbus_bool_t _dbus_list_copy (DBusList **list, + DBusList **dest); +int _dbus_list_get_length (DBusList **list); +DBusList* _dbus_list_alloc_link (void *data); +void _dbus_list_free_link (DBusList *link); +void _dbus_list_unlink (DBusList **list, + DBusList *link); +void _dbus_list_append_link (DBusList **list, + DBusList *link); +void _dbus_list_prepend_link (DBusList **list, + DBusList *link); +dbus_bool_t _dbus_list_length_is_one (DBusList **list); + + + + +void _dbus_list_foreach (DBusList **list, + DBusForeachFunction function, + void *data); + +#define _dbus_list_get_next_link(list, link) ((link)->next == *(list) ? NULL : (link)->next) +#define _dbus_list_get_prev_link(list, link) ((link) == *(list) ? NULL : (link)->prev) + +DBUS_END_DECLS + +#endif /* DBUS_LIST_H */ diff --git a/include/dbus-1/dbus/dbus-macros.h b/include/dbus-1/dbus/dbus-macros.h new file mode 100644 index 00000000..d1e40ecb --- /dev/null +++ b/include/dbus-1/dbus/dbus-macros.h @@ -0,0 +1,174 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-macros.h generic macros + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_MACROS_H +#define DBUS_MACROS_H + +#ifdef __cplusplus +# define DBUS_BEGIN_DECLS extern "C" { +# define DBUS_END_DECLS } +#else +# define DBUS_BEGIN_DECLS +# define DBUS_END_DECLS +#endif + +#ifndef TRUE +# define TRUE 1 +#endif +#ifndef FALSE +# define FALSE 0 +#endif + +#ifndef NULL +# ifdef __cplusplus +# define NULL (0L) +# else /* !__cplusplus */ +# define NULL ((void*) 0) +# endif /* !__cplusplus */ +#endif + +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +# define DBUS_DEPRECATED __attribute__ ((__deprecated__)) +#elif defined(_MSC_VER) && (_MSC_VER >= 1300) +# define DBUS_DEPRECATED __declspec(deprecated) +#else +# define DBUS_DEPRECATED +#endif + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8) +# define _DBUS_GNUC_EXTENSION __extension__ +#else +# define _DBUS_GNUC_EXTENSION +#endif + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +#define _DBUS_GNUC_PRINTF( format_idx, arg_idx ) \ + __attribute__((__format__ (__printf__, format_idx, arg_idx))) +#define _DBUS_GNUC_NORETURN \ + __attribute__((__noreturn__)) +#else /* !__GNUC__ */ +#define _DBUS_GNUC_PRINTF( format_idx, arg_idx ) +#define _DBUS_GNUC_NORETURN +#endif /* !__GNUC__ */ + +/** @def _DBUS_GNUC_PRINTF + * used to tell gcc about printf format strings + */ +/** @def _DBUS_GNUC_NORETURN + * used to tell gcc about functions that never return, such as _dbus_abort() + */ + + +/* Normally docs are in .c files, but there isn't a .c file for this. */ +/** + * @defgroup DBusMacros Utility macros + * @ingroup DBus + * @brief #TRUE, #FALSE, #NULL, and so on + * + * Utility macros. + * + * @{ + */ + +/** + * @def DBUS_BEGIN_DECLS + * + * Macro used prior to declaring functions in the D-Bus header + * files. Expands to "extern "C"" when using a C++ compiler, + * and expands to nothing when using a C compiler. + * + * Please don't use this in your own code, consider it + * D-Bus internal. + */ +/** + * @def DBUS_END_DECLS + * + * Macro used after declaring functions in the D-Bus header + * files. Expands to "}" when using a C++ compiler, + * and expands to nothing when using a C compiler. + * + * Please don't use this in your own code, consider it + * D-Bus internal. + */ +/** + * @def TRUE + * + * Expands to "1" + */ +/** + * @def FALSE + * + * Expands to "0" + */ +/** + * @def NULL + * + * A null pointer, defined appropriately for C or C++. + */ +/** + * @def DBUS_DEPRECATED + * + * Tells the compiler to warn about a function or type if it's used. + * Code marked in this way should also be enclosed in + * @code + * #ifndef DBUS_DISABLE_DEPRECATED + * deprecated stuff here + * #endif + * @endcode + * + * Please don't use this in your own code, consider it + * D-Bus internal. + */ +/** + * @def _DBUS_GNUC_EXTENSION + * + * Tells gcc not to warn about extensions to the C standard in the + * following expression, even if compiling with -pedantic. Do not use + * this macro in your own code; please consider it to be internal to libdbus. + */ + +/* + * @def DBUS_EXPORT + * + * Declare the following symbol as public. This is currently a noop on + * platforms other than Windows. + */ + +#if defined(_WIN32) +# if defined(DBUS_STATIC_BUILD) +# define DBUS_EXPORT +# elif defined(dbus_1_EXPORTS) +# define DBUS_EXPORT __declspec(dllexport) +# else +# define DBUS_EXPORT __declspec(dllimport) +# endif +#else +#define DBUS_EXPORT +#endif + +/** @} */ + +#endif /* DBUS_MACROS_H */ diff --git a/include/dbus-1/dbus/dbus-mainloop.h b/include/dbus-1/dbus/dbus-mainloop.h new file mode 100644 index 00000000..656f8231 --- /dev/null +++ b/include/dbus-1/dbus/dbus-mainloop.h @@ -0,0 +1,76 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-mainloop.h Main loop utility + * + * Copyright (C) 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_MAINLOOP_H +#define DBUS_MAINLOOP_H + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#include <dbus/dbus.h> + +typedef struct DBusLoop DBusLoop; + +typedef dbus_bool_t (* DBusWatchFunction) (DBusWatch *watch, + unsigned int condition, + void *data); +typedef void (* DBusTimeoutFunction) (DBusTimeout *timeout, + void *data); + +DBusLoop* _dbus_loop_new (void); +DBusLoop* _dbus_loop_ref (DBusLoop *loop); +void _dbus_loop_unref (DBusLoop *loop); +dbus_bool_t _dbus_loop_add_watch (DBusLoop *loop, + DBusWatch *watch, + DBusWatchFunction function, + void *data, + DBusFreeFunction free_data_func); +void _dbus_loop_remove_watch (DBusLoop *loop, + DBusWatch *watch, + DBusWatchFunction function, + void *data); +dbus_bool_t _dbus_loop_add_timeout (DBusLoop *loop, + DBusTimeout *timeout, + DBusTimeoutFunction function, + void *data, + DBusFreeFunction free_data_func); +void _dbus_loop_remove_timeout (DBusLoop *loop, + DBusTimeout *timeout, + DBusTimeoutFunction function, + void *data); + +dbus_bool_t _dbus_loop_queue_dispatch (DBusLoop *loop, + DBusConnection *connection); + +void _dbus_loop_run (DBusLoop *loop); +void _dbus_loop_quit (DBusLoop *loop); +dbus_bool_t _dbus_loop_iterate (DBusLoop *loop, + dbus_bool_t block); +dbus_bool_t _dbus_loop_dispatch (DBusLoop *loop); + +int _dbus_get_oom_wait (void); +void _dbus_wait_for_memory (void); + +#endif /* !DOXYGEN_SHOULD_SKIP_THIS */ + +#endif /* DBUS_MAINLOOP_H */ + diff --git a/include/dbus-1/dbus/dbus-marshal-basic.h b/include/dbus-1/dbus/dbus-marshal-basic.h new file mode 100644 index 00000000..0c27fc9e --- /dev/null +++ b/include/dbus-1/dbus/dbus-marshal-basic.h @@ -0,0 +1,273 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-marshal-basic.h Marshalling routines for basic (primitive) types + * + * Copyright (C) 2002 CodeFactory AB + * Copyright (C) 2004, 2005 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_MARSHAL_BASIC_H +#define DBUS_MARSHAL_BASIC_H + +#ifdef HAVE_BYTESWAP_H +#include <byteswap.h> +#endif + +#include <dbus/dbus-protocol.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-arch-deps.h> +#include <dbus/dbus-string.h> + +#ifdef WORDS_BIGENDIAN +#define DBUS_COMPILER_BYTE_ORDER DBUS_BIG_ENDIAN +#else +#define DBUS_COMPILER_BYTE_ORDER DBUS_LITTLE_ENDIAN +#endif + +#ifdef HAVE_BYTESWAP_H +#define DBUS_UINT16_SWAP_LE_BE_CONSTANT(val) bswap_16(val) +#define DBUS_UINT32_SWAP_LE_BE_CONSTANT(val) bswap_32(val) +#else /* HAVE_BYTESWAP_H */ + +#define DBUS_UINT16_SWAP_LE_BE_CONSTANT(val) ((dbus_uint16_t) ( \ + (dbus_uint16_t) ((dbus_uint16_t) (val) >> 8) | \ + (dbus_uint16_t) ((dbus_uint16_t) (val) << 8))) + +#define DBUS_UINT32_SWAP_LE_BE_CONSTANT(val) ((dbus_uint32_t) ( \ + (((dbus_uint32_t) (val) & (dbus_uint32_t) 0x000000ffU) << 24) | \ + (((dbus_uint32_t) (val) & (dbus_uint32_t) 0x0000ff00U) << 8) | \ + (((dbus_uint32_t) (val) & (dbus_uint32_t) 0x00ff0000U) >> 8) | \ + (((dbus_uint32_t) (val) & (dbus_uint32_t) 0xff000000U) >> 24))) + +#endif /* HAVE_BYTESWAP_H */ + +#ifdef DBUS_HAVE_INT64 + +#ifdef HAVE_BYTESWAP_H +#define DBUS_UINT64_SWAP_LE_BE_CONSTANT(val) bswap_64(val) +#else /* HAVE_BYTESWAP_H */ + +#define DBUS_UINT64_SWAP_LE_BE_CONSTANT(val) ((dbus_uint64_t) ( \ + (((dbus_uint64_t) (val) & \ + (dbus_uint64_t) DBUS_UINT64_CONSTANT (0x00000000000000ff)) << 56) | \ + (((dbus_uint64_t) (val) & \ + (dbus_uint64_t) DBUS_UINT64_CONSTANT (0x000000000000ff00)) << 40) | \ + (((dbus_uint64_t) (val) & \ + (dbus_uint64_t) DBUS_UINT64_CONSTANT (0x0000000000ff0000)) << 24) | \ + (((dbus_uint64_t) (val) & \ + (dbus_uint64_t) DBUS_UINT64_CONSTANT (0x00000000ff000000)) << 8) | \ + (((dbus_uint64_t) (val) & \ + (dbus_uint64_t) DBUS_UINT64_CONSTANT (0x000000ff00000000)) >> 8) | \ + (((dbus_uint64_t) (val) & \ + (dbus_uint64_t) DBUS_UINT64_CONSTANT (0x0000ff0000000000)) >> 24) | \ + (((dbus_uint64_t) (val) & \ + (dbus_uint64_t) DBUS_UINT64_CONSTANT (0x00ff000000000000)) >> 40) | \ + (((dbus_uint64_t) (val) & \ + (dbus_uint64_t) DBUS_UINT64_CONSTANT (0xff00000000000000)) >> 56))) +#endif /* DBUS_HAVE_INT64 */ + +#endif /* HAVE_BYTESWAP_H */ + +#define DBUS_UINT16_SWAP_LE_BE(val) (DBUS_UINT16_SWAP_LE_BE_CONSTANT (val)) +#define DBUS_INT16_SWAP_LE_BE(val) ((dbus_int16_t)DBUS_UINT16_SWAP_LE_BE_CONSTANT (val)) + +#define DBUS_UINT32_SWAP_LE_BE(val) (DBUS_UINT32_SWAP_LE_BE_CONSTANT (val)) +#define DBUS_INT32_SWAP_LE_BE(val) ((dbus_int32_t)DBUS_UINT32_SWAP_LE_BE_CONSTANT (val)) + +#ifdef DBUS_HAVE_INT64 +# define DBUS_UINT64_SWAP_LE_BE(val) (DBUS_UINT64_SWAP_LE_BE_CONSTANT (val)) +# define DBUS_INT64_SWAP_LE_BE(val) ((dbus_int64_t)DBUS_UINT64_SWAP_LE_BE_CONSTANT (val)) +#endif /* DBUS_HAVE_INT64 */ + +#ifdef WORDS_BIGENDIAN + +# define DBUS_INT16_TO_BE(val) ((dbus_int16_t) (val)) +# define DBUS_UINT16_TO_BE(val) ((dbus_uint16_t) (val)) +# define DBUS_INT16_TO_LE(val) (DBUS_INT16_SWAP_LE_BE (val)) +# define DBUS_UINT16_TO_LE(val) (DBUS_UINT16_SWAP_LE_BE (val)) +# define DBUS_INT32_TO_BE(val) ((dbus_int32_t) (val)) +# define DBUS_UINT32_TO_BE(val) ((dbus_uint32_t) (val)) +# define DBUS_INT32_TO_LE(val) (DBUS_INT32_SWAP_LE_BE (val)) +# define DBUS_UINT32_TO_LE(val) (DBUS_UINT32_SWAP_LE_BE (val)) +# ifdef DBUS_HAVE_INT64 +# define DBUS_INT64_TO_BE(val) ((dbus_int64_t) (val)) +# define DBUS_UINT64_TO_BE(val) ((dbus_uint64_t) (val)) +# define DBUS_INT64_TO_LE(val) (DBUS_INT64_SWAP_LE_BE (val)) +# define DBUS_UINT64_TO_LE(val) (DBUS_UINT64_SWAP_LE_BE (val)) +# endif /* DBUS_HAVE_INT64 */ + +#else /* WORDS_BIGENDIAN */ + +# define DBUS_INT16_TO_LE(val) ((dbus_int16_t) (val)) +# define DBUS_UINT16_TO_LE(val) ((dbus_uint16_t) (val)) +# define DBUS_INT16_TO_BE(val) ((dbus_int16_t) DBUS_UINT16_SWAP_LE_BE (val)) +# define DBUS_UINT16_TO_BE(val) (DBUS_UINT16_SWAP_LE_BE (val)) +# define DBUS_INT32_TO_LE(val) ((dbus_int32_t) (val)) +# define DBUS_UINT32_TO_LE(val) ((dbus_uint32_t) (val)) +# define DBUS_INT32_TO_BE(val) ((dbus_int32_t) DBUS_UINT32_SWAP_LE_BE (val)) +# define DBUS_UINT32_TO_BE(val) (DBUS_UINT32_SWAP_LE_BE (val)) +# ifdef DBUS_HAVE_INT64 +# define DBUS_INT64_TO_LE(val) ((dbus_int64_t) (val)) +# define DBUS_UINT64_TO_LE(val) ((dbus_uint64_t) (val)) +# define DBUS_INT64_TO_BE(val) ((dbus_int64_t) DBUS_UINT64_SWAP_LE_BE (val)) +# define DBUS_UINT64_TO_BE(val) (DBUS_UINT64_SWAP_LE_BE (val)) +# endif /* DBUS_HAVE_INT64 */ +#endif + +/* The transformation is symmetric, so the FROM just maps to the TO. */ +#define DBUS_INT16_FROM_LE(val) (DBUS_INT16_TO_LE (val)) +#define DBUS_UINT16_FROM_LE(val) (DBUS_UINT16_TO_LE (val)) +#define DBUS_INT16_FROM_BE(val) (DBUS_INT16_TO_BE (val)) +#define DBUS_UINT16_FROM_BE(val) (DBUS_UINT16_TO_BE (val)) +#define DBUS_INT32_FROM_LE(val) (DBUS_INT32_TO_LE (val)) +#define DBUS_UINT32_FROM_LE(val) (DBUS_UINT32_TO_LE (val)) +#define DBUS_INT32_FROM_BE(val) (DBUS_INT32_TO_BE (val)) +#define DBUS_UINT32_FROM_BE(val) (DBUS_UINT32_TO_BE (val)) +#ifdef DBUS_HAVE_INT64 +# define DBUS_INT64_FROM_LE(val) (DBUS_INT64_TO_LE (val)) +# define DBUS_UINT64_FROM_LE(val) (DBUS_UINT64_TO_LE (val)) +# define DBUS_INT64_FROM_BE(val) (DBUS_INT64_TO_BE (val)) +# define DBUS_UINT64_FROM_BE(val) (DBUS_UINT64_TO_BE (val)) +#endif /* DBUS_HAVE_INT64 */ + +#ifndef DBUS_HAVE_INT64 +/** + * An 8-byte struct you could use to access int64 without having + * int64 support + */ +typedef struct +{ + dbus_uint32_t first32; /**< first 32 bits in the 8 bytes (beware endian issues) */ + dbus_uint32_t second32; /**< second 32 bits in the 8 bytes (beware endian issues) */ +} DBus8ByteStruct; +#endif /* DBUS_HAVE_INT64 */ + +/** + * A simple 8-byte value union that lets you access 8 bytes as if they + * were various types; useful when dealing with basic types via + * void pointers and varargs. + */ +typedef union +{ + dbus_int16_t i16; /**< as int16 */ + dbus_uint16_t u16; /**< as int16 */ + dbus_int32_t i32; /**< as int32 */ + dbus_uint32_t u32; /**< as int32 */ +#ifdef DBUS_HAVE_INT64 + dbus_int64_t i64; /**< as int64 */ + dbus_uint64_t u64; /**< as int64 */ +#else + DBus8ByteStruct u64; /**< as 8-byte-struct */ +#endif + double dbl; /**< as double */ + unsigned char byt; /**< as byte */ + char *str; /**< as char* */ +} DBusBasicValue; + +#ifdef DBUS_DISABLE_ASSERT +#define _dbus_unpack_uint16(byte_order, data) \ + (((byte_order) == DBUS_LITTLE_ENDIAN) ? \ + DBUS_UINT16_FROM_LE (*(dbus_uint16_t*)(data)) : \ + DBUS_UINT16_FROM_BE (*(dbus_uint16_t*)(data))) + +#define _dbus_unpack_uint32(byte_order, data) \ + (((byte_order) == DBUS_LITTLE_ENDIAN) ? \ + DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)(data)) : \ + DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)(data))) +#endif + +#ifndef _dbus_unpack_uint16 +dbus_uint16_t _dbus_unpack_uint16 (int byte_order, + const unsigned char *data); +#endif + +void _dbus_pack_uint32 (dbus_uint32_t value, + int byte_order, + unsigned char *data); +#ifndef _dbus_unpack_uint32 +dbus_uint32_t _dbus_unpack_uint32 (int byte_order, + const unsigned char *data); +#endif + +dbus_bool_t _dbus_marshal_set_basic (DBusString *str, + int pos, + int type, + const void *value, + int byte_order, + int *old_end_pos, + int *new_end_pos); +dbus_bool_t _dbus_marshal_write_basic (DBusString *str, + int insert_at, + int type, + const void *value, + int byte_order, + int *pos_after); +dbus_bool_t _dbus_marshal_write_fixed_multi (DBusString *str, + int insert_at, + int element_type, + const void *value, + int n_elements, + int byte_order, + int *pos_after); +void _dbus_marshal_read_basic (const DBusString *str, + int pos, + int type, + void *value, + int byte_order, + int *new_pos); +void _dbus_marshal_read_fixed_multi (const DBusString *str, + int pos, + int element_type, + void *value, + int n_elements, + int byte_order, + int *new_pos); +void _dbus_marshal_skip_basic (const DBusString *str, + int type, + int byte_order, + int *pos); +void _dbus_marshal_skip_array (const DBusString *str, + int element_type, + int byte_order, + int *pos); +void _dbus_marshal_set_uint32 (DBusString *str, + int pos, + dbus_uint32_t value, + int byte_order); +dbus_uint32_t _dbus_marshal_read_uint32 (const DBusString *str, + int pos, + int byte_order, + int *new_pos); +dbus_bool_t _dbus_type_is_valid (int typecode); +int _dbus_type_get_alignment (int typecode); +dbus_bool_t _dbus_type_is_fixed (int typecode); +int _dbus_type_get_alignment (int typecode); +const char* _dbus_type_to_string (int typecode); + +int _dbus_first_type_in_signature (const DBusString *str, + int pos); + +int _dbus_first_type_in_signature_c_str (const char *str, + int pos); + +void _dbus_swap_array (unsigned char *data, + int n_elements, + int alignment); + +#endif /* DBUS_MARSHAL_BASIC_H */ diff --git a/include/dbus-1/dbus/dbus-marshal-byteswap.h b/include/dbus-1/dbus/dbus-marshal-byteswap.h new file mode 100644 index 00000000..be2dd758 --- /dev/null +++ b/include/dbus-1/dbus/dbus-marshal-byteswap.h @@ -0,0 +1,37 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-marshal-byteswap.h Swap a block of marshaled data + * + * Copyright (C) 2005 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_MARSHAL_BYTESWAP_H +#define DBUS_MARSHAL_BYTESWAP_H + +#include <dbus/dbus-protocol.h> +#include <dbus/dbus-marshal-recursive.h> + +void _dbus_marshal_byteswap (const DBusString *signature, + int signature_start, + int old_byte_order, + int new_byte_order, + DBusString *value_str, + int value_pos); + +#endif /* DBUS_MARSHAL_BYTESWAP_H */ diff --git a/include/dbus-1/dbus/dbus-marshal-header.h b/include/dbus-1/dbus/dbus-marshal-header.h new file mode 100644 index 00000000..fd16c5f0 --- /dev/null +++ b/include/dbus-1/dbus/dbus-marshal-header.h @@ -0,0 +1,128 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-marshal-header.h Managing marshaling/demarshaling of message headers + * + * Copyright (C) 2005 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_MARSHAL_HEADER_H +#define DBUS_MARSHAL_HEADER_H + +#include <dbus/dbus-marshal-basic.h> +#include <dbus/dbus-marshal-validate.h> + +typedef struct DBusHeader DBusHeader; +typedef struct DBusHeaderField DBusHeaderField; + +#define _DBUS_HEADER_FIELD_VALUE_UNKNOWN -1 +#define _DBUS_HEADER_FIELD_VALUE_NONEXISTENT -2 + +/** + * Cached information about a header field in the message + */ +struct DBusHeaderField +{ + int value_pos; /**< Position of field value, or -1/-2 */ +}; + +/** + * Message header data and some cached details of it. + */ +struct DBusHeader +{ + DBusString data; /**< Header network data, stored + * separately from body so we can + * independently realloc it. + */ + + DBusHeaderField fields[DBUS_HEADER_FIELD_LAST + 1]; /**< Track the location + * of each field in header + */ + + dbus_uint32_t padding : 3; /**< bytes of alignment in header */ + dbus_uint32_t byte_order : 8; /**< byte order of header */ +}; + +dbus_bool_t _dbus_header_init (DBusHeader *header, + int byte_order); +void _dbus_header_free (DBusHeader *header); +void _dbus_header_reinit (DBusHeader *header, + int byte_order); +dbus_bool_t _dbus_header_create (DBusHeader *header, + int type, + const char *destination, + const char *path, + const char *interface, + const char *member, + const char *error_name); +dbus_bool_t _dbus_header_copy (const DBusHeader *header, + DBusHeader *dest); +int _dbus_header_get_message_type (DBusHeader *header); +void _dbus_header_set_serial (DBusHeader *header, + dbus_uint32_t serial); +dbus_uint32_t _dbus_header_get_serial (DBusHeader *header); +void _dbus_header_update_lengths (DBusHeader *header, + int body_len); +dbus_bool_t _dbus_header_set_field_basic (DBusHeader *header, + int field, + int type, + const void *value); +dbus_bool_t _dbus_header_get_field_basic (DBusHeader *header, + int field, + int type, + void *value); +dbus_bool_t _dbus_header_get_field_raw (DBusHeader *header, + int field, + const DBusString **str, + int *pos); +dbus_bool_t _dbus_header_delete_field (DBusHeader *header, + int field); +void _dbus_header_toggle_flag (DBusHeader *header, + dbus_uint32_t flag, + dbus_bool_t value); +dbus_bool_t _dbus_header_get_flag (DBusHeader *header, + dbus_uint32_t flag); +dbus_bool_t _dbus_header_ensure_signature (DBusHeader *header, + DBusString **type_str, + int *type_pos); +dbus_bool_t _dbus_header_have_message_untrusted (int max_message_length, + DBusValidity *validity, + int *byte_order, + int *fields_array_len, + int *header_len, + int *body_len, + const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_header_load (DBusHeader *header, + DBusValidationMode mode, + DBusValidity *validity, + int byte_order, + int fields_array_len, + int header_len, + int body_len, + const DBusString *str, + int start, + int len); +void _dbus_header_byteswap (DBusHeader *header, + int new_order); + + + +#endif /* DBUS_MARSHAL_HEADER_H */ diff --git a/include/dbus-1/dbus/dbus-marshal-recursive.h b/include/dbus-1/dbus/dbus-marshal-recursive.h new file mode 100644 index 00000000..97e5466b --- /dev/null +++ b/include/dbus-1/dbus/dbus-marshal-recursive.h @@ -0,0 +1,191 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-marshal-recursive.h Marshalling routines for recursive types + * + * Copyright (C) 2004, 2005 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_MARSHAL_RECURSIVE_H +#define DBUS_MARSHAL_RECURSIVE_H + +#include <dbus/dbus-protocol.h> +#include <dbus/dbus-list.h> + +typedef struct DBusTypeReader DBusTypeReader; +typedef struct DBusTypeWriter DBusTypeWriter; +typedef struct DBusTypeReaderClass DBusTypeReaderClass; +typedef struct DBusArrayLenFixup DBusArrayLenFixup; + +/** + * The type reader is an iterator for reading values from a block of + * values. + */ +struct DBusTypeReader +{ + dbus_uint32_t byte_order : 8; /**< byte order of the block */ + + dbus_uint32_t finished : 1; /**< marks we're at end iterator for cases + * where we don't have another way to tell + */ + dbus_uint32_t array_len_offset : 3; /**< bytes back from start_pos that len ends */ + const DBusString *type_str; /**< string containing signature of block */ + int type_pos; /**< current position in signature */ + const DBusString *value_str; /**< string containing values of block */ + int value_pos; /**< current position in values */ + + const DBusTypeReaderClass *klass; /**< the vtable for the reader */ + union + { + struct { + int start_pos; /**< for array readers, the start of the array values */ + } array; + } u; /**< class-specific data */ +}; + +/** + * The type writer is an iterator for writing to a block of values. + */ +struct DBusTypeWriter +{ + dbus_uint32_t byte_order : 8; /**< byte order to write values with */ + + dbus_uint32_t container_type : 8; /**< what are we inside? (e.g. struct, variant, array) */ + + dbus_uint32_t type_pos_is_expectation : 1; /**< type_pos can be either an insertion point for or an expected next type */ + + dbus_uint32_t enabled : 1; /**< whether to write values */ + + DBusString *type_str; /**< where to write typecodes (or read type expectations) */ + int type_pos; /**< current pos in type_str */ + DBusString *value_str; /**< where to write values */ + int value_pos; /**< next position to write */ + + union + { + struct { + int start_pos; /**< position of first element in the array */ + int len_pos; /**< position of length of the array */ + int element_type_pos; /**< position of array element type in type_str */ + } array; + } u; /**< class-specific data */ +}; + +/** + * When modifying an existing block of values, array lengths may need + * to be adjusted; those adjustments are described by this struct. + */ +struct DBusArrayLenFixup +{ + int len_pos_in_reader; /**< where the length was in the original block */ + int new_len; /**< the new value of the length in the written-out block */ +}; + +void _dbus_type_reader_init (DBusTypeReader *reader, + int byte_order, + const DBusString *type_str, + int type_pos, + const DBusString *value_str, + int value_pos); +void _dbus_type_reader_init_types_only (DBusTypeReader *reader, + const DBusString *type_str, + int type_pos); +int _dbus_type_reader_get_current_type (const DBusTypeReader *reader); +int _dbus_type_reader_get_element_type (const DBusTypeReader *reader); +int _dbus_type_reader_get_value_pos (const DBusTypeReader *reader); +void _dbus_type_reader_read_basic (const DBusTypeReader *reader, + void *value); +int _dbus_type_reader_get_array_length (const DBusTypeReader *reader); +void _dbus_type_reader_read_fixed_multi (const DBusTypeReader *reader, + void *value, + int *n_elements); +void _dbus_type_reader_read_raw (const DBusTypeReader *reader, + const unsigned char **value_location); +void _dbus_type_reader_recurse (DBusTypeReader *reader, + DBusTypeReader *subreader); +dbus_bool_t _dbus_type_reader_next (DBusTypeReader *reader); +dbus_bool_t _dbus_type_reader_has_next (const DBusTypeReader *reader); +void _dbus_type_reader_get_signature (const DBusTypeReader *reader, + const DBusString **str_p, + int *start_p, + int *len_p); +dbus_bool_t _dbus_type_reader_set_basic (DBusTypeReader *reader, + const void *value, + const DBusTypeReader *realign_root); +dbus_bool_t _dbus_type_reader_delete (DBusTypeReader *reader, + const DBusTypeReader *realign_root); +dbus_bool_t _dbus_type_reader_greater_than (const DBusTypeReader *lhs, + const DBusTypeReader *rhs); + +dbus_bool_t _dbus_type_reader_equal_values (const DBusTypeReader *lhs, + const DBusTypeReader *rhs); + +void _dbus_type_signature_next (const char *signature, + int *type_pos); + +void _dbus_type_writer_init (DBusTypeWriter *writer, + int byte_order, + DBusString *type_str, + int type_pos, + DBusString *value_str, + int value_pos); +void _dbus_type_writer_init_types_delayed (DBusTypeWriter *writer, + int byte_order, + DBusString *value_str, + int value_pos); +void _dbus_type_writer_add_types (DBusTypeWriter *writer, + DBusString *type_str, + int type_pos); +void _dbus_type_writer_remove_types (DBusTypeWriter *writer); +void _dbus_type_writer_init_values_only (DBusTypeWriter *writer, + int byte_order, + const DBusString *type_str, + int type_pos, + DBusString *value_str, + int value_pos); +dbus_bool_t _dbus_type_writer_write_basic (DBusTypeWriter *writer, + int type, + const void *value); +dbus_bool_t _dbus_type_writer_write_fixed_multi (DBusTypeWriter *writer, + int element_type, + const void *value, + int n_elements); +dbus_bool_t _dbus_type_writer_recurse (DBusTypeWriter *writer, + int container_type, + const DBusString *contained_type, + int contained_type_start, + DBusTypeWriter *sub); +dbus_bool_t _dbus_type_writer_unrecurse (DBusTypeWriter *writer, + DBusTypeWriter *sub); +dbus_bool_t _dbus_type_writer_append_array (DBusTypeWriter *writer, + const DBusString *contained_type, + int contained_type_start, + DBusTypeWriter *sub); +dbus_bool_t _dbus_type_writer_write_reader (DBusTypeWriter *writer, + DBusTypeReader *reader); +dbus_bool_t _dbus_type_writer_write_reader_partial (DBusTypeWriter *writer, + DBusTypeReader *reader, + const DBusTypeReader *start_after, + int start_after_new_pos, + int start_after_new_len, + DBusList **fixups); +void _dbus_type_writer_set_enabled (DBusTypeWriter *writer, + dbus_bool_t enabled); + + +#endif /* DBUS_MARSHAL_RECURSIVE_H */ diff --git a/include/dbus-1/dbus/dbus-marshal-validate.h b/include/dbus-1/dbus/dbus-marshal-validate.h new file mode 100644 index 00000000..5817de32 --- /dev/null +++ b/include/dbus-1/dbus/dbus-marshal-validate.h @@ -0,0 +1,198 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-marshal-validate.h Validation routines for marshaled data + * + * Copyright (C) 2005 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_MARSHAL_VALIDATE_H +#define DBUS_MARSHAL_VALIDATE_H + +/** + * @addtogroup DBusMarshal + * + * @{ + */ + +/** + * This is used rather than a bool for high visibility + */ +typedef enum +{ + DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY, + DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED +} DBusValidationMode; + +/** + * This is primarily used in unit testing, so we can verify that each + * invalid message is invalid for the expected reasons. Thus we really + * want a distinct enum value for every codepath leaving the validator + * functions. Enum values are specified manually for ease of debugging + * (so you can see the enum value given a printf) + */ +typedef enum +{ +#define _DBUS_NEGATIVE_VALIDITY_COUNT 4 + DBUS_VALIDITY_UNKNOWN_OOM_ERROR = -4, /**< can't determine validity due to OOM */ + DBUS_INVALID_FOR_UNKNOWN_REASON = -3, + DBUS_VALID_BUT_INCOMPLETE = -2, + DBUS_VALIDITY_UNKNOWN = -1, + DBUS_VALID = 0, /**< the data is valid */ + DBUS_INVALID_UNKNOWN_TYPECODE = 1, + DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE = 2, + DBUS_INVALID_SIGNATURE_TOO_LONG = 3, /* this one is impossible right now since + * you can't put a too-long value in a byte + */ + DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION = 4, + DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION = 5, + DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED = 6, + DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED = 7, + DBUS_INVALID_STRUCT_HAS_NO_FIELDS = 8, + DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL = 9, + DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE = 10, + DBUS_INVALID_NOT_ENOUGH_DATA = 11, + DBUS_INVALID_TOO_MUCH_DATA = 12, /**< trailing junk makes it invalid */ + DBUS_INVALID_BAD_BYTE_ORDER = 13, + DBUS_INVALID_BAD_PROTOCOL_VERSION = 14, + DBUS_INVALID_BAD_MESSAGE_TYPE = 15, + DBUS_INVALID_BAD_SERIAL = 16, + DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH = 17, + DBUS_INVALID_INSANE_BODY_LENGTH = 18, + DBUS_INVALID_MESSAGE_TOO_LONG = 19, + DBUS_INVALID_HEADER_FIELD_CODE = 20, + DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE = 21, + DBUS_INVALID_USES_LOCAL_INTERFACE = 22, + DBUS_INVALID_USES_LOCAL_PATH = 23, + DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE = 24, + DBUS_INVALID_BAD_DESTINATION = 25, + DBUS_INVALID_BAD_INTERFACE = 26, + DBUS_INVALID_BAD_MEMBER = 27, + DBUS_INVALID_BAD_ERROR_NAME = 28, + DBUS_INVALID_BAD_SENDER = 29, + DBUS_INVALID_MISSING_PATH = 30, + DBUS_INVALID_MISSING_INTERFACE = 31, + DBUS_INVALID_MISSING_MEMBER = 32, + DBUS_INVALID_MISSING_ERROR_NAME = 33, + DBUS_INVALID_MISSING_REPLY_SERIAL = 34, + DBUS_INVALID_LENGTH_OUT_OF_BOUNDS = 35, + DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM = 36, + DBUS_INVALID_BAD_PATH = 37, + DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS = 38, + DBUS_INVALID_BAD_UTF8_IN_STRING = 39, + DBUS_INVALID_ARRAY_LENGTH_INCORRECT = 40, + DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS = 41, + DBUS_INVALID_VARIANT_SIGNATURE_BAD = 42, + DBUS_INVALID_VARIANT_SIGNATURE_EMPTY = 43, + DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES = 44, + DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL = 45, + DBUS_INVALID_STRING_MISSING_NUL = 46, + DBUS_INVALID_SIGNATURE_MISSING_NUL = 47, + DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION = 48, + DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED = 49, + DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED = 50, + DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS = 51, + DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD = 52, + DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS = 53, + DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY = 54, + DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE = 55, + DBUS_INVALID_MISSING_UNIX_FDS = 56, + DBUS_VALIDITY_LAST +} DBusValidity; + +DBusValidity _dbus_validate_signature_with_reason (const DBusString *type_str, + int type_pos, + int len); +DBusValidity _dbus_validate_body_with_reason (const DBusString *expected_signature, + int expected_signature_start, + int byte_order, + int *bytes_remaining, + const DBusString *value_str, + int value_pos, + int len); + +const char *_dbus_validity_to_error_message (DBusValidity validity); + +dbus_bool_t _dbus_validate_path (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_validate_interface (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_validate_member (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_validate_error_name (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_validate_bus_name (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_validate_signature (const DBusString *str, + int start, + int len); + +#ifdef DBUS_DISABLE_CHECKS + +/* Be sure they don't exist, since we don't want to use them outside of checks + * and so we want the compile failure. + */ +#define DECLARE_DBUS_NAME_CHECK(what) +#define DEFINE_DBUS_NAME_CHECK(what) + +#else /* !DBUS_DISABLE_CHECKS */ + +/** A name check is used in _dbus_return_if_fail(), it's not suitable + * for validating untrusted data. use _dbus_validate_whatever for that. + */ +#define DECLARE_DBUS_NAME_CHECK(what) \ +dbus_bool_t _dbus_check_is_valid_##what (const char *name) + +/** Define a name check to be used in _dbus_return_if_fail() statements. + */ +#define DEFINE_DBUS_NAME_CHECK(what) \ +dbus_bool_t \ +_dbus_check_is_valid_##what (const char *name) \ +{ \ + DBusString str; \ + \ + if (name == NULL) \ + return FALSE; \ + \ + _dbus_string_init_const (&str, name); \ + return _dbus_validate_##what (&str, 0, \ + _dbus_string_get_length (&str)); \ +} +#endif /* !DBUS_DISABLE_CHECKS */ + +/** defines _dbus_check_is_valid_path() */ +DECLARE_DBUS_NAME_CHECK(path); +/** defines _dbus_check_is_valid_interface() */ +DECLARE_DBUS_NAME_CHECK(interface); +/** defines _dbus_check_is_valid_member() */ +DECLARE_DBUS_NAME_CHECK(member); +/** defines _dbus_check_is_valid_error_name() */ +DECLARE_DBUS_NAME_CHECK(error_name); +/** defines _dbus_check_is_valid_bus_name() */ +DECLARE_DBUS_NAME_CHECK(bus_name); +/** defines _dbus_check_is_valid_signature() */ +DECLARE_DBUS_NAME_CHECK(signature); + +/** @} */ + +#endif /* DBUS_MARSHAL_VALIDATE_H */ diff --git a/include/dbus-1/dbus/dbus-memory.h b/include/dbus-1/dbus/dbus-memory.h new file mode 100644 index 00000000..ea28423c --- /dev/null +++ b/include/dbus-1/dbus/dbus-memory.h @@ -0,0 +1,65 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-memory.h D-Bus memory handling + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_MEMORY_H +#define DBUS_MEMORY_H + +#include <dbus/dbus-macros.h> +#include <stddef.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusMemory + * @{ + */ + +DBUS_EXPORT +void* dbus_malloc (size_t bytes); +DBUS_EXPORT +void* dbus_malloc0 (size_t bytes); +DBUS_EXPORT +void* dbus_realloc (void *memory, + size_t bytes); +DBUS_EXPORT +void dbus_free (void *memory); + +#define dbus_new(type, count) ((type*)dbus_malloc (sizeof (type) * (count))) +#define dbus_new0(type, count) ((type*)dbus_malloc0 (sizeof (type) * (count))) + +DBUS_EXPORT +void dbus_free_string_array (char **str_array); + +typedef void (* DBusFreeFunction) (void *memory); + +DBUS_EXPORT +void dbus_shutdown (void); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_MEMORY_H */ diff --git a/include/dbus-1/dbus/dbus-mempool.h b/include/dbus-1/dbus/dbus-mempool.h new file mode 100644 index 00000000..afe52472 --- /dev/null +++ b/include/dbus-1/dbus/dbus-mempool.h @@ -0,0 +1,44 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-mempool.h Memory pools + * + * Copyright (C) 2002 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_MEMPOOL_H +#define DBUS_MEMPOOL_H + +#include <dbus/dbus-internals.h> +#include <dbus/dbus-memory.h> +#include <dbus/dbus-types.h> + +DBUS_BEGIN_DECLS + +typedef struct DBusMemPool DBusMemPool; + +DBusMemPool* _dbus_mem_pool_new (int element_size, + dbus_bool_t zero_elements); +void _dbus_mem_pool_free (DBusMemPool *pool); +void* _dbus_mem_pool_alloc (DBusMemPool *pool); +dbus_bool_t _dbus_mem_pool_dealloc (DBusMemPool *pool, + void *element); + +DBUS_END_DECLS + +#endif /* DBUS_MEMPOOL_H */ diff --git a/include/dbus-1/dbus/dbus-message-factory.h b/include/dbus-1/dbus/dbus-message-factory.h new file mode 100644 index 00000000..b0747504 --- /dev/null +++ b/include/dbus-1/dbus/dbus-message-factory.h @@ -0,0 +1,61 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-message-factory.h Generator of valid and invalid message data for test suite + * + * Copyright (C) 2005 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_MESSAGE_FACTORY_H +#define DBUS_MESSAGE_FACTORY_H + +#ifdef DBUS_BUILD_TESTS + +#include <dbus/dbus-string.h> +#include <dbus/dbus-marshal-basic.h> +#include <dbus/dbus-marshal-validate.h> + +DBUS_BEGIN_DECLS + +typedef struct +{ + DBusValidity expected_validity; + + DBusString data; + +} DBusMessageData; + +#define _DBUS_MESSAGE_DATA_MAX_NESTING 10 +typedef struct +{ + int sequence_nos[_DBUS_MESSAGE_DATA_MAX_NESTING]; + int depth; + int count; +} DBusMessageDataIter; + +void _dbus_message_data_free (DBusMessageData *data); +void _dbus_message_data_iter_init (DBusMessageDataIter *iter); +dbus_bool_t _dbus_message_data_iter_get_and_next (DBusMessageDataIter *iter, + DBusMessageData *data); + + +DBUS_END_DECLS + +#endif /* DBUS_BUILD_TESTS */ + +#endif /* DBUS_MESSAGE_FACTORY_H */ diff --git a/include/dbus-1/dbus/dbus-message-internal.h b/include/dbus-1/dbus/dbus-message-internal.h new file mode 100644 index 00000000..870934b9 --- /dev/null +++ b/include/dbus-1/dbus/dbus-message-internal.h @@ -0,0 +1,89 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-message-internal.h DBusMessage object internal interfaces + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_MESSAGE_INTERNAL_H +#define DBUS_MESSAGE_INTERNAL_H + +#include <dbus/dbus-marshal-validate.h> +#include <dbus/dbus-message.h> +#include <dbus/dbus-resources.h> +#include <dbus/dbus-list.h> + +DBUS_BEGIN_DECLS + +typedef struct DBusMessageLoader DBusMessageLoader; + +void _dbus_message_get_network_data (DBusMessage *message, + const DBusString **header, + const DBusString **body); +void _dbus_message_get_unix_fds (DBusMessage *message, + const int **fds, + unsigned *n_fds); + +void _dbus_message_lock (DBusMessage *message); +void _dbus_message_unlock (DBusMessage *message); +dbus_bool_t _dbus_message_add_counter (DBusMessage *message, + DBusCounter *counter); +void _dbus_message_add_counter_link (DBusMessage *message, + DBusList *link); +void _dbus_message_remove_counter (DBusMessage *message, + DBusCounter *counter, + DBusList **link_return); + +DBusMessageLoader* _dbus_message_loader_new (void); +DBusMessageLoader* _dbus_message_loader_ref (DBusMessageLoader *loader); +void _dbus_message_loader_unref (DBusMessageLoader *loader); + +void _dbus_message_loader_get_buffer (DBusMessageLoader *loader, + DBusString **buffer); +void _dbus_message_loader_return_buffer (DBusMessageLoader *loader, + DBusString *buffer, + int bytes_read); + +dbus_bool_t _dbus_message_loader_get_unix_fds (DBusMessageLoader *loader, + int **fds, + unsigned *max_n_fds); +void _dbus_message_loader_return_unix_fds (DBusMessageLoader *loader, + int *fds, + unsigned n_fds); + +dbus_bool_t _dbus_message_loader_queue_messages (DBusMessageLoader *loader); +DBusMessage* _dbus_message_loader_peek_message (DBusMessageLoader *loader); +DBusMessage* _dbus_message_loader_pop_message (DBusMessageLoader *loader); +DBusList* _dbus_message_loader_pop_message_link (DBusMessageLoader *loader); +void _dbus_message_loader_putback_message_link (DBusMessageLoader *loader, + DBusList *link); + +dbus_bool_t _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader); +DBusValidity _dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader); + +void _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader, + long size); +long _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader); + +void _dbus_message_loader_set_max_message_unix_fds(DBusMessageLoader *loader, + long n); +long _dbus_message_loader_get_max_message_unix_fds(DBusMessageLoader *loader); + +DBUS_END_DECLS + +#endif /* DBUS_MESSAGE_INTERNAL_H */ diff --git a/include/dbus-1/dbus/dbus-message-private.h b/include/dbus-1/dbus/dbus-message-private.h new file mode 100644 index 00000000..57888fa5 --- /dev/null +++ b/include/dbus-1/dbus/dbus-message-private.h @@ -0,0 +1,148 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-message-private.h header shared between dbus-message.c and dbus-message-util.c + * + * Copyright (C) 2005 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_MESSAGE_PRIVATE_H +#define DBUS_MESSAGE_PRIVATE_H + +#include <dbus/dbus-message.h> +#include <dbus/dbus-message-internal.h> +#include <dbus/dbus-string.h> +#include <dbus/dbus-dataslot.h> +#include <dbus/dbus-marshal-header.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusMessageInternals + * @{ + */ + +/** + * @typedef DBusMessageLoader + * + * The DBusMessageLoader object encapsulates the process of converting + * a byte stream into a series of DBusMessage. It buffers the incoming + * bytes as efficiently as possible, and generates a queue of + * messages. DBusMessageLoader is typically used as part of a + * DBusTransport implementation. The DBusTransport then hands off + * the loaded messages to a DBusConnection, making the messages + * visible to the application. + * + * @todo write tests for break-loader that a) randomly delete header + * fields and b) set string fields to zero-length and other funky + * values. + * + */ + +/** + * Implementation details of DBusMessageLoader. + * All members are private. + */ +struct DBusMessageLoader +{ + int refcount; /**< Reference count. */ + + DBusString data; /**< Buffered data */ + + DBusList *messages; /**< Complete messages. */ + + long max_message_size; /**< Maximum size of a message */ + long max_message_unix_fds; /**< Maximum unix fds in a message */ + + DBusValidity corruption_reason; /**< why we were corrupted */ + + unsigned int corrupted : 1; /**< We got broken data, and are no longer working */ + + unsigned int buffer_outstanding : 1; /**< Someone is using the buffer to read */ + +#ifdef HAVE_UNIX_FD_PASSING + unsigned int unix_fds_outstanding : 1; /**< Someone is using the unix fd array to read */ + + int *unix_fds; /**< File descriptors that have been read from the transport but not yet been handed to any message. Array will be allocated at first use. */ + unsigned n_unix_fds_allocated; /**< Number of file descriptors this array has space for */ + unsigned n_unix_fds; /**< Number of valid file descriptors in array */ +#endif +}; + + +/** How many bits are in the changed_stamp used to validate iterators */ +#define CHANGED_STAMP_BITS 21 + +/** + * @brief Internals of DBusMessage + * + * Object representing a message received from or to be sent to + * another application. This is an opaque object, all members + * are private. + */ +struct DBusMessage +{ + DBusAtomic refcount; /**< Reference count */ + + DBusHeader header; /**< Header network data and associated cache */ + + DBusString body; /**< Body network data. */ + + char byte_order; /**< Message byte order. */ + + unsigned int locked : 1; /**< Message being sent, no modifications allowed. */ + +#ifndef DBUS_DISABLE_CHECKS + unsigned int in_cache : 1; /**< Has been "freed" since it's in the cache (this is a debug feature) */ +#endif + + DBusList *counters; /**< 0-N DBusCounter used to track message size/unix fds. */ + long size_counter_delta; /**< Size we incremented the size counters by. */ + + dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS; /**< Incremented when iterators are invalidated. */ + + DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */ + +#ifndef DBUS_DISABLE_CHECKS + int generation; /**< _dbus_current_generation when message was created */ +#endif + +#ifdef HAVE_UNIX_FD_PASSING + int *unix_fds; + /**< Unix file descriptors associated with this message. These are + closed when the message is destroyed, hence make sure to dup() + them when adding or removing them here. */ + unsigned n_unix_fds; /**< Number of valid fds in the array */ + unsigned n_unix_fds_allocated; /**< Allocated size of the array */ + + long unix_fd_counter_delta; /**< Size we incremented the unix fd counter by */ +#endif +}; + +dbus_bool_t _dbus_message_iter_get_args_valist (DBusMessageIter *iter, + DBusError *error, + int first_arg_type, + va_list var_args); + + +void _dbus_check_fdleaks(void); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_MESSAGE_H */ diff --git a/include/dbus-1/dbus/dbus-message.h b/include/dbus-1/dbus/dbus-message.h new file mode 100644 index 00000000..5500492d --- /dev/null +++ b/include/dbus-1/dbus/dbus-message.h @@ -0,0 +1,309 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-message.h DBusMessage object + * + * Copyright (C) 2002, 2003, 2005 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_MESSAGE_H +#define DBUS_MESSAGE_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-arch-deps.h> +#include <dbus/dbus-memory.h> +#include <dbus/dbus-errors.h> +#include <stdarg.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusMessage + * @{ + */ + +typedef struct DBusMessage DBusMessage; +/** Opaque type representing a message iterator. Can be copied by value, and contains no allocated memory so never needs to be freed and can be allocated on the stack. */ +typedef struct DBusMessageIter DBusMessageIter; + +/** + * DBusMessageIter struct; contains no public fields. + */ +struct DBusMessageIter +{ + void *dummy1; /**< Don't use this */ + void *dummy2; /**< Don't use this */ + dbus_uint32_t dummy3; /**< Don't use this */ + int dummy4; /**< Don't use this */ + int dummy5; /**< Don't use this */ + int dummy6; /**< Don't use this */ + int dummy7; /**< Don't use this */ + int dummy8; /**< Don't use this */ + int dummy9; /**< Don't use this */ + int dummy10; /**< Don't use this */ + int dummy11; /**< Don't use this */ + int pad1; /**< Don't use this */ + int pad2; /**< Don't use this */ + void *pad3; /**< Don't use this */ +}; + +DBUS_EXPORT +DBusMessage* dbus_message_new (int message_type); +DBUS_EXPORT +DBusMessage* dbus_message_new_method_call (const char *bus_name, + const char *path, + const char *interface, + const char *method); +DBUS_EXPORT +DBusMessage* dbus_message_new_method_return (DBusMessage *method_call); +DBUS_EXPORT +DBusMessage* dbus_message_new_signal (const char *path, + const char *interface, + const char *name); +DBUS_EXPORT +DBusMessage* dbus_message_new_error (DBusMessage *reply_to, + const char *error_name, + const char *error_message); +DBUS_EXPORT +DBusMessage* dbus_message_new_error_printf (DBusMessage *reply_to, + const char *error_name, + const char *error_format, + ...); + +DBUS_EXPORT +DBusMessage* dbus_message_copy (const DBusMessage *message); + +DBUS_EXPORT +DBusMessage* dbus_message_ref (DBusMessage *message); +DBUS_EXPORT +void dbus_message_unref (DBusMessage *message); +DBUS_EXPORT +int dbus_message_get_type (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_set_path (DBusMessage *message, + const char *object_path); +DBUS_EXPORT +const char* dbus_message_get_path (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_has_path (DBusMessage *message, + const char *object_path); +DBUS_EXPORT +dbus_bool_t dbus_message_set_interface (DBusMessage *message, + const char *interface); +DBUS_EXPORT +const char* dbus_message_get_interface (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_has_interface (DBusMessage *message, + const char *interface); +DBUS_EXPORT +dbus_bool_t dbus_message_set_member (DBusMessage *message, + const char *member); +DBUS_EXPORT +const char* dbus_message_get_member (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_has_member (DBusMessage *message, + const char *member); +DBUS_EXPORT +dbus_bool_t dbus_message_set_error_name (DBusMessage *message, + const char *name); +DBUS_EXPORT +const char* dbus_message_get_error_name (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_set_destination (DBusMessage *message, + const char *destination); +DBUS_EXPORT +const char* dbus_message_get_destination (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_set_sender (DBusMessage *message, + const char *sender); +DBUS_EXPORT +const char* dbus_message_get_sender (DBusMessage *message); +DBUS_EXPORT +const char* dbus_message_get_signature (DBusMessage *message); +DBUS_EXPORT +void dbus_message_set_no_reply (DBusMessage *message, + dbus_bool_t no_reply); +DBUS_EXPORT +dbus_bool_t dbus_message_get_no_reply (DBusMessage *message); +DBUS_EXPORT +dbus_bool_t dbus_message_is_method_call (DBusMessage *message, + const char *interface, + const char *method); +DBUS_EXPORT +dbus_bool_t dbus_message_is_signal (DBusMessage *message, + const char *interface, + const char *signal_name); +DBUS_EXPORT +dbus_bool_t dbus_message_is_error (DBusMessage *message, + const char *error_name); +DBUS_EXPORT +dbus_bool_t dbus_message_has_destination (DBusMessage *message, + const char *bus_name); +DBUS_EXPORT +dbus_bool_t dbus_message_has_sender (DBusMessage *message, + const char *unique_bus_name); +DBUS_EXPORT +dbus_bool_t dbus_message_has_signature (DBusMessage *message, + const char *signature); +DBUS_EXPORT +dbus_uint32_t dbus_message_get_serial (DBusMessage *message); +DBUS_EXPORT +void dbus_message_set_serial (DBusMessage *message, + dbus_uint32_t serial); +DBUS_EXPORT +dbus_bool_t dbus_message_set_reply_serial (DBusMessage *message, + dbus_uint32_t reply_serial); +DBUS_EXPORT +dbus_uint32_t dbus_message_get_reply_serial (DBusMessage *message); + +DBUS_EXPORT +void dbus_message_set_auto_start (DBusMessage *message, + dbus_bool_t auto_start); +DBUS_EXPORT +dbus_bool_t dbus_message_get_auto_start (DBusMessage *message); + +DBUS_EXPORT +dbus_bool_t dbus_message_get_path_decomposed (DBusMessage *message, + char ***path); + +DBUS_EXPORT +dbus_bool_t dbus_message_append_args (DBusMessage *message, + int first_arg_type, + ...); +DBUS_EXPORT +dbus_bool_t dbus_message_append_args_valist (DBusMessage *message, + int first_arg_type, + va_list var_args); +DBUS_EXPORT +dbus_bool_t dbus_message_get_args (DBusMessage *message, + DBusError *error, + int first_arg_type, + ...); +DBUS_EXPORT +dbus_bool_t dbus_message_get_args_valist (DBusMessage *message, + DBusError *error, + int first_arg_type, + va_list var_args); + +DBUS_EXPORT +dbus_bool_t dbus_message_contains_unix_fds (DBusMessage *message); + +DBUS_EXPORT +dbus_bool_t dbus_message_iter_init (DBusMessage *message, + DBusMessageIter *iter); +DBUS_EXPORT +dbus_bool_t dbus_message_iter_has_next (DBusMessageIter *iter); +DBUS_EXPORT +dbus_bool_t dbus_message_iter_next (DBusMessageIter *iter); +DBUS_EXPORT +char* dbus_message_iter_get_signature (DBusMessageIter *iter); +DBUS_EXPORT +int dbus_message_iter_get_arg_type (DBusMessageIter *iter); +DBUS_EXPORT +int dbus_message_iter_get_element_type (DBusMessageIter *iter); +DBUS_EXPORT +void dbus_message_iter_recurse (DBusMessageIter *iter, + DBusMessageIter *sub); +DBUS_EXPORT +void dbus_message_iter_get_basic (DBusMessageIter *iter, + void *value); +#ifndef DBUS_DISABLE_DEPRECATED +/* This function returns the wire protocol size of the array in bytes, + * you do not want to know that probably + */ +DBUS_EXPORT +DBUS_DEPRECATED int dbus_message_iter_get_array_len (DBusMessageIter *iter); +#endif +DBUS_EXPORT +void dbus_message_iter_get_fixed_array (DBusMessageIter *iter, + void *value, + int *n_elements); + + +DBUS_EXPORT +void dbus_message_iter_init_append (DBusMessage *message, + DBusMessageIter *iter); +DBUS_EXPORT +dbus_bool_t dbus_message_iter_append_basic (DBusMessageIter *iter, + int type, + const void *value); +DBUS_EXPORT +dbus_bool_t dbus_message_iter_append_fixed_array (DBusMessageIter *iter, + int element_type, + const void *value, + int n_elements); +DBUS_EXPORT +dbus_bool_t dbus_message_iter_open_container (DBusMessageIter *iter, + int type, + const char *contained_signature, + DBusMessageIter *sub); +DBUS_EXPORT +dbus_bool_t dbus_message_iter_close_container (DBusMessageIter *iter, + DBusMessageIter *sub); +DBUS_EXPORT +void dbus_message_iter_abandon_container (DBusMessageIter *iter, + DBusMessageIter *sub); + +DBUS_EXPORT +void dbus_message_lock (DBusMessage *message); + +DBUS_EXPORT +dbus_bool_t dbus_set_error_from_message (DBusError *error, + DBusMessage *message); + + +DBUS_EXPORT +dbus_bool_t dbus_message_allocate_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +void dbus_message_free_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +dbus_bool_t dbus_message_set_data (DBusMessage *message, + dbus_int32_t slot, + void *data, + DBusFreeFunction free_data_func); +DBUS_EXPORT +void* dbus_message_get_data (DBusMessage *message, + dbus_int32_t slot); + +DBUS_EXPORT +int dbus_message_type_from_string (const char *type_str); +DBUS_EXPORT +const char* dbus_message_type_to_string (int type); + +DBUS_EXPORT +dbus_bool_t dbus_message_marshal (DBusMessage *msg, + char **marshalled_data_p, + int *len_p); +DBUS_EXPORT +DBusMessage* dbus_message_demarshal (const char *str, + int len, + DBusError *error); + +DBUS_EXPORT +int dbus_message_demarshal_bytes_needed (const char *str, + int len); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_MESSAGE_H */ diff --git a/include/dbus-1/dbus/dbus-misc.h b/include/dbus-1/dbus/dbus-misc.h new file mode 100644 index 00000000..3504bcaa --- /dev/null +++ b/include/dbus-1/dbus/dbus-misc.h @@ -0,0 +1,52 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-misc.h A few assorted public functions that don't fit elsewhere + * + * Copyright (C) 2006 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_MISC_H +#define DBUS_MISC_H + +#include <dbus/dbus-types.h> +#include <dbus/dbus-errors.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusMisc + * @{ + */ +DBUS_EXPORT +char* dbus_get_local_machine_id (void); + +DBUS_EXPORT +void dbus_get_version (int *major_version_p, + int *minor_version_p, + int *micro_version_p); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_MISC_H */ + diff --git a/include/dbus-1/dbus/dbus-nonce.h b/include/dbus-1/dbus/dbus-nonce.h new file mode 100644 index 00000000..474ea728 --- /dev/null +++ b/include/dbus-1/dbus/dbus-nonce.h @@ -0,0 +1,72 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-nonce.h Nonce handling functions used by nonce-tcp (internal to D-Bus implementation) + * + * Copyright (C) 2009 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + * + * Licensed under the Academic Free License version 2.1 + * + * 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 + * + */ +#ifndef DBUS_NONCE_H +#define DBUS_NONCE_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-errors.h> +#include <dbus/dbus-string.h> + +DBUS_BEGIN_DECLS + +typedef struct DBusNonceFile DBusNonceFile; + +struct DBusNonceFile +{ + DBusString path; + DBusString dir; +}; + +// server + +dbus_bool_t _dbus_noncefile_create (DBusNonceFile *noncefile, + DBusError *error); + +dbus_bool_t _dbus_noncefile_delete (DBusNonceFile *noncefile, + DBusError *error); + +dbus_bool_t _dbus_noncefile_check_nonce (int fd, + const DBusNonceFile *noncefile, + DBusError *error); + +const DBusString* _dbus_noncefile_get_path (const DBusNonceFile *noncefile); + +int _dbus_accept_with_noncefile (int listen_fd, + const DBusNonceFile *noncefile); + +// shared + +dbus_bool_t _dbus_read_nonce (const DBusString *fname, + DBusString *nonce, + DBusError *error); + +// client + +dbus_bool_t _dbus_send_nonce (int fd, + const DBusString *noncefile, + DBusError *error); + +DBUS_END_DECLS + +#endif /* DBUS_NONCE_H */ diff --git a/include/dbus-1/dbus/dbus-object-tree.h b/include/dbus-1/dbus/dbus-object-tree.h new file mode 100644 index 00000000..022dd93f --- /dev/null +++ b/include/dbus-1/dbus/dbus-object-tree.h @@ -0,0 +1,62 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-object-tree.h DBusObjectTree (internals of DBusConnection) + * + * Copyright (C) 2003 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_OBJECT_TREE_H +#define DBUS_OBJECT_TREE_H + +#include <dbus/dbus-connection.h> + +DBUS_BEGIN_DECLS + +typedef struct DBusObjectTree DBusObjectTree; + +DBusObjectTree* _dbus_object_tree_new (DBusConnection *connection); +DBusObjectTree* _dbus_object_tree_ref (DBusObjectTree *tree); +void _dbus_object_tree_unref (DBusObjectTree *tree); + +dbus_bool_t _dbus_object_tree_register (DBusObjectTree *tree, + dbus_bool_t fallback, + const char **path, + const DBusObjectPathVTable *vtable, + void *user_data, + DBusError *error); +void _dbus_object_tree_unregister_and_unlock (DBusObjectTree *tree, + const char **path); +DBusHandlerResult _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, + DBusMessage *message); +void* _dbus_object_tree_get_user_data_unlocked (DBusObjectTree *tree, + const char **path); +void _dbus_object_tree_free_all_unlocked (DBusObjectTree *tree); + + +dbus_bool_t _dbus_object_tree_list_registered_and_unlock (DBusObjectTree *tree, + const char **parent_path, + char ***child_entries); + +dbus_bool_t _dbus_decompose_path (const char *data, + int len, + char ***path, + int *path_len); + +DBUS_END_DECLS + +#endif /* DBUS_OBJECT_TREE_H */ diff --git a/include/dbus-1/dbus/dbus-pending-call-internal.h b/include/dbus-1/dbus/dbus-pending-call-internal.h new file mode 100644 index 00000000..1875eea8 --- /dev/null +++ b/include/dbus-1/dbus/dbus-pending-call-internal.h @@ -0,0 +1,67 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-pending-call-internal.h DBusPendingCall internal interfaces + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_PENDING_CALL_INTERNAL_H +#define DBUS_PENDING_CALL_INTERNAL_H + + +#include <dbus/dbus-internals.h> +#include <dbus/dbus-message.h> +#include <dbus/dbus-connection.h> +#include <dbus/dbus-list.h> + +DBUS_BEGIN_DECLS + +dbus_bool_t _dbus_pending_call_is_timeout_added_unlocked (DBusPendingCall *pending); +void _dbus_pending_call_set_timeout_added_unlocked (DBusPendingCall *pending, + dbus_bool_t is_added); +DBusTimeout * _dbus_pending_call_get_timeout_unlocked (DBusPendingCall *pending); +dbus_uint32_t _dbus_pending_call_get_reply_serial_unlocked (DBusPendingCall *pending); +void _dbus_pending_call_set_reply_serial_unlocked (DBusPendingCall *pending, + dbus_uint32_t serial); +DBusConnection * _dbus_pending_call_get_connection_and_lock (DBusPendingCall *pending); +DBusConnection * _dbus_pending_call_get_connection_unlocked (DBusPendingCall *pending); +dbus_bool_t _dbus_pending_call_get_completed_unlocked (DBusPendingCall *pending); +void _dbus_pending_call_complete (DBusPendingCall *pending); +void _dbus_pending_call_set_reply_unlocked (DBusPendingCall *pending, + DBusMessage *message); +void _dbus_pending_call_queue_timeout_error_unlocked (DBusPendingCall *pending, + DBusConnection *connection); +void _dbus_pending_call_set_reply_serial_unlocked (DBusPendingCall *pending, + dbus_uint32_t serial); +dbus_bool_t _dbus_pending_call_set_timeout_error_unlocked (DBusPendingCall *pending, + DBusMessage *message, + dbus_uint32_t serial); +DBusPendingCall* _dbus_pending_call_new_unlocked (DBusConnection *connection, + int timeout_milliseconds, + DBusTimeoutHandler timeout_handler); +DBusPendingCall* _dbus_pending_call_ref_unlocked (DBusPendingCall *pending); +void _dbus_pending_call_unref_and_unlock (DBusPendingCall *pending); +dbus_bool_t _dbus_pending_call_set_data_unlocked (DBusPendingCall *pending, + dbus_int32_t slot, + void *data, + DBusFreeFunction free_data_func); + + +DBUS_END_DECLS + +#endif /* DBUS_PENDING_CALL_INTERNAL_H */ diff --git a/include/dbus-1/dbus/dbus-pending-call.h b/include/dbus-1/dbus/dbus-pending-call.h new file mode 100644 index 00000000..8f64b8be --- /dev/null +++ b/include/dbus-1/dbus/dbus-pending-call.h @@ -0,0 +1,76 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-pending-call.h Object representing a call in progress. + * + * Copyright (C) 2002, 2003 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_PENDING_CALL_H +#define DBUS_PENDING_CALL_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-connection.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusPendingCall + * @{ + */ + +DBUS_EXPORT +DBusPendingCall* dbus_pending_call_ref (DBusPendingCall *pending); +DBUS_EXPORT +void dbus_pending_call_unref (DBusPendingCall *pending); +DBUS_EXPORT +dbus_bool_t dbus_pending_call_set_notify (DBusPendingCall *pending, + DBusPendingCallNotifyFunction function, + void *user_data, + DBusFreeFunction free_user_data); +DBUS_EXPORT +void dbus_pending_call_cancel (DBusPendingCall *pending); +DBUS_EXPORT +dbus_bool_t dbus_pending_call_get_completed (DBusPendingCall *pending); +DBUS_EXPORT +DBusMessage* dbus_pending_call_steal_reply (DBusPendingCall *pending); +DBUS_EXPORT +void dbus_pending_call_block (DBusPendingCall *pending); + +DBUS_EXPORT +dbus_bool_t dbus_pending_call_allocate_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +void dbus_pending_call_free_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +dbus_bool_t dbus_pending_call_set_data (DBusPendingCall *pending, + dbus_int32_t slot, + void *data, + DBusFreeFunction free_data_func); +DBUS_EXPORT +void* dbus_pending_call_get_data (DBusPendingCall *pending, + dbus_int32_t slot); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_PENDING_CALL_H */ diff --git a/include/dbus-1/dbus/dbus-pipe.h b/include/dbus-1/dbus/dbus-pipe.h new file mode 100644 index 00000000..f6eac5f9 --- /dev/null +++ b/include/dbus-1/dbus/dbus-pipe.h @@ -0,0 +1,59 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-sysdeps.h Wrappers around system/libc features (internal to D-Bus implementation) + * + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_PIPE_H +#define DBUS_PIPE_H + +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif + +#ifdef HAVE_INTTYPES_H +#include <inttypes.h> +#endif + +#include <dbus/dbus-types.h> +#include <dbus/dbus-errors.h> +#include <dbus/dbus-string.h> +#include <dbus/dbus-sysdeps.h> + +struct DBusPipe { + intptr_t fd_or_handle; +}; + +void _dbus_pipe_init (DBusPipe *pipe, + intptr_t fd); +void _dbus_pipe_init_stdout (DBusPipe *pipe); +int _dbus_pipe_write (DBusPipe *pipe, + const DBusString *buffer, + int start, + int len, + DBusError *error); +int _dbus_pipe_close (DBusPipe *pipe, + DBusError *error); +dbus_bool_t _dbus_pipe_is_valid (DBusPipe *pipe); +void _dbus_pipe_invalidate (DBusPipe *pipe); +dbus_bool_t _dbus_pipe_is_stdout_or_stderr (DBusPipe *pipe); + +#endif diff --git a/include/dbus-1/dbus/dbus-protocol.h b/include/dbus-1/dbus/dbus-protocol.h new file mode 100644 index 00000000..17798e94 --- /dev/null +++ b/include/dbus-1/dbus/dbus-protocol.h @@ -0,0 +1,462 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-protocol.h D-Bus protocol constants + * + * Copyright (C) 2002, 2003 CodeFactory AB + * Copyright (C) 2004, 2005 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_PROTOCOL_H +#define DBUS_PROTOCOL_H + +/* Don't include anything in here from anywhere else. It's + * intended for use by any random library. + */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* avoids confusing emacs indentation */ +#endif +#endif + +/* Normally docs are in .c files, but there isn't a .c file for this. */ +/** + * @defgroup DBusProtocol Protocol constants + * @ingroup DBus + * + * @brief Defines constants which are part of the D-Bus protocol + * + * This header is intended for use by any library, not only libdbus. + * + * @{ + */ + + +/* Message byte order */ +#define DBUS_LITTLE_ENDIAN ('l') /**< Code marking LSB-first byte order in the wire protocol. */ +#define DBUS_BIG_ENDIAN ('B') /**< Code marking MSB-first byte order in the wire protocol. */ + +/** Protocol version. */ +#define DBUS_MAJOR_PROTOCOL_VERSION 1 + +/** Type code that is never equal to a legitimate type code */ +#define DBUS_TYPE_INVALID ((int) '\0') +/** #DBUS_TYPE_INVALID as a string literal instead of a int literal */ +#define DBUS_TYPE_INVALID_AS_STRING "\0" + +/* Primitive types */ +/** Type code marking an 8-bit unsigned integer */ +#define DBUS_TYPE_BYTE ((int) 'y') +/** #DBUS_TYPE_BYTE as a string literal instead of a int literal */ +#define DBUS_TYPE_BYTE_AS_STRING "y" +/** Type code marking a boolean */ +#define DBUS_TYPE_BOOLEAN ((int) 'b') +/** #DBUS_TYPE_BOOLEAN as a string literal instead of a int literal */ +#define DBUS_TYPE_BOOLEAN_AS_STRING "b" +/** Type code marking a 16-bit signed integer */ +#define DBUS_TYPE_INT16 ((int) 'n') +/** #DBUS_TYPE_INT16 as a string literal instead of a int literal */ +#define DBUS_TYPE_INT16_AS_STRING "n" +/** Type code marking a 16-bit unsigned integer */ +#define DBUS_TYPE_UINT16 ((int) 'q') +/** #DBUS_TYPE_UINT16 as a string literal instead of a int literal */ +#define DBUS_TYPE_UINT16_AS_STRING "q" +/** Type code marking a 32-bit signed integer */ +#define DBUS_TYPE_INT32 ((int) 'i') +/** #DBUS_TYPE_INT32 as a string literal instead of a int literal */ +#define DBUS_TYPE_INT32_AS_STRING "i" +/** Type code marking a 32-bit unsigned integer */ +#define DBUS_TYPE_UINT32 ((int) 'u') +/** #DBUS_TYPE_UINT32 as a string literal instead of a int literal */ +#define DBUS_TYPE_UINT32_AS_STRING "u" +/** Type code marking a 64-bit signed integer */ +#define DBUS_TYPE_INT64 ((int) 'x') +/** #DBUS_TYPE_INT64 as a string literal instead of a int literal */ +#define DBUS_TYPE_INT64_AS_STRING "x" +/** Type code marking a 64-bit unsigned integer */ +#define DBUS_TYPE_UINT64 ((int) 't') +/** #DBUS_TYPE_UINT64 as a string literal instead of a int literal */ +#define DBUS_TYPE_UINT64_AS_STRING "t" +/** Type code marking an 8-byte double in IEEE 754 format */ +#define DBUS_TYPE_DOUBLE ((int) 'd') +/** #DBUS_TYPE_DOUBLE as a string literal instead of a int literal */ +#define DBUS_TYPE_DOUBLE_AS_STRING "d" +/** Type code marking a UTF-8 encoded, nul-terminated Unicode string */ +#define DBUS_TYPE_STRING ((int) 's') +/** #DBUS_TYPE_STRING as a string literal instead of a int literal */ +#define DBUS_TYPE_STRING_AS_STRING "s" +/** Type code marking a D-Bus object path */ +#define DBUS_TYPE_OBJECT_PATH ((int) 'o') +/** #DBUS_TYPE_OBJECT_PATH as a string literal instead of a int literal */ +#define DBUS_TYPE_OBJECT_PATH_AS_STRING "o" +/** Type code marking a D-Bus type signature */ +#define DBUS_TYPE_SIGNATURE ((int) 'g') +/** #DBUS_TYPE_SIGNATURE as a string literal instead of a int literal */ +#define DBUS_TYPE_SIGNATURE_AS_STRING "g" +/** Type code marking a unix file descriptor */ +#define DBUS_TYPE_UNIX_FD ((int) 'h') +/** #DBUS_TYPE_UNIX_FD as a string literal instead of a int literal */ +#define DBUS_TYPE_UNIX_FD_AS_STRING "h" + +/* Compound types */ +/** Type code marking a D-Bus array type */ +#define DBUS_TYPE_ARRAY ((int) 'a') +/** #DBUS_TYPE_ARRAY as a string literal instead of a int literal */ +#define DBUS_TYPE_ARRAY_AS_STRING "a" +/** Type code marking a D-Bus variant type */ +#define DBUS_TYPE_VARIANT ((int) 'v') +/** #DBUS_TYPE_VARIANT as a string literal instead of a int literal */ +#define DBUS_TYPE_VARIANT_AS_STRING "v" + +/** STRUCT and DICT_ENTRY are sort of special since their codes can't + * appear in a type string, instead + * DBUS_STRUCT_BEGIN_CHAR/DBUS_DICT_ENTRY_BEGIN_CHAR have to appear + */ +/** Type code used to represent a struct; however, this type code does not appear + * in type signatures, instead #DBUS_STRUCT_BEGIN_CHAR and #DBUS_STRUCT_END_CHAR will + * appear in a signature. + */ +#define DBUS_TYPE_STRUCT ((int) 'r') +/** #DBUS_TYPE_STRUCT as a string literal instead of a int literal */ +#define DBUS_TYPE_STRUCT_AS_STRING "r" +/** Type code used to represent a dict entry; however, this type code does not appear + * in type signatures, instead #DBUS_DICT_ENTRY_BEGIN_CHAR and #DBUS_DICT_ENTRY_END_CHAR will + * appear in a signature. + */ +#define DBUS_TYPE_DICT_ENTRY ((int) 'e') +/** #DBUS_TYPE_DICT_ENTRY as a string literal instead of a int literal */ +#define DBUS_TYPE_DICT_ENTRY_AS_STRING "e" + +/** Does not include #DBUS_TYPE_INVALID, #DBUS_STRUCT_BEGIN_CHAR, #DBUS_STRUCT_END_CHAR, + * #DBUS_DICT_ENTRY_BEGIN_CHAR, or #DBUS_DICT_ENTRY_END_CHAR - i.e. it is the number of + * valid types, not the number of distinct characters that may appear in a type signature. + */ +#define DBUS_NUMBER_OF_TYPES (16) + +/* characters other than typecodes that appear in type signatures */ + +/** Code marking the start of a struct type in a type signature */ +#define DBUS_STRUCT_BEGIN_CHAR ((int) '(') +/** #DBUS_STRUCT_BEGIN_CHAR as a string literal instead of a int literal */ +#define DBUS_STRUCT_BEGIN_CHAR_AS_STRING "(" +/** Code marking the end of a struct type in a type signature */ +#define DBUS_STRUCT_END_CHAR ((int) ')') +/** #DBUS_STRUCT_END_CHAR a string literal instead of a int literal */ +#define DBUS_STRUCT_END_CHAR_AS_STRING ")" +/** Code marking the start of a dict entry type in a type signature */ +#define DBUS_DICT_ENTRY_BEGIN_CHAR ((int) '{') +/** #DBUS_DICT_ENTRY_BEGIN_CHAR as a string literal instead of a int literal */ +#define DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING "{" +/** Code marking the end of a dict entry type in a type signature */ +#define DBUS_DICT_ENTRY_END_CHAR ((int) '}') +/** #DBUS_DICT_ENTRY_END_CHAR as a string literal instead of a int literal */ +#define DBUS_DICT_ENTRY_END_CHAR_AS_STRING "}" + +/** Max length in bytes of a bus name, interface, or member (not object + * path, paths are unlimited). This is limited because lots of stuff + * is O(n) in this number, plus it would be obnoxious to type in a + * paragraph-long method name so most likely something like that would + * be an exploit. + */ +#define DBUS_MAXIMUM_NAME_LENGTH 255 + +/** This one is 255 so it fits in a byte */ +#define DBUS_MAXIMUM_SIGNATURE_LENGTH 255 + +/** Max length of a match rule string; to keep people from hosing the + * daemon with some huge rule + */ +#define DBUS_MAXIMUM_MATCH_RULE_LENGTH 1024 + +/** Max arg number you can match on in a match rule, e.g. + * arg0='hello' is OK, arg3489720987='hello' is not + */ +#define DBUS_MAXIMUM_MATCH_RULE_ARG_NUMBER 63 + +/** Max length of a marshaled array in bytes (64M, 2^26) We use signed + * int for lengths so must be INT_MAX or less. We need something a + * bit smaller than INT_MAX because the array is inside a message with + * header info, etc. so an INT_MAX array wouldn't allow the message + * overhead. The 64M number is an attempt at a larger number than + * we'd reasonably ever use, but small enough that your bus would chew + * through it fairly quickly without locking up forever. If you have + * data that's likely to be larger than this, you should probably be + * sending it in multiple incremental messages anyhow. + */ +#define DBUS_MAXIMUM_ARRAY_LENGTH (67108864) +/** Number of bits you need in an unsigned to store the max array size */ +#define DBUS_MAXIMUM_ARRAY_LENGTH_BITS 26 + +/** The maximum total message size including header and body; similar + * rationale to max array size. + */ +#define DBUS_MAXIMUM_MESSAGE_LENGTH (DBUS_MAXIMUM_ARRAY_LENGTH * 2) +/** Number of bits you need in an unsigned to store the max message size */ +#define DBUS_MAXIMUM_MESSAGE_LENGTH_BITS 27 + +/** The maximum total number of unix fds in a message. Similar + * rationale as DBUS_MAXIMUM_MESSAGE_LENGTH. However we divide by four + * given that one fd is an int and hence at least 32 bits. + */ +#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS (DBUS_MAXIMUM_MESSAGE_LENGTH/4) +/** Number of bits you need in an unsigned to store the max message unix fds */ +#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS_BITS (DBUS_MAXIMUM_MESSAGE_LENGTH_BITS-2) + +/** Depth of recursion in the type tree. This is automatically limited + * to DBUS_MAXIMUM_SIGNATURE_LENGTH since you could only have an array + * of array of array of ... that fit in the max signature. But that's + * probably a bit too large. + */ +#define DBUS_MAXIMUM_TYPE_RECURSION_DEPTH 32 + +/* Types of message */ + +/** This value is never a valid message type, see dbus_message_get_type() */ +#define DBUS_MESSAGE_TYPE_INVALID 0 +/** Message type of a method call message, see dbus_message_get_type() */ +#define DBUS_MESSAGE_TYPE_METHOD_CALL 1 +/** Message type of a method return message, see dbus_message_get_type() */ +#define DBUS_MESSAGE_TYPE_METHOD_RETURN 2 +/** Message type of an error reply message, see dbus_message_get_type() */ +#define DBUS_MESSAGE_TYPE_ERROR 3 +/** Message type of a signal message, see dbus_message_get_type() */ +#define DBUS_MESSAGE_TYPE_SIGNAL 4 + +#define DBUS_NUM_MESSAGE_TYPES 5 + +/* Header flags */ + +/** If set, this flag means that the sender of a message does not care about getting + * a reply, so the recipient need not send one. See dbus_message_set_no_reply(). + */ +#define DBUS_HEADER_FLAG_NO_REPLY_EXPECTED 0x1 +/** + * If set, this flag means that even if the message bus knows how to start an owner for + * the destination bus name (see dbus_message_set_destination()), it should not + * do so. If this flag is not set, the bus may launch a program to process the + * message. + */ +#define DBUS_HEADER_FLAG_NO_AUTO_START 0x2 + +/* Header fields */ + +/** Not equal to any valid header field code */ +#define DBUS_HEADER_FIELD_INVALID 0 +/** Header field code for the path - the path is the object emitting a signal or the object receiving a method call. + * See dbus_message_set_path(). + */ +#define DBUS_HEADER_FIELD_PATH 1 +/** Header field code for the interface containing a member (method or signal). + * See dbus_message_set_interface(). + */ +#define DBUS_HEADER_FIELD_INTERFACE 2 +/** Header field code for a member (method or signal). See dbus_message_set_member(). */ +#define DBUS_HEADER_FIELD_MEMBER 3 +/** Header field code for an error name (found in #DBUS_MESSAGE_TYPE_ERROR messages). + * See dbus_message_set_error_name(). + */ +#define DBUS_HEADER_FIELD_ERROR_NAME 4 +/** Header field code for a reply serial, used to match a #DBUS_MESSAGE_TYPE_METHOD_RETURN message with the + * message that it's a reply to. See dbus_message_set_reply_serial(). + */ +#define DBUS_HEADER_FIELD_REPLY_SERIAL 5 +/** + * Header field code for the destination bus name of a message. See dbus_message_set_destination(). + */ +#define DBUS_HEADER_FIELD_DESTINATION 6 +/** + * Header field code for the sender of a message; usually initialized by the message bus. + * See dbus_message_set_sender(). + */ +#define DBUS_HEADER_FIELD_SENDER 7 +/** + * Header field code for the type signature of a message. + */ +#define DBUS_HEADER_FIELD_SIGNATURE 8 +/** + * Header field code for the number of unix file descriptors associated + * with this message. + */ +#define DBUS_HEADER_FIELD_UNIX_FDS 9 + + +/** + * Value of the highest-numbered header field code, can be used to determine + * the size of an array indexed by header field code. Remember though + * that unknown codes must be ignored, so check for that before + * indexing the array. + */ +#define DBUS_HEADER_FIELD_LAST DBUS_HEADER_FIELD_UNIX_FDS + +/** Header format is defined as a signature: + * byte byte order + * byte message type ID + * byte flags + * byte protocol version + * uint32 body length + * uint32 serial + * array of struct (byte,variant) (field name, value) + * + * The length of the header can be computed as the + * fixed size of the initial data, plus the length of + * the array at the end, plus padding to an 8-boundary. + */ +#define DBUS_HEADER_SIGNATURE \ + DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_UINT32_AS_STRING \ + DBUS_TYPE_UINT32_AS_STRING \ + DBUS_TYPE_ARRAY_AS_STRING \ + DBUS_STRUCT_BEGIN_CHAR_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_VARIANT_AS_STRING \ + DBUS_STRUCT_END_CHAR_AS_STRING + + +/** + * The smallest header size that can occur. (It won't be valid due to + * missing required header fields.) This is 4 bytes, two uint32, an + * array length. This isn't any kind of resource limit, just the + * necessary/logical outcome of the header signature. + */ +#define DBUS_MINIMUM_HEADER_SIZE 16 + +/* Errors */ +/* WARNING these get autoconverted to an enum in dbus-glib.h. Thus, + * if you change the order it breaks the ABI. Keep them in order. + * Also, don't change the formatting since that will break the sed + * script. + */ +/** A generic error; "something went wrong" - see the error message for more. */ +#define DBUS_ERROR_FAILED "org.freedesktop.DBus.Error.Failed" +/** There was not enough memory to complete an operation. */ +#define DBUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory" +/** The bus doesn't know how to launch a service to supply the bus name you wanted. */ +#define DBUS_ERROR_SERVICE_UNKNOWN "org.freedesktop.DBus.Error.ServiceUnknown" +/** The bus name you referenced doesn't exist (i.e. no application owns it). */ +#define DBUS_ERROR_NAME_HAS_NO_OWNER "org.freedesktop.DBus.Error.NameHasNoOwner" +/** No reply to a message expecting one, usually means a timeout occurred. */ +#define DBUS_ERROR_NO_REPLY "org.freedesktop.DBus.Error.NoReply" +/** Something went wrong reading or writing to a socket, for example. */ +#define DBUS_ERROR_IO_ERROR "org.freedesktop.DBus.Error.IOError" +/** A D-Bus bus address was malformed. */ +#define DBUS_ERROR_BAD_ADDRESS "org.freedesktop.DBus.Error.BadAddress" +/** Requested operation isn't supported (like ENOSYS on UNIX). */ +#define DBUS_ERROR_NOT_SUPPORTED "org.freedesktop.DBus.Error.NotSupported" +/** Some limited resource is exhausted. */ +#define DBUS_ERROR_LIMITS_EXCEEDED "org.freedesktop.DBus.Error.LimitsExceeded" +/** Security restrictions don't allow doing what you're trying to do. */ +#define DBUS_ERROR_ACCESS_DENIED "org.freedesktop.DBus.Error.AccessDenied" +/** Authentication didn't work. */ +#define DBUS_ERROR_AUTH_FAILED "org.freedesktop.DBus.Error.AuthFailed" +/** Unable to connect to server (probably caused by ECONNREFUSED on a socket). */ +#define DBUS_ERROR_NO_SERVER "org.freedesktop.DBus.Error.NoServer" +/** Certain timeout errors, possibly ETIMEDOUT on a socket. + * Note that #DBUS_ERROR_NO_REPLY is used for message reply timeouts. + * @warning this is confusingly-named given that #DBUS_ERROR_TIMED_OUT also exists. We can't fix + * it for compatibility reasons so just be careful. + */ +#define DBUS_ERROR_TIMEOUT "org.freedesktop.DBus.Error.Timeout" +/** No network access (probably ENETUNREACH on a socket). */ +#define DBUS_ERROR_NO_NETWORK "org.freedesktop.DBus.Error.NoNetwork" +/** Can't bind a socket since its address is in use (i.e. EADDRINUSE). */ +#define DBUS_ERROR_ADDRESS_IN_USE "org.freedesktop.DBus.Error.AddressInUse" +/** The connection is disconnected and you're trying to use it. */ +#define DBUS_ERROR_DISCONNECTED "org.freedesktop.DBus.Error.Disconnected" +/** Invalid arguments passed to a method call. */ +#define DBUS_ERROR_INVALID_ARGS "org.freedesktop.DBus.Error.InvalidArgs" +/** Missing file. */ +#define DBUS_ERROR_FILE_NOT_FOUND "org.freedesktop.DBus.Error.FileNotFound" +/** Existing file and the operation you're using does not silently overwrite. */ +#define DBUS_ERROR_FILE_EXISTS "org.freedesktop.DBus.Error.FileExists" +/** Method name you invoked isn't known by the object you invoked it on. */ +#define DBUS_ERROR_UNKNOWN_METHOD "org.freedesktop.DBus.Error.UnknownMethod" +/** Certain timeout errors, e.g. while starting a service. + * @warning this is confusingly-named given that #DBUS_ERROR_TIMEOUT also exists. We can't fix + * it for compatibility reasons so just be careful. + */ +#define DBUS_ERROR_TIMED_OUT "org.freedesktop.DBus.Error.TimedOut" +/** Tried to remove or modify a match rule that didn't exist. */ +#define DBUS_ERROR_MATCH_RULE_NOT_FOUND "org.freedesktop.DBus.Error.MatchRuleNotFound" +/** The match rule isn't syntactically valid. */ +#define DBUS_ERROR_MATCH_RULE_INVALID "org.freedesktop.DBus.Error.MatchRuleInvalid" +/** While starting a new process, the exec() call failed. */ +#define DBUS_ERROR_SPAWN_EXEC_FAILED "org.freedesktop.DBus.Error.Spawn.ExecFailed" +/** While starting a new process, the fork() call failed. */ +#define DBUS_ERROR_SPAWN_FORK_FAILED "org.freedesktop.DBus.Error.Spawn.ForkFailed" +/** While starting a new process, the child exited with a status code. */ +#define DBUS_ERROR_SPAWN_CHILD_EXITED "org.freedesktop.DBus.Error.Spawn.ChildExited" +/** While starting a new process, the child exited on a signal. */ +#define DBUS_ERROR_SPAWN_CHILD_SIGNALED "org.freedesktop.DBus.Error.Spawn.ChildSignaled" +/** While starting a new process, something went wrong. */ +#define DBUS_ERROR_SPAWN_FAILED "org.freedesktop.DBus.Error.Spawn.Failed" +/** We failed to setup the environment correctly. */ +#define DBUS_ERROR_SPAWN_SETUP_FAILED "org.freedesktop.DBus.Error.Spawn.FailedToSetup" +/** We failed to setup the config parser correctly. */ +#define DBUS_ERROR_SPAWN_CONFIG_INVALID "org.freedesktop.DBus.Error.Spawn.ConfigInvalid" +/** Bus name was not valid. */ +#define DBUS_ERROR_SPAWN_SERVICE_INVALID "org.freedesktop.DBus.Error.Spawn.ServiceNotValid" +/** Service file not found in system-services directory. */ +#define DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND "org.freedesktop.DBus.Error.Spawn.ServiceNotFound" +/** Permissions are incorrect on the setuid helper. */ +#define DBUS_ERROR_SPAWN_PERMISSIONS_INVALID "org.freedesktop.DBus.Error.Spawn.PermissionsInvalid" +/** Service file invalid (Name, User or Exec missing). */ +#define DBUS_ERROR_SPAWN_FILE_INVALID "org.freedesktop.DBus.Error.Spawn.FileInvalid" +/** Tried to get a UNIX process ID and it wasn't available. */ +#define DBUS_ERROR_SPAWN_NO_MEMORY "org.freedesktop.DBus.Error.Spawn.NoMemory" +/** Tried to get a UNIX process ID and it wasn't available. */ +#define DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN "org.freedesktop.DBus.Error.UnixProcessIdUnknown" +/** A type signature is not valid. */ +#define DBUS_ERROR_INVALID_SIGNATURE "org.freedesktop.DBus.Error.InvalidSignature" +/** A file contains invalid syntax or is otherwise broken. */ +#define DBUS_ERROR_INVALID_FILE_CONTENT "org.freedesktop.DBus.Error.InvalidFileContent" +/** Asked for SELinux security context and it wasn't available. */ +#define DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown" +/** Asked for ADT audit data and it wasn't available. */ +#define DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN "org.freedesktop.DBus.Error.AdtAuditDataUnknown" +/** There's already an object with the requested object path. */ +#define DBUS_ERROR_OBJECT_PATH_IN_USE "org.freedesktop.DBus.Error.ObjectPathInUse" +/** The message meta data does not match the payload. e.g. expected + number of file descriptors were not sent over the socket this message was received on. */ +#define DBUS_ERROR_INCONSISTENT_MESSAGE "org.freedesktop.DBus.Error.InconsistentMessage" + +/* XML introspection format */ + +/** XML namespace of the introspection format version 1.0 */ +#define DBUS_INTROSPECT_1_0_XML_NAMESPACE "http://www.freedesktop.org/standards/dbus" +/** XML public identifier of the introspection format version 1.0 */ +#define DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +/** XML system identifier of the introspection format version 1.0 */ +#define DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" +/** XML document type declaration of the introspection format version 1.0 */ +#define DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<!DOCTYPE node PUBLIC \""DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER"\"\n\""DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER"\">\n" + +/** @} */ + +#ifdef __cplusplus +#if 0 +{ /* avoids confusing emacs indentation */ +#endif +} +#endif + +#endif /* DBUS_PROTOCOL_H */ diff --git a/include/dbus-1/dbus/dbus-resources.h b/include/dbus-1/dbus/dbus-resources.h new file mode 100644 index 00000000..4763a97f --- /dev/null +++ b/include/dbus-1/dbus/dbus-resources.h @@ -0,0 +1,57 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-resources.h Resource tracking/limits + * + * Copyright (C) 2003 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_RESOURCES_H +#define DBUS_RESOURCES_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-errors.h> +#include <dbus/dbus-connection.h> + +DBUS_BEGIN_DECLS + +typedef struct DBusCounter DBusCounter; + +typedef void (* DBusCounterNotifyFunction) (DBusCounter *counter, + void *user_data); + +DBusCounter* _dbus_counter_new (void); +DBusCounter* _dbus_counter_ref (DBusCounter *counter); +void _dbus_counter_unref (DBusCounter *counter); + +void _dbus_counter_adjust_size (DBusCounter *counter, + long delta); +void _dbus_counter_adjust_unix_fd (DBusCounter *counter, + long delta); +long _dbus_counter_get_size_value (DBusCounter *counter); +long _dbus_counter_get_unix_fd_value (DBusCounter *counter); + +void _dbus_counter_set_notify (DBusCounter *counter, + long size_guard_value, + long unix_fd_guard_value, + DBusCounterNotifyFunction function, + void *user_data); + + +DBUS_END_DECLS + +#endif /* DBUS_RESOURCES_H */ diff --git a/include/dbus-1/dbus/dbus-server-debug-pipe.h b/include/dbus-1/dbus/dbus-server-debug-pipe.h new file mode 100644 index 00000000..4574311d --- /dev/null +++ b/include/dbus-1/dbus/dbus-server-debug-pipe.h @@ -0,0 +1,47 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-server-debug-pipe.h In-proc debug server implementation + * + * Copyright (C) 2003 CodeFactory AB + * Copyright (C) 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_SERVER_DEBUG_PIPE_H +#define DBUS_SERVER_DEBUG_PIPE_H + +#include <dbus/dbus-internals.h> +#include <dbus/dbus-server-protected.h> +#include <dbus/dbus-transport-protected.h> + +DBUS_BEGIN_DECLS + +DBusServer* _dbus_server_debug_pipe_new (const char *server_name, + DBusError *error); +DBusTransport* _dbus_transport_debug_pipe_new (const char *server_name, + DBusError *error); +DBusServerListenResult _dbus_server_listen_debug_pipe (DBusAddressEntry *entry, + DBusServer **server_p, + DBusError *error); +DBusTransportOpenResult _dbus_transport_open_debug_pipe (DBusAddressEntry *entry, + DBusTransport **transport_p, + DBusError *error); + + +DBUS_END_DECLS + +#endif /* DBUS_SERVER_DEBUG_PIPE_H */ diff --git a/include/dbus-1/dbus/dbus-server-protected.h b/include/dbus-1/dbus/dbus-server-protected.h new file mode 100644 index 00000000..cc2de8dd --- /dev/null +++ b/include/dbus-1/dbus/dbus-server-protected.h @@ -0,0 +1,159 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-server-protected.h Used by subclasses of DBusServer object (internal to D-Bus implementation) + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_SERVER_PROTECTED_H +#define DBUS_SERVER_PROTECTED_H + +#include <dbus/dbus-internals.h> +#include <dbus/dbus-threads-internal.h> +#include <dbus/dbus-server.h> +#include <dbus/dbus-address.h> +#include <dbus/dbus-timeout.h> +#include <dbus/dbus-watch.h> +#include <dbus/dbus-resources.h> +#include <dbus/dbus-dataslot.h> +#include <dbus/dbus-string.h> + +DBUS_BEGIN_DECLS + +typedef struct DBusServerVTable DBusServerVTable; + +/** + * Virtual table to be implemented by all server "subclasses" + */ +struct DBusServerVTable +{ + void (* finalize) (DBusServer *server); + /**< The finalize method must free the server. */ + + void (* disconnect) (DBusServer *server); + /**< Disconnect this server. */ +}; + +/** + * Internals of DBusServer object + */ +struct DBusServer +{ + DBusAtomic refcount; /**< Reference count. */ + const DBusServerVTable *vtable; /**< Virtual methods for this instance. */ + DBusMutex *mutex; /**< Lock on the server object */ + + DBusGUID guid; /**< Globally unique ID of server */ + + DBusString guid_hex; /**< Hex-encoded version of GUID */ + + DBusWatchList *watches; /**< Our watches */ + DBusTimeoutList *timeouts; /**< Our timeouts */ + + char *address; /**< Address this server is listening on. */ + + int max_connections; /**< Max number of connections allowed at once. */ + + DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */ + + DBusNewConnectionFunction new_connection_function; + /**< Callback to invoke when a new connection is created. */ + void *new_connection_data; + /**< Data for new connection callback */ + DBusFreeFunction new_connection_free_data_function; + /**< Callback to invoke to free new_connection_data + * when server is finalized or data is replaced. + */ + + char **auth_mechanisms; /**< Array of allowed authentication mechanisms */ + + unsigned int disconnected : 1; /**< TRUE if we are disconnected. */ + +#ifndef DBUS_DISABLE_CHECKS + unsigned int have_server_lock : 1; /**< Does someone have the server mutex locked */ +#endif +}; + +dbus_bool_t _dbus_server_init_base (DBusServer *server, + const DBusServerVTable *vtable, + const DBusString *address); +void _dbus_server_finalize_base (DBusServer *server); +dbus_bool_t _dbus_server_add_watch (DBusServer *server, + DBusWatch *watch); +void _dbus_server_remove_watch (DBusServer *server, + DBusWatch *watch); +void _dbus_server_toggle_watch (DBusServer *server, + DBusWatch *watch, + dbus_bool_t enabled); +dbus_bool_t _dbus_server_add_timeout (DBusServer *server, + DBusTimeout *timeout); +void _dbus_server_remove_timeout (DBusServer *server, + DBusTimeout *timeout); +void _dbus_server_toggle_timeout (DBusServer *server, + DBusTimeout *timeout, + dbus_bool_t enabled); + +void _dbus_server_ref_unlocked (DBusServer *server); +void _dbus_server_unref_unlocked (DBusServer *server); + +typedef enum +{ + DBUS_SERVER_LISTEN_NOT_HANDLED, /**< we aren't in charge of this address type */ + DBUS_SERVER_LISTEN_OK, /**< we set up the listen */ + DBUS_SERVER_LISTEN_BAD_ADDRESS, /**< malformed address */ + DBUS_SERVER_LISTEN_DID_NOT_CONNECT /**< well-formed address but failed to set it up */ +} DBusServerListenResult; + +DBusServerListenResult _dbus_server_listen_platform_specific (DBusAddressEntry *entry, + DBusServer **server_p, + DBusError *error); + +#ifdef DBUS_DISABLE_CHECKS +#define TOOK_LOCK_CHECK(server) +#define RELEASING_LOCK_CHECK(server) +#define HAVE_LOCK_CHECK(server) +#else +#define TOOK_LOCK_CHECK(server) do { \ + _dbus_assert (!(server)->have_server_lock); \ + (server)->have_server_lock = TRUE; \ + } while (0) +#define RELEASING_LOCK_CHECK(server) do { \ + _dbus_assert ((server)->have_server_lock); \ + (server)->have_server_lock = FALSE; \ + } while (0) +#define HAVE_LOCK_CHECK(server) _dbus_assert ((server)->have_server_lock) +/* A "DO_NOT_HAVE_LOCK_CHECK" is impossible since we need the lock to check the flag */ +#endif + +#define TRACE_LOCKS 0 + +#define SERVER_LOCK(server) do { \ + if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); } \ + _dbus_mutex_lock ((server)->mutex); \ + TOOK_LOCK_CHECK (server); \ + } while (0) + +#define SERVER_UNLOCK(server) do { \ + if (TRACE_LOCKS) { _dbus_verbose ("UNLOCK\n"); } \ + RELEASING_LOCK_CHECK (server); \ + _dbus_mutex_unlock ((server)->mutex); \ + } while (0) + +DBUS_END_DECLS + +#endif /* DBUS_SERVER_PROTECTED_H */ diff --git a/include/dbus-1/dbus/dbus-server-socket.h b/include/dbus-1/dbus/dbus-server-socket.h new file mode 100644 index 00000000..0a7c7891 --- /dev/null +++ b/include/dbus-1/dbus/dbus-server-socket.h @@ -0,0 +1,52 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-server-socket.h Server implementation for sockets + * + * Copyright (C) 2002, 2006 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_SERVER_SOCKET_H +#define DBUS_SERVER_SOCKET_H + +#include <dbus/dbus-internals.h> +#include <dbus/dbus-server-protected.h> +#include <dbus/dbus-nonce.h> + +DBUS_BEGIN_DECLS + +DBusServer* _dbus_server_new_for_socket (int *fds, + int n_fds, + const DBusString *address, + DBusNonceFile *noncefile); +DBusServer* _dbus_server_new_for_tcp_socket (const char *host, + const char *bind, + const char *port, + const char *family, + DBusError *error, + dbus_bool_t use_nonce); +DBusServerListenResult _dbus_server_listen_socket (DBusAddressEntry *entry, + DBusServer **server_p, + DBusError *error); + + +void _dbus_server_socket_own_filename (DBusServer *server, + char *filename); + +DBUS_END_DECLS + +#endif /* DBUS_SERVER_SOCKET_H */ diff --git a/include/dbus-1/dbus/dbus-server-unix.h b/include/dbus-1/dbus/dbus-server-unix.h new file mode 100644 index 00000000..92b996ca --- /dev/null +++ b/include/dbus-1/dbus/dbus-server-unix.h @@ -0,0 +1,37 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-server-unix.h Server implementation for Unix network protocols. + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_SERVER_UNIX_H +#define DBUS_SERVER_UNIX_H + +#include <dbus/dbus-internals.h> +#include <dbus/dbus-server-protected.h> + +DBUS_BEGIN_DECLS + +DBusServer* _dbus_server_new_for_domain_socket (const char *path, + dbus_bool_t abstract, + DBusError *error); + +DBUS_END_DECLS + +#endif /* DBUS_SERVER_UNIX_H */ diff --git a/include/dbus-1/dbus/dbus-server-win.h b/include/dbus-1/dbus/dbus-server-win.h new file mode 100644 index 00000000..65c27568 --- /dev/null +++ b/include/dbus-1/dbus/dbus-server-win.h @@ -0,0 +1,36 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-server-win.h Server implementation for windows network protocols. + * + * Copyright (C) 2002 Red Hat Inc. + * Copyright (C) 2007 Ralf Habacker <ralf.habacker@freenet.de> + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_SERVER_WIN_H +#define DBUS_SERVER_WIN_H + +#include <dbus/dbus-internals.h> +#include <dbus/dbus-server-protected.h> + +DBUS_BEGIN_DECLS + +/* add definitions here */ + +DBUS_END_DECLS + +#endif /* DBUS_SERVER_WIN_H */ diff --git a/include/dbus-1/dbus/dbus-server.h b/include/dbus-1/dbus/dbus-server.h new file mode 100644 index 00000000..bdbefa0f --- /dev/null +++ b/include/dbus-1/dbus/dbus-server.h @@ -0,0 +1,106 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-server.h DBusServer object + * + * Copyright (C) 2002, 2003 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_SERVER_H +#define DBUS_SERVER_H + +#include <dbus/dbus-errors.h> +#include <dbus/dbus-message.h> +#include <dbus/dbus-connection.h> +#include <dbus/dbus-protocol.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusServer + * @{ + */ + +typedef struct DBusServer DBusServer; + +/** Called when a new connection to the server is available. Must reference and save the new + * connection, or close the new connection. Set with dbus_server_set_new_connection_function(). + */ +typedef void (* DBusNewConnectionFunction) (DBusServer *server, + DBusConnection *new_connection, + void *data); + +DBUS_EXPORT +DBusServer* dbus_server_listen (const char *address, + DBusError *error); +DBUS_EXPORT +DBusServer* dbus_server_ref (DBusServer *server); +DBUS_EXPORT +void dbus_server_unref (DBusServer *server); +DBUS_EXPORT +void dbus_server_disconnect (DBusServer *server); +DBUS_EXPORT +dbus_bool_t dbus_server_get_is_connected (DBusServer *server); +DBUS_EXPORT +char* dbus_server_get_address (DBusServer *server); +DBUS_EXPORT +char* dbus_server_get_id (DBusServer *server); +DBUS_EXPORT +void dbus_server_set_new_connection_function (DBusServer *server, + DBusNewConnectionFunction function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_server_set_watch_functions (DBusServer *server, + DBusAddWatchFunction add_function, + DBusRemoveWatchFunction remove_function, + DBusWatchToggledFunction toggled_function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_server_set_timeout_functions (DBusServer *server, + DBusAddTimeoutFunction add_function, + DBusRemoveTimeoutFunction remove_function, + DBusTimeoutToggledFunction toggled_function, + void *data, + DBusFreeFunction free_data_function); +DBUS_EXPORT +dbus_bool_t dbus_server_set_auth_mechanisms (DBusServer *server, + const char **mechanisms); + +DBUS_EXPORT +dbus_bool_t dbus_server_allocate_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +void dbus_server_free_data_slot (dbus_int32_t *slot_p); +DBUS_EXPORT +dbus_bool_t dbus_server_set_data (DBusServer *server, + int slot, + void *data, + DBusFreeFunction free_data_func); +DBUS_EXPORT +void* dbus_server_get_data (DBusServer *server, + int slot); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_SERVER_H */ diff --git a/include/dbus-1/dbus/dbus-sha.h b/include/dbus-1/dbus/dbus-sha.h new file mode 100644 index 00000000..c48035b9 --- /dev/null +++ b/include/dbus-1/dbus/dbus-sha.h @@ -0,0 +1,55 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-sha.h SHA-1 implementation + * + * Copyright (C) 2003 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_SHA_H +#define DBUS_SHA_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-errors.h> +#include <dbus/dbus-string.h> + +DBUS_BEGIN_DECLS + +typedef struct DBusSHAContext DBusSHAContext; + +/** + * Struct storing state of the SHA algorithm + */ +struct DBusSHAContext +{ + dbus_uint32_t digest[5]; /**< Message digest */ + dbus_uint32_t count_lo; /**< 64-bit bit count */ + dbus_uint32_t count_hi; /**< No clue */ + dbus_uint32_t data[16]; /**< SHA data buffer */ +}; + +void _dbus_sha_init (DBusSHAContext *context); +void _dbus_sha_update (DBusSHAContext *context, + const DBusString *data); +dbus_bool_t _dbus_sha_final (DBusSHAContext *context, + DBusString *results); +dbus_bool_t _dbus_sha_compute (const DBusString *data, + DBusString *ascii_output); + +DBUS_END_DECLS + +#endif /* DBUS_SHA_H */ diff --git a/include/dbus-1/dbus/dbus-shared.h b/include/dbus-1/dbus/dbus-shared.h new file mode 100644 index 00000000..6a576704 --- /dev/null +++ b/include/dbus-1/dbus/dbus-shared.h @@ -0,0 +1,131 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-shared.h Stuff used by both dbus/dbus.h low-level and C/C++ binding APIs + * + * Copyright (C) 2004 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_SHARED_H +#define DBUS_SHARED_H + +/* Don't include anything in here from anywhere else. It's + * intended for use by any random library. + */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* avoids confusing emacs indentation */ +#endif +#endif + +/* Normally docs are in .c files, but there isn't a .c file for this. */ +/** + * @defgroup DBusShared Shared constants + * @ingroup DBus + * + * @brief Shared header included by both libdbus and C/C++ bindings such as the GLib bindings. + * + * Usually a C/C++ binding such as the GLib or Qt binding won't want to include dbus.h in its + * public headers. However, a few constants and macros may be useful to include; those are + * found here and in dbus-protocol.h + * + * @{ + */ + + +/** + * Well-known bus types. See dbus_bus_get(). + */ +typedef enum +{ + DBUS_BUS_SESSION, /**< The login session bus */ + DBUS_BUS_SYSTEM, /**< The systemwide bus */ + DBUS_BUS_STARTER /**< The bus that started us, if any */ +} DBusBusType; + +/** + * Results that a message handler can return. + */ +typedef enum +{ + DBUS_HANDLER_RESULT_HANDLED, /**< Message has had its effect - no need to run more handlers. */ + DBUS_HANDLER_RESULT_NOT_YET_HANDLED, /**< Message has not had any effect - see if other handlers want it. */ + DBUS_HANDLER_RESULT_NEED_MEMORY /**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or #DBUS_HANDLER_RESULT_NOT_YET_HANDLED. Please try again later with more memory. */ +} DBusHandlerResult; + +/* Bus names */ + +/** The bus name used to talk to the bus itself. */ +#define DBUS_SERVICE_DBUS "org.freedesktop.DBus" + +/* Paths */ +/** The object path used to talk to the bus itself. */ +#define DBUS_PATH_DBUS "/org/freedesktop/DBus" +/** The object path used in local/in-process-generated messages. */ +#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local" + +/* Interfaces, these #define don't do much other than + * catch typos at compile time + */ +/** The interface exported by the object with #DBUS_SERVICE_DBUS and #DBUS_PATH_DBUS */ +#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" +/** The interface supported by introspectable objects */ +#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable" +/** The interface supported by objects with properties */ +#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" +/** The interface supported by most dbus peers */ +#define DBUS_INTERFACE_PEER "org.freedesktop.DBus.Peer" + +/** This is a special interface whose methods can only be invoked + * by the local implementation (messages from remote apps aren't + * allowed to specify this interface). + */ +#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local" + +/* Owner flags */ +#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */ +#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */ +#define DBUS_NAME_FLAG_DO_NOT_QUEUE 0x4 /**< If we can not become the primary owner do not place us in the queue */ + +/* Replies to request for a name */ +#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 /**< Service has become the primary owner of the requested name */ +#define DBUS_REQUEST_NAME_REPLY_IN_QUEUE 2 /**< Service could not become the primary owner and has been placed in the queue */ +#define DBUS_REQUEST_NAME_REPLY_EXISTS 3 /**< Service is already in the queue */ +#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 /**< Service is already the primary owner */ + +/* Replies to releasing a name */ +#define DBUS_RELEASE_NAME_REPLY_RELEASED 1 /**< Service was released from the given name */ +#define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT 2 /**< The given name does not exist on the bus */ +#define DBUS_RELEASE_NAME_REPLY_NOT_OWNER 3 /**< Service is not an owner of the given name */ + +/* Replies to service starts */ +#define DBUS_START_REPLY_SUCCESS 1 /**< Service was auto started */ +#define DBUS_START_REPLY_ALREADY_RUNNING 2 /**< Service was already running */ + +/** @} */ + +#ifdef __cplusplus +#if 0 +{ /* avoids confusing emacs indentation */ +#endif +} +#endif + +#endif /* DBUS_SHARED_H */ diff --git a/include/dbus-1/dbus/dbus-shell.h b/include/dbus-1/dbus/dbus-shell.h new file mode 100644 index 00000000..06da274e --- /dev/null +++ b/include/dbus-1/dbus/dbus-shell.h @@ -0,0 +1,41 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-shell.h Shell command line utility functions. + * + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +#ifndef DBUS_SHELL_H +#define DBUS_SHELL_H + +DBUS_BEGIN_DECLS + +char* _dbus_shell_unquote (const char *quoted_string); +dbus_bool_t _dbus_shell_parse_argv (const char *command_line, + int *argcp, + char ***argvp, + DBusError *error); + +DBUS_END_DECLS + +#endif /* DBUS_SHELL_H */ + + diff --git a/include/dbus-1/dbus/dbus-signature.h b/include/dbus-1/dbus/dbus-signature.h new file mode 100644 index 00000000..ebf00c1e --- /dev/null +++ b/include/dbus-1/dbus/dbus-signature.h @@ -0,0 +1,92 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-signatures.h utility functions for D-Bus types + * + * Copyright (C) 2005 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_SIGNATURES_H +#define DBUS_SIGNATURES_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-errors.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusSignature + * @{ + */ + +/** + * DBusSignatureIter struct; contains no public fields + */ +typedef struct +{ + void *dummy1; /**< Don't use this */ + void *dummy2; /**< Don't use this */ + dbus_uint32_t dummy8; /**< Don't use this */ + int dummy12; /**< Don't use this */ + int dummy17; /**< Don't use this */ +} DBusSignatureIter; + +DBUS_EXPORT +void dbus_signature_iter_init (DBusSignatureIter *iter, + const char *signature); + +DBUS_EXPORT +int dbus_signature_iter_get_current_type (const DBusSignatureIter *iter); + +DBUS_EXPORT +char * dbus_signature_iter_get_signature (const DBusSignatureIter *iter); + +DBUS_EXPORT +int dbus_signature_iter_get_element_type (const DBusSignatureIter *iter); + +DBUS_EXPORT +dbus_bool_t dbus_signature_iter_next (DBusSignatureIter *iter); + +DBUS_EXPORT +void dbus_signature_iter_recurse (const DBusSignatureIter *iter, + DBusSignatureIter *subiter); + +DBUS_EXPORT +dbus_bool_t dbus_signature_validate (const char *signature, + DBusError *error); + +DBUS_EXPORT +dbus_bool_t dbus_signature_validate_single (const char *signature, + DBusError *error); + +DBUS_EXPORT +dbus_bool_t dbus_type_is_basic (int typecode); +DBUS_EXPORT +dbus_bool_t dbus_type_is_container (int typecode); +DBUS_EXPORT +dbus_bool_t dbus_type_is_fixed (int typecode); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_SIGNATURE_H */ diff --git a/include/dbus-1/dbus/dbus-sockets-win.h b/include/dbus-1/dbus/dbus-sockets-win.h new file mode 100644 index 00000000..5dead058 --- /dev/null +++ b/include/dbus-1/dbus/dbus-sockets-win.h @@ -0,0 +1,76 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-sockets.h Wrappers around socket features (internal to D-BUS implementation) + * + * Copyright (C) 2005 Novell, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_SOCKETS_H +#define DBUS_SOCKETS_H + +#if defined(DBUS_WIN) || defined(DBUS_WINCE) + + + +#ifndef STRICT +#define STRICT +#include <winsock2.h> +#undef STRICT +#endif +#include <winsock2.h> + +#undef interface + +#if HAVE_ERRNO_H +#include <errno.h> +#endif + +/* Make use of the fact that the WSAE* error codes don't + * overlap with errno E* codes. Wrapper functions store + * the return value from WSAGetLastError() in errno. + */ +#if defined(EPROTONOSUPPORT) || \ + defined(EAFNOSUPPORT) || \ + defined(EWOULDBLOCK) +#error This does not look like Win32 and the Microsoft C library +#endif + +#define DBUS_SOCKET_IS_INVALID(s) ((SOCKET)(s) == INVALID_SOCKET) +#define DBUS_SOCKET_API_RETURNS_ERROR(n) ((n) == SOCKET_ERROR) +#define DBUS_SOCKET_SET_ERRNO() (_dbus_win_set_errno (WSAGetLastError())) + +#define DBUS_CLOSE_SOCKET(s) closesocket(s) + +#else + +#include <sys/socket.h> +#include <sys/un.h> +#include <netinet/in.h> +#include <netdb.h> +#include <errno.h> + +#define DBUS_SOCKET_IS_INVALID(s) ((s) < 0) +#define DBUS_SOCKET_API_RETURNS_ERROR(n) ((n) < 0) +#define DBUS_SOCKET_SET_ERRNO() /* empty */ + +#define DBUS_CLOSE_SOCKET(s) close(s) + +#endif /* !Win32 */ + +#endif /* DBUS_SOCKETS_H */ diff --git a/include/dbus-1/dbus/dbus-spawn.h b/include/dbus-1/dbus/dbus-spawn.h new file mode 100644 index 00000000..5af54b72 --- /dev/null +++ b/include/dbus-1/dbus/dbus-spawn.h @@ -0,0 +1,61 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-spawn.h Wrapper around fork/exec + * + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_SPAWN_H +#define DBUS_SPAWN_H + +#include <dbus/dbus-string.h> +#include <dbus/dbus-errors.h> +#include <dbus/dbus-watch.h> + +DBUS_BEGIN_DECLS + +typedef void (* DBusSpawnChildSetupFunc) (void *user_data); + +typedef struct DBusBabysitter DBusBabysitter; + +dbus_bool_t _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, + char **argv, + char **env, + DBusSpawnChildSetupFunc child_setup, + void *user_data, + DBusError *error); +DBusBabysitter* _dbus_babysitter_ref (DBusBabysitter *sitter); +void _dbus_babysitter_unref (DBusBabysitter *sitter); +void _dbus_babysitter_kill_child (DBusBabysitter *sitter); +dbus_bool_t _dbus_babysitter_get_child_exited (DBusBabysitter *sitter); +void _dbus_babysitter_set_child_exit_error (DBusBabysitter *sitter, + DBusError *error); +dbus_bool_t _dbus_babysitter_get_child_exit_status (DBusBabysitter *sitter, + int *status); +dbus_bool_t _dbus_babysitter_set_watch_functions (DBusBabysitter *sitter, + DBusAddWatchFunction add_function, + DBusRemoveWatchFunction remove_function, + DBusWatchToggledFunction toggled_function, + void *data, + DBusFreeFunction free_data_function); + +DBUS_END_DECLS + +#endif /* DBUS_SPAWN_H */ diff --git a/include/dbus-1/dbus/dbus-string-private.h b/include/dbus-1/dbus/dbus-string-private.h new file mode 100644 index 00000000..365d89a3 --- /dev/null +++ b/include/dbus-1/dbus/dbus-string-private.h @@ -0,0 +1,124 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-string-private.h String utility class (internal to D-Bus implementation) + * + * Copyright (C) 2002, 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_STRING_PRIVATE_H +#define DBUS_STRING_PRIVATE_H + +#include <dbus/dbus-memory.h> +#include <dbus/dbus-types.h> + +#ifndef DBUS_CAN_USE_DBUS_STRING_PRIVATE +#error "Don't go including dbus-string-private.h for no good reason" +#endif + +DBUS_BEGIN_DECLS + +/** + * @brief Internals of DBusString. + * + * DBusString internals. DBusString is an opaque objects, it must be + * used via accessor functions. + */ +typedef struct +{ + unsigned char *str; /**< String data, plus nul termination */ + int len; /**< Length without nul */ + int allocated; /**< Allocated size of data */ + int max_length; /**< Max length of this string, without nul byte */ + unsigned int constant : 1; /**< String data is not owned by DBusString */ + unsigned int locked : 1; /**< DBusString has been locked and can't be changed */ + unsigned int invalid : 1; /**< DBusString is invalid (e.g. already freed) */ + unsigned int align_offset : 3; /**< str - align_offset is the actual malloc block */ +} DBusRealString; + + +/** + * @defgroup DBusStringInternals DBusString implementation details + * @ingroup DBusInternals + * @brief DBusString implementation details + * + * The guts of DBusString. + * + * @{ + */ + +/** + * This is the maximum max length (and thus also the maximum length) + * of a DBusString + */ +#define _DBUS_STRING_MAX_MAX_LENGTH (_DBUS_INT32_MAX - _DBUS_STRING_ALLOCATION_PADDING) + +/** + * Checks a bunch of assertions about a string object + * + * @param real the DBusRealString + */ +#define DBUS_GENERIC_STRING_PREAMBLE(real) _dbus_assert ((real) != NULL); _dbus_assert (!(real)->invalid); _dbus_assert ((real)->len >= 0); _dbus_assert ((real)->allocated >= 0); _dbus_assert ((real)->max_length >= 0); _dbus_assert ((real)->len <= ((real)->allocated - _DBUS_STRING_ALLOCATION_PADDING)); _dbus_assert ((real)->len <= (real)->max_length) + +/** + * Checks assertions about a string object that needs to be + * modifiable - may not be locked or const. Also declares + * the "real" variable pointing to DBusRealString. + * @param str the string + */ +#define DBUS_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \ + DBUS_GENERIC_STRING_PREAMBLE (real); \ + _dbus_assert (!(real)->constant); \ + _dbus_assert (!(real)->locked) + +/** + * Checks assertions about a string object that may be locked but + * can't be const. i.e. a string object that we can free. Also + * declares the "real" variable pointing to DBusRealString. + * + * @param str the string + */ +#define DBUS_LOCKED_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \ + DBUS_GENERIC_STRING_PREAMBLE (real); \ + _dbus_assert (!(real)->constant) + +/** + * Checks assertions about a string that may be const or locked. Also + * declares the "real" variable pointing to DBusRealString. + * @param str the string. + */ +#define DBUS_CONST_STRING_PREAMBLE(str) const DBusRealString *real = (DBusRealString*) str; \ + DBUS_GENERIC_STRING_PREAMBLE (real) + +/** + * Checks for ASCII blank byte + * @param c the byte + */ +#define DBUS_IS_ASCII_BLANK(c) ((c) == ' ' || (c) == '\t') + +/** + * Checks for ASCII whitespace byte + * @param c the byte + */ +#define DBUS_IS_ASCII_WHITE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r') + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_STRING_PRIVATE_H */ diff --git a/include/dbus-1/dbus/dbus-string.h b/include/dbus-1/dbus/dbus-string.h new file mode 100644 index 00000000..2f1ed31c --- /dev/null +++ b/include/dbus-1/dbus/dbus-string.h @@ -0,0 +1,332 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-string.h String utility class (internal to D-Bus implementation) + * + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2006 Ralf Habacker <ralf.habacker@freenet.de> + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_STRING_H +#define DBUS_STRING_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-memory.h> + +#include <stdarg.h> + +DBUS_BEGIN_DECLS + +/** + * DBusString object + */ + +typedef struct DBusString DBusString; + +struct DBusString +{ +#if defined(DBUS_WIN) && defined(_DEBUG) + const char *dummy1; /**< placeholder */ +#else + const void *dummy1; /**< placeholder */ +#endif + int dummy2; /**< placeholder */ + int dummy3; /**< placeholder */ + int dummy4; /**< placeholder */ + unsigned int dummy5 : 1; /**< placeholder */ + unsigned int dummy6 : 1; /**< placeholder */ + unsigned int dummy7 : 1; /**< placeholder */ + unsigned int dummy8 : 3; /**< placeholder */ +}; + +#ifdef DBUS_DISABLE_ASSERT +/* Some simple inlining hacks; the current linker is not smart enough + * to inline non-exported symbols across files in the library. + * Note that these break type safety (due to the casts) + */ +#define _dbus_string_get_data(s) ((char*)(((DBusString*)(s))->dummy1)) +#define _dbus_string_get_length(s) (((DBusString*)(s))->dummy2) +#define _dbus_string_set_byte(s, i, b) ((((unsigned char*)(((DBusString*)(s))->dummy1))[(i)]) = (unsigned char) (b)) +#define _dbus_string_get_byte(s, i) (((const unsigned char*)(((DBusString*)(s))->dummy1))[(i)]) +#define _dbus_string_get_const_data(s) ((const char*)(((DBusString*)(s))->dummy1)) +#define _dbus_string_get_const_data_len(s,start,len) (((const char*)(((DBusString*)(s))->dummy1)) + (start)) +#endif + +dbus_bool_t _dbus_string_init (DBusString *str); +void _dbus_string_init_const (DBusString *str, + const char *value); +void _dbus_string_init_const_len (DBusString *str, + const char *value, + int len); +dbus_bool_t _dbus_string_init_preallocated (DBusString *str, + int allocate_size); +void _dbus_string_free (DBusString *str); +void _dbus_string_lock (DBusString *str); +dbus_bool_t _dbus_string_compact (DBusString *str, + int max_waste); +#ifndef _dbus_string_get_data +char* _dbus_string_get_data (DBusString *str); +#endif /* _dbus_string_get_data */ +#ifndef _dbus_string_get_const_data +const char* _dbus_string_get_const_data (const DBusString *str); +#endif /* _dbus_string_get_const_data */ +char* _dbus_string_get_data_len (DBusString *str, + int start, + int len); +#ifndef _dbus_string_get_const_data_len +const char* _dbus_string_get_const_data_len (const DBusString *str, + int start, + int len); +#endif +#ifndef _dbus_string_set_byte +void _dbus_string_set_byte (DBusString *str, + int i, + unsigned char byte); +#endif +#ifndef _dbus_string_get_byte +unsigned char _dbus_string_get_byte (const DBusString *str, + int start); +#endif /* _dbus_string_get_byte */ +dbus_bool_t _dbus_string_insert_bytes (DBusString *str, + int i, + int n_bytes, + unsigned char byte); +dbus_bool_t _dbus_string_insert_byte (DBusString *str, + int i, + unsigned char byte); +dbus_bool_t _dbus_string_steal_data (DBusString *str, + char **data_return); +dbus_bool_t _dbus_string_steal_data_len (DBusString *str, + char **data_return, + int start, + int len); +dbus_bool_t _dbus_string_copy_data (const DBusString *str, + char **data_return); +dbus_bool_t _dbus_string_copy_data_len (const DBusString *str, + char **data_return, + int start, + int len); +void _dbus_string_copy_to_buffer (const DBusString *str, + char *buffer, + int len); +void _dbus_string_copy_to_buffer_with_nul (const DBusString *str, + char *buffer, + int avail_len); +#ifndef _dbus_string_get_length +int _dbus_string_get_length (const DBusString *str); +#endif /* !_dbus_string_get_length */ + +dbus_bool_t _dbus_string_lengthen (DBusString *str, + int additional_length); +void _dbus_string_shorten (DBusString *str, + int length_to_remove); +dbus_bool_t _dbus_string_set_length (DBusString *str, + int length); +dbus_bool_t _dbus_string_align_length (DBusString *str, + int alignment); +dbus_bool_t _dbus_string_alloc_space (DBusString *str, + int extra_bytes); +dbus_bool_t _dbus_string_append (DBusString *str, + const char *buffer); +dbus_bool_t _dbus_string_append_len (DBusString *str, + const char *buffer, + int len); +dbus_bool_t _dbus_string_append_int (DBusString *str, + long value); +dbus_bool_t _dbus_string_append_uint (DBusString *str, + unsigned long value); +dbus_bool_t _dbus_string_append_double (DBusString *str, + double value); +dbus_bool_t _dbus_string_append_byte (DBusString *str, + unsigned char byte); +dbus_bool_t _dbus_string_append_unichar (DBusString *str, + dbus_unichar_t ch); +dbus_bool_t _dbus_string_append_4_aligned (DBusString *str, + const unsigned char octets[4]); +dbus_bool_t _dbus_string_append_8_aligned (DBusString *str, + const unsigned char octets[8]); +dbus_bool_t _dbus_string_append_printf (DBusString *str, + const char *format, + ...) _DBUS_GNUC_PRINTF (2, 3); +dbus_bool_t _dbus_string_append_printf_valist (DBusString *str, + const char *format, + va_list args); +dbus_bool_t _dbus_string_insert_2_aligned (DBusString *str, + int insert_at, + const unsigned char octets[2]); +dbus_bool_t _dbus_string_insert_4_aligned (DBusString *str, + int insert_at, + const unsigned char octets[4]); +dbus_bool_t _dbus_string_insert_8_aligned (DBusString *str, + int insert_at, + const unsigned char octets[8]); +dbus_bool_t _dbus_string_insert_alignment (DBusString *str, + int *insert_at, + int alignment); +void _dbus_string_delete (DBusString *str, + int start, + int len); +dbus_bool_t _dbus_string_move (DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_copy (const DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_move_len (DBusString *source, + int start, + int len, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_copy_len (const DBusString *source, + int start, + int len, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_replace_len (const DBusString *source, + int start, + int len, + DBusString *dest, + int replace_at, + int replace_len); +dbus_bool_t _dbus_string_split_on_byte (DBusString *source, + unsigned char byte, + DBusString *tail); +void _dbus_string_get_unichar (const DBusString *str, + int start, + dbus_unichar_t *ch_return, + int *end_return); +dbus_bool_t _dbus_string_parse_int (const DBusString *str, + int start, + long *value_return, + int *end_return); +dbus_bool_t _dbus_string_parse_uint (const DBusString *str, + int start, + unsigned long *value_return, + int *end_return); +dbus_bool_t _dbus_string_parse_double (const DBusString *str, + int start, + double *value, + int *end_return); +dbus_bool_t _dbus_string_find (const DBusString *str, + int start, + const char *substr, + int *found); +dbus_bool_t _dbus_string_find_eol (const DBusString *str, + int start, + int *found, + int *found_len); +dbus_bool_t _dbus_string_find_to (const DBusString *str, + int start, + int end, + const char *substr, + int *found); +dbus_bool_t _dbus_string_find_byte_backward (const DBusString *str, + int start, + unsigned char byte, + int *found); +dbus_bool_t _dbus_string_find_blank (const DBusString *str, + int start, + int *found); +void _dbus_string_skip_blank (const DBusString *str, + int start, + int *end); +void _dbus_string_skip_white (const DBusString *str, + int start, + int *end); +void _dbus_string_skip_white_reverse (const DBusString *str, + int end, + int *start); +dbus_bool_t _dbus_string_equal (const DBusString *a, + const DBusString *b); +dbus_bool_t _dbus_string_equal_c_str (const DBusString *a, + const char *c_str); +dbus_bool_t _dbus_string_equal_len (const DBusString *a, + const DBusString *b, + int len); +dbus_bool_t _dbus_string_equal_substring (const DBusString *a, + int a_start, + int a_len, + const DBusString *b, + int b_start); +dbus_bool_t _dbus_string_starts_with_c_str (const DBusString *a, + const char *c_str); +dbus_bool_t _dbus_string_ends_with_c_str (const DBusString *a, + const char *c_str); +dbus_bool_t _dbus_string_pop_line (DBusString *source, + DBusString *dest); +void _dbus_string_delete_first_word (DBusString *str); +void _dbus_string_delete_leading_blanks (DBusString *str); +void _dbus_string_chop_white (DBusString *str); +dbus_bool_t _dbus_string_append_byte_as_hex (DBusString *str, + int byte); +dbus_bool_t _dbus_string_hex_encode (const DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_hex_decode (const DBusString *source, + int start, + int *end_return, + DBusString *dest, + int insert_at); +void _dbus_string_tolower_ascii (const DBusString *str, + int start, + int len); +void _dbus_string_toupper_ascii (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_string_validate_ascii (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_string_validate_utf8 (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_string_validate_nul (const DBusString *str, + int start, + int len); +void _dbus_string_zero (DBusString *str); + + +/** + * We allocate 1 byte for nul termination, plus 7 bytes for possible + * align_offset, so we always need 8 bytes on top of the string's + * length to be in the allocated block. + */ +#define _DBUS_STRING_ALLOCATION_PADDING 8 + +/** + * Defines a static const variable with type #DBusString called "name" + * containing the given string literal. + * + * @param name the name of the variable + * @param str the string value + */ +#define _DBUS_STRING_DEFINE_STATIC(name, str) \ + static const char _dbus_static_string_##name[] = str; \ + static const DBusString name = { _dbus_static_string_##name, \ + sizeof(_dbus_static_string_##name), \ + sizeof(_dbus_static_string_##name) + \ + _DBUS_STRING_ALLOCATION_PADDING, \ + sizeof(_dbus_static_string_##name), \ + TRUE, TRUE, FALSE, 0 } + +DBUS_END_DECLS + +#endif /* DBUS_STRING_H */ diff --git a/include/dbus-1/dbus/dbus-sysdeps-unix.h b/include/dbus-1/dbus/dbus-sysdeps-unix.h new file mode 100644 index 00000000..807d2cf5 --- /dev/null +++ b/include/dbus-1/dbus/dbus-sysdeps-unix.h @@ -0,0 +1,138 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-sysdeps-unix.h UNIX-specific wrappers around system/libc features (internal to D-Bus implementation) + * + * Copyright (C) 2002, 2003, 2006 Red Hat, Inc. + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_SYSDEPS_UNIX_H +#define DBUS_SYSDEPS_UNIX_H + +#include <dbus/dbus-sysdeps.h> + +#ifdef DBUS_WIN +#error "Don't include this on Windows" +#endif + +DBUS_BEGIN_DECLS + +/** + * @defgroup DBusSysdepsUnix UNIX-specific internal API + * @ingroup DBusInternals + * @brief Internal system-dependent API available on UNIX only + * @{ + */ + +dbus_bool_t +_dbus_close (int fd, + DBusError *error); +int _dbus_dup (int fd, + DBusError *error); +int +_dbus_read (int fd, + DBusString *buffer, + int count); +int +_dbus_write (int fd, + const DBusString *buffer, + int start, + int len); +int +_dbus_write_two (int fd, + const DBusString *buffer1, + int start1, + int len1, + const DBusString *buffer2, + int start2, + int len2); + +dbus_bool_t _dbus_open_unix_socket (int *fd, + DBusError *error); +int _dbus_connect_unix_socket (const char *path, + dbus_bool_t abstract, + DBusError *error); +int _dbus_listen_unix_socket (const char *path, + dbus_bool_t abstract, + DBusError *error); + +int _dbus_listen_systemd_sockets (int **fd, + DBusError *error); + +dbus_bool_t _dbus_read_credentials (int client_fd, + DBusCredentials *credentials, + DBusError *error); +dbus_bool_t _dbus_send_credentials (int server_fd, + DBusError *error); + +/** Information about a UNIX user */ +typedef struct DBusUserInfo DBusUserInfo; +/** Information about a UNIX group */ +typedef struct DBusGroupInfo DBusGroupInfo; + +/** + * Information about a UNIX user + */ +struct DBusUserInfo +{ + dbus_uid_t uid; /**< UID */ + dbus_gid_t primary_gid; /**< GID */ + dbus_gid_t *group_ids; /**< Groups IDs, *including* above primary group */ + int n_group_ids; /**< Size of group IDs array */ + char *username; /**< Username */ + char *homedir; /**< Home directory */ +}; + +/** + * Information about a UNIX group + */ +struct DBusGroupInfo +{ + dbus_gid_t gid; /**< GID */ + char *groupname; /**< Group name */ +}; + +dbus_bool_t _dbus_user_info_fill (DBusUserInfo *info, + const DBusString *username, + DBusError *error); +dbus_bool_t _dbus_user_info_fill_uid (DBusUserInfo *info, + dbus_uid_t uid, + DBusError *error); +void _dbus_user_info_free (DBusUserInfo *info); + +dbus_bool_t _dbus_group_info_fill (DBusGroupInfo *info, + const DBusString *groupname, + DBusError *error); +dbus_bool_t _dbus_group_info_fill_gid (DBusGroupInfo *info, + dbus_gid_t gid, + DBusError *error); +void _dbus_group_info_free (DBusGroupInfo *info); + +dbus_uid_t _dbus_getuid (void); +dbus_uid_t _dbus_geteuid (void); +dbus_gid_t _dbus_getgid (void); + +dbus_bool_t _dbus_parse_uid (const DBusString *uid_str, + dbus_uid_t *uid); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_SYSDEPS_UNIX_H */ diff --git a/include/dbus-1/dbus/dbus-sysdeps-win.h b/include/dbus-1/dbus/dbus-sysdeps-win.h new file mode 100644 index 00000000..a8ff9433 --- /dev/null +++ b/include/dbus-1/dbus/dbus-sysdeps-win.h @@ -0,0 +1,88 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-sysdeps.c Wrappers around system/libc features (internal to D-BUS implementation) + * + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2003 CodeFactory AB + * Copyright (C) 2005 Novell, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_SYSDEPS_WIN_H +#define DBUS_SYSDEPS_WIN_H + +extern void *_dbus_win_get_dll_hmodule (void); +#define _WINSOCKAPI_ + +#include "dbus-hash.h" +#include "dbus-string.h" +#include <ctype.h> +#include <malloc.h> +#include <windows.h> +#undef interface + +#define DBUS_CONSOLE_DIR "/var/run/console/" + + +void _dbus_win_set_errno (int err); +const char* _dbus_win_error_from_last_error (void); + +void _dbus_win_startup_winsock (void); +void _dbus_win_warn_win_error (const char *message, + int code); + +char * _dbus_win_error_string (int error_number); +void _dbus_win_free_error_string (char *string); + +extern const char* _dbus_lm_strerror (int error_number); + + +dbus_bool_t _dbus_win_account_to_sid (const wchar_t *waccount, + void **ppsid, + DBusError *error); + +dbus_bool_t +_dbus_win32_sid_to_name_and_domain (dbus_uid_t uid, + wchar_t **wname, + wchar_t **wdomain, + DBusError *error); + + +/* Don't define DBUS_CONSOLE_DIR on Win32 */ + +wchar_t *_dbus_win_utf8_to_utf16 (const char *str, + DBusError *error); +char *_dbus_win_utf16_to_utf8 (const wchar_t *str, + DBusError *error); + +void _dbus_win_set_error_from_win_error (DBusError *error, int code); + +dbus_bool_t +_dbus_win_sid_to_name_and_domain (dbus_uid_t uid, + wchar_t **wname, + wchar_t **wdomain, + DBusError *error); + +dbus_bool_t _dbus_file_exists (const char *filename); + +dbus_bool_t _dbus_get_config_file_name(DBusString *config_file, + char *s); + +#endif + +/** @} end of sysdeps-win.h */ diff --git a/include/dbus-1/dbus/dbus-sysdeps-wince-glue.h b/include/dbus-1/dbus/dbus-sysdeps-wince-glue.h new file mode 100644 index 00000000..f5ac6c8a --- /dev/null +++ b/include/dbus-1/dbus/dbus-sysdeps-wince-glue.h @@ -0,0 +1,246 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-sysdeps-wince-glue.h Emulation of system/libc features for Windows CE (internal to D-Bus implementation) + * + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_SYSDEPS_WINCE_GLUE_H +#define DBUS_SYSDEPS_WINCE_GLUE_H + +#include <time.h> +#include <stdarg.h> + +/* For getaddrinfo, configure/cmake defined _WIN32_WCE to something >= 0x0401. */ +#include <windows.h> +#undef interface + +DBUS_BEGIN_DECLS + +/* shlobj.h declares these only for _WIN32_IE that we don't want to define. + In any case, with mingw32ce we only get a SHGetSpecialFolderPath. */ +#define SHGetSpecialFolderPathW SHGetSpecialFolderPath +BOOL WINAPI SHGetSpecialFolderPathA(HWND,LPSTR,int,BOOL); +BOOL WINAPI SHGetSpecialFolderPathW(HWND,LPWSTR,int,BOOL); + +#ifndef TLS_OUT_OF_INDEXES +#define TLS_OUT_OF_INDEXES 0xffffffff +#endif + + +/* Seriously. Windows CE does not have errno. Don't you hate it when + that happens? */ +#define errno ((int)GetLastError ()) + +#define ENOENT ERROR_FILE_NOT_FOUND +#define EMFILE ERROR_TOO_MANY_OPEN_FILES +#define EACCES ERROR_ACCESS_DENIED +#define EBADF ERROR_INVALID_HANDLE +#define ENOMEM ERROR_NOT_ENOUGH_MEMORY +#define EXDEV ERROR_NOT_SAME_DEVICE +#define ENFILE ERROR_NO_MORE_FILES +#define EROFS ERROR_WRITE_PROTECT +#define ENOLCK ERROR_SHARING_BUFFER_EXCEEDED +#define ENOSYS ERROR_NOT_SUPPORTED +#define EEXIST ERROR_FILE_EXISTS +#define EPERM ERROR_CANNOT_MAKE +#define EINVAL ERROR_INVALID_PARAMETER +#define EINTR ERROR_INVALID_AT_INTERRUPT_TIME +#define EPIPE ERROR_BROKEN_PIPE +#define ENOSPC ERROR_DISK_FULL +#define ENOTEMPTY ERROR_DIR_NOT_EMPTY +#define EBUSY ERROR_BUSY +#define ENAMETOOLONG ERROR_FILENAME_EXCED_RANGE +#define EAGAIN ERROR_MORE_DATA +#define ENOTDIR ERROR_DIRECTORY +#define ERANGE ERROR_ARITHMETIC_OVERFLOW +#define ENXIO ERROR_FILE_INVALID +#define EFAULT ERROR_PROCESS_ABORTED +#define EIO ERROR_IO_DEVICE +#define EDEADLOCK ERROR_POSSIBLE_DEADLOCK +#define ENODEV ERROR_BAD_DEVICE + +/* Windows CE is missing more stuff that is pretty standard. */ + +#define strdup _strdup +#define stricmp _stricmp +#define strnicmp _strnicmp + +#define environ _dbus_wince_environ +extern char *environ[]; + +#define getenv _dbus_wince_getenv +char *getenv (const char *name); + +#define putenv _dbus_wince_putenv +int putenv (char *str); + +#define clock _dbus_wince_clock +clock_t clock (void); + +#define abort _dbus_wince_abort +void abort (void); + +#define _S_IFMT 0170000 /* file type mask */ +#define _S_IFDIR 0040000 /* directory */ +#define _S_IFCHR 0020000 /* character special */ +#define _S_IFIFO 0010000 /* pipe */ +#define _S_IFREG 0100000 /* regular */ +#define _S_IREAD 0000400 /* read permission, owner */ +#define _S_IWRITE 0000200 /* write permission, owner */ +#define _S_IEXEC 0000100 /* execute/search permission, owner */ + +#ifndef __OFF_T_DEFINED +typedef long off_t; +#define __OFF_T_DEFINED +#endif +#ifndef _INTPTR_T_DEFINED +typedef int intptr_t; +#define _INTPTR_T_DEFINED +#endif +#ifndef _UINTPTR_T_DEFINED +typedef unsigned int uintptr_t; +#define _UINTPTR_T_DEFINED +#endif + +#ifndef _MAX_FNAME +#define _MAX_FNAME 256 +#endif + +#ifndef _IOFBF +#define _IOFBF 0 +#endif +#ifndef _IOLBF +#define _IOLBF 1 +#endif +#ifndef _IONBF +#define _IONBF 2 +#endif + + +/* Windows CE is missing some Windows functions that we want. */ + +#define GetSystemTimeAsFileTime _dbus_wince_GetSystemTimeAsFileTime +void GetSystemTimeAsFileTime (LPFILETIME ftp); + +#define _mbsrchr _dbus_wince_mbsrchr +unsigned char* _mbsrchr (const unsigned char*, unsigned int); + +#define OpenFileMappingA _dbus_wince_OpenFileMappingA +HANDLE OpenFileMappingA(DWORD,BOOL,LPCSTR); + +#define MoveFileExA _dbus_wince_MoveFileExA +BOOL MoveFileExA(LPCSTR,LPCSTR,DWORD); +#ifndef MOVEFILE_REPLACE_EXISTING +#define MOVEFILE_REPLACE_EXISTING 0x00000001 +#endif + +#define SetHandleInformation _dbus_wince_SetHandleInformation +BOOL SetHandleInformation(HANDLE,DWORD,DWORD); +#ifndef HANDLE_FLAG_INHERIT +#define HANDLE_FLAG_INHERIT 0x01 +#endif +#ifndef HANDLE_FLAG_PROTECT +#define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x02 +#endif + +#define SearchPathA _dbus_wince_SearchPathA +DWORD SearchPathA(LPCSTR,LPCSTR,LPCSTR,DWORD,LPSTR,LPSTR*); + +/* Instead of emulating all functions needed for this, we replace the + whole thing. */ +dbus_bool_t _dbus_getsid(char **sid); + + +#define LookupAccountNameW _dbus_wince_LookupAccountNameW +BOOL LookupAccountNameW(LPCWSTR,LPCWSTR,PSID,PDWORD,LPWSTR,PDWORD,PSID_NAME_USE); + +#define IsValidSid _dbus_wince_IsValidSid +BOOL IsValidSid(PSID); + + +/* Windows CE does only have the UNICODE interfaces (FooW), but we + want to use the ASCII interfaces (FooA). We implement them + here. */ + +#define CreateFileA _dbus_wince_CreateFileA +HANDLE CreateFileA(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE); + +#define DeleteFileA _dbus_wince_DeleteFileA +BOOL DeleteFileA(LPCSTR); + +#define GetFileAttributesA _dbus_wince_GetFileAttributesA +DWORD GetFileAttributesA(LPCSTR); + +#define GetFileAttributesExA _dbus_wince_GetFileAttributesExA +BOOL GetFileAttributesExA(LPCSTR,GET_FILEEX_INFO_LEVELS,PVOID); + +#define CreateFileMappingA _dbus_wince_CreateFileMappingA +HANDLE CreateFileMappingA(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,DWORD,DWORD,LPCSTR); + +#define CreateDirectoryA _dbus_wince_CreateDirectoryA +BOOL CreateDirectoryA(LPCSTR,LPSECURITY_ATTRIBUTES); + +#define RemoveDirectoryA _dbus_wince_RemoveDirectoryA +BOOL RemoveDirectoryA(LPCSTR); + +#define FindFirstFileA _dbus_wince_FindFirstFileA +HANDLE FindFirstFileA(LPCSTR,LPWIN32_FIND_DATAA); + +#define FindNextFileA _dbus_wince_FindNextFileA +BOOL FindNextFileA(HANDLE,LPWIN32_FIND_DATAA); + +#define CreateMutexA _dbus_wince_CreateMutexA +HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES,BOOL,LPCSTR); + +#define CreateProcessA _dbus_wince_CreateProcessA +BOOL CreateProcessA(LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,PVOID,LPCSTR,LPSTARTUPINFOA,LPPROCESS_INFORMATION); +#ifndef CREATE_NO_WINDOW +#define CREATE_NO_WINDOW 0x08000000 +#endif + + +#define RegOpenKeyExA _dbus_wince_RegOpenKeyExA +LONG RegOpenKeyExA(HKEY,LPCSTR,DWORD,REGSAM,PHKEY); + +#define RegQueryValueExA _dbus_wince_RegQueryValueExA +LONG WINAPI RegQueryValueExA(HKEY,LPCSTR,LPDWORD,LPDWORD,LPBYTE,LPDWORD); + + +#define FormatMessageA _dbus_wince_FormatMessageA +DWORD FormatMessageA(DWORD,PCVOID,DWORD,DWORD,LPSTR,DWORD,va_list*); + +#define GetModuleFileNameA _dbus_wince_GetModuleFileNameA +DWORD GetModuleFileNameA(HINSTANCE,LPSTR,DWORD); + +#define GetTempPathA _dbus_wince_GetTempPathA +DWORD GetTempPathA(DWORD,LPSTR); + +#define SHGetSpecialFolderPathA _dbus_wince_SHGetSpecialFolderPathA +BOOL SHGetSpecialFolderPathA(HWND,LPSTR,int,BOOL); + + +#define OutputDebugStringA _dbus_wince_OutputDebugStringA +void OutputDebugStringA(LPCSTR); + + +DBUS_END_DECLS + +#endif /* DBUS_SYSDEPS_WINCE_GLUE_H */ diff --git a/include/dbus-1/dbus/dbus-sysdeps.h b/include/dbus-1/dbus/dbus-sysdeps.h new file mode 100644 index 00000000..c98db36d --- /dev/null +++ b/include/dbus-1/dbus/dbus-sysdeps.h @@ -0,0 +1,531 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-sysdeps.h Wrappers around system/libc features (internal to D-Bus implementation) + * + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_SYSDEPS_H +#define DBUS_SYSDEPS_H + +#include "config.h" + +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif + +#include <dbus/dbus-errors.h> +#include <dbus/dbus-file.h> +#include <dbus/dbus-string.h> + +/* this is perhaps bogus, but strcmp() etc. are faster if we use the + * stuff straight out of string.h, so have this here for now. + */ +#include <string.h> +#include <stdarg.h> + +/* AIX sys/poll.h does #define events reqevents, and other + * wonderousness, so must include sys/poll before declaring + * DBusPollFD + */ +#ifdef HAVE_POLL +#include <sys/poll.h> +#endif + +#ifdef DBUS_WINCE +/* Windows CE lacks some system functions (such as errno and clock). + We bring them in here. */ +#include "dbus-sysdeps-wince-glue.h" +#endif + +DBUS_BEGIN_DECLS + +#ifdef DBUS_WIN +#define _DBUS_PATH_SEPARATOR ";" +#else +#define _DBUS_PATH_SEPARATOR ":" +#endif + +/* Forward declarations */ + + +/** An opaque list type */ +typedef struct DBusList DBusList; + +/** Object that contains a list of credentials such as UNIX or Windows user ID */ +typedef struct DBusCredentials DBusCredentials; + +/** A wrapper around a pipe descriptor or handle */ +typedef struct DBusPipe DBusPipe; + +/** + * @addtogroup DBusSysdeps + * + * @{ + */ + +void _dbus_abort (void) _DBUS_GNUC_NORETURN; + +const char* _dbus_getenv (const char *varname); +dbus_bool_t _dbus_setenv (const char *varname, + const char *value); +dbus_bool_t _dbus_clearenv (void); +char ** _dbus_get_environment (void); + +/** A process ID */ +typedef unsigned long dbus_pid_t; +/** A user ID */ +typedef unsigned long dbus_uid_t; +/** A group ID */ +typedef unsigned long dbus_gid_t; + +/** an invalid PID used to represent an uninitialized dbus_pid_t field */ +#define DBUS_PID_UNSET ((dbus_pid_t) -1) +/** an invalid UID used to represent an uninitialized dbus_uid_t field */ +#define DBUS_UID_UNSET ((dbus_uid_t) -1) +/** an invalid GID used to represent an uninitialized dbus_gid_t field */ +#define DBUS_GID_UNSET ((dbus_gid_t) -1) + +/** an appropriate printf format for dbus_pid_t */ +#define DBUS_PID_FORMAT "%lu" +/** an appropriate printf format for dbus_uid_t */ +#define DBUS_UID_FORMAT "%lu" +/** an appropriate printf format for dbus_gid_t */ +#define DBUS_GID_FORMAT "%lu" + + +/** + * Socket interface + * + * @todo Use for the file descriptors a struct + * - struct DBusSocket{ int d; }; - + * instead of int to get type-safety which + * will be checked by the compiler. + * + */ + +dbus_bool_t _dbus_open_tcp_socket (int *fd, + DBusError *error); +dbus_bool_t _dbus_close_socket (int fd, + DBusError *error); +int _dbus_read_socket (int fd, + DBusString *buffer, + int count); +int _dbus_write_socket (int fd, + const DBusString *buffer, + int start, + int len); +int _dbus_write_socket_two (int fd, + const DBusString *buffer1, + int start1, + int len1, + const DBusString *buffer2, + int start2, + int len2); + +int _dbus_read_socket_with_unix_fds (int fd, + DBusString *buffer, + int count, + int *fds, + int *n_fds); +int _dbus_write_socket_with_unix_fds (int fd, + const DBusString *buffer, + int start, + int len, + const int *fds, + int n_fds); +int _dbus_write_socket_with_unix_fds_two (int fd, + const DBusString *buffer1, + int start1, + int len1, + const DBusString *buffer2, + int start2, + int len2, + const int *fds, + int n_fds); + +dbus_bool_t _dbus_socket_is_invalid (int fd); + +int _dbus_connect_tcp_socket (const char *host, + const char *port, + const char *family, + DBusError *error); +int _dbus_connect_tcp_socket_with_nonce (const char *host, + const char *port, + const char *family, + const char *noncefile, + DBusError *error); +int _dbus_listen_tcp_socket (const char *host, + const char *port, + const char *family, + DBusString *retport, + int **fds_p, + DBusError *error); +int _dbus_accept (int listen_fd); + + +dbus_bool_t _dbus_read_credentials_socket (int client_fd, + DBusCredentials *credentials, + DBusError *error); +dbus_bool_t _dbus_send_credentials_socket (int server_fd, + DBusError *error); + +dbus_bool_t _dbus_credentials_add_from_user (DBusCredentials *credentials, + const DBusString *username); +dbus_bool_t _dbus_credentials_add_from_current_process (DBusCredentials *credentials); +dbus_bool_t _dbus_append_user_from_current_process (DBusString *str); + +dbus_bool_t _dbus_parse_unix_user_from_config (const DBusString *username, + dbus_uid_t *uid_p); +dbus_bool_t _dbus_parse_unix_group_from_config (const DBusString *groupname, + dbus_gid_t *gid_p); +dbus_bool_t _dbus_unix_groups_from_uid (dbus_uid_t uid, + dbus_gid_t **group_ids, + int *n_group_ids); +dbus_bool_t _dbus_unix_user_is_at_console (dbus_uid_t uid, + DBusError *error); +dbus_bool_t _dbus_unix_user_is_process_owner (dbus_uid_t uid); +dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid); + +dbus_bool_t _dbus_append_keyring_directory_for_credentials (DBusString *directory, + DBusCredentials *credentials); + +void _dbus_daemon_publish_session_bus_address (const char* address); + +void _dbus_daemon_unpublish_session_bus_address (void); + +dbus_bool_t _dbus_socket_can_pass_unix_fd(int fd); + +/** Opaque type representing an atomically-modifiable integer + * that can be used from multiple threads. + */ +typedef struct DBusAtomic DBusAtomic; + +/** + * An atomic integer safe to increment or decrement from multiple threads. + */ +struct DBusAtomic +{ +#ifdef DBUS_WIN + volatile long value; /**< Value of the atomic integer. */ +#else + volatile dbus_int32_t value; /**< Value of the atomic integer. */ +#endif +}; + +/* The value we get from autofoo is in the form of a cpp expression; + * convert that to a conventional defined/undef switch. (We can't get + * the conventional defined/undef because of multiarch builds only running + * ./configure once, on Darwin.) */ +#if DBUS_HAVE_ATOMIC_INT_COND +# define DBUS_HAVE_ATOMIC_INT 1 +#else +# undef DBUS_HAVE_ATOMIC_INT +#endif + +dbus_int32_t _dbus_atomic_inc (DBusAtomic *atomic); +dbus_int32_t _dbus_atomic_dec (DBusAtomic *atomic); + + +/* AIX uses different values for poll */ + +#ifdef _AIX +/** There is data to read */ +#define _DBUS_POLLIN 0x0001 +/** There is urgent data to read */ +#define _DBUS_POLLPRI 0x0004 +/** Writing now will not block */ +#define _DBUS_POLLOUT 0x0002 +/** Error condition */ +#define _DBUS_POLLERR 0x4000 +/** Hung up */ +#define _DBUS_POLLHUP 0x2000 +/** Invalid request: fd not open */ +#define _DBUS_POLLNVAL 0x8000 +#elif defined(__HAIKU__) +/** There is data to read */ +#define _DBUS_POLLIN 0x0001 +/** Writing now will not block */ +#define _DBUS_POLLOUT 0x0002 +/** Error condition */ +#define _DBUS_POLLERR 0x0004 +/** There is urgent data to read */ +#define _DBUS_POLLPRI 0x0020 +/** Hung up */ +#define _DBUS_POLLHUP 0x0080 +/** Invalid request: fd not open */ +#define _DBUS_POLLNVAL 0x1000 +#else +/** There is data to read */ +#define _DBUS_POLLIN 0x0001 +/** There is urgent data to read */ +#define _DBUS_POLLPRI 0x0002 +/** Writing now will not block */ +#define _DBUS_POLLOUT 0x0004 +/** Error condition */ +#define _DBUS_POLLERR 0x0008 +/** Hung up */ +#define _DBUS_POLLHUP 0x0010 +/** Invalid request: fd not open */ +#define _DBUS_POLLNVAL 0x0020 +#endif + +/** + * A portable struct pollfd wrapper. + */ +typedef struct +{ + int fd; /**< File descriptor */ + short events; /**< Events to poll for */ + short revents; /**< Events that occurred */ +} DBusPollFD; + +int _dbus_poll (DBusPollFD *fds, + int n_fds, + int timeout_milliseconds); + +void _dbus_sleep_milliseconds (int milliseconds); + +void _dbus_get_current_time (long *tv_sec, + long *tv_usec); + +/** + * directory interface + */ +dbus_bool_t _dbus_create_directory (const DBusString *filename, + DBusError *error); +dbus_bool_t _dbus_delete_directory (const DBusString *filename, + DBusError *error); + +dbus_bool_t _dbus_concat_dir_and_file (DBusString *dir, + const DBusString *next_component); +dbus_bool_t _dbus_string_get_dirname (const DBusString *filename, + DBusString *dirname); +dbus_bool_t _dbus_path_is_absolute (const DBusString *filename); + +dbus_bool_t _dbus_get_standard_session_servicedirs (DBusList **dirs); +dbus_bool_t _dbus_get_standard_system_servicedirs (DBusList **dirs); + +dbus_bool_t _dbus_append_system_config_file (DBusString *str); +dbus_bool_t _dbus_append_session_config_file (DBusString *str); + +/** Opaque type for reading a directory listing */ +typedef struct DBusDirIter DBusDirIter; + +DBusDirIter* _dbus_directory_open (const DBusString *filename, + DBusError *error); +dbus_bool_t _dbus_directory_get_next_file (DBusDirIter *iter, + DBusString *filename, + DBusError *error); +void _dbus_directory_close (DBusDirIter *iter); + +dbus_bool_t _dbus_check_dir_is_private_to_user (DBusString *dir, + DBusError *error); + +void _dbus_fd_set_close_on_exec (intptr_t fd); + +const char* _dbus_get_tmpdir (void); + +/** + * Random numbers + */ +void _dbus_generate_pseudorandom_bytes_buffer (char *buffer, + int n_bytes); +void _dbus_generate_random_bytes_buffer (char *buffer, + int n_bytes); +dbus_bool_t _dbus_generate_random_bytes (DBusString *str, + int n_bytes); +dbus_bool_t _dbus_generate_random_ascii (DBusString *str, + int n_bytes); + +const char* _dbus_error_from_errno (int error_number); +const char* _dbus_error_from_system_errno (void); + +void _dbus_set_errno_to_zero (void); +dbus_bool_t _dbus_get_is_errno_nonzero (void); +dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock (void); +dbus_bool_t _dbus_get_is_errno_enomem (void); +dbus_bool_t _dbus_get_is_errno_eintr (void); +dbus_bool_t _dbus_get_is_errno_epipe (void); +const char* _dbus_strerror_from_errno (void); + +void _dbus_disable_sigpipe (void); + + +void _dbus_exit (int code) _DBUS_GNUC_NORETURN; + +int _dbus_printf_string_upper_bound (const char *format, + va_list args); + + +/** + * Portable struct with stat() results + */ +typedef struct +{ + unsigned long mode; /**< File mode */ + unsigned long nlink; /**< Number of hard links */ + dbus_uid_t uid; /**< User owning file */ + dbus_gid_t gid; /**< Group owning file */ + unsigned long size; /**< Size of file */ + unsigned long atime; /**< Access time */ + unsigned long mtime; /**< Modify time */ + unsigned long ctime; /**< Creation time */ +} DBusStat; + +dbus_bool_t _dbus_stat (const DBusString *filename, + DBusStat *statbuf, + DBusError *error); +dbus_bool_t _dbus_full_duplex_pipe (int *fd1, + int *fd2, + dbus_bool_t blocking, + DBusError *error); + +void _dbus_print_backtrace (void); + +dbus_bool_t _dbus_become_daemon (const DBusString *pidfile, + DBusPipe *print_pid_pipe, + DBusError *error, + dbus_bool_t keep_umask); + +dbus_bool_t _dbus_verify_daemon_user (const char *user); +dbus_bool_t _dbus_change_to_daemon_user (const char *user, + DBusError *error); + +dbus_bool_t _dbus_write_pid_to_file_and_pipe (const DBusString *pidfile, + DBusPipe *print_pid_pipe, + dbus_pid_t pid_to_write, + DBusError *error); + +dbus_bool_t _dbus_command_for_pid (unsigned long pid, + DBusString *str, + int max_len, + DBusError *error); + +/** A UNIX signal handler */ +typedef void (* DBusSignalHandler) (int sig); + +void _dbus_set_signal_handler (int sig, + DBusSignalHandler handler); + +dbus_bool_t _dbus_user_at_console (const char *username, + DBusError *error); + +void _dbus_init_system_log (void); + +typedef enum { + DBUS_SYSTEM_LOG_INFO, + DBUS_SYSTEM_LOG_SECURITY, + DBUS_SYSTEM_LOG_FATAL +} DBusSystemLogSeverity; + +void _dbus_system_log (DBusSystemLogSeverity severity, const char *msg, ...) _DBUS_GNUC_PRINTF (2, 3); +void _dbus_system_logv (DBusSystemLogSeverity severity, const char *msg, va_list args); + +/* Define DBUS_VA_COPY() to do the right thing for copying va_list variables. + * config.h may have already defined DBUS_VA_COPY as va_copy or __va_copy. + */ +#if !defined (DBUS_VA_COPY) +# if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32)) +# define DBUS_VA_COPY(ap1, ap2) (*(ap1) = *(ap2)) +# elif defined (DBUS_VA_COPY_AS_ARRAY) +# define DBUS_VA_COPY(ap1, ap2) memcpy ((ap1), (ap2), sizeof (va_list)) +# else /* va_list is a pointer */ +# define DBUS_VA_COPY(ap1, ap2) ((ap1) = (ap2)) +# endif /* va_list is a pointer */ +#endif /* !DBUS_VA_COPY */ + + +/** + * Casts a primitive C type to a byte array and then indexes + * a particular byte of the array. + */ +#define _DBUS_BYTE_OF_PRIMITIVE(p, i) \ + (((const char*)&(p))[(i)]) +/** On x86 there is an 80-bit FPU, and if you do "a == b" it may have a + * or b in an 80-bit register, thus failing to compare the two 64-bit + * doubles for bitwise equality. So this macro compares the two doubles + * bitwise. + */ +#define _DBUS_DOUBLES_BITWISE_EQUAL(a, b) \ + (_DBUS_BYTE_OF_PRIMITIVE (a, 0) == _DBUS_BYTE_OF_PRIMITIVE (b, 0) && \ + _DBUS_BYTE_OF_PRIMITIVE (a, 1) == _DBUS_BYTE_OF_PRIMITIVE (b, 1) && \ + _DBUS_BYTE_OF_PRIMITIVE (a, 2) == _DBUS_BYTE_OF_PRIMITIVE (b, 2) && \ + _DBUS_BYTE_OF_PRIMITIVE (a, 3) == _DBUS_BYTE_OF_PRIMITIVE (b, 3) && \ + _DBUS_BYTE_OF_PRIMITIVE (a, 4) == _DBUS_BYTE_OF_PRIMITIVE (b, 4) && \ + _DBUS_BYTE_OF_PRIMITIVE (a, 5) == _DBUS_BYTE_OF_PRIMITIVE (b, 5) && \ + _DBUS_BYTE_OF_PRIMITIVE (a, 6) == _DBUS_BYTE_OF_PRIMITIVE (b, 6) && \ + _DBUS_BYTE_OF_PRIMITIVE (a, 7) == _DBUS_BYTE_OF_PRIMITIVE (b, 7)) + +dbus_bool_t _dbus_get_autolaunch_address (DBusString *address, + DBusError *error); + +dbus_bool_t _dbus_lookup_session_address (dbus_bool_t *supported, + DBusString *address, + DBusError *error); + +/** Type representing a universally unique ID + * @todo rename to UUID instead of GUID + */ +typedef union DBusGUID DBusGUID; + +dbus_bool_t _dbus_read_local_machine_uuid (DBusGUID *machine_id, + dbus_bool_t create_if_not_found, + DBusError *error); + +/** + * Initialize threads as in dbus_threads_init_default(), appropriately + * for the platform. + * @returns #FALSE if no memory + */ +dbus_bool_t _dbus_threads_init_platform_specific (void); + +dbus_bool_t _dbus_split_paths_and_append (DBusString *dirs, + const char *suffix, + DBusList **dir_list); + +unsigned long _dbus_pid_for_log (void); + +/* FIXME move back to dbus-sysdeps-unix.h probably - + * the PID file handling just needs a little more abstraction + * in the bus daemon first. + */ +dbus_pid_t _dbus_getpid (void); + +dbus_bool_t _dbus_change_to_daemon_user (const char *user, + DBusError *error); + +void _dbus_flush_caches (void); + +/* + * replaces the term DBUS_PREFIX in configure_time_path by the + * current dbus installation directory. On unix this function is a noop + * + * @param configure_time_path + * @return real path + */ +const char * +_dbus_replace_install_prefix (const char *configure_time_path); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_SYSDEPS_H */ diff --git a/include/dbus-1/dbus/dbus-test.h b/include/dbus-1/dbus/dbus-test.h new file mode 100644 index 00000000..0238b0ce --- /dev/null +++ b/include/dbus-1/dbus/dbus-test.h @@ -0,0 +1,83 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-test.h Declarations of test functions. + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_TEST_H +#define DBUS_TEST_H + +#include <dbus/dbus-types.h> +#include <dbus/dbus-string.h> +#include <dbus/dbus-marshal-validate.h> + +dbus_bool_t _dbus_hash_test (void); +dbus_bool_t _dbus_dict_test (void); +dbus_bool_t _dbus_list_test (void); +dbus_bool_t _dbus_marshal_test (void); +dbus_bool_t _dbus_marshal_recursive_test (void); +dbus_bool_t _dbus_marshal_byteswap_test (void); +dbus_bool_t _dbus_marshal_header_test (void); +dbus_bool_t _dbus_marshal_validate_test (void); +dbus_bool_t _dbus_misc_test (void); +dbus_bool_t _dbus_signature_test (void); +dbus_bool_t _dbus_mem_pool_test (void); +dbus_bool_t _dbus_string_test (void); +dbus_bool_t _dbus_address_test (void); +dbus_bool_t _dbus_server_test (void); +dbus_bool_t _dbus_message_test (const char *test_data_dir); +dbus_bool_t _dbus_auth_test (const char *test_data_dir); +dbus_bool_t _dbus_md5_test (void); +dbus_bool_t _dbus_sha_test (const char *test_data_dir); +dbus_bool_t _dbus_keyring_test (void); +dbus_bool_t _dbus_data_slot_test (void); +dbus_bool_t _dbus_sysdeps_test (void); +dbus_bool_t _dbus_spawn_test (const char *test_data_dir); +dbus_bool_t _dbus_userdb_test (const char *test_data_dir); +dbus_bool_t _dbus_memory_test (void); +dbus_bool_t _dbus_object_tree_test (void); +dbus_bool_t _dbus_pending_call_test (const char *test_data_dir); +dbus_bool_t _dbus_credentials_test (const char *test_data_dir); + +void dbus_internal_do_not_use_run_tests (const char *test_data_dir, + const char *specific_test); +dbus_bool_t dbus_internal_do_not_use_try_message_file (const DBusString *filename, + DBusValidity expected_validity); +dbus_bool_t dbus_internal_do_not_use_try_message_data (const DBusString *data, + DBusValidity expected_validity); +dbus_bool_t dbus_internal_do_not_use_load_message_file (const DBusString *filename, + DBusString *data); + + +/* returns FALSE on fatal failure */ +typedef dbus_bool_t (* DBusForeachMessageFileFunc) (const DBusString *filename, + DBusValidity expected_validity, + void *data); + +dbus_bool_t dbus_internal_do_not_use_foreach_message_file (const char *test_data_dir, + DBusForeachMessageFileFunc func, + void *user_data); +dbus_bool_t dbus_internal_do_not_use_generate_bodies (int sequence, + int byte_order, + DBusString *signature, + DBusString *body); + + +#endif /* DBUS_TEST_H */ diff --git a/include/dbus-1/dbus/dbus-threads-internal.h b/include/dbus-1/dbus/dbus-threads-internal.h new file mode 100644 index 00000000..11f9ce20 --- /dev/null +++ b/include/dbus-1/dbus/dbus-threads-internal.h @@ -0,0 +1,53 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-threads-internal.h D-Bus thread primitives + * + * Copyright (C) 2002, 2005 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_THREADS_INTERNAL_H +#define DBUS_THREADS_INTERNAL_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-types.h> +#include <dbus/dbus-threads.h> + +DBUS_BEGIN_DECLS + +DBusMutex* _dbus_mutex_new (void); +void _dbus_mutex_free (DBusMutex *mutex); +void _dbus_mutex_lock (DBusMutex *mutex); +void _dbus_mutex_unlock (DBusMutex *mutex); +void _dbus_mutex_new_at_location (DBusMutex **location_p); +void _dbus_mutex_free_at_location (DBusMutex **location_p); + +DBusCondVar* _dbus_condvar_new (void); +void _dbus_condvar_free (DBusCondVar *cond); +void _dbus_condvar_wait (DBusCondVar *cond, + DBusMutex *mutex); +dbus_bool_t _dbus_condvar_wait_timeout (DBusCondVar *cond, + DBusMutex *mutex, + int timeout_milliseconds); +void _dbus_condvar_wake_one (DBusCondVar *cond); +void _dbus_condvar_wake_all (DBusCondVar *cond); +void _dbus_condvar_new_at_location (DBusCondVar **location_p); +void _dbus_condvar_free_at_location (DBusCondVar **location_p); + +DBUS_END_DECLS + +#endif /* DBUS_THREADS_INTERNAL_H */ diff --git a/include/dbus-1/dbus/dbus-threads.h b/include/dbus-1/dbus/dbus-threads.h new file mode 100644 index 00000000..ba07ca57 --- /dev/null +++ b/include/dbus-1/dbus/dbus-threads.h @@ -0,0 +1,198 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-threads.h D-Bus threads handling + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_THREADS_H +#define DBUS_THREADS_H + +#include <dbus/dbus-macros.h> +#include <dbus/dbus-types.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusThreads + * @{ + */ + +/** An opaque mutex type provided by the #DBusThreadFunctions implementation installed by dbus_threads_init(). */ +typedef struct DBusMutex DBusMutex; +/** An opaque condition variable type provided by the #DBusThreadFunctions implementation installed by dbus_threads_init(). */ +typedef struct DBusCondVar DBusCondVar; + +/** Deprecated, provide DBusRecursiveMutexNewFunction instead. */ +typedef DBusMutex* (* DBusMutexNewFunction) (void); +/** Deprecated, provide DBusRecursiveMutexFreeFunction instead. */ +typedef void (* DBusMutexFreeFunction) (DBusMutex *mutex); +/** Deprecated, provide DBusRecursiveMutexLockFunction instead. Return value is lock success, but gets ignored in practice. */ +typedef dbus_bool_t (* DBusMutexLockFunction) (DBusMutex *mutex); +/** Deprecated, provide DBusRecursiveMutexUnlockFunction instead. Return value is unlock success, but gets ignored in practice. */ +typedef dbus_bool_t (* DBusMutexUnlockFunction) (DBusMutex *mutex); + +/** Creates a new recursively-lockable mutex, or returns #NULL if not + * enough memory. Can only fail due to lack of memory. Found in + * #DBusThreadFunctions. Do not just use PTHREAD_MUTEX_RECURSIVE for + * this, because it does not save/restore the recursion count when + * waiting on a condition. libdbus requires the Java-style behavior + * where the mutex is fully unlocked to wait on a condition. + */ +typedef DBusMutex* (* DBusRecursiveMutexNewFunction) (void); +/** Frees a recursively-lockable mutex. Found in #DBusThreadFunctions. + */ +typedef void (* DBusRecursiveMutexFreeFunction) (DBusMutex *mutex); +/** Locks a recursively-lockable mutex. Found in #DBusThreadFunctions. + * Can only fail due to lack of memory. + */ +typedef void (* DBusRecursiveMutexLockFunction) (DBusMutex *mutex); +/** Unlocks a recursively-lockable mutex. Found in #DBusThreadFunctions. + * Can only fail due to lack of memory. + */ +typedef void (* DBusRecursiveMutexUnlockFunction) (DBusMutex *mutex); + +/** Creates a new condition variable. Found in #DBusThreadFunctions. + * Can only fail (returning #NULL) due to lack of memory. + */ +typedef DBusCondVar* (* DBusCondVarNewFunction) (void); +/** Frees a condition variable. Found in #DBusThreadFunctions. + */ +typedef void (* DBusCondVarFreeFunction) (DBusCondVar *cond); + +/** Waits on a condition variable. Found in + * #DBusThreadFunctions. Must work with either a recursive or + * nonrecursive mutex, whichever the thread implementation + * provides. Note that PTHREAD_MUTEX_RECURSIVE does not work with + * condition variables (does not save/restore the recursion count) so + * don't try using simply pthread_cond_wait() and a + * PTHREAD_MUTEX_RECURSIVE to implement this, it won't work right. + * + * Has no error conditions. Must succeed if it returns. + */ +typedef void (* DBusCondVarWaitFunction) (DBusCondVar *cond, + DBusMutex *mutex); + +/** Waits on a condition variable with a timeout. Found in + * #DBusThreadFunctions. Returns #TRUE if the wait did not + * time out, and #FALSE if it did. + * + * Has no error conditions. Must succeed if it returns. + */ +typedef dbus_bool_t (* DBusCondVarWaitTimeoutFunction) (DBusCondVar *cond, + DBusMutex *mutex, + int timeout_milliseconds); +/** Wakes one waiting thread on a condition variable. Found in #DBusThreadFunctions. + * + * Has no error conditions. Must succeed if it returns. + */ +typedef void (* DBusCondVarWakeOneFunction) (DBusCondVar *cond); + +/** Wakes all waiting threads on a condition variable. Found in #DBusThreadFunctions. + * + * Has no error conditions. Must succeed if it returns. + */ +typedef void (* DBusCondVarWakeAllFunction) (DBusCondVar *cond); + +/** + * Flags indicating which functions are present in #DBusThreadFunctions. Used to allow + * the library to detect older callers of dbus_threads_init() if new possible functions + * are added to #DBusThreadFunctions. + */ +typedef enum +{ + DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK = 1 << 0, + DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK = 1 << 1, + DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK = 1 << 2, + DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK = 1 << 3, + DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK = 1 << 4, + DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK = 1 << 5, + DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK = 1 << 6, + DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK = 1 << 7, + DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK = 1 << 8, + DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK = 1 << 9, + DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK = 1 << 10, + DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK = 1 << 11, + DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK = 1 << 12, + DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK = 1 << 13, + DBUS_THREAD_FUNCTIONS_ALL_MASK = (1 << 14) - 1 +} DBusThreadFunctionsMask; + +/** + * Functions that must be implemented to make the D-Bus library + * thread-aware. The recursive mutex functions should be specified + * rather than the old, deprecated nonrecursive ones. + * + * The condition variable functions have to work with recursive + * mutexes if you provide those, or with nonrecursive mutexes if you + * provide those. + * + * If implementing threads using pthreads, be aware that + * PTHREAD_MUTEX_RECURSIVE is broken in combination with condition + * variables. libdbus relies on the Java-style behavior that when + * waiting on a condition, the recursion count is saved and restored, + * and the mutex is completely unlocked, not just decremented one + * level of recursion. + * + * Thus with pthreads you probably have to roll your own emulated + * recursive mutexes, you can't use PTHREAD_MUTEX_RECURSIVE. This is + * what dbus_threads_init_default() does on platforms that use + * pthreads. + */ +typedef struct +{ + unsigned int mask; /**< Mask indicating which functions are present. */ + + DBusMutexNewFunction mutex_new; /**< Function to create a mutex; optional and deprecated. */ + DBusMutexFreeFunction mutex_free; /**< Function to free a mutex; optional and deprecated. */ + DBusMutexLockFunction mutex_lock; /**< Function to lock a mutex; optional and deprecated. */ + DBusMutexUnlockFunction mutex_unlock; /**< Function to unlock a mutex; optional and deprecated. */ + + DBusCondVarNewFunction condvar_new; /**< Function to create a condition variable */ + DBusCondVarFreeFunction condvar_free; /**< Function to free a condition variable */ + DBusCondVarWaitFunction condvar_wait; /**< Function to wait on a condition */ + DBusCondVarWaitTimeoutFunction condvar_wait_timeout; /**< Function to wait on a condition with a timeout */ + DBusCondVarWakeOneFunction condvar_wake_one; /**< Function to wake one thread waiting on the condition */ + DBusCondVarWakeAllFunction condvar_wake_all; /**< Function to wake all threads waiting on the condition */ + + DBusRecursiveMutexNewFunction recursive_mutex_new; /**< Function to create a recursive mutex */ + DBusRecursiveMutexFreeFunction recursive_mutex_free; /**< Function to free a recursive mutex */ + DBusRecursiveMutexLockFunction recursive_mutex_lock; /**< Function to lock a recursive mutex */ + DBusRecursiveMutexUnlockFunction recursive_mutex_unlock; /**< Function to unlock a recursive mutex */ + + void (* padding1) (void); /**< Reserved for future expansion */ + void (* padding2) (void); /**< Reserved for future expansion */ + void (* padding3) (void); /**< Reserved for future expansion */ + void (* padding4) (void); /**< Reserved for future expansion */ + +} DBusThreadFunctions; + +DBUS_EXPORT +dbus_bool_t dbus_threads_init (const DBusThreadFunctions *functions); +DBUS_EXPORT +dbus_bool_t dbus_threads_init_default (void); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_THREADS_H */ diff --git a/include/dbus-1/dbus/dbus-timeout.h b/include/dbus-1/dbus/dbus-timeout.h new file mode 100644 index 00000000..d0a8af4a --- /dev/null +++ b/include/dbus-1/dbus/dbus-timeout.h @@ -0,0 +1,75 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-timeout.h DBusTimeout internal interfaces + * + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_TIMEOUT_H +#define DBUS_TIMEOUT_H + +#include <dbus/dbus-connection.h> +#include <dbus/dbus-internals.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusTimeoutInternals + * @{ + */ + +/* Public methods on DBusTimeout are in dbus-connection.h */ + +typedef struct DBusTimeoutList DBusTimeoutList; + +/** function to run when the timeout is handled */ +typedef dbus_bool_t (* DBusTimeoutHandler) (void *data); + +DBusTimeout* _dbus_timeout_new (int interval, + DBusTimeoutHandler handler, + void *data, + DBusFreeFunction free_data_function); +DBusTimeout* _dbus_timeout_ref (DBusTimeout *timeout); +void _dbus_timeout_unref (DBusTimeout *timeout); +void _dbus_timeout_set_interval (DBusTimeout *timeout, + int interval); +void _dbus_timeout_set_enabled (DBusTimeout *timeout, + dbus_bool_t enabled); + +DBusTimeoutList *_dbus_timeout_list_new (void); +void _dbus_timeout_list_free (DBusTimeoutList *timeout_list); +dbus_bool_t _dbus_timeout_list_set_functions (DBusTimeoutList *timeout_list, + DBusAddTimeoutFunction add_function, + DBusRemoveTimeoutFunction remove_function, + DBusTimeoutToggledFunction toggled_function, + void *data, + DBusFreeFunction free_data_function); +dbus_bool_t _dbus_timeout_list_add_timeout (DBusTimeoutList *timeout_list, + DBusTimeout *timeout); +void _dbus_timeout_list_remove_timeout (DBusTimeoutList *timeout_list, + DBusTimeout *timeout); +void _dbus_timeout_list_toggle_timeout (DBusTimeoutList *timeout_list, + DBusTimeout *timeout, + dbus_bool_t enabled); + + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_TIMEOUT_H */ diff --git a/include/dbus-1/dbus/dbus-transport-protected.h b/include/dbus-1/dbus/dbus-transport-protected.h new file mode 100644 index 00000000..44b9d785 --- /dev/null +++ b/include/dbus-1/dbus/dbus-transport-protected.h @@ -0,0 +1,146 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-transport-protected.h Used by subclasses of DBusTransport object (internal to D-Bus implementation) + * + * Copyright (C) 2002, 2004 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_TRANSPORT_PROTECTED_H +#define DBUS_TRANSPORT_PROTECTED_H + +#include <dbus/dbus-internals.h> +#include <dbus/dbus-errors.h> +#include <dbus/dbus-transport.h> +#include <dbus/dbus-message-internal.h> +#include <dbus/dbus-auth.h> +#include <dbus/dbus-resources.h> + +DBUS_BEGIN_DECLS + +typedef struct DBusTransportVTable DBusTransportVTable; + +/** + * The virtual table that must be implemented to + * create a new kind of transport. + */ +struct DBusTransportVTable +{ + void (* finalize) (DBusTransport *transport); + /**< The finalize method must free the transport. */ + + dbus_bool_t (* handle_watch) (DBusTransport *transport, + DBusWatch *watch, + unsigned int flags); + /**< The handle_watch method handles reading/writing + * data as indicated by the flags. + */ + + void (* disconnect) (DBusTransport *transport); + /**< Disconnect this transport. */ + + dbus_bool_t (* connection_set) (DBusTransport *transport); + /**< Called when transport->connection has been filled in */ + + void (* do_iteration) (DBusTransport *transport, + unsigned int flags, + int timeout_milliseconds); + /**< Called to do a single "iteration" (block on select/poll + * followed by reading or writing data). + */ + + void (* live_messages_changed) (DBusTransport *transport); + /**< Outstanding messages counter changed */ + + dbus_bool_t (* get_socket_fd) (DBusTransport *transport, + int *fd_p); + /**< Get socket file descriptor */ +}; + +/** + * Object representing a transport such as a socket. + * A transport can shuttle messages from point A to point B, + * and is the backend for a #DBusConnection. + * + */ +struct DBusTransport +{ + int refcount; /**< Reference count. */ + + const DBusTransportVTable *vtable; /**< Virtual methods for this instance. */ + + DBusConnection *connection; /**< Connection owning this transport. */ + + DBusMessageLoader *loader; /**< Message-loading buffer. */ + + DBusAuth *auth; /**< Authentication conversation */ + + DBusCredentials *credentials; /**< Credentials of other end read from the socket */ + + long max_live_messages_size; /**< Max total size of received messages. */ + long max_live_messages_unix_fds; /**< Max total unix fds of received messages. */ + + DBusCounter *live_messages; /**< Counter for size/unix fds of all live messages. */ + + char *address; /**< Address of the server we are connecting to (#NULL for the server side of a transport) */ + + char *expected_guid; /**< GUID we expect the server to have, #NULL on server side or if we don't have an expectation */ + + DBusAllowUnixUserFunction unix_user_function; /**< Function for checking whether a user is authorized. */ + void *unix_user_data; /**< Data for unix_user_function */ + + DBusFreeFunction free_unix_user_data; /**< Function to free unix_user_data */ + + DBusAllowWindowsUserFunction windows_user_function; /**< Function for checking whether a user is authorized. */ + void *windows_user_data; /**< Data for windows_user_function */ + + DBusFreeFunction free_windows_user_data; /**< Function to free windows_user_data */ + + unsigned int disconnected : 1; /**< #TRUE if we are disconnected. */ + unsigned int authenticated : 1; /**< Cache of auth state; use _dbus_transport_get_is_authenticated() to query value */ + unsigned int send_credentials_pending : 1; /**< #TRUE if we need to send credentials */ + unsigned int receive_credentials_pending : 1; /**< #TRUE if we need to receive credentials */ + unsigned int is_server : 1; /**< #TRUE if on the server side */ + unsigned int unused_bytes_recovered : 1; /**< #TRUE if we've recovered unused bytes from auth */ + unsigned int allow_anonymous : 1; /**< #TRUE if an anonymous client can connect */ +}; + +dbus_bool_t _dbus_transport_init_base (DBusTransport *transport, + const DBusTransportVTable *vtable, + const DBusString *server_guid, + const DBusString *address); +void _dbus_transport_finalize_base (DBusTransport *transport); + + +typedef enum +{ + DBUS_TRANSPORT_OPEN_NOT_HANDLED, /**< we aren't in charge of this address type */ + DBUS_TRANSPORT_OPEN_OK, /**< we set up the listen */ + DBUS_TRANSPORT_OPEN_BAD_ADDRESS, /**< malformed address */ + DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT /**< well-formed address but failed to set it up */ +} DBusTransportOpenResult; + +DBusTransportOpenResult _dbus_transport_open_platform_specific (DBusAddressEntry *entry, + DBusTransport **transport_p, + DBusError *error); + +#define DBUS_TRANSPORT_CAN_SEND_UNIX_FD(x) \ + _dbus_auth_get_unix_fd_negotiated((x)->auth) + +DBUS_END_DECLS + +#endif /* DBUS_TRANSPORT_PROTECTED_H */ diff --git a/include/dbus-1/dbus/dbus-transport-socket.h b/include/dbus-1/dbus/dbus-transport-socket.h new file mode 100644 index 00000000..8aefae37 --- /dev/null +++ b/include/dbus-1/dbus/dbus-transport-socket.h @@ -0,0 +1,46 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-transport-socket.h Socket subclasses of DBusTransport + * + * Copyright (C) 2002, 2006 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_TRANSPORT_SOCKET_H +#define DBUS_TRANSPORT_SOCKET_H + +#include <dbus/dbus-transport-protected.h> + +DBUS_BEGIN_DECLS + +DBusTransport* _dbus_transport_new_for_socket (int fd, + const DBusString *server_guid, + const DBusString *address); +DBusTransport* _dbus_transport_new_for_tcp_socket (const char *host, + const char *port, + const char *family, + const char *noncefile, + DBusError *error); +DBusTransportOpenResult _dbus_transport_open_socket (DBusAddressEntry *entry, + DBusTransport **transport_p, + DBusError *error); + + + +DBUS_END_DECLS + +#endif /* DBUS_TRANSPORT_SOCKET_H */ diff --git a/include/dbus-1/dbus/dbus-transport-unix.h b/include/dbus-1/dbus/dbus-transport-unix.h new file mode 100644 index 00000000..783a8313 --- /dev/null +++ b/include/dbus-1/dbus/dbus-transport-unix.h @@ -0,0 +1,37 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-transport-unix.h UNIX socket subclasses of DBusTransport + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_TRANSPORT_UNIX_H +#define DBUS_TRANSPORT_UNIX_H + +#include <dbus/dbus-transport.h> + +DBUS_BEGIN_DECLS + +DBusTransport* _dbus_transport_new_for_domain_socket (const char *path, + dbus_bool_t abstract, + DBusError *error); + + +DBUS_END_DECLS + +#endif /* DBUS_TRANSPORT_UNIX_H */ diff --git a/include/dbus-1/dbus/dbus-transport-win.h b/include/dbus-1/dbus/dbus-transport-win.h new file mode 100644 index 00000000..af997a27 --- /dev/null +++ b/include/dbus-1/dbus/dbus-transport-win.h @@ -0,0 +1,33 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-transport-win.h Windows socket subclasses of DBusTransport + * + * Copyright (C) 2002 Red Hat Inc. + * Copyright (C) 2007 Ralf Habacker <ralf.habacker@freenet.de> + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_TRANSPORT_WIN_H +#define DBUS_TRANSPORT_WIN_H + +#include <dbus/dbus-transport.h> + +DBUS_BEGIN_DECLS + +DBUS_END_DECLS + +#endif /* DBUS_TRANSPORT_WIN_H */ diff --git a/include/dbus-1/dbus/dbus-transport.h b/include/dbus-1/dbus/dbus-transport.h new file mode 100644 index 00000000..0db048a2 --- /dev/null +++ b/include/dbus-1/dbus/dbus-transport.h @@ -0,0 +1,103 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-transport.h DBusTransport object (internal to D-BUS implementation) + * + * Copyright (C) 2002, 2004 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_TRANSPORT_H +#define DBUS_TRANSPORT_H + +#include <dbus/dbus-internals.h> +#include <dbus/dbus-connection.h> +#include <dbus/dbus-protocol.h> +#include <dbus/dbus-address.h> + +DBUS_BEGIN_DECLS + +typedef struct DBusTransport DBusTransport; + +DBusTransport* _dbus_transport_open (DBusAddressEntry *entry, + DBusError *error); +DBusTransport* _dbus_transport_ref (DBusTransport *transport); +void _dbus_transport_unref (DBusTransport *transport); +void _dbus_transport_disconnect (DBusTransport *transport); +dbus_bool_t _dbus_transport_get_is_connected (DBusTransport *transport); +dbus_bool_t _dbus_transport_get_is_authenticated (DBusTransport *transport); +dbus_bool_t _dbus_transport_get_is_anonymous (DBusTransport *transport); +dbus_bool_t _dbus_transport_can_pass_unix_fd (DBusTransport *transport); + +const char* _dbus_transport_get_address (DBusTransport *transport); +const char* _dbus_transport_get_server_id (DBusTransport *transport); +dbus_bool_t _dbus_transport_handle_watch (DBusTransport *transport, + DBusWatch *watch, + unsigned int condition); +dbus_bool_t _dbus_transport_set_connection (DBusTransport *transport, + DBusConnection *connection); +void _dbus_transport_do_iteration (DBusTransport *transport, + unsigned int flags, + int timeout_milliseconds); +DBusDispatchStatus _dbus_transport_get_dispatch_status (DBusTransport *transport); +dbus_bool_t _dbus_transport_queue_messages (DBusTransport *transport); + +void _dbus_transport_set_max_message_size (DBusTransport *transport, + long size); +long _dbus_transport_get_max_message_size (DBusTransport *transport); +void _dbus_transport_set_max_received_size (DBusTransport *transport, + long size); +long _dbus_transport_get_max_received_size (DBusTransport *transport); + +void _dbus_transport_set_max_message_unix_fds (DBusTransport *transport, + long n); +long _dbus_transport_get_max_message_unix_fds (DBusTransport *transport); +void _dbus_transport_set_max_received_unix_fds(DBusTransport *transport, + long n); +long _dbus_transport_get_max_received_unix_fds(DBusTransport *transport); + +dbus_bool_t _dbus_transport_get_socket_fd (DBusTransport *transport, + int *fd_p); +dbus_bool_t _dbus_transport_get_unix_user (DBusTransport *transport, + unsigned long *uid); +dbus_bool_t _dbus_transport_get_unix_process_id (DBusTransport *transport, + unsigned long *pid); +dbus_bool_t _dbus_transport_get_adt_audit_session_data (DBusTransport *transport, + void **data, + int *data_size); +void _dbus_transport_set_unix_user_function (DBusTransport *transport, + DBusAllowUnixUserFunction function, + void *data, + DBusFreeFunction free_data_function, + void **old_data, + DBusFreeFunction *old_free_data_function); +dbus_bool_t _dbus_transport_get_windows_user (DBusTransport *transport, + char **windows_sid_p); +void _dbus_transport_set_windows_user_function (DBusTransport *transport, + DBusAllowWindowsUserFunction function, + void *data, + DBusFreeFunction free_data_function, + void **old_data, + DBusFreeFunction *old_free_data_function); +dbus_bool_t _dbus_transport_set_auth_mechanisms (DBusTransport *transport, + const char **mechanisms); +void _dbus_transport_set_allow_anonymous (DBusTransport *transport, + dbus_bool_t value); + + +DBUS_END_DECLS + +#endif /* DBUS_TRANSPORT_H */ diff --git a/include/dbus-1/dbus/dbus-types.h b/include/dbus-1/dbus/dbus-types.h new file mode 100644 index 00000000..54f348f3 --- /dev/null +++ b/include/dbus-1/dbus/dbus-types.h @@ -0,0 +1,139 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-types.h types such as dbus_bool_t + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_TYPES_H +#define DBUS_TYPES_H + +#include <stddef.h> +#include <dbus/dbus-arch-deps.h> + +typedef dbus_uint32_t dbus_unichar_t; +/* boolean size must be fixed at 4 bytes due to wire protocol! */ +typedef dbus_uint32_t dbus_bool_t; + +/* Normally docs are in .c files, but there isn't a .c file for this. */ +/** + * @defgroup DBusTypes Basic types + * @ingroup DBus + * @brief dbus_bool_t, dbus_int32_t, etc. + * + * Typedefs for common primitive types. + * + * @{ + */ + +/** + * @typedef dbus_bool_t + * + * A boolean, valid values are #TRUE and #FALSE. + */ + +/** + * @typedef dbus_uint32_t + * + * A 32-bit unsigned integer on all platforms. + */ + +/** + * @typedef dbus_int32_t + * + * A 32-bit signed integer on all platforms. + */ + +/** + * @typedef dbus_uint16_t + * + * A 16-bit unsigned integer on all platforms. + */ + +/** + * @typedef dbus_int16_t + * + * A 16-bit signed integer on all platforms. + */ + + +/** + * @typedef dbus_uint64_t + * + * A 64-bit unsigned integer on all platforms that support it. + * If supported, #DBUS_HAVE_INT64 will be defined. + * + * C99 requires a 64-bit type and most likely all interesting + * compilers support one. GLib for example flat-out requires + * a 64-bit type. + * + * You probably want to just assume #DBUS_HAVE_INT64 is always defined. + */ + +/** + * @typedef dbus_int64_t + * + * A 64-bit signed integer on all platforms that support it. + * If supported, #DBUS_HAVE_INT64 will be defined. + * + * C99 requires a 64-bit type and most likely all interesting + * compilers support one. GLib for example flat-out requires + * a 64-bit type. + * + * You probably want to just assume #DBUS_HAVE_INT64 is always defined. + */ + +/** + * @def DBUS_HAVE_INT64 + * + * Defined if 64-bit integers are available. Will be defined + * on any platform you care about, unless you care about + * some truly ancient UNIX, or some bizarre embedded platform. + * + * C99 requires a 64-bit type and most likely all interesting + * compilers support one. GLib for example flat-out requires + * a 64-bit type. + * + * You should feel comfortable ignoring this macro and just using + * int64 unconditionally. + * + */ + +/** + * @def DBUS_INT64_CONSTANT + * + * Declare a 64-bit signed integer constant. The macro + * adds the necessary "LL" or whatever after the integer, + * giving a literal such as "325145246765LL" + */ + +/** + * @def DBUS_UINT64_CONSTANT + * + * Declare a 64-bit unsigned integer constant. The macro + * adds the necessary "ULL" or whatever after the integer, + * giving a literal such as "325145246765ULL" + */ + +/** @} */ + +#endif /* DBUS_TYPES_H */ diff --git a/include/dbus-1/dbus/dbus-userdb.h b/include/dbus-1/dbus/dbus-userdb.h new file mode 100644 index 00000000..cb49d9e7 --- /dev/null +++ b/include/dbus-1/dbus/dbus-userdb.h @@ -0,0 +1,121 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-userdb.h User database abstraction + * + * Copyright (C) 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_USERDB_H +#define DBUS_USERDB_H + +#include <dbus/dbus-sysdeps-unix.h> + +#ifdef DBUS_WIN +#error "Don't include this on Windows" +#endif + +DBUS_BEGIN_DECLS + +typedef struct DBusUserDatabase DBusUserDatabase; + +#ifdef DBUS_USERDB_INCLUDES_PRIVATE +#include <dbus/dbus-hash.h> + +/** + * Internals of DBusUserDatabase + */ +struct DBusUserDatabase +{ + int refcount; /**< Reference count */ + + DBusHashTable *users; /**< Users in the database by UID */ + DBusHashTable *groups; /**< Groups in the database by GID */ + DBusHashTable *users_by_name; /**< Users in the database by name */ + DBusHashTable *groups_by_name; /**< Groups in the database by name */ + +}; + + +DBusUserDatabase* _dbus_user_database_new (void); +DBusUserDatabase* _dbus_user_database_ref (DBusUserDatabase *db); +void _dbus_user_database_flush (DBusUserDatabase *db); +void _dbus_user_database_unref (DBusUserDatabase *db); +dbus_bool_t _dbus_user_database_get_uid (DBusUserDatabase *db, + dbus_uid_t uid, + const DBusUserInfo **info, + DBusError *error); +dbus_bool_t _dbus_user_database_get_gid (DBusUserDatabase *db, + dbus_gid_t gid, + const DBusGroupInfo **info, + DBusError *error); +dbus_bool_t _dbus_user_database_get_username (DBusUserDatabase *db, + const DBusString *username, + const DBusUserInfo **info, + DBusError *error); +dbus_bool_t _dbus_user_database_get_groupname (DBusUserDatabase *db, + const DBusString *groupname, + const DBusGroupInfo **info, + DBusError *error); + +DBusUserInfo* _dbus_user_database_lookup (DBusUserDatabase *db, + dbus_uid_t uid, + const DBusString *username, + DBusError *error); +DBusGroupInfo* _dbus_user_database_lookup_group (DBusUserDatabase *db, + dbus_gid_t gid, + const DBusString *groupname, + DBusError *error); +void _dbus_user_info_free_allocated (DBusUserInfo *info); +void _dbus_group_info_free_allocated (DBusGroupInfo *info); +#endif /* DBUS_USERDB_INCLUDES_PRIVATE */ + +DBusUserDatabase* _dbus_user_database_get_system (void); +void _dbus_user_database_lock_system (void); +void _dbus_user_database_unlock_system (void); +void _dbus_user_database_flush_system (void); + +dbus_bool_t _dbus_get_user_id (const DBusString *username, + dbus_uid_t *uid); +dbus_bool_t _dbus_get_group_id (const DBusString *group_name, + dbus_gid_t *gid); +dbus_bool_t _dbus_get_user_id_and_primary_group (const DBusString *username, + dbus_uid_t *uid_p, + dbus_gid_t *gid_p); +dbus_bool_t _dbus_credentials_from_uid (dbus_uid_t user_id, + DBusCredentials *credentials); +dbus_bool_t _dbus_groups_from_uid (dbus_uid_t uid, + dbus_gid_t **group_ids, + int *n_group_ids); +dbus_bool_t _dbus_is_console_user (dbus_uid_t uid, + DBusError *error); + +dbus_bool_t _dbus_is_a_number (const DBusString *str, + unsigned long *num); + +dbus_bool_t _dbus_username_from_current_process (const DBusString **username); +dbus_bool_t _dbus_homedir_from_current_process (const DBusString **homedir); +dbus_bool_t _dbus_homedir_from_username (const DBusString *username, + DBusString *homedir); + +dbus_bool_t _dbus_homedir_from_uid (dbus_uid_t uid, + DBusString *homedir); + +DBUS_END_DECLS + +#endif /* DBUS_USERDB_H */ diff --git a/include/dbus-1/dbus/dbus-uuidgen.h b/include/dbus-1/dbus/dbus-uuidgen.h new file mode 100644 index 00000000..9c1b8595 --- /dev/null +++ b/include/dbus-1/dbus/dbus-uuidgen.h @@ -0,0 +1,47 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-uuidgen.h The guts of the dbus-uuidgen binary live in libdbus, in this file. + * + * Copyright (C) 2006 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifdef DBUS_INSIDE_DBUS_H +#error "You can't include dbus-uuidgen.h in the public header dbus.h" +#endif + +#ifndef DBUS_UUIDGEN_H +#define DBUS_UUIDGEN_H + +#include <dbus/dbus-types.h> +#include <dbus/dbus-errors.h> + +DBUS_BEGIN_DECLS + +dbus_bool_t dbus_internal_do_not_use_get_uuid (const char *filename, + char **uuid_p, + dbus_bool_t create_if_not_found, + DBusError *error); +dbus_bool_t dbus_internal_do_not_use_ensure_uuid (const char *filename, + char **uuid_p, + DBusError *error); +dbus_bool_t dbus_internal_do_not_use_create_uuid (char **uuid_p); + + +DBUS_END_DECLS + +#endif /* DBUS_UUIDGEN_H */ diff --git a/include/dbus-1/dbus/dbus-watch.h b/include/dbus-1/dbus/dbus-watch.h new file mode 100644 index 00000000..fa953ec1 --- /dev/null +++ b/include/dbus-1/dbus/dbus-watch.h @@ -0,0 +1,83 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-watch.h DBusWatch internal interfaces + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef DBUS_WATCH_H +#define DBUS_WATCH_H + +#include <dbus/dbus-internals.h> +#include <dbus/dbus-connection.h> + +DBUS_BEGIN_DECLS + +/** + * @addtogroup DBusWatchInternals + * @{ + */ + +/* Public methods on DBusWatch are in dbus-connection.h */ + +typedef struct DBusWatchList DBusWatchList; + +/** function to run when the watch is handled */ +typedef dbus_bool_t (* DBusWatchHandler) (DBusWatch *watch, + unsigned int flags, + void *data); + +DBusWatch* _dbus_watch_new (int fd, + unsigned int flags, + dbus_bool_t enabled, + DBusWatchHandler handler, + void *data, + DBusFreeFunction free_data_function); +DBusWatch* _dbus_watch_ref (DBusWatch *watch); +void _dbus_watch_unref (DBusWatch *watch); +void _dbus_watch_invalidate (DBusWatch *watch); +void _dbus_watch_sanitize_condition (DBusWatch *watch, + unsigned int *condition); +void _dbus_watch_set_handler (DBusWatch *watch, + DBusWatchHandler handler, + void *data, + DBusFreeFunction free_data_function); + + +DBusWatchList* _dbus_watch_list_new (void); +void _dbus_watch_list_free (DBusWatchList *watch_list); +dbus_bool_t _dbus_watch_list_set_functions (DBusWatchList *watch_list, + DBusAddWatchFunction add_function, + DBusRemoveWatchFunction remove_function, + DBusWatchToggledFunction toggled_function, + void *data, + DBusFreeFunction free_data_function); +dbus_bool_t _dbus_watch_list_add_watch (DBusWatchList *watch_list, + DBusWatch *watch); +void _dbus_watch_list_remove_watch (DBusWatchList *watch_list, + DBusWatch *watch); +void _dbus_watch_list_toggle_watch (DBusWatchList *watch_list, + DBusWatch *watch, + dbus_bool_t enabled); +dbus_bool_t _dbus_watch_get_enabled (DBusWatch *watch); + +/** @} */ + +DBUS_END_DECLS + +#endif /* DBUS_WATCH_H */ diff --git a/include/dbus-1/dbus/dbus.h b/include/dbus-1/dbus/dbus.h new file mode 100644 index 00000000..1f099508 --- /dev/null +++ b/include/dbus-1/dbus/dbus.h @@ -0,0 +1,103 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus.h Convenience header including all other headers + * + * Copyright (C) 2002, 2003 Red Hat Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_H +#define DBUS_H + +#define DBUS_INSIDE_DBUS_H 1 + +#include <dbus/dbus-arch-deps.h> +#include <dbus/dbus-address.h> +#include <dbus/dbus-bus.h> +#include <dbus/dbus-connection.h> +#include <dbus/dbus-errors.h> +#include <dbus/dbus-macros.h> +#include <dbus/dbus-message.h> +#include <dbus/dbus-misc.h> +#include <dbus/dbus-pending-call.h> +#include <dbus/dbus-protocol.h> +#include <dbus/dbus-server.h> +#include <dbus/dbus-shared.h> +#include <dbus/dbus-signature.h> +#include <dbus/dbus-threads.h> +#include <dbus/dbus-types.h> + +#undef DBUS_INSIDE_DBUS_H + +/** + * @defgroup DBus D-Bus low-level public API + * @brief The low-level public API of the D-Bus library + * + * libdbus provides a low-level C API intended primarily for use by + * bindings to specific object systems and languages. D-Bus is most + * convenient when used with the GLib bindings, Python bindings, Qt + * bindings, Mono bindings, and so forth. This low-level API has a + * lot of complexity useful only for bindings. + * + * @{ + */ + +/** @} */ + +/** + * @mainpage + * + * This manual documents the <em>low-level</em> D-Bus C API. <b>If you use + * this low-level API directly, you're signing up for some pain.</b> + * + * Caveats aside, you might get started learning the low-level API by reading + * about @ref DBusConnection and @ref DBusMessage. + * + * There are several other places to look for D-Bus information, such + * as the tutorial and the specification; those can be found at <a + * href="http://www.freedesktop.org/wiki/Software/dbus">the D-Bus + * website</a>. If you're interested in a sysadmin or package + * maintainer's perspective on the dbus-daemon itself and its + * configuration, be sure to check out the man pages as well. + * + * The low-level API documented in this manual deliberately lacks + * most convenience functions - those are left up to higher-level libraries + * based on frameworks such as GLib, Qt, Python, Mono, Java, + * etc. These higher-level libraries (often called "D-Bus bindings") + * have features such as object systems and main loops that allow a + * <em>much</em> more convenient API. + * + * The low-level API also contains plenty of clutter to support + * integration with arbitrary object systems, languages, main loops, + * and so forth. These features add a lot of noise to the API that you + * probably don't care about unless you're coding a binding. + * + * This manual also contains docs for @ref DBusInternals "D-Bus internals", + * so you can use it to get oriented to the D-Bus source code if you're + * interested in patching the code. You should also read the + * file HACKING which comes with the source code if you plan to contribute to + * D-Bus. + * + * As you read the code, you can identify internal D-Bus functions + * because they start with an underscore ('_') character. Also, any + * identifier or macro that lacks a DBus, dbus_, or DBUS_ namepace + * prefix is internal, with a couple of exceptions such as #NULL, + * #TRUE, and #FALSE. + */ + +#endif /* DBUS_H */ diff --git a/include/dbus-1/dbus/sd-daemon.h b/include/dbus-1/dbus/sd-daemon.h new file mode 100644 index 00000000..c68c96d2 --- /dev/null +++ b/include/dbus-1/dbus/sd-daemon.h @@ -0,0 +1,257 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosddaemonhfoo +#define foosddaemonhfoo + +/*** + Copyright 2010 Lennart Poettering + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ + +#include <sys/types.h> +#include <inttypes.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + Reference implementation of a few systemd related interfaces for + writing daemons. These interfaces are trivial to implement. To + simplify porting we provide this reference implementation. + Applications are welcome to reimplement the algorithms described + here if they do not want to include these two source files. + + The following functionality is provided: + + - Support for logging with log levels on stderr + - File descriptor passing for socket-based activation + - Daemon startup and status notification + - Detection of systemd boots + + You may compile this with -DDISABLE_SYSTEMD to disable systemd + support. This makes all those calls NOPs that are directly related to + systemd (i.e. only sd_is_xxx() will stay useful). + + Since this is drop-in code we don't want any of our symbols to be + exported in any case. Hence we declare hidden visibility for all of + them. + + You may find an up-to-date version of these source files online: + + http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.h + http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c + + This should compile on non-Linux systems, too, but with the + exception of the sd_is_xxx() calls all functions will become NOPs. + + See sd-daemon(7) for more information. +*/ + +#if __GNUC__ >= 4 +#define _sd_printf_attr_(a,b) __attribute__ ((format (printf, a, b))) +#define _sd_hidden_ __attribute__ ((visibility("hidden"))) +#else +#define _sd_printf_attr_(a,b) +#define _sd_hidden_ +#endif + +/* + Log levels for usage on stderr: + + fprintf(stderr, SD_NOTICE "Hello World!\n"); + + This is similar to printk() usage in the kernel. +*/ +#define SD_EMERG "<0>" /* system is unusable */ +#define SD_ALERT "<1>" /* action must be taken immediately */ +#define SD_CRIT "<2>" /* critical conditions */ +#define SD_ERR "<3>" /* error conditions */ +#define SD_WARNING "<4>" /* warning conditions */ +#define SD_NOTICE "<5>" /* normal but significant condition */ +#define SD_INFO "<6>" /* informational */ +#define SD_DEBUG "<7>" /* debug-level messages */ + +/* The first passed file descriptor is fd 3 */ +#define SD_LISTEN_FDS_START 3 + +/* + Returns how many file descriptors have been passed, or a negative + errno code on failure. Optionally, removes the $LISTEN_FDS and + $LISTEN_PID file descriptors from the environment (recommended, but + problematic in threaded environments). If r is the return value of + this function you'll find the file descriptors passed as fds + SD_LISTEN_FDS_START to SD_LISTEN_FDS_START+r-1. Returns a negative + errno style error code on failure. This function call ensures that + the FD_CLOEXEC flag is set for the passed file descriptors, to make + sure they are not passed on to child processes. If FD_CLOEXEC shall + not be set, the caller needs to unset it after this call for all file + descriptors that are used. + + See sd_listen_fds(3) for more information. +*/ +int sd_listen_fds(int unset_environment) _sd_hidden_; + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is a FIFO in the file system stored under the + specified path, 0 otherwise. If path is NULL a path name check will + not be done and the call only verifies if the file descriptor + refers to a FIFO. Returns a negative errno style error code on + failure. + + See sd_is_fifo(3) for more information. +*/ +int sd_is_fifo(int fd, const char *path) _sd_hidden_; + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is a socket of the specified family (AF_INET, + ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If + family is 0 a socket family check will not be done. If type is 0 a + socket type check will not be done and the call only verifies if + the file descriptor refers to a socket. If listening is > 0 it is + verified that the socket is in listening mode. (i.e. listen() has + been called) If listening is == 0 it is verified that the socket is + not in listening mode. If listening is < 0 no listening mode check + is done. Returns a negative errno style error code on failure. + + See sd_is_socket(3) for more information. +*/ +int sd_is_socket(int fd, int family, int type, int listening) _sd_hidden_; + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is an Internet socket, of the specified family + (either AF_INET or AF_INET6) and the specified type (SOCK_DGRAM, + SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version + check is not done. If type is 0 a socket type check will not be + done. If port is 0 a socket port check will not be done. The + listening flag is used the same way as in sd_is_socket(). Returns a + negative errno style error code on failure. + + See sd_is_socket_inet(3) for more information. +*/ +int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) _sd_hidden_; + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is an AF_UNIX socket of the specified type + (SOCK_DGRAM, SOCK_STREAM, ...) and path, 0 otherwise. If type is 0 + a socket type check will not be done. If path is NULL a socket path + check will not be done. For normal AF_UNIX sockets set length to + 0. For abstract namespace sockets set length to the length of the + socket name (including the initial 0 byte), and pass the full + socket path in path (including the initial 0 byte). The listening + flag is used the same way as in sd_is_socket(). Returns a negative + errno style error code on failure. + + See sd_is_socket_unix(3) for more information. +*/ +int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) _sd_hidden_; + +/* + Informs systemd about changed daemon state. This takes a number of + newline seperated environment-style variable assignments in a + string. The following variables are known: + + READY=1 Tells systemd that daemon startup is finished (only + relevant for services of Type=notify). The passed + argument is a boolean "1" or "0". Since there is + little value in signalling non-readiness the only + value daemons should send is "READY=1". + + STATUS=... Passes a single-line status string back to systemd + that describes the daemon state. This is free-from + and can be used for various purposes: general state + feedback, fsck-like programs could pass completion + percentages and failing programs could pass a human + readable error message. Example: "STATUS=Completed + 66% of file system check..." + + ERRNO=... If a daemon fails, the errno-style error code, + formatted as string. Example: "ERRNO=2" for ENOENT. + + BUSERROR=... If a daemon fails, the D-Bus error-style error + code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut" + + MAINPID=... The main pid of a daemon, in case systemd did not + fork off the process itself. Example: "MAINPID=4711" + + Daemons can choose to send additional variables. However, it is + recommened to prefix variable names not listed above with X_. + + Returns a negative errno-style error code on failure. Returns > 0 + if systemd could be notified, 0 if it couldn't possibly because + systemd is not running. + + Example: When a daemon finished starting up, it could issue this + call to notify systemd about it: + + sd_notify(0, "READY=1"); + + See sd_notifyf() for more complete examples. + + See sd_notify(3) for more information. +*/ +int sd_notify(int unset_environment, const char *state) _sd_hidden_; + +/* + Similar to sd_notify() but takes a format string. + + Example 1: A daemon could send the following after initialization: + + sd_notifyf(0, "READY=1\n" + "STATUS=Processing requests...\n" + "MAINPID=%lu", + (unsigned long) getpid()); + + Example 2: A daemon could send the following shortly before + exiting, on failure: + + sd_notifyf(0, "STATUS=Failed to start up: %s\n" + "ERRNO=%i", + strerror(errno), + errno); + + See sd_notifyf(3) for more information. +*/ +int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2,3) _sd_hidden_; + +/* + Returns > 0 if the system was booted with systemd. Returns < 0 on + error. Returns 0 if the system was not booted with systemd. Note + that all of the functions above handle non-systemd boots just + fine. You should NOT protect them with a call to this function. Also + note that this function checks whether the system, not the user + session is controlled by systemd. However the functions above work + for both session and system services. + + See sd_booted(3) for more information. +*/ +int sd_booted(void) _sd_hidden_; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/faad.h b/include/faad.h new file mode 100644 index 00000000..72f40728 --- /dev/null +++ b/include/faad.h @@ -0,0 +1,35 @@ +/* +** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding +** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com +** +** 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. +** +** Any non-GPL usage of this software or parts of this software is strictly +** forbidden. +** +** The "appropriate copyright message" mentioned in section 2c of the GPLv2 +** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" +** +** Commercial non-GPL licensing of this software is possible. +** For more info contact Nero AG through Mpeg4AAClicense@nero.com. +** +** $Id: faad.h,v 1.51 2007/11/01 12:33:29 menno Exp $ +**/ + +/* warn people for update */ +#pragma message("please update faad2 include filename and function names!") + +/* Backwards compatible link */ +#include "neaacdec.h" diff --git a/include/libavcodec/avcodec.h b/include/libavcodec/avcodec.h new file mode 100644 index 00000000..974e87cc --- /dev/null +++ b/include/libavcodec/avcodec.h @@ -0,0 +1,3968 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AVCODEC_H +#define AVCODEC_AVCODEC_H + +/** + * @file + * external API header + */ + +#include <errno.h> +#include "libavutil/avutil.h" + +#define LIBAVCODEC_VERSION_MAJOR 52 +#define LIBAVCODEC_VERSION_MINOR 72 +#define LIBAVCODEC_VERSION_MICRO 2 + +#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, \ + LIBAVCODEC_VERSION_MICRO) +#define LIBAVCODEC_VERSION AV_VERSION(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, \ + LIBAVCODEC_VERSION_MICRO) +#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT + +#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) + +#define AV_NOPTS_VALUE INT64_C(0x8000000000000000) +#define AV_TIME_BASE 1000000 +#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE} + +/** + * Identifies the syntax and semantics of the bitstream. + * The principle is roughly: + * Two decoders with the same ID can decode the same streams. + * Two encoders with the same ID can encode compatible streams. + * There may be slight deviations from the principle due to implementation + * details. + * + * If you add a codec ID to this list, add it so that + * 1. no value of a existing codec ID changes (that would break ABI), + * 2. it is as close as possible to similar codecs. + */ +enum CodecID { + CODEC_ID_NONE, + + /* video codecs */ + CODEC_ID_MPEG1VIDEO, + CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding + CODEC_ID_MPEG2VIDEO_XVMC, + CODEC_ID_H261, + CODEC_ID_H263, + CODEC_ID_RV10, + CODEC_ID_RV20, + CODEC_ID_MJPEG, + CODEC_ID_MJPEGB, + CODEC_ID_LJPEG, + CODEC_ID_SP5X, + CODEC_ID_JPEGLS, + CODEC_ID_MPEG4, + CODEC_ID_RAWVIDEO, + CODEC_ID_MSMPEG4V1, + CODEC_ID_MSMPEG4V2, + CODEC_ID_MSMPEG4V3, + CODEC_ID_WMV1, + CODEC_ID_WMV2, + CODEC_ID_H263P, + CODEC_ID_H263I, + CODEC_ID_FLV1, + CODEC_ID_SVQ1, + CODEC_ID_SVQ3, + CODEC_ID_DVVIDEO, + CODEC_ID_HUFFYUV, + CODEC_ID_CYUV, + CODEC_ID_H264, + CODEC_ID_INDEO3, + CODEC_ID_VP3, + CODEC_ID_THEORA, + CODEC_ID_ASV1, + CODEC_ID_ASV2, + CODEC_ID_FFV1, + CODEC_ID_4XM, + CODEC_ID_VCR1, + CODEC_ID_CLJR, + CODEC_ID_MDEC, + CODEC_ID_ROQ, + CODEC_ID_INTERPLAY_VIDEO, + CODEC_ID_XAN_WC3, + CODEC_ID_XAN_WC4, + CODEC_ID_RPZA, + CODEC_ID_CINEPAK, + CODEC_ID_WS_VQA, + CODEC_ID_MSRLE, + CODEC_ID_MSVIDEO1, + CODEC_ID_IDCIN, + CODEC_ID_8BPS, + CODEC_ID_SMC, + CODEC_ID_FLIC, + CODEC_ID_TRUEMOTION1, + CODEC_ID_VMDVIDEO, + CODEC_ID_MSZH, + CODEC_ID_ZLIB, + CODEC_ID_QTRLE, + CODEC_ID_SNOW, + CODEC_ID_TSCC, + CODEC_ID_ULTI, + CODEC_ID_QDRAW, + CODEC_ID_VIXL, + CODEC_ID_QPEG, +#if LIBAVCODEC_VERSION_MAJOR < 53 + CODEC_ID_XVID, +#endif + CODEC_ID_PNG, + CODEC_ID_PPM, + CODEC_ID_PBM, + CODEC_ID_PGM, + CODEC_ID_PGMYUV, + CODEC_ID_PAM, + CODEC_ID_FFVHUFF, + CODEC_ID_RV30, + CODEC_ID_RV40, + CODEC_ID_VC1, + CODEC_ID_WMV3, + CODEC_ID_LOCO, + CODEC_ID_WNV1, + CODEC_ID_AASC, + CODEC_ID_INDEO2, + CODEC_ID_FRAPS, + CODEC_ID_TRUEMOTION2, + CODEC_ID_BMP, + CODEC_ID_CSCD, + CODEC_ID_MMVIDEO, + CODEC_ID_ZMBV, + CODEC_ID_AVS, + CODEC_ID_SMACKVIDEO, + CODEC_ID_NUV, + CODEC_ID_KMVC, + CODEC_ID_FLASHSV, + CODEC_ID_CAVS, + CODEC_ID_JPEG2000, + CODEC_ID_VMNC, + CODEC_ID_VP5, + CODEC_ID_VP6, + CODEC_ID_VP6F, + CODEC_ID_TARGA, + CODEC_ID_DSICINVIDEO, + CODEC_ID_TIERTEXSEQVIDEO, + CODEC_ID_TIFF, + CODEC_ID_GIF, + CODEC_ID_FFH264, + CODEC_ID_DXA, + CODEC_ID_DNXHD, + CODEC_ID_THP, + CODEC_ID_SGI, + CODEC_ID_C93, + CODEC_ID_BETHSOFTVID, + CODEC_ID_PTX, + CODEC_ID_TXD, + CODEC_ID_VP6A, + CODEC_ID_AMV, + CODEC_ID_VB, + CODEC_ID_PCX, + CODEC_ID_SUNRAST, + CODEC_ID_INDEO4, + CODEC_ID_INDEO5, + CODEC_ID_MIMIC, + CODEC_ID_RL2, + CODEC_ID_8SVX_EXP, + CODEC_ID_8SVX_FIB, + CODEC_ID_ESCAPE124, + CODEC_ID_DIRAC, + CODEC_ID_BFI, + CODEC_ID_CMV, + CODEC_ID_MOTIONPIXELS, + CODEC_ID_TGV, + CODEC_ID_TGQ, + CODEC_ID_TQI, + CODEC_ID_AURA, + CODEC_ID_AURA2, + CODEC_ID_V210X, + CODEC_ID_TMV, + CODEC_ID_V210, + CODEC_ID_DPX, + CODEC_ID_MAD, + CODEC_ID_FRWU, + CODEC_ID_FLASHSV2, + CODEC_ID_CDGRAPHICS, + CODEC_ID_R210, + CODEC_ID_ANM, + CODEC_ID_BINKVIDEO, + CODEC_ID_IFF_ILBM, + CODEC_ID_IFF_BYTERUN1, + CODEC_ID_KGV1, + CODEC_ID_YOP, + CODEC_ID_VP8, + + /* various PCM "codecs" */ + CODEC_ID_PCM_S16LE= 0x10000, + CODEC_ID_PCM_S16BE, + CODEC_ID_PCM_U16LE, + CODEC_ID_PCM_U16BE, + CODEC_ID_PCM_S8, + CODEC_ID_PCM_U8, + CODEC_ID_PCM_MULAW, + CODEC_ID_PCM_ALAW, + CODEC_ID_PCM_S32LE, + CODEC_ID_PCM_S32BE, + CODEC_ID_PCM_U32LE, + CODEC_ID_PCM_U32BE, + CODEC_ID_PCM_S24LE, + CODEC_ID_PCM_S24BE, + CODEC_ID_PCM_U24LE, + CODEC_ID_PCM_U24BE, + CODEC_ID_PCM_S24DAUD, + CODEC_ID_PCM_ZORK, + CODEC_ID_PCM_S16LE_PLANAR, + CODEC_ID_PCM_DVD, + CODEC_ID_PCM_F32BE, + CODEC_ID_PCM_F32LE, + CODEC_ID_PCM_F64BE, + CODEC_ID_PCM_F64LE, + CODEC_ID_PCM_BLURAY, + + /* various ADPCM codecs */ + CODEC_ID_ADPCM_IMA_QT= 0x11000, + CODEC_ID_ADPCM_IMA_WAV, + CODEC_ID_ADPCM_IMA_DK3, + CODEC_ID_ADPCM_IMA_DK4, + CODEC_ID_ADPCM_IMA_WS, + CODEC_ID_ADPCM_IMA_SMJPEG, + CODEC_ID_ADPCM_MS, + CODEC_ID_ADPCM_4XM, + CODEC_ID_ADPCM_XA, + CODEC_ID_ADPCM_ADX, + CODEC_ID_ADPCM_EA, + CODEC_ID_ADPCM_G726, + CODEC_ID_ADPCM_CT, + CODEC_ID_ADPCM_SWF, + CODEC_ID_ADPCM_YAMAHA, + CODEC_ID_ADPCM_SBPRO_4, + CODEC_ID_ADPCM_SBPRO_3, + CODEC_ID_ADPCM_SBPRO_2, + CODEC_ID_ADPCM_THP, + CODEC_ID_ADPCM_IMA_AMV, + CODEC_ID_ADPCM_EA_R1, + CODEC_ID_ADPCM_EA_R3, + CODEC_ID_ADPCM_EA_R2, + CODEC_ID_ADPCM_IMA_EA_SEAD, + CODEC_ID_ADPCM_IMA_EA_EACS, + CODEC_ID_ADPCM_EA_XAS, + CODEC_ID_ADPCM_EA_MAXIS_XA, + CODEC_ID_ADPCM_IMA_ISS, + + /* AMR */ + CODEC_ID_AMR_NB= 0x12000, + CODEC_ID_AMR_WB, + + /* RealAudio codecs*/ + CODEC_ID_RA_144= 0x13000, + CODEC_ID_RA_288, + + /* various DPCM codecs */ + CODEC_ID_ROQ_DPCM= 0x14000, + CODEC_ID_INTERPLAY_DPCM, + CODEC_ID_XAN_DPCM, + CODEC_ID_SOL_DPCM, + + /* audio codecs */ + CODEC_ID_MP2= 0x15000, + CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3 + CODEC_ID_AAC, + CODEC_ID_AC3, + CODEC_ID_DTS, + CODEC_ID_VORBIS, + CODEC_ID_DVAUDIO, + CODEC_ID_WMAV1, + CODEC_ID_WMAV2, + CODEC_ID_MACE3, + CODEC_ID_MACE6, + CODEC_ID_VMDAUDIO, + CODEC_ID_SONIC, + CODEC_ID_SONIC_LS, + CODEC_ID_FLAC, + CODEC_ID_MP3ADU, + CODEC_ID_MP3ON4, + CODEC_ID_SHORTEN, + CODEC_ID_ALAC, + CODEC_ID_WESTWOOD_SND1, + CODEC_ID_GSM, ///< as in Berlin toast format + CODEC_ID_QDM2, + CODEC_ID_COOK, + CODEC_ID_TRUESPEECH, + CODEC_ID_TTA, + CODEC_ID_SMACKAUDIO, + CODEC_ID_QCELP, + CODEC_ID_WAVPACK, + CODEC_ID_DSICINAUDIO, + CODEC_ID_IMC, + CODEC_ID_MUSEPACK7, + CODEC_ID_MLP, + CODEC_ID_GSM_MS, /* as found in WAV */ + CODEC_ID_ATRAC3, + CODEC_ID_VOXWARE, + CODEC_ID_APE, + CODEC_ID_NELLYMOSER, + CODEC_ID_MUSEPACK8, + CODEC_ID_SPEEX, + CODEC_ID_WMAVOICE, + CODEC_ID_WMAPRO, + CODEC_ID_WMALOSSLESS, + CODEC_ID_ATRAC3P, + CODEC_ID_EAC3, + CODEC_ID_SIPR, + CODEC_ID_MP1, + CODEC_ID_TWINVQ, + CODEC_ID_TRUEHD, + CODEC_ID_MP4ALS, + CODEC_ID_ATRAC1, + CODEC_ID_BINKAUDIO_RDFT, + CODEC_ID_BINKAUDIO_DCT, + + /* subtitle codecs */ + CODEC_ID_DVD_SUBTITLE= 0x17000, + CODEC_ID_DVB_SUBTITLE, + CODEC_ID_TEXT, ///< raw UTF-8 text + CODEC_ID_XSUB, + CODEC_ID_SSA, + CODEC_ID_MOV_TEXT, + CODEC_ID_HDMV_PGS_SUBTITLE, + CODEC_ID_DVB_TELETEXT, + + /* other specific kind of codecs (generally used for attachments) */ + CODEC_ID_TTF= 0x18000, + + CODEC_ID_PROBE= 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it + + CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS + * stream (only used by libavformat) */ +}; + +#if LIBAVCODEC_VERSION_MAJOR < 53 +#define CodecType AVMediaType + +#define CODEC_TYPE_UNKNOWN AVMEDIA_TYPE_UNKNOWN +#define CODEC_TYPE_VIDEO AVMEDIA_TYPE_VIDEO +#define CODEC_TYPE_AUDIO AVMEDIA_TYPE_AUDIO +#define CODEC_TYPE_DATA AVMEDIA_TYPE_DATA +#define CODEC_TYPE_SUBTITLE AVMEDIA_TYPE_SUBTITLE +#define CODEC_TYPE_ATTACHMENT AVMEDIA_TYPE_ATTACHMENT +#define CODEC_TYPE_NB AVMEDIA_TYPE_NB +#endif + +/** + * all in native-endian format + */ +enum SampleFormat { + SAMPLE_FMT_NONE = -1, + SAMPLE_FMT_U8, ///< unsigned 8 bits + SAMPLE_FMT_S16, ///< signed 16 bits + SAMPLE_FMT_S32, ///< signed 32 bits + SAMPLE_FMT_FLT, ///< float + SAMPLE_FMT_DBL, ///< double + SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if dynamically linking to libavcodec +}; + +/* Audio channel masks */ +#define CH_FRONT_LEFT 0x00000001 +#define CH_FRONT_RIGHT 0x00000002 +#define CH_FRONT_CENTER 0x00000004 +#define CH_LOW_FREQUENCY 0x00000008 +#define CH_BACK_LEFT 0x00000010 +#define CH_BACK_RIGHT 0x00000020 +#define CH_FRONT_LEFT_OF_CENTER 0x00000040 +#define CH_FRONT_RIGHT_OF_CENTER 0x00000080 +#define CH_BACK_CENTER 0x00000100 +#define CH_SIDE_LEFT 0x00000200 +#define CH_SIDE_RIGHT 0x00000400 +#define CH_TOP_CENTER 0x00000800 +#define CH_TOP_FRONT_LEFT 0x00001000 +#define CH_TOP_FRONT_CENTER 0x00002000 +#define CH_TOP_FRONT_RIGHT 0x00004000 +#define CH_TOP_BACK_LEFT 0x00008000 +#define CH_TOP_BACK_CENTER 0x00010000 +#define CH_TOP_BACK_RIGHT 0x00020000 +#define CH_STEREO_LEFT 0x20000000 ///< Stereo downmix. +#define CH_STEREO_RIGHT 0x40000000 ///< See CH_STEREO_LEFT. + +/** Channel mask value used for AVCodecContext.request_channel_layout + to indicate that the user requests the channel order of the decoder output + to be the native codec channel order. */ +#define CH_LAYOUT_NATIVE 0x8000000000000000LL + +/* Audio channel convenience macros */ +#define CH_LAYOUT_MONO (CH_FRONT_CENTER) +#define CH_LAYOUT_STEREO (CH_FRONT_LEFT|CH_FRONT_RIGHT) +#define CH_LAYOUT_2_1 (CH_LAYOUT_STEREO|CH_BACK_CENTER) +#define CH_LAYOUT_SURROUND (CH_LAYOUT_STEREO|CH_FRONT_CENTER) +#define CH_LAYOUT_4POINT0 (CH_LAYOUT_SURROUND|CH_BACK_CENTER) +#define CH_LAYOUT_2_2 (CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT) +#define CH_LAYOUT_QUAD (CH_LAYOUT_STEREO|CH_BACK_LEFT|CH_BACK_RIGHT) +#define CH_LAYOUT_5POINT0 (CH_LAYOUT_SURROUND|CH_SIDE_LEFT|CH_SIDE_RIGHT) +#define CH_LAYOUT_5POINT1 (CH_LAYOUT_5POINT0|CH_LOW_FREQUENCY) +#define CH_LAYOUT_5POINT0_BACK (CH_LAYOUT_SURROUND|CH_BACK_LEFT|CH_BACK_RIGHT) +#define CH_LAYOUT_5POINT1_BACK (CH_LAYOUT_5POINT0_BACK|CH_LOW_FREQUENCY) +#define CH_LAYOUT_7POINT0 (CH_LAYOUT_5POINT0|CH_BACK_LEFT|CH_BACK_RIGHT) +#define CH_LAYOUT_7POINT1 (CH_LAYOUT_5POINT1|CH_BACK_LEFT|CH_BACK_RIGHT) +#define CH_LAYOUT_7POINT1_WIDE (CH_LAYOUT_5POINT1_BACK|\ + CH_FRONT_LEFT_OF_CENTER|CH_FRONT_RIGHT_OF_CENTER) +#define CH_LAYOUT_STEREO_DOWNMIX (CH_STEREO_LEFT|CH_STEREO_RIGHT) + +/* in bytes */ +#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio + +/** + * Required number of additionally allocated bytes at the end of the input bitstream for decoding. + * This is mainly needed because some optimized bitstream readers read + * 32 or 64 bit at once and could read over the end.<br> + * Note: If the first 23 bits of the additional bytes are not 0, then damaged + * MPEG bitstreams could cause overread and segfault. + */ +#define FF_INPUT_BUFFER_PADDING_SIZE 8 + +/** + * minimum encoding buffer size + * Used to avoid some checks during header writing. + */ +#define FF_MIN_BUFFER_SIZE 16384 + + +/** + * motion estimation type. + */ +enum Motion_Est_ID { + ME_ZERO = 1, ///< no search, that is use 0,0 vector whenever one is needed + ME_FULL, + ME_LOG, + ME_PHODS, + ME_EPZS, ///< enhanced predictive zonal search + ME_X1, ///< reserved for experiments + ME_HEX, ///< hexagon based search + ME_UMH, ///< uneven multi-hexagon search + ME_ITER, ///< iterative search + ME_TESA, ///< transformed exhaustive search algorithm +}; + +enum AVDiscard{ + /* We leave some space between them for extensions (drop some + * keyframes for intra-only or drop just some bidir frames). */ + AVDISCARD_NONE =-16, ///< discard nothing + AVDISCARD_DEFAULT= 0, ///< discard useless packets like 0 size packets in avi + AVDISCARD_NONREF = 8, ///< discard all non reference + AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames + AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes + AVDISCARD_ALL = 48, ///< discard all +}; + +enum AVColorPrimaries{ + AVCOL_PRI_BT709 =1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B + AVCOL_PRI_UNSPECIFIED=2, + AVCOL_PRI_BT470M =4, + AVCOL_PRI_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM + AVCOL_PRI_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC + AVCOL_PRI_SMPTE240M =7, ///< functionally identical to above + AVCOL_PRI_FILM =8, + AVCOL_PRI_NB , ///< Not part of ABI +}; + +enum AVColorTransferCharacteristic{ + AVCOL_TRC_BT709 =1, ///< also ITU-R BT1361 + AVCOL_TRC_UNSPECIFIED=2, + AVCOL_TRC_GAMMA22 =4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM + AVCOL_TRC_GAMMA28 =5, ///< also ITU-R BT470BG + AVCOL_TRC_NB , ///< Not part of ABI +}; + +enum AVColorSpace{ + AVCOL_SPC_RGB =0, + AVCOL_SPC_BT709 =1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B + AVCOL_SPC_UNSPECIFIED=2, + AVCOL_SPC_FCC =4, + AVCOL_SPC_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 + AVCOL_SPC_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above + AVCOL_SPC_SMPTE240M =7, + AVCOL_SPC_NB , ///< Not part of ABI +}; + +enum AVColorRange{ + AVCOL_RANGE_UNSPECIFIED=0, + AVCOL_RANGE_MPEG =1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges + AVCOL_RANGE_JPEG =2, ///< the normal 2^n-1 "JPEG" YUV ranges + AVCOL_RANGE_NB , ///< Not part of ABI +}; + +/** + * X X 3 4 X X are luma samples, + * 1 2 1-6 are possible chroma positions + * X X 5 6 X 0 is undefined/unknown position + */ +enum AVChromaLocation{ + AVCHROMA_LOC_UNSPECIFIED=0, + AVCHROMA_LOC_LEFT =1, ///< mpeg2/4, h264 default + AVCHROMA_LOC_CENTER =2, ///< mpeg1, jpeg, h263 + AVCHROMA_LOC_TOPLEFT =3, ///< DV + AVCHROMA_LOC_TOP =4, + AVCHROMA_LOC_BOTTOMLEFT =5, + AVCHROMA_LOC_BOTTOM =6, + AVCHROMA_LOC_NB , ///< Not part of ABI +}; + +typedef struct RcOverride{ + int start_frame; + int end_frame; + int qscale; // If this is 0 then quality_factor will be used instead. + float quality_factor; +} RcOverride; + +#define FF_MAX_B_FRAMES 16 + +/* encoding support + These flags can be passed in AVCodecContext.flags before initialization. + Note: Not everything is supported yet. +*/ + +#define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale. +#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263. +#define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC. +#define CODEC_FLAG_GMC 0x0020 ///< Use GMC. +#define CODEC_FLAG_MV0 0x0040 ///< Always try a MB with MV=<0,0>. +#define CODEC_FLAG_PART 0x0080 ///< Use data partitioning. +/** + * The parent program guarantees that the input for B-frames containing + * streams is not written to for at least s->max_b_frames+1 frames, if + * this is not set the input will be copied. + */ +#define CODEC_FLAG_INPUT_PRESERVED 0x0100 +#define CODEC_FLAG_PASS1 0x0200 ///< Use internal 2pass ratecontrol in first pass mode. +#define CODEC_FLAG_PASS2 0x0400 ///< Use internal 2pass ratecontrol in second pass mode. +#define CODEC_FLAG_EXTERN_HUFF 0x1000 ///< Use external Huffman table (for MJPEG). +#define CODEC_FLAG_GRAY 0x2000 ///< Only decode/encode grayscale. +#define CODEC_FLAG_EMU_EDGE 0x4000 ///< Don't draw edges. +#define CODEC_FLAG_PSNR 0x8000 ///< error[?] variables will be set during encoding. +#define CODEC_FLAG_TRUNCATED 0x00010000 /** Input bitstream might be truncated at a random + location instead of only at frame boundaries. */ +#define CODEC_FLAG_NORMALIZE_AQP 0x00020000 ///< Normalize adaptive quantization. +#define CODEC_FLAG_INTERLACED_DCT 0x00040000 ///< Use interlaced DCT. +#define CODEC_FLAG_LOW_DELAY 0x00080000 ///< Force low delay. +#define CODEC_FLAG_ALT_SCAN 0x00100000 ///< Use alternate scan. +#define CODEC_FLAG_GLOBAL_HEADER 0x00400000 ///< Place global headers in extradata instead of every keyframe. +#define CODEC_FLAG_BITEXACT 0x00800000 ///< Use only bitexact stuff (except (I)DCT). +/* Fx : Flag for h263+ extra options */ +#define CODEC_FLAG_AC_PRED 0x01000000 ///< H.263 advanced intra coding / MPEG-4 AC prediction +#define CODEC_FLAG_H263P_UMV 0x02000000 ///< unlimited motion vector +#define CODEC_FLAG_CBP_RD 0x04000000 ///< Use rate distortion optimization for cbp. +#define CODEC_FLAG_QP_RD 0x08000000 ///< Use rate distortion optimization for qp selectioon. +#define CODEC_FLAG_H263P_AIV 0x00000008 ///< H.263 alternative inter VLC +#define CODEC_FLAG_OBMC 0x00000001 ///< OBMC +#define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter +#define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000 +#define CODEC_FLAG_INTERLACED_ME 0x20000000 ///< interlaced motion estimation +#define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< Will reserve space for SVCD scan offset user data. +#define CODEC_FLAG_CLOSED_GOP 0x80000000 +#define CODEC_FLAG2_FAST 0x00000001 ///< Allow non spec compliant speedup tricks. +#define CODEC_FLAG2_STRICT_GOP 0x00000002 ///< Strictly enforce GOP size. +#define CODEC_FLAG2_NO_OUTPUT 0x00000004 ///< Skip bitstream encoding. +#define CODEC_FLAG2_LOCAL_HEADER 0x00000008 ///< Place global headers at every keyframe instead of in extradata. +#define CODEC_FLAG2_BPYRAMID 0x00000010 ///< H.264 allow B-frames to be used as references. +#define CODEC_FLAG2_WPRED 0x00000020 ///< H.264 weighted biprediction for B-frames +#define CODEC_FLAG2_MIXED_REFS 0x00000040 ///< H.264 one reference per partition, as opposed to one reference per macroblock +#define CODEC_FLAG2_8X8DCT 0x00000080 ///< H.264 high profile 8x8 transform +#define CODEC_FLAG2_FASTPSKIP 0x00000100 ///< H.264 fast pskip +#define CODEC_FLAG2_AUD 0x00000200 ///< H.264 access unit delimiters +#define CODEC_FLAG2_BRDO 0x00000400 ///< B-frame rate-distortion optimization +#define CODEC_FLAG2_INTRA_VLC 0x00000800 ///< Use MPEG-2 intra VLC table. +#define CODEC_FLAG2_MEMC_ONLY 0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC). +#define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format. +#define CODEC_FLAG2_SKIP_RD 0x00004000 ///< RD optimal MB level residual skipping +#define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries. +#define CODEC_FLAG2_NON_LINEAR_QUANT 0x00010000 ///< Use MPEG-2 nonlinear quantizer. +#define CODEC_FLAG2_BIT_RESERVOIR 0x00020000 ///< Use a bit reservoir when encoding if possible +#define CODEC_FLAG2_MBTREE 0x00040000 ///< Use macroblock tree ratecontrol (x264 only) +#define CODEC_FLAG2_PSY 0x00080000 ///< Use psycho visual optimizations. +#define CODEC_FLAG2_SSIM 0x00100000 ///< Compute SSIM during encoding, error[] values are undefined. + +/* Unsupported options : + * Syntax Arithmetic coding (SAC) + * Reference Picture Selection + * Independent Segment Decoding */ +/* /Fx */ +/* codec capabilities */ + +#define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 ///< Decoder can use draw_horiz_band callback. +/** + * Codec uses get_buffer() for allocating buffers and supports custom allocators. + * If not set, it might not use get_buffer() at all or use operations that + * assume the buffer was allocated by avcodec_default_get_buffer. + */ +#define CODEC_CAP_DR1 0x0002 +/* If 'parse_only' field is true, then avcodec_parse_frame() can be used. */ +#define CODEC_CAP_PARSE_ONLY 0x0004 +#define CODEC_CAP_TRUNCATED 0x0008 +/* Codec can export data for HW decoding (XvMC). */ +#define CODEC_CAP_HWACCEL 0x0010 +/** + * Codec has a nonzero delay and needs to be fed with NULL at the end to get the delayed data. + * If this is not set, the codec is guaranteed to never be fed with NULL data. + */ +#define CODEC_CAP_DELAY 0x0020 +/** + * Codec can be fed a final frame with a smaller size. + * This can be used to prevent truncation of the last audio samples. + */ +#define CODEC_CAP_SMALL_LAST_FRAME 0x0040 +/** + * Codec can export data for HW decoding (VDPAU). + */ +#define CODEC_CAP_HWACCEL_VDPAU 0x0080 +/** + * Codec can output multiple frames per AVPacket + * Normally demuxers return one frame at a time, demuxers which do not do + * are connected to a parser to split what they return into proper frames. + * This flag is reserved to the very rare category of codecs which have a + * bitstream that cannot be split into frames without timeconsuming + * operations like full decoding. Demuxers carring such bitstreams thus + * may return multiple frames in a packet. This has many disadvantages like + * prohibiting stream copy in many cases thus it should only be considered + * as a last resort. + */ +#define CODEC_CAP_SUBFRAMES 0x0100 +/** + * Codec is experimental and is thus avoided in favor of non experimental + * encoders + */ +#define CODEC_CAP_EXPERIMENTAL 0x0200 + +//The following defines may change, don't expect compatibility if you use them. +#define MB_TYPE_INTRA4x4 0x0001 +#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific +#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific +#define MB_TYPE_16x16 0x0008 +#define MB_TYPE_16x8 0x0010 +#define MB_TYPE_8x16 0x0020 +#define MB_TYPE_8x8 0x0040 +#define MB_TYPE_INTERLACED 0x0080 +#define MB_TYPE_DIRECT2 0x0100 //FIXME +#define MB_TYPE_ACPRED 0x0200 +#define MB_TYPE_GMC 0x0400 +#define MB_TYPE_SKIP 0x0800 +#define MB_TYPE_P0L0 0x1000 +#define MB_TYPE_P1L0 0x2000 +#define MB_TYPE_P0L1 0x4000 +#define MB_TYPE_P1L1 0x8000 +#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0) +#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1) +#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1) +#define MB_TYPE_QUANT 0x00010000 +#define MB_TYPE_CBP 0x00020000 +//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...) + +/** + * Pan Scan area. + * This specifies the area which should be displayed. + * Note there may be multiple such areas for one frame. + */ +typedef struct AVPanScan{ + /** + * id + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int id; + + /** + * width and height in 1/16 pel + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int width; + int height; + + /** + * position of the top left corner in 1/16 pel for up to 3 fields/frames + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int16_t position[3][2]; +}AVPanScan; + +#define FF_COMMON_FRAME \ + /**\ + * pointer to the picture planes.\ + * This might be different from the first allocated byte\ + * - encoding: \ + * - decoding: \ + */\ + uint8_t *data[4];\ + int linesize[4];\ + /**\ + * pointer to the first allocated byte of the picture. Can be used in get_buffer/release_buffer.\ + * This isn't used by libavcodec unless the default get/release_buffer() is used.\ + * - encoding: \ + * - decoding: \ + */\ + uint8_t *base[4];\ + /**\ + * 1 -> keyframe, 0-> not\ + * - encoding: Set by libavcodec.\ + * - decoding: Set by libavcodec.\ + */\ + int key_frame;\ +\ + /**\ + * Picture type of the frame, see ?_TYPE below.\ + * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\ + * - decoding: Set by libavcodec.\ + */\ + int pict_type;\ +\ + /**\ + * presentation timestamp in time_base units (time when frame should be shown to user)\ + * If AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed.\ + * - encoding: MUST be set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int64_t pts;\ +\ + /**\ + * picture number in bitstream order\ + * - encoding: set by\ + * - decoding: Set by libavcodec.\ + */\ + int coded_picture_number;\ + /**\ + * picture number in display order\ + * - encoding: set by\ + * - decoding: Set by libavcodec.\ + */\ + int display_picture_number;\ +\ + /**\ + * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) \ + * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\ + * - decoding: Set by libavcodec.\ + */\ + int quality; \ +\ + /**\ + * buffer age (1->was last buffer and dint change, 2->..., ...).\ + * Set to INT_MAX if the buffer has not been used yet.\ + * - encoding: unused\ + * - decoding: MUST be set by get_buffer().\ + */\ + int age;\ +\ + /**\ + * is this picture used as reference\ + * The values for this are the same as the MpegEncContext.picture_structure\ + * variable, that is 1->top field, 2->bottom field, 3->frame/both fields.\ + * Set to 4 for delayed, non-reference frames.\ + * - encoding: unused\ + * - decoding: Set by libavcodec. (before get_buffer() call)).\ + */\ + int reference;\ +\ + /**\ + * QP table\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + int8_t *qscale_table;\ + /**\ + * QP store stride\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + int qstride;\ +\ + /**\ + * mbskip_table[mb]>=1 if MB didn't change\ + * stride= mb_width = (width+15)>>4\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + uint8_t *mbskip_table;\ +\ + /**\ + * motion vector table\ + * @code\ + * example:\ + * int mv_sample_log2= 4 - motion_subsample_log2;\ + * int mb_width= (width+15)>>4;\ + * int mv_stride= (mb_width << mv_sample_log2) + 1;\ + * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];\ + * @endcode\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int16_t (*motion_val[2])[2];\ +\ + /**\ + * macroblock type table\ + * mb_type_base + mb_width + 2\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + uint32_t *mb_type;\ +\ + /**\ + * log2 of the size of the block which a single vector in motion_val represents: \ + * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + uint8_t motion_subsample_log2;\ +\ + /**\ + * for some private data of the user\ + * - encoding: unused\ + * - decoding: Set by user.\ + */\ + void *opaque;\ +\ + /**\ + * error\ + * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.\ + * - decoding: unused\ + */\ + uint64_t error[4];\ +\ + /**\ + * type of the buffer (to keep track of who has to deallocate data[*])\ + * - encoding: Set by the one who allocates it.\ + * - decoding: Set by the one who allocates it.\ + * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.\ + */\ + int type;\ + \ + /**\ + * When decoding, this signals how much the picture must be delayed.\ + * extra_delay = repeat_pict / (2*fps)\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + int repeat_pict;\ + \ + /**\ + * \ + */\ + int qscale_type;\ + \ + /**\ + * The content of the picture is interlaced.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec. (default 0)\ + */\ + int interlaced_frame;\ + \ + /**\ + * If the content is interlaced, is top field displayed first.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int top_field_first;\ + \ + /**\ + * Pan scan.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + AVPanScan *pan_scan;\ + \ + /**\ + * Tell user application that palette has changed from previous frame.\ + * - encoding: ??? (no palette-enabled encoder yet)\ + * - decoding: Set by libavcodec. (default 0).\ + */\ + int palette_has_changed;\ + \ + /**\ + * codec suggestion on buffer type if != 0\ + * - encoding: unused\ + * - decoding: Set by libavcodec. (before get_buffer() call)).\ + */\ + int buffer_hints;\ +\ + /**\ + * DCT coefficients\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + short *dct_coeff;\ +\ + /**\ + * motion reference frame index\ + * the order in which these are stored can depend on the codec.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int8_t *ref_index[2];\ +\ + /**\ + * reordered opaque 64bit number (generally a PTS) from AVCodecContext.reordered_opaque\ + * output in AVFrame.reordered_opaque\ + * - encoding: unused\ + * - decoding: Read by user.\ + */\ + int64_t reordered_opaque;\ +\ + /**\ + * hardware accelerator private data (FFmpeg allocated)\ + * - encoding: unused\ + * - decoding: Set by libavcodec\ + */\ + void *hwaccel_picture_private;\ + + +#define FF_QSCALE_TYPE_MPEG1 0 +#define FF_QSCALE_TYPE_MPEG2 1 +#define FF_QSCALE_TYPE_H264 2 +#define FF_QSCALE_TYPE_VP56 3 + +#define FF_BUFFER_TYPE_INTERNAL 1 +#define FF_BUFFER_TYPE_USER 2 ///< direct rendering buffers (image is (de)allocated by user) +#define FF_BUFFER_TYPE_SHARED 4 ///< Buffer from somewhere else; don't deallocate image (data/base), all other tables are not shared. +#define FF_BUFFER_TYPE_COPY 8 ///< Just a (modified) copy of some other buffer, don't deallocate anything. + + +#define FF_I_TYPE 1 ///< Intra +#define FF_P_TYPE 2 ///< Predicted +#define FF_B_TYPE 3 ///< Bi-dir predicted +#define FF_S_TYPE 4 ///< S(GMC)-VOP MPEG4 +#define FF_SI_TYPE 5 ///< Switching Intra +#define FF_SP_TYPE 6 ///< Switching Predicted +#define FF_BI_TYPE 7 + +#define FF_BUFFER_HINTS_VALID 0x01 // Buffer hints value is meaningful (if 0 ignore). +#define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer. +#define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content. +#define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update). + +typedef struct AVPacket { + /** + * Presentation timestamp in AVStream->time_base units; the time at which + * the decompressed packet will be presented to the user. + * Can be AV_NOPTS_VALUE if it is not stored in the file. + * pts MUST be larger or equal to dts as presentation cannot happen before + * decompression, unless one wants to view hex dumps. Some formats misuse + * the terms dts and pts/cts to mean something different. Such timestamps + * must be converted to true pts/dts before they are stored in AVPacket. + */ + int64_t pts; + /** + * Decompression timestamp in AVStream->time_base units; the time at which + * the packet is decompressed. + * Can be AV_NOPTS_VALUE if it is not stored in the file. + */ + int64_t dts; + uint8_t *data; + int size; + int stream_index; + int flags; + /** + * Duration of this packet in AVStream->time_base units, 0 if unknown. + * Equals next_pts - this_pts in presentation order. + */ + int duration; + void (*destruct)(struct AVPacket *); + void *priv; + int64_t pos; ///< byte position in stream, -1 if unknown + + /** + * Time difference in AVStream->time_base units from the pts of this + * packet to the point at which the output from the decoder has converged + * independent from the availability of previous frames. That is, the + * frames are virtually identical no matter if decoding started from + * the very first frame or from this keyframe. + * Is AV_NOPTS_VALUE if unknown. + * This field is not the display duration of the current packet. + * + * The purpose of this field is to allow seeking in streams that have no + * keyframes in the conventional sense. It corresponds to the + * recovery point SEI in H.264 and match_time_delta in NUT. It is also + * essential for some types of subtitle streams to ensure that all + * subtitles are correctly displayed after seeking. + */ + int64_t convergence_duration; +} AVPacket; +#define AV_PKT_FLAG_KEY 0x0001 +#if LIBAVCODEC_VERSION_MAJOR < 53 +#define PKT_FLAG_KEY AV_PKT_FLAG_KEY +#endif + +/** + * Audio Video Frame. + * New fields can be added to the end of FF_COMMON_FRAME with minor version + * bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. No fields should be added into AVFrame before or after + * FF_COMMON_FRAME! + * sizeof(AVFrame) must not be used outside libav*. + */ +typedef struct AVFrame { + FF_COMMON_FRAME +} AVFrame; + +/** + * main external API structure. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVCodecContext) must not be used outside libav*. + */ +typedef struct AVCodecContext { + /** + * information on struct for av_log + * - set by avcodec_alloc_context + */ + const AVClass *av_class; + /** + * the average bitrate + * - encoding: Set by user; unused for constant quantizer encoding. + * - decoding: Set by libavcodec. 0 or some bitrate if this info is available in the stream. + */ + int bit_rate; + + /** + * number of bits the bitstream is allowed to diverge from the reference. + * the reference can be CBR (for CBR pass1) or VBR (for pass2) + * - encoding: Set by user; unused for constant quantizer encoding. + * - decoding: unused + */ + int bit_rate_tolerance; + + /** + * CODEC_FLAG_*. + * - encoding: Set by user. + * - decoding: Set by user. + */ + int flags; + + /** + * Some codecs need additional format info. It is stored here. + * If any muxer uses this then ALL demuxers/parsers AND encoders for the + * specific codec MUST set it correctly otherwise stream copy breaks. + * In general use of this field by muxers is not recommanded. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. (FIXME: Is this OK?) + */ + int sub_id; + + /** + * Motion estimation algorithm used for video coding. + * 1 (zero), 2 (full), 3 (log), 4 (phods), 5 (epzs), 6 (x1), 7 (hex), + * 8 (umh), 9 (iter), 10 (tesa) [7, 8, 10 are x264 specific, 9 is snow specific] + * - encoding: MUST be set by user. + * - decoding: unused + */ + int me_method; + + /** + * some codecs need / can use extradata like Huffman tables. + * mjpeg: Huffman tables + * rv10: additional flags + * mpeg4: global headers (they can be in the bitstream or here) + * The allocated memory should be FF_INPUT_BUFFER_PADDING_SIZE bytes larger + * than extradata_size to avoid prolems if it is read with the bitstream reader. + * The bytewise contents of extradata must not depend on the architecture or CPU endianness. + * - encoding: Set/allocated/freed by libavcodec. + * - decoding: Set/allocated/freed by user. + */ + uint8_t *extradata; + int extradata_size; + + /** + * This is the fundamental unit of time (in seconds) in terms + * of which frame timestamps are represented. For fixed-fps content, + * timebase should be 1/framerate and timestamp increments should be + * identically 1. + * - encoding: MUST be set by user. + * - decoding: Set by libavcodec. + */ + AVRational time_base; + + /* video only */ + /** + * picture width / height. + * - encoding: MUST be set by user. + * - decoding: Set by libavcodec. + * Note: For compatibility it is possible to set this instead of + * coded_width/height before decoding. + */ + int width, height; + +#define FF_ASPECT_EXTENDED 15 + + /** + * the number of pictures in a group of pictures, or 0 for intra_only + * - encoding: Set by user. + * - decoding: unused + */ + int gop_size; + + /** + * Pixel format, see PIX_FMT_xxx. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + enum PixelFormat pix_fmt; + + /** + * Frame rate emulation. If not zero, the lower layer (i.e. format handler) + * has to read frames at native frame rate. + * - encoding: Set by user. + * - decoding: unused + */ + int rate_emu; + + /** + * If non NULL, 'draw_horiz_band' is called by the libavcodec + * decoder to draw a horizontal band. It improves cache usage. Not + * all codecs can do that. You must check the codec capabilities + * beforehand. + * The function is also used by hardware acceleration APIs. + * It is called at least once during frame decoding to pass + * the data needed for hardware render. + * In that mode instead of pixel data, AVFrame points to + * a structure specific to the acceleration API. The application + * reads the structure and can change some fields to indicate progress + * or mark state. + * - encoding: unused + * - decoding: Set by user. + * @param height the height of the slice + * @param y the y position of the slice + * @param type 1->top field, 2->bottom field, 3->frame + * @param offset offset into the AVFrame.data from which the slice should be read + */ + void (*draw_horiz_band)(struct AVCodecContext *s, + const AVFrame *src, int offset[4], + int y, int type, int height); + + /* audio only */ + int sample_rate; ///< samples per second + int channels; ///< number of audio channels + + /** + * audio sample format + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + enum SampleFormat sample_fmt; ///< sample format + + /* The following data should not be initialized. */ + /** + * Samples per packet, initialized when calling 'init'. + */ + int frame_size; + int frame_number; ///< audio or video frame number +#if LIBAVCODEC_VERSION_MAJOR < 53 + int real_pict_num; ///< Returns the real picture number of previous encoded frame. +#endif + + /** + * Number of frames the decoded output will be delayed relative to + * the encoded input. + * - encoding: Set by libavcodec. + * - decoding: unused + */ + int delay; + + /* - encoding parameters */ + float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0) + float qblur; ///< amount of qscale smoothing over time (0.0-1.0) + + /** + * minimum quantizer + * - encoding: Set by user. + * - decoding: unused + */ + int qmin; + + /** + * maximum quantizer + * - encoding: Set by user. + * - decoding: unused + */ + int qmax; + + /** + * maximum quantizer difference between frames + * - encoding: Set by user. + * - decoding: unused + */ + int max_qdiff; + + /** + * maximum number of B-frames between non-B-frames + * Note: The output will be delayed by max_b_frames+1 relative to the input. + * - encoding: Set by user. + * - decoding: unused + */ + int max_b_frames; + + /** + * qscale factor between IP and B-frames + * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset). + * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). + * - encoding: Set by user. + * - decoding: unused + */ + float b_quant_factor; + + /** obsolete FIXME remove */ + int rc_strategy; +#define FF_RC_STRATEGY_XVID 1 + + int b_frame_strategy; + + /** + * hurry up amount + * - encoding: unused + * - decoding: Set by user. 1-> Skip B-frames, 2-> Skip IDCT/dequant too, 5-> Skip everything except header + * @deprecated Deprecated in favor of skip_idct and skip_frame. + */ + int hurry_up; + + struct AVCodec *codec; + + void *priv_data; + + int rtp_payload_size; /* The size of the RTP payload: the coder will */ + /* do its best to deliver a chunk with size */ + /* below rtp_payload_size, the chunk will start */ + /* with a start code on some codecs like H.263. */ + /* This doesn't take account of any particular */ + /* headers inside the transmitted RTP payload. */ + + + /* The RTP callback: This function is called */ + /* every time the encoder has a packet to send. */ + /* It depends on the encoder if the data starts */ + /* with a Start Code (it should). H.263 does. */ + /* mb_nb contains the number of macroblocks */ + /* encoded in the RTP payload. */ + void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb); + + /* statistics, used for 2-pass encoding */ + int mv_bits; + int header_bits; + int i_tex_bits; + int p_tex_bits; + int i_count; + int p_count; + int skip_count; + int misc_bits; + + /** + * number of bits used for the previously encoded frame + * - encoding: Set by libavcodec. + * - decoding: unused + */ + int frame_bits; + + /** + * Private data of the user, can be used to carry app specific stuff. + * - encoding: Set by user. + * - decoding: Set by user. + */ + void *opaque; + + char codec_name[32]; + enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */ + enum CodecID codec_id; /* see CODEC_ID_xxx */ + + /** + * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). + * This is used to work around some encoder bugs. + * A demuxer should set this to what is stored in the field used to identify the codec. + * If there are multiple such fields in a container then the demuxer should choose the one + * which maximizes the information about the used codec. + * If the codec tag field in a container is larger then 32 bits then the demuxer should + * remap the longer ID to 32 bits with a table or other structure. Alternatively a new + * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated + * first. + * - encoding: Set by user, if not then the default based on codec_id will be used. + * - decoding: Set by user, will be converted to uppercase by libavcodec during init. + */ + unsigned int codec_tag; + + /** + * Work around bugs in encoders which sometimes cannot be detected automatically. + * - encoding: Set by user + * - decoding: Set by user + */ + int workaround_bugs; +#define FF_BUG_AUTODETECT 1 ///< autodetection +#define FF_BUG_OLD_MSMPEG4 2 +#define FF_BUG_XVID_ILACE 4 +#define FF_BUG_UMP4 8 +#define FF_BUG_NO_PADDING 16 +#define FF_BUG_AMV 32 +#define FF_BUG_AC_VLC 0 ///< Will be removed, libavcodec can now handle these non-compliant files by default. +#define FF_BUG_QPEL_CHROMA 64 +#define FF_BUG_STD_QPEL 128 +#define FF_BUG_QPEL_CHROMA2 256 +#define FF_BUG_DIRECT_BLOCKSIZE 512 +#define FF_BUG_EDGE 1024 +#define FF_BUG_HPEL_CHROMA 2048 +#define FF_BUG_DC_CLIP 4096 +#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders. +#define FF_BUG_TRUNCATED 16384 +//#define FF_BUG_FAKE_SCALABILITY 16 //Autodetection should work 100%. + + /** + * luma single coefficient elimination threshold + * - encoding: Set by user. + * - decoding: unused + */ + int luma_elim_threshold; + + /** + * chroma single coeff elimination threshold + * - encoding: Set by user. + * - decoding: unused + */ + int chroma_elim_threshold; + + /** + * strictly follow the standard (MPEG4, ...). + * - encoding: Set by user. + * - decoding: Set by user. + * Setting this to STRICT or higher means the encoder and decoder will + * generally do stupid things. While setting it to inofficial or lower + * will mean the encoder might use things that are not supported by all + * spec compliant decoders. Decoders make no difference between normal, + * inofficial and experimental, that is they always try to decode things + * when they can unless they are explicitly asked to behave stupid + * (=strictly conform to the specs) + */ + int strict_std_compliance; +#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to a older more strict version of the spec or reference software. +#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences. +#define FF_COMPLIANCE_NORMAL 0 +#define FF_COMPLIANCE_INOFFICIAL -1 ///< Allow inofficial extensions. +#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things. + + /** + * qscale offset between IP and B-frames + * - encoding: Set by user. + * - decoding: unused + */ + float b_quant_offset; + + /** + * Error recognization; higher values will detect more errors but may + * misdetect some more or less valid parts as errors. + * - encoding: unused + * - decoding: Set by user. + */ + int error_recognition; +#define FF_ER_CAREFUL 1 +#define FF_ER_COMPLIANT 2 +#define FF_ER_AGGRESSIVE 3 +#define FF_ER_VERY_AGGRESSIVE 4 + + /** + * Called at the beginning of each frame to get a buffer for it. + * If pic.reference is set then the frame will be read later by libavcodec. + * avcodec_align_dimensions2() should be used to find the required width and + * height, as they normally need to be rounded up to the next multiple of 16. + * if CODEC_CAP_DR1 is not set then get_buffer() must call + * avcodec_default_get_buffer() instead of providing buffers allocated by + * some other means. + * - encoding: unused + * - decoding: Set by libavcodec., user can override. + */ + int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * Called to release buffers which were allocated with get_buffer. + * A released buffer can be reused in get_buffer(). + * pic.data[*] must be set to NULL. + * - encoding: unused + * - decoding: Set by libavcodec., user can override. + */ + void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * Size of the frame reordering buffer in the decoder. + * For MPEG-2 it is 1 IPB or 0 low delay IP. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ + int has_b_frames; + + /** + * number of bytes per packet if constant and known or 0 + * Used by some WAV based audio codecs. + */ + int block_align; + + int parse_only; /* - decoding only: If true, only parsing is done + (function avcodec_parse_frame()). The frame + data is returned. Only MPEG codecs support this now. */ + + /** + * 0-> h263 quant 1-> mpeg quant + * - encoding: Set by user. + * - decoding: unused + */ + int mpeg_quant; + + /** + * pass1 encoding statistics output buffer + * - encoding: Set by libavcodec. + * - decoding: unused + */ + char *stats_out; + + /** + * pass2 encoding statistics input buffer + * Concatenated stuff from stats_out of pass1 should be placed here. + * - encoding: Allocated/set/freed by user. + * - decoding: unused + */ + char *stats_in; + + /** + * ratecontrol qmin qmax limiting method + * 0-> clipping, 1-> use a nice continous function to limit qscale wthin qmin/qmax. + * - encoding: Set by user. + * - decoding: unused + */ + float rc_qsquish; + + float rc_qmod_amp; + int rc_qmod_freq; + + /** + * ratecontrol override, see RcOverride + * - encoding: Allocated/set/freed by user. + * - decoding: unused + */ + RcOverride *rc_override; + int rc_override_count; + + /** + * rate control equation + * - encoding: Set by user + * - decoding: unused + */ + const char *rc_eq; + + /** + * maximum bitrate + * - encoding: Set by user. + * - decoding: unused + */ + int rc_max_rate; + + /** + * minimum bitrate + * - encoding: Set by user. + * - decoding: unused + */ + int rc_min_rate; + + /** + * decoder bitstream buffer size + * - encoding: Set by user. + * - decoding: unused + */ + int rc_buffer_size; + float rc_buffer_aggressivity; + + /** + * qscale factor between P and I-frames + * If > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset). + * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). + * - encoding: Set by user. + * - decoding: unused + */ + float i_quant_factor; + + /** + * qscale offset between P and I-frames + * - encoding: Set by user. + * - decoding: unused + */ + float i_quant_offset; + + /** + * initial complexity for pass1 ratecontrol + * - encoding: Set by user. + * - decoding: unused + */ + float rc_initial_cplx; + + /** + * DCT algorithm, see FF_DCT_* below + * - encoding: Set by user. + * - decoding: unused + */ + int dct_algo; +#define FF_DCT_AUTO 0 +#define FF_DCT_FASTINT 1 +#define FF_DCT_INT 2 +#define FF_DCT_MMX 3 +#define FF_DCT_MLIB 4 +#define FF_DCT_ALTIVEC 5 +#define FF_DCT_FAAN 6 + + /** + * luminance masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float lumi_masking; + + /** + * temporary complexity masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float temporal_cplx_masking; + + /** + * spatial complexity masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float spatial_cplx_masking; + + /** + * p block masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float p_masking; + + /** + * darkness masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float dark_masking; + + /** + * IDCT algorithm, see FF_IDCT_* below. + * - encoding: Set by user. + * - decoding: Set by user. + */ + int idct_algo; +#define FF_IDCT_AUTO 0 +#define FF_IDCT_INT 1 +#define FF_IDCT_SIMPLE 2 +#define FF_IDCT_SIMPLEMMX 3 +#define FF_IDCT_LIBMPEG2MMX 4 +#define FF_IDCT_PS2 5 +#define FF_IDCT_MLIB 6 +#define FF_IDCT_ARM 7 +#define FF_IDCT_ALTIVEC 8 +#define FF_IDCT_SH4 9 +#define FF_IDCT_SIMPLEARM 10 +#define FF_IDCT_H264 11 +#define FF_IDCT_VP3 12 +#define FF_IDCT_IPP 13 +#define FF_IDCT_XVIDMMX 14 +#define FF_IDCT_CAVS 15 +#define FF_IDCT_SIMPLEARMV5TE 16 +#define FF_IDCT_SIMPLEARMV6 17 +#define FF_IDCT_SIMPLEVIS 18 +#define FF_IDCT_WMV2 19 +#define FF_IDCT_FAAN 20 +#define FF_IDCT_EA 21 +#define FF_IDCT_SIMPLENEON 22 +#define FF_IDCT_SIMPLEALPHA 23 +#define FF_IDCT_BINK 24 + + /** + * slice count + * - encoding: Set by libavcodec. + * - decoding: Set by user (or 0). + */ + int slice_count; + /** + * slice offsets in the frame in bytes + * - encoding: Set/allocated by libavcodec. + * - decoding: Set/allocated by user (or NULL). + */ + int *slice_offset; + + /** + * error concealment flags + * - encoding: unused + * - decoding: Set by user. + */ + int error_concealment; +#define FF_EC_GUESS_MVS 1 +#define FF_EC_DEBLOCK 2 + + /** + * dsp_mask could be add used to disable unwanted CPU features + * CPU features (i.e. MMX, SSE. ...) + * + * With the FORCE flag you may instead enable given CPU features. + * (Dangerous: Usable in case of misdetection, improper usage however will + * result into program crash.) + */ + unsigned dsp_mask; +#define FF_MM_FORCE 0x80000000 /* Force usage of selected flags (OR) */ + /* lower 16 bits - CPU features */ +#define FF_MM_MMX 0x0001 ///< standard MMX +#define FF_MM_3DNOW 0x0004 ///< AMD 3DNOW +#if LIBAVCODEC_VERSION_MAJOR < 53 +#define FF_MM_MMXEXT 0x0002 ///< SSE integer functions or AMD MMX ext +#endif +#define FF_MM_MMX2 0x0002 ///< SSE integer functions or AMD MMX ext +#define FF_MM_SSE 0x0008 ///< SSE functions +#define FF_MM_SSE2 0x0010 ///< PIV SSE2 functions +#define FF_MM_3DNOWEXT 0x0020 ///< AMD 3DNowExt +#define FF_MM_SSE3 0x0040 ///< Prescott SSE3 functions +#define FF_MM_SSSE3 0x0080 ///< Conroe SSSE3 functions +#define FF_MM_SSE4 0x0100 ///< Penryn SSE4.1 functions +#define FF_MM_SSE42 0x0200 ///< Nehalem SSE4.2 functions +#define FF_MM_IWMMXT 0x0100 ///< XScale IWMMXT +#define FF_MM_ALTIVEC 0x0001 ///< standard AltiVec + + /** + * bits per sample/pixel from the demuxer (needed for huffyuv). + * - encoding: Set by libavcodec. + * - decoding: Set by user. + */ + int bits_per_coded_sample; + + /** + * prediction method (needed for huffyuv) + * - encoding: Set by user. + * - decoding: unused + */ + int prediction_method; +#define FF_PRED_LEFT 0 +#define FF_PRED_PLANE 1 +#define FF_PRED_MEDIAN 2 + + /** + * sample aspect ratio (0 if unknown) + * That is the width of a pixel divided by the height of the pixel. + * Numerator and denominator must be relatively prime and smaller than 256 for some video standards. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + AVRational sample_aspect_ratio; + + /** + * the picture in the bitstream + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ + AVFrame *coded_frame; + + /** + * debug + * - encoding: Set by user. + * - decoding: Set by user. + */ + int debug; +#define FF_DEBUG_PICT_INFO 1 +#define FF_DEBUG_RC 2 +#define FF_DEBUG_BITSTREAM 4 +#define FF_DEBUG_MB_TYPE 8 +#define FF_DEBUG_QP 16 +#define FF_DEBUG_MV 32 +#define FF_DEBUG_DCT_COEFF 0x00000040 +#define FF_DEBUG_SKIP 0x00000080 +#define FF_DEBUG_STARTCODE 0x00000100 +#define FF_DEBUG_PTS 0x00000200 +#define FF_DEBUG_ER 0x00000400 +#define FF_DEBUG_MMCO 0x00000800 +#define FF_DEBUG_BUGS 0x00001000 +#define FF_DEBUG_VIS_QP 0x00002000 +#define FF_DEBUG_VIS_MB_TYPE 0x00004000 +#define FF_DEBUG_BUFFERS 0x00008000 + + /** + * debug + * - encoding: Set by user. + * - decoding: Set by user. + */ + int debug_mv; +#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames +#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames +#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames + + /** + * error + * - encoding: Set by libavcodec if flags&CODEC_FLAG_PSNR. + * - decoding: unused + */ + uint64_t error[4]; + + /** + * minimum MB quantizer + * - encoding: unused + * - decoding: unused + */ + int mb_qmin; + + /** + * maximum MB quantizer + * - encoding: unused + * - decoding: unused + */ + int mb_qmax; + + /** + * motion estimation comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_cmp; + /** + * subpixel motion estimation comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_sub_cmp; + /** + * macroblock comparison function (not supported yet) + * - encoding: Set by user. + * - decoding: unused + */ + int mb_cmp; + /** + * interlaced DCT comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int ildct_cmp; +#define FF_CMP_SAD 0 +#define FF_CMP_SSE 1 +#define FF_CMP_SATD 2 +#define FF_CMP_DCT 3 +#define FF_CMP_PSNR 4 +#define FF_CMP_BIT 5 +#define FF_CMP_RD 6 +#define FF_CMP_ZERO 7 +#define FF_CMP_VSAD 8 +#define FF_CMP_VSSE 9 +#define FF_CMP_NSSE 10 +#define FF_CMP_W53 11 +#define FF_CMP_W97 12 +#define FF_CMP_DCTMAX 13 +#define FF_CMP_DCT264 14 +#define FF_CMP_CHROMA 256 + + /** + * ME diamond size & shape + * - encoding: Set by user. + * - decoding: unused + */ + int dia_size; + + /** + * amount of previous MV predictors (2a+1 x 2a+1 square) + * - encoding: Set by user. + * - decoding: unused + */ + int last_predictor_count; + + /** + * prepass for motion estimation + * - encoding: Set by user. + * - decoding: unused + */ + int pre_me; + + /** + * motion estimation prepass comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_pre_cmp; + + /** + * ME prepass diamond size & shape + * - encoding: Set by user. + * - decoding: unused + */ + int pre_dia_size; + + /** + * subpel ME quality + * - encoding: Set by user. + * - decoding: unused + */ + int me_subpel_quality; + + /** + * callback to negotiate the pixelFormat + * @param fmt is the list of formats which are supported by the codec, + * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality. + * The first is always the native one. + * @return the chosen format + * - encoding: unused + * - decoding: Set by user, if not set the native format will be chosen. + */ + enum PixelFormat (*get_format)(struct AVCodecContext *s, const enum PixelFormat * fmt); + + /** + * DTG active format information (additional aspect ratio + * information only used in DVB MPEG-2 transport streams) + * 0 if not set. + * + * - encoding: unused + * - decoding: Set by decoder. + */ + int dtg_active_format; +#define FF_DTG_AFD_SAME 8 +#define FF_DTG_AFD_4_3 9 +#define FF_DTG_AFD_16_9 10 +#define FF_DTG_AFD_14_9 11 +#define FF_DTG_AFD_4_3_SP_14_9 13 +#define FF_DTG_AFD_16_9_SP_14_9 14 +#define FF_DTG_AFD_SP_4_3 15 + + /** + * maximum motion estimation search range in subpel units + * If 0 then no limit. + * + * - encoding: Set by user. + * - decoding: unused + */ + int me_range; + + /** + * intra quantizer bias + * - encoding: Set by user. + * - decoding: unused + */ + int intra_quant_bias; +#define FF_DEFAULT_QUANT_BIAS 999999 + + /** + * inter quantizer bias + * - encoding: Set by user. + * - decoding: unused + */ + int inter_quant_bias; + + /** + * color table ID + * - encoding: unused + * - decoding: Which clrtable should be used for 8bit RGB images. + * Tables have to be stored somewhere. FIXME + */ + int color_table_id; + + /** + * internal_buffer count + * Don't touch, used by libavcodec default_get_buffer(). + */ + int internal_buffer_count; + + /** + * internal_buffers + * Don't touch, used by libavcodec default_get_buffer(). + */ + void *internal_buffer; + +#define FF_LAMBDA_SHIFT 7 +#define FF_LAMBDA_SCALE (1<<FF_LAMBDA_SHIFT) +#define FF_QP2LAMBDA 118 ///< factor to convert from H.263 QP to lambda +#define FF_LAMBDA_MAX (256*128-1) + +#define FF_QUALITY_SCALE FF_LAMBDA_SCALE //FIXME maybe remove + /** + * Global quality for codecs which cannot change it per frame. + * This should be proportional to MPEG-1/2/4 qscale. + * - encoding: Set by user. + * - decoding: unused + */ + int global_quality; + +#define FF_CODER_TYPE_VLC 0 +#define FF_CODER_TYPE_AC 1 +#define FF_CODER_TYPE_RAW 2 +#define FF_CODER_TYPE_RLE 3 +#define FF_CODER_TYPE_DEFLATE 4 + /** + * coder type + * - encoding: Set by user. + * - decoding: unused + */ + int coder_type; + + /** + * context model + * - encoding: Set by user. + * - decoding: unused + */ + int context_model; +#if 0 + /** + * + * - encoding: unused + * - decoding: Set by user. + */ + uint8_t * (*realloc)(struct AVCodecContext *s, uint8_t *buf, int buf_size); +#endif + + /** + * slice flags + * - encoding: unused + * - decoding: Set by user. + */ + int slice_flags; +#define SLICE_FLAG_CODED_ORDER 0x0001 ///< draw_horiz_band() is called in coded order instead of display +#define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG2 field pics) +#define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1) + + /** + * XVideo Motion Acceleration + * - encoding: forbidden + * - decoding: set by decoder + */ + int xvmc_acceleration; + + /** + * macroblock decision mode + * - encoding: Set by user. + * - decoding: unused + */ + int mb_decision; +#define FF_MB_DECISION_SIMPLE 0 ///< uses mb_cmp +#define FF_MB_DECISION_BITS 1 ///< chooses the one which needs the fewest bits +#define FF_MB_DECISION_RD 2 ///< rate distortion + + /** + * custom intra quantization matrix + * - encoding: Set by user, can be NULL. + * - decoding: Set by libavcodec. + */ + uint16_t *intra_matrix; + + /** + * custom inter quantization matrix + * - encoding: Set by user, can be NULL. + * - decoding: Set by libavcodec. + */ + uint16_t *inter_matrix; + + /** + * fourcc from the AVI stream header (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). + * This is used to work around some encoder bugs. + * - encoding: unused + * - decoding: Set by user, will be converted to uppercase by libavcodec during init. + */ + unsigned int stream_codec_tag; + + /** + * scene change detection threshold + * 0 is default, larger means fewer detected scene changes. + * - encoding: Set by user. + * - decoding: unused + */ + int scenechange_threshold; + + /** + * minimum Lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int lmin; + + /** + * maximum Lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int lmax; + + /** + * palette control structure + * - encoding: ??? (no palette-enabled encoder yet) + * - decoding: Set by user. + */ + struct AVPaletteControl *palctrl; + + /** + * noise reduction strength + * - encoding: Set by user. + * - decoding: unused + */ + int noise_reduction; + + /** + * Called at the beginning of a frame to get cr buffer for it. + * Buffer type (size, hints) must be the same. libavcodec won't check it. + * libavcodec will pass previous buffer in pic, function should return + * same buffer or new buffer with old frame "painted" into it. + * If pic.data[0] == NULL must behave like get_buffer(). + * if CODEC_CAP_DR1 is not set then reget_buffer() must call + * avcodec_default_reget_buffer() instead of providing buffers allocated by + * some other means. + * - encoding: unused + * - decoding: Set by libavcodec., user can override + */ + int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * Number of bits which should be loaded into the rc buffer before decoding starts. + * - encoding: Set by user. + * - decoding: unused + */ + int rc_initial_buffer_occupancy; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int inter_threshold; + + /** + * CODEC_FLAG2_* + * - encoding: Set by user. + * - decoding: Set by user. + */ + int flags2; + + /** + * Simulates errors in the bitstream to test error concealment. + * - encoding: Set by user. + * - decoding: unused + */ + int error_rate; + + /** + * MP3 antialias algorithm, see FF_AA_* below. + * - encoding: unused + * - decoding: Set by user. + */ + int antialias_algo; +#define FF_AA_AUTO 0 +#define FF_AA_FASTINT 1 //not implemented yet +#define FF_AA_INT 2 +#define FF_AA_FLOAT 3 + /** + * quantizer noise shaping + * - encoding: Set by user. + * - decoding: unused + */ + int quantizer_noise_shaping; + + /** + * thread count + * is used to decide how many independent tasks should be passed to execute() + * - encoding: Set by user. + * - decoding: Set by user. + */ + int thread_count; + + /** + * The codec may call this to execute several independent things. + * It will return only after finishing all tasks. + * The user may replace this with some multithreaded implementation, + * the default implementation will execute the parts serially. + * @param count the number of things to execute + * - encoding: Set by libavcodec, user can override. + * - decoding: Set by libavcodec, user can override. + */ + int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size); + + /** + * thread opaque + * Can be used by execute() to store some per AVCodecContext stuff. + * - encoding: set by execute() + * - decoding: set by execute() + */ + void *thread_opaque; + + /** + * Motion estimation threshold below which no motion estimation is + * performed, but instead the user specified motion vectors are used. + * + * - encoding: Set by user. + * - decoding: unused + */ + int me_threshold; + + /** + * Macroblock threshold below which the user specified macroblock types will be used. + * - encoding: Set by user. + * - decoding: unused + */ + int mb_threshold; + + /** + * precision of the intra DC coefficient - 8 + * - encoding: Set by user. + * - decoding: unused + */ + int intra_dc_precision; + + /** + * noise vs. sse weight for the nsse comparsion function + * - encoding: Set by user. + * - decoding: unused + */ + int nsse_weight; + + /** + * Number of macroblock rows at the top which are skipped. + * - encoding: unused + * - decoding: Set by user. + */ + int skip_top; + + /** + * Number of macroblock rows at the bottom which are skipped. + * - encoding: unused + * - decoding: Set by user. + */ + int skip_bottom; + + /** + * profile + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int profile; +#define FF_PROFILE_UNKNOWN -99 + +#define FF_PROFILE_AAC_MAIN 0 +#define FF_PROFILE_AAC_LOW 1 +#define FF_PROFILE_AAC_SSR 2 +#define FF_PROFILE_AAC_LTP 3 + +#define FF_PROFILE_H264_BASELINE 66 +#define FF_PROFILE_H264_MAIN 77 +#define FF_PROFILE_H264_EXTENDED 88 +#define FF_PROFILE_H264_HIGH 100 +#define FF_PROFILE_H264_HIGH_10 110 +#define FF_PROFILE_H264_HIGH_422 122 +#define FF_PROFILE_H264_HIGH_444 244 +#define FF_PROFILE_H264_CAVLC_444 44 + + /** + * level + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int level; +#define FF_LEVEL_UNKNOWN -99 + + /** + * low resolution decoding, 1-> 1/2 size, 2->1/4 size + * - encoding: unused + * - decoding: Set by user. + */ + int lowres; + + /** + * Bitstream width / height, may be different from width/height if lowres + * or other things are used. + * - encoding: unused + * - decoding: Set by user before init if known. Codec should override / dynamically change if needed. + */ + int coded_width, coded_height; + + /** + * frame skip threshold + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_threshold; + + /** + * frame skip factor + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_factor; + + /** + * frame skip exponent + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_exp; + + /** + * frame skip comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_cmp; + + /** + * Border processing masking, raises the quantizer for mbs on the borders + * of the picture. + * - encoding: Set by user. + * - decoding: unused + */ + float border_masking; + + /** + * minimum MB lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int mb_lmin; + + /** + * maximum MB lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int mb_lmax; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int me_penalty_compensation; + + /** + * + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_loop_filter; + + /** + * + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_idct; + + /** + * + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_frame; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int bidir_refine; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int brd_scale; + + /** + * constant rate factor - quality-based VBR - values ~correspond to qps + * - encoding: Set by user. + * - decoding: unused + */ + float crf; + + /** + * constant quantization parameter rate control method + * - encoding: Set by user. + * - decoding: unused + */ + int cqp; + + /** + * minimum GOP size + * - encoding: Set by user. + * - decoding: unused + */ + int keyint_min; + + /** + * number of reference frames + * - encoding: Set by user. + * - decoding: Set by lavc. + */ + int refs; + + /** + * chroma qp offset from luma + * - encoding: Set by user. + * - decoding: unused + */ + int chromaoffset; + + /** + * Influences how often B-frames are used. + * - encoding: Set by user. + * - decoding: unused + */ + int bframebias; + + /** + * trellis RD quantization + * - encoding: Set by user. + * - decoding: unused + */ + int trellis; + + /** + * Reduce fluctuations in qp (before curve compression). + * - encoding: Set by user. + * - decoding: unused + */ + float complexityblur; + + /** + * in-loop deblocking filter alphac0 parameter + * alpha is in the range -6...6 + * - encoding: Set by user. + * - decoding: unused + */ + int deblockalpha; + + /** + * in-loop deblocking filter beta parameter + * beta is in the range -6...6 + * - encoding: Set by user. + * - decoding: unused + */ + int deblockbeta; + + /** + * macroblock subpartition sizes to consider - p8x8, p4x4, b8x8, i8x8, i4x4 + * - encoding: Set by user. + * - decoding: unused + */ + int partitions; +#define X264_PART_I4X4 0x001 /* Analyze i4x4 */ +#define X264_PART_I8X8 0x002 /* Analyze i8x8 (requires 8x8 transform) */ +#define X264_PART_P8X8 0x010 /* Analyze p16x8, p8x16 and p8x8 */ +#define X264_PART_P4X4 0x020 /* Analyze p8x4, p4x8, p4x4 */ +#define X264_PART_B8X8 0x100 /* Analyze b16x8, b8x16 and b8x8 */ + + /** + * direct MV prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto) + * - encoding: Set by user. + * - decoding: unused + */ + int directpred; + + /** + * Audio cutoff bandwidth (0 means "automatic") + * - encoding: Set by user. + * - decoding: unused + */ + int cutoff; + + /** + * Multiplied by qscale for each frame and added to scene_change_score. + * - encoding: Set by user. + * - decoding: unused + */ + int scenechange_factor; + + /** + * + * Note: Value depends upon the compare function used for fullpel ME. + * - encoding: Set by user. + * - decoding: unused + */ + int mv0_threshold; + + /** + * Adjusts sensitivity of b_frame_strategy 1. + * - encoding: Set by user. + * - decoding: unused + */ + int b_sensitivity; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int compression_level; +#define FF_COMPRESSION_DEFAULT -1 + + /** + * Sets whether to use LPC mode - used by FLAC encoder. + * - encoding: Set by user. + * - decoding: unused + */ + int use_lpc; + + /** + * LPC coefficient precision - used by FLAC encoder + * - encoding: Set by user. + * - decoding: unused + */ + int lpc_coeff_precision; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int min_prediction_order; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int max_prediction_order; + + /** + * search method for selecting prediction order + * - encoding: Set by user. + * - decoding: unused + */ + int prediction_order_method; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int min_partition_order; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int max_partition_order; + + /** + * GOP timecode frame start number, in non drop frame format + * - encoding: Set by user. + * - decoding: unused + */ + int64_t timecode_frame_start; + +#if LIBAVCODEC_VERSION_MAJOR < 53 + /** + * Decoder should decode to this many channels if it can (0 for default) + * - encoding: unused + * - decoding: Set by user. + * @deprecated Deprecated in favor of request_channel_layout. + */ + int request_channels; +#endif + + /** + * Percentage of dynamic range compression to be applied by the decoder. + * The default value is 1.0, corresponding to full compression. + * - encoding: unused + * - decoding: Set by user. + */ + float drc_scale; + + /** + * opaque 64bit number (generally a PTS) that will be reordered and + * output in AVFrame.reordered_opaque + * - encoding: unused + * - decoding: Set by user. + */ + int64_t reordered_opaque; + + /** + * Bits per sample/pixel of internal libavcodec pixel/sample format. + * This field is applicable only when sample_fmt is SAMPLE_FMT_S32. + * - encoding: set by user. + * - decoding: set by libavcodec. + */ + int bits_per_raw_sample; + + /** + * Audio channel layout. + * - encoding: set by user. + * - decoding: set by libavcodec. + */ + int64_t channel_layout; + + /** + * Request decoder to use this channel layout if it can (0 for default) + * - encoding: unused + * - decoding: Set by user. + */ + int64_t request_channel_layout; + + /** + * Ratecontrol attempt to use, at maximum, <value> of what can be used without an underflow. + * - encoding: Set by user. + * - decoding: unused. + */ + float rc_max_available_vbv_use; + + /** + * Ratecontrol attempt to use, at least, <value> times the amount needed to prevent a vbv overflow. + * - encoding: Set by user. + * - decoding: unused. + */ + float rc_min_vbv_overflow_use; + + /** + * Hardware accelerator in use + * - encoding: unused. + * - decoding: Set by libavcodec + */ + struct AVHWAccel *hwaccel; + + /** + * For some codecs, the time base is closer to the field rate than the frame rate. + * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration + * if no telecine is used ... + * + * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2. + */ + int ticks_per_frame; + + /** + * Hardware accelerator context. + * For some hardware accelerators, a global context needs to be + * provided by the user. In that case, this holds display-dependent + * data FFmpeg cannot instantiate itself. Please refer to the + * FFmpeg HW accelerator documentation to know how to fill this + * is. e.g. for VA API, this is a struct vaapi_context. + * - encoding: unused + * - decoding: Set by user + */ + void *hwaccel_context; + + /** + * Chromaticity coordinates of the source primaries. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorPrimaries color_primaries; + + /** + * Color Transfer Characteristic. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorTransferCharacteristic color_trc; + + /** + * YUV colorspace type. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorSpace colorspace; + + /** + * MPEG vs JPEG YUV range. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorRange color_range; + + /** + * This defines the location of chroma samples. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVChromaLocation chroma_sample_location; + + /** + * The codec may call this to execute several independent things. + * It will return only after finishing all tasks. + * The user may replace this with some multithreaded implementation, + * the default implementation will execute the parts serially. + * Also see avcodec_thread_init and e.g. the --enable-pthread configure option. + * @param c context passed also to func + * @param count the number of things to execute + * @param arg2 argument passed unchanged to func + * @param ret return values of executed functions, must have space for "count" values. May be NULL. + * @param func function that will be called count times, with jobnr from 0 to count-1. + * threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS and so that no + * two instances of func executing at the same time will have the same threadnr. + * @return always 0 currently, but code should handle a future improvement where when any call to func + * returns < 0 no further calls to func may be done and < 0 is returned. + * - encoding: Set by libavcodec, user can override. + * - decoding: Set by libavcodec, user can override. + */ + int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count); + + /** + * explicit P-frame weighted prediction analysis method + * 0: off + * 1: fast blind weighting (one reference duplicate with -1 offset) + * 2: smart weighting (full fade detection analysis) + * - encoding: Set by user. + * - decoding: unused + */ + int weighted_p_pred; + + /** + * AQ mode + * 0: Disabled + * 1: Variance AQ (complexity mask) + * 2: Auto-variance AQ (experimental) + * - encoding: Set by user + * - decoding: unused + */ + int aq_mode; + + /** + * AQ strength + * Reduces blocking and blurring in flat and textured areas. + * - encoding: Set by user + * - decoding: unused + */ + float aq_strength; + + /** + * PSY RD + * Strength of psychovisual optimization + * - encoding: Set by user + * - decoding: unused + */ + float psy_rd; + + /** + * PSY trellis + * Strength of psychovisual optimization + * - encoding: Set by user + * - decoding: unused + */ + float psy_trellis; + + /** + * RC lookahead + * Number of frames for frametype and ratecontrol lookahead + * - encoding: Set by user + * - decoding: unused + */ + int rc_lookahead; +} AVCodecContext; + +/** + * AVCodec. + */ +typedef struct AVCodec { + /** + * Name of the codec implementation. + * The name is globally unique among encoders and among decoders (but an + * encoder and a decoder can share the same name). + * This is the primary way to find a codec from the user perspective. + */ + const char *name; + enum AVMediaType type; + enum CodecID id; + int priv_data_size; + int (*init)(AVCodecContext *); + int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data); + int (*close)(AVCodecContext *); + int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt); + /** + * Codec capabilities. + * see CODEC_CAP_* + */ + int capabilities; + struct AVCodec *next; + /** + * Flush buffers. + * Will be called when seeking + */ + void (*flush)(AVCodecContext *); + const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0} + const enum PixelFormat *pix_fmts; ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1 + /** + * Descriptive name for the codec, meant to be more human readable than name. + * You should use the NULL_IF_CONFIG_SMALL() macro to define it. + */ + const char *long_name; + const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 + const enum SampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 + const int64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 +} AVCodec; + +/** + * AVHWAccel. + */ +typedef struct AVHWAccel { + /** + * Name of the hardware accelerated codec. + * The name is globally unique among encoders and among decoders (but an + * encoder and a decoder can share the same name). + */ + const char *name; + + /** + * Type of codec implemented by the hardware accelerator. + * + * See AVMEDIA_TYPE_xxx + */ + enum AVMediaType type; + + /** + * Codec implemented by the hardware accelerator. + * + * See CODEC_ID_xxx + */ + enum CodecID id; + + /** + * Supported pixel format. + * + * Only hardware accelerated formats are supported here. + */ + enum PixelFormat pix_fmt; + + /** + * Hardware accelerated codec capabilities. + * see FF_HWACCEL_CODEC_CAP_* + */ + int capabilities; + + struct AVHWAccel *next; + + /** + * Called at the beginning of each frame or field picture. + * + * Meaningful frame information (codec specific) is guaranteed to + * be parsed at this point. This function is mandatory. + * + * Note that buf can be NULL along with buf_size set to 0. + * Otherwise, this means the whole frame is available at this point. + * + * @param avctx the codec context + * @param buf the frame data buffer base + * @param buf_size the size of the frame in bytes + * @return zero if successful, a negative value otherwise + */ + int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); + + /** + * Callback for each slice. + * + * Meaningful slice information (codec specific) is guaranteed to + * be parsed at this point. This function is mandatory. + * + * @param avctx the codec context + * @param buf the slice data buffer base + * @param buf_size the size of the slice in bytes + * @return zero if successful, a negative value otherwise + */ + int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); + + /** + * Called at the end of each frame or field picture. + * + * The whole picture is parsed at this point and can now be sent + * to the hardware accelerator. This function is mandatory. + * + * @param avctx the codec context + * @return zero if successful, a negative value otherwise + */ + int (*end_frame)(AVCodecContext *avctx); + + /** + * Size of HW accelerator private data. + * + * Private data is allocated with av_mallocz() before + * AVCodecContext.get_buffer() and deallocated after + * AVCodecContext.release_buffer(). + */ + int priv_data_size; +} AVHWAccel; + +/** + * four components are given, that's all. + * the last component is alpha + */ +typedef struct AVPicture { + uint8_t *data[4]; + int linesize[4]; ///< number of bytes per line +} AVPicture; + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * AVPaletteControl + * This structure defines a method for communicating palette changes + * between and demuxer and a decoder. + * + * @deprecated Use AVPacket to send palette changes instead. + * This is totally broken. + */ +#define AVPALETTE_SIZE 1024 +#define AVPALETTE_COUNT 256 +typedef struct AVPaletteControl { + + /* Demuxer sets this to 1 to indicate the palette has changed; + * decoder resets to 0. */ + int palette_changed; + + /* 4-byte ARGB palette entries, stored in native byte order; note that + * the individual palette components should be on a 8-bit scale; if + * the palette data comes from an IBM VGA native format, the component + * data is probably 6 bits in size and needs to be scaled. */ + unsigned int palette[AVPALETTE_COUNT]; + +} AVPaletteControl attribute_deprecated; +#endif + +enum AVSubtitleType { + SUBTITLE_NONE, + + SUBTITLE_BITMAP, ///< A bitmap, pict will be set + + /** + * Plain text, the text field must be set by the decoder and is + * authoritative. ass and pict fields may contain approximations. + */ + SUBTITLE_TEXT, + + /** + * Formatted text, the ass field must be set by the decoder and is + * authoritative. pict and text fields may contain approximations. + */ + SUBTITLE_ASS, +}; + +typedef struct AVSubtitleRect { + int x; ///< top left corner of pict, undefined when pict is not set + int y; ///< top left corner of pict, undefined when pict is not set + int w; ///< width of pict, undefined when pict is not set + int h; ///< height of pict, undefined when pict is not set + int nb_colors; ///< number of colors in pict, undefined when pict is not set + + /** + * data+linesize for the bitmap of this subtitle. + * can be set for text/ass as well once they where rendered + */ + AVPicture pict; + enum AVSubtitleType type; + + char *text; ///< 0 terminated plain UTF-8 text + + /** + * 0 terminated ASS/SSA compatible event line. + * The pressentation of this is unaffected by the other values in this + * struct. + */ + char *ass; +} AVSubtitleRect; + +typedef struct AVSubtitle { + uint16_t format; /* 0 = graphics */ + uint32_t start_display_time; /* relative to packet pts, in ms */ + uint32_t end_display_time; /* relative to packet pts, in ms */ + unsigned num_rects; + AVSubtitleRect **rects; + int64_t pts; ///< Same as packet pts, in AV_TIME_BASE +} AVSubtitle; + +/* packet functions */ + +/** + * @deprecated use NULL instead + */ +attribute_deprecated void av_destruct_packet_nofree(AVPacket *pkt); + +/** + * Default packet destructor. + */ +void av_destruct_packet(AVPacket *pkt); + +/** + * Initialize optional fields of a packet with default values. + * + * @param pkt packet + */ +void av_init_packet(AVPacket *pkt); + +/** + * Allocate the payload of a packet and initialize its fields with + * default values. + * + * @param pkt packet + * @param size wanted payload size + * @return 0 if OK, AVERROR_xxx otherwise + */ +int av_new_packet(AVPacket *pkt, int size); + +/** + * Reduce packet size, correctly zeroing padding + * + * @param pkt packet + * @param size new size + */ +void av_shrink_packet(AVPacket *pkt, int size); + +/** + * @warning This is a hack - the packet memory allocation stuff is broken. The + * packet is allocated if it was not really allocated. + */ +int av_dup_packet(AVPacket *pkt); + +/** + * Free a packet. + * + * @param pkt packet to free + */ +void av_free_packet(AVPacket *pkt); + +/* resample.c */ + +struct ReSampleContext; +struct AVResampleContext; + +typedef struct ReSampleContext ReSampleContext; + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * @deprecated Use av_audio_resample_init() instead. + */ +attribute_deprecated ReSampleContext *audio_resample_init(int output_channels, int input_channels, + int output_rate, int input_rate); +#endif +/** + * Initializes audio resampling context + * + * @param output_channels number of output channels + * @param input_channels number of input channels + * @param output_rate output sample rate + * @param input_rate input sample rate + * @param sample_fmt_out requested output sample format + * @param sample_fmt_in input sample format + * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq + * @param log2_phase_count log2 of the number of entries in the polyphase filterbank + * @param linear If 1 then the used FIR filter will be linearly interpolated + between the 2 closest, if 0 the closest will be used + * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate + * @return allocated ReSampleContext, NULL if error occured + */ +ReSampleContext *av_audio_resample_init(int output_channels, int input_channels, + int output_rate, int input_rate, + enum SampleFormat sample_fmt_out, + enum SampleFormat sample_fmt_in, + int filter_length, int log2_phase_count, + int linear, double cutoff); + +int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples); +void audio_resample_close(ReSampleContext *s); + + +/** + * Initializes an audio resampler. + * Note, if either rate is not an integer then simply scale both rates up so they are. + * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq + * @param log2_phase_count log2 of the number of entries in the polyphase filterbank + * @param linear If 1 then the used FIR filter will be linearly interpolated + between the 2 closest, if 0 the closest will be used + * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate + */ +struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff); + +/** + * resamples. + * @param src an array of unconsumed samples + * @param consumed the number of samples of src which have been consumed are returned here + * @param src_size the number of unconsumed samples available + * @param dst_size the amount of space in samples available in dst + * @param update_ctx If this is 0 then the context will not be modified, that way several channels can be resampled with the same context. + * @return the number of samples written in dst or -1 if an error occurred + */ +int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx); + + +/** + * Compensates samplerate/timestamp drift. The compensation is done by changing + * the resampler parameters, so no audible clicks or similar distortions occur + * @param compensation_distance distance in output samples over which the compensation should be performed + * @param sample_delta number of output samples which should be output less + * + * example: av_resample_compensate(c, 10, 500) + * here instead of 510 samples only 500 samples would be output + * + * note, due to rounding the actual compensation might be slightly different, + * especially if the compensation_distance is large and the in_rate used during init is small + */ +void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance); +void av_resample_close(struct AVResampleContext *c); + +/** + * Allocate memory for a picture. Call avpicture_free to free it. + * + * @param picture the picture to be filled in + * @param pix_fmt the format of the picture + * @param width the width of the picture + * @param height the height of the picture + * @return zero if successful, a negative value if not + */ +int avpicture_alloc(AVPicture *picture, enum PixelFormat pix_fmt, int width, int height); + +/** + * Free a picture previously allocated by avpicture_alloc(). + * + * @param picture the AVPicture to be freed + */ +void avpicture_free(AVPicture *picture); + +/** + * Fill in the AVPicture fields. + * The fields of the given AVPicture are filled in by using the 'ptr' address + * which points to the image data buffer. Depending on the specified picture + * format, one or multiple image data pointers and line sizes will be set. + * If a planar format is specified, several pointers will be set pointing to + * the different picture planes and the line sizes of the different planes + * will be stored in the lines_sizes array. + * Call with ptr == NULL to get the required size for the ptr buffer. + * + * @param picture AVPicture whose fields are to be filled in + * @param ptr Buffer which will contain or contains the actual image data + * @param pix_fmt The format in which the picture data is stored. + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @return size of the image data in bytes + */ +int avpicture_fill(AVPicture *picture, uint8_t *ptr, + enum PixelFormat pix_fmt, int width, int height); +int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height, + unsigned char *dest, int dest_size); + +/** + * Calculate the size in bytes that a picture of the given width and height + * would occupy if stored in the given picture format. + * Note that this returns the size of a compact representation as generated + * by avpicture_layout, which can be smaller than the size required for e.g. + * avpicture_fill. + * + * @param pix_fmt the given picture format + * @param width the width of the image + * @param height the height of the image + * @return Image data size in bytes or -1 on error (e.g. too large dimensions). + */ +int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height); +void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift); +const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt); +void avcodec_set_dimensions(AVCodecContext *s, int width, int height); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * Returns the pixel format corresponding to the name name. + * + * If there is no pixel format with name name, then looks for a + * pixel format with the name corresponding to the native endian + * format of name. + * For example in a little-endian system, first looks for "gray16", + * then for "gray16le". + * + * Finally if no pixel format has been found, returns PIX_FMT_NONE. + * + * @deprecated Deprecated in favor of av_get_pix_fmt(). + */ +attribute_deprecated enum PixelFormat avcodec_get_pix_fmt(const char* name); +#endif + +/** + * Returns a value representing the fourCC code associated to the + * pixel format pix_fmt, or 0 if no associated fourCC code can be + * found. + */ +unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat pix_fmt); + +#define FF_LOSS_RESOLUTION 0x0001 /**< loss due to resolution change */ +#define FF_LOSS_DEPTH 0x0002 /**< loss due to color depth change */ +#define FF_LOSS_COLORSPACE 0x0004 /**< loss due to color space conversion */ +#define FF_LOSS_ALPHA 0x0008 /**< loss of alpha bits */ +#define FF_LOSS_COLORQUANT 0x0010 /**< loss due to color quantization */ +#define FF_LOSS_CHROMA 0x0020 /**< loss of chroma (e.g. RGB to gray conversion) */ + +/** + * Computes what kind of losses will occur when converting from one specific + * pixel format to another. + * When converting from one pixel format to another, information loss may occur. + * For example, when converting from RGB24 to GRAY, the color information will + * be lost. Similarly, other losses occur when converting from some formats to + * other formats. These losses can involve loss of chroma, but also loss of + * resolution, loss of color depth, loss due to the color space conversion, loss + * of the alpha bits or loss due to color quantization. + * avcodec_get_fix_fmt_loss() informs you about the various types of losses + * which will occur when converting from one pixel format to another. + * + * @param[in] dst_pix_fmt destination pixel format + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @return Combination of flags informing you what kind of losses will occur. + */ +int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt, + int has_alpha); + +/** + * Finds the best pixel format to convert to given a certain source pixel + * format. When converting from one pixel format to another, information loss + * may occur. For example, when converting from RGB24 to GRAY, the color + * information will be lost. Similarly, other losses occur when converting from + * some formats to other formats. avcodec_find_best_pix_fmt() searches which of + * the given pixel formats should be used to suffer the least amount of loss. + * The pixel formats from which it chooses one, are determined by the + * pix_fmt_mask parameter. + * + * @code + * src_pix_fmt = PIX_FMT_YUV420P; + * pix_fmt_mask = (1 << PIX_FMT_YUV422P) || (1 << PIX_FMT_RGB24); + * dst_pix_fmt = avcodec_find_best_pix_fmt(pix_fmt_mask, src_pix_fmt, alpha, &loss); + * @endcode + * + * @param[in] pix_fmt_mask bitmask determining which pixel format to choose from + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur. + * @return The best pixel format to convert to or -1 if none was found. + */ +enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt, + int has_alpha, int *loss_ptr); + + +/** + * Print in buf the string corresponding to the pixel format with + * number pix_fmt, or an header if pix_fmt is negative. + * + * @param[in] buf the buffer where to write the string + * @param[in] buf_size the size of buf + * @param[in] pix_fmt the number of the pixel format to print the corresponding info string, or + * a negative value to print the corresponding header. + * Meaningful values for obtaining a pixel format info vary from 0 to PIX_FMT_NB -1. + */ +void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt); + +#define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */ +#define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */ + +/** + * Tell if an image really has transparent alpha values. + * @return ored mask of FF_ALPHA_xxx constants + */ +int img_get_alpha_info(const AVPicture *src, + enum PixelFormat pix_fmt, int width, int height); + +/* deinterlace a picture */ +/* deinterlace - if not supported return -1 */ +int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, + enum PixelFormat pix_fmt, int width, int height); + +/* external high level API */ + +/** + * If c is NULL, returns the first registered codec, + * if c is non-NULL, returns the next registered codec after c, + * or NULL if c is the last one. + */ +AVCodec *av_codec_next(AVCodec *c); + +/** + * Returns the LIBAVCODEC_VERSION_INT constant. + */ +unsigned avcodec_version(void); + +/** + * Returns the libavcodec build-time configuration. + */ +const char *avcodec_configuration(void); + +/** + * Returns the libavcodec license. + */ +const char *avcodec_license(void); + +/** + * Initializes libavcodec. + * + * @warning This function must be called before any other libavcodec + * function. + */ +void avcodec_init(void); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * @deprecated Deprecated in favor of avcodec_register(). + */ +attribute_deprecated void register_avcodec(AVCodec *codec); +#endif + +/** + * Register the codec codec and initialize libavcodec. + * + * @see avcodec_init() + */ +void avcodec_register(AVCodec *codec); + +/** + * Finds a registered encoder with a matching codec ID. + * + * @param id CodecID of the requested encoder + * @return An encoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_encoder(enum CodecID id); + +/** + * Finds a registered encoder with the specified name. + * + * @param name name of the requested encoder + * @return An encoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_encoder_by_name(const char *name); + +/** + * Finds a registered decoder with a matching codec ID. + * + * @param id CodecID of the requested decoder + * @return A decoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_decoder(enum CodecID id); + +/** + * Finds a registered decoder with the specified name. + * + * @param name name of the requested decoder + * @return A decoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_decoder_by_name(const char *name); +void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); + +/** + * Sets the fields of the given AVCodecContext to default values. + * + * @param s The AVCodecContext of which the fields should be set to default values. + */ +void avcodec_get_context_defaults(AVCodecContext *s); + +/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! + * we WILL change its arguments and name a few times! */ +void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType); + +/** + * Allocates an AVCodecContext and sets its fields to default values. The + * resulting struct can be deallocated by simply calling av_free(). + * + * @return An AVCodecContext filled with default values or NULL on failure. + * @see avcodec_get_context_defaults + */ +AVCodecContext *avcodec_alloc_context(void); + +/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! + * we WILL change its arguments and name a few times! */ +AVCodecContext *avcodec_alloc_context2(enum AVMediaType); + +/** + * Copy the settings of the source AVCodecContext into the destination + * AVCodecContext. The resulting destination codec context will be + * unopened, i.e. you are required to call avcodec_open() before you + * can use this AVCodecContext to decode/encode video/audio data. + * + * @param dest target codec context, should be initialized with + * avcodec_alloc_context(), but otherwise uninitialized + * @param src source codec context + * @return AVERROR() on error (e.g. memory allocation error), 0 on success + */ +int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src); + +/** + * Sets the fields of the given AVFrame to default values. + * + * @param pic The AVFrame of which the fields should be set to default values. + */ +void avcodec_get_frame_defaults(AVFrame *pic); + +/** + * Allocates an AVFrame and sets its fields to default values. The resulting + * struct can be deallocated by simply calling av_free(). + * + * @return An AVFrame filled with default values or NULL on failure. + * @see avcodec_get_frame_defaults + */ +AVFrame *avcodec_alloc_frame(void); + +int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic); +void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic); +int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic); + +/** + * Returns the amount of padding in pixels which the get_buffer callback must + * provide around the edge of the image for codecs which do not have the + * CODEC_FLAG_EMU_EDGE flag. + * + * @return Required padding in pixels. + */ +unsigned avcodec_get_edge_width(void); +/** + * Modifies width and height values so that they will result in a memory + * buffer that is acceptable for the codec if you do not use any horizontal + * padding. + * + * May only be used if a codec with CODEC_CAP_DR1 has been opened. + * If CODEC_FLAG_EMU_EDGE is not set, the dimensions must have been increased + * according to avcodec_get_edge_width() before. + */ +void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); +/** + * Modifies width and height values so that they will result in a memory + * buffer that is acceptable for the codec if you also ensure that all + * line sizes are a multiple of the respective linesize_align[i]. + * + * May only be used if a codec with CODEC_CAP_DR1 has been opened. + * If CODEC_FLAG_EMU_EDGE is not set, the dimensions must have been increased + * according to avcodec_get_edge_width() before. + */ +void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, + int linesize_align[4]); + +/** + * Checks if the given dimension of a picture is valid, meaning that all + * bytes of the picture can be addressed with a signed int. + * + * @param[in] w Width of the picture. + * @param[in] h Height of the picture. + * @return Zero if valid, a negative value if invalid. + */ +int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h); +enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat * fmt); + +int avcodec_thread_init(AVCodecContext *s, int thread_count); +void avcodec_thread_free(AVCodecContext *s); +int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size); +int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count); +//FIXME func typedef + +/** + * Initializes the AVCodecContext to use the given AVCodec. Prior to using this + * function the context has to be allocated. + * + * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), + * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for + * retrieving a codec. + * + * @warning This function is not thread safe! + * + * @code + * avcodec_register_all(); + * codec = avcodec_find_decoder(CODEC_ID_H264); + * if (!codec) + * exit(1); + * + * context = avcodec_alloc_context(); + * + * if (avcodec_open(context, codec) < 0) + * exit(1); + * @endcode + * + * @param avctx The context which will be set up to use the given codec. + * @param codec The codec to use within the context. + * @return zero on success, a negative value on error + * @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder + */ +int avcodec_open(AVCodecContext *avctx, AVCodec *codec); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * Decodes an audio frame from buf into samples. + * Wrapper function which calls avcodec_decode_audio3. + * + * @deprecated Use avcodec_decode_audio3 instead. + * @param avctx the codec context + * @param[out] samples the output buffer + * @param[in,out] frame_size_ptr the output buffer size in bytes + * @param[in] buf the input buffer + * @param[in] buf_size the input buffer size in bytes + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame could be decompressed. + */ +attribute_deprecated int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, + const uint8_t *buf, int buf_size); +#endif + +/** + * Decodes the audio frame of size avpkt->size from avpkt->data into samples. + * Some decoders may support multiple frames in a single AVPacket, such + * decoders would then just decode the first frame. In this case, + * avcodec_decode_audio3 has to be called again with an AVPacket that contains + * the remaining data in order to decode the second frame etc. + * If no frame + * could be outputted, frame_size_ptr is zero. Otherwise, it is the + * decompressed frame size in bytes. + * + * @warning You must set frame_size_ptr to the allocated size of the + * output buffer before calling avcodec_decode_audio3(). + * + * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than + * the actual read bytes because some optimized bitstream readers read 32 or 64 + * bits at once and could read over the end. + * + * @warning The end of the input buffer avpkt->data should be set to 0 to ensure that + * no overreading happens for damaged MPEG streams. + * + * @note You might have to align the input buffer avpkt->data and output buffer + * samples. The alignment requirements depend on the CPU: On some CPUs it isn't + * necessary at all, on others it won't work at all if not aligned and on others + * it will work but it will have an impact on performance. + * + * In practice, avpkt->data should have 4 byte alignment at minimum and + * samples should be 16 byte aligned unless the CPU doesn't need it + * (AltiVec and SSE do). + * + * @param avctx the codec context + * @param[out] samples the output buffer, sample type in avctx->sample_fmt + * @param[in,out] frame_size_ptr the output buffer size in bytes + * @param[in] avpkt The input AVPacket containing the input buffer. + * You can create such packet with av_init_packet() and by then setting + * data and size, some decoders might in addition need other fields. + * All decoders are designed to use the least fields possible though. + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame data was decompressed (used) from the input AVPacket. + */ +int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, + AVPacket *avpkt); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * Decodes a video frame from buf into picture. + * Wrapper function which calls avcodec_decode_video2. + * + * @deprecated Use avcodec_decode_video2 instead. + * @param avctx the codec context + * @param[out] picture The AVFrame in which the decoded video frame will be stored. + * @param[in] buf the input buffer + * @param[in] buf_size the size of the input buffer in bytes + * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame could be decompressed. + */ +attribute_deprecated int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + const uint8_t *buf, int buf_size); +#endif + +/** + * Decodes the video frame of size avpkt->size from avpkt->data into picture. + * Some decoders may support multiple frames in a single AVPacket, such + * decoders would then just decode the first frame. + * + * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than + * the actual read bytes because some optimized bitstream readers read 32 or 64 + * bits at once and could read over the end. + * + * @warning The end of the input buffer buf should be set to 0 to ensure that + * no overreading happens for damaged MPEG streams. + * + * @note You might have to align the input buffer avpkt->data. + * The alignment requirements depend on the CPU: on some CPUs it isn't + * necessary at all, on others it won't work at all if not aligned and on others + * it will work but it will have an impact on performance. + * + * In practice, avpkt->data should have 4 byte alignment at minimum. + * + * @note Some codecs have a delay between input and output, these need to be + * fed with avpkt->data=NULL, avpkt->size=0 at the end to return the remaining frames. + * + * @param avctx the codec context + * @param[out] picture The AVFrame in which the decoded video frame will be stored. + * Use avcodec_alloc_frame to get an AVFrame, the codec will + * allocate memory for the actual bitmap. + * @param[in] avpkt The input AVpacket containing the input buffer. + * You can create such packet with av_init_packet() and by then setting + * data and size, some decoders might in addition need other fields like + * flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least + * fields possible. + * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame could be decompressed. + */ +int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + AVPacket *avpkt); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/* Decode a subtitle message. Return -1 if error, otherwise return the + * number of bytes used. If no subtitle could be decompressed, + * got_sub_ptr is zero. Otherwise, the subtitle is stored in *sub. */ +attribute_deprecated int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + const uint8_t *buf, int buf_size); +#endif + +/** + * Decodes a subtitle message. + * Returns a negative value on error, otherwise returns the number of bytes used. + * If no subtitle could be decompressed, got_sub_ptr is zero. + * Otherwise, the subtitle is stored in *sub. + * + * @param avctx the codec context + * @param[out] sub The AVSubtitle in which the decoded subtitle will be stored. + * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, otherwise, it is nonzero. + * @param[in] avpkt The input AVPacket containing the input buffer. + */ +int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + AVPacket *avpkt); +int avcodec_parse_frame(AVCodecContext *avctx, uint8_t **pdata, + int *data_size_ptr, + uint8_t *buf, int buf_size); + +/** + * Encodes an audio frame from samples into buf. + * + * @note The output buffer should be at least FF_MIN_BUFFER_SIZE bytes large. + * However, for PCM audio the user will know how much space is needed + * because it depends on the value passed in buf_size as described + * below. In that case a lower value can be used. + * + * @param avctx the codec context + * @param[out] buf the output buffer + * @param[in] buf_size the output buffer size + * @param[in] samples the input buffer containing the samples + * The number of samples read from this buffer is frame_size*channels, + * both of which are defined in avctx. + * For PCM audio the number of samples read from samples is equal to + * buf_size * input_sample_size / output_sample_size. + * @return On error a negative value is returned, on success zero or the number + * of bytes used to encode the data read from the input buffer. + */ +int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const short *samples); + +/** + * Encodes a video frame from pict into buf. + * The input picture should be + * stored using a specific format, namely avctx.pix_fmt. + * + * @param avctx the codec context + * @param[out] buf the output buffer for the bitstream of encoded frame + * @param[in] buf_size the size of the output buffer in bytes + * @param[in] pict the input picture to encode + * @return On error a negative value is returned, on success zero or the number + * of bytes used from the output buffer. + */ +int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const AVFrame *pict); +int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const AVSubtitle *sub); + +int avcodec_close(AVCodecContext *avctx); + +/** + * Register all the codecs, parsers and bitstream filters which were enabled at + * configuration time. If you do not call this function you can select exactly + * which formats you want to support, by using the individual registration + * functions. + * + * @see avcodec_register + * @see av_register_codec_parser + * @see av_register_bitstream_filter + */ +void avcodec_register_all(void); + +/** + * Flush buffers, should be called when seeking or when switching to a different stream. + */ +void avcodec_flush_buffers(AVCodecContext *avctx); + +void avcodec_default_free_buffers(AVCodecContext *s); + +/* misc useful functions */ + +/** + * Returns a single letter to describe the given picture type pict_type. + * + * @param[in] pict_type the picture type + * @return A single character representing the picture type. + */ +char av_get_pict_type_char(int pict_type); + +/** + * Returns codec bits per sample. + * + * @param[in] codec_id the codec + * @return Number of bits per sample or zero if unknown for the given codec. + */ +int av_get_bits_per_sample(enum CodecID codec_id); + +/** + * Returns sample format bits per sample. + * + * @param[in] sample_fmt the sample format + * @return Number of bits per sample or zero if unknown for the given sample format. + */ +int av_get_bits_per_sample_format(enum SampleFormat sample_fmt); + +/* frame parsing */ +typedef struct AVCodecParserContext { + void *priv_data; + struct AVCodecParser *parser; + int64_t frame_offset; /* offset of the current frame */ + int64_t cur_offset; /* current offset + (incremented by each av_parser_parse()) */ + int64_t next_frame_offset; /* offset of the next frame */ + /* video info */ + int pict_type; /* XXX: Put it back in AVCodecContext. */ + /** + * This field is used for proper frame duration computation in lavf. + * It signals, how much longer the frame duration of the current frame + * is compared to normal frame duration. + * + * frame_duration = (1 + repeat_pict) * time_base + * + * It is used by codecs like H.264 to display telecined material. + */ + int repeat_pict; /* XXX: Put it back in AVCodecContext. */ + int64_t pts; /* pts of the current frame */ + int64_t dts; /* dts of the current frame */ + + /* private data */ + int64_t last_pts; + int64_t last_dts; + int fetch_timestamp; + +#define AV_PARSER_PTS_NB 4 + int cur_frame_start_index; + int64_t cur_frame_offset[AV_PARSER_PTS_NB]; + int64_t cur_frame_pts[AV_PARSER_PTS_NB]; + int64_t cur_frame_dts[AV_PARSER_PTS_NB]; + + int flags; +#define PARSER_FLAG_COMPLETE_FRAMES 0x0001 + + int64_t offset; ///< byte offset from starting packet start + int64_t cur_frame_end[AV_PARSER_PTS_NB]; + + /*! + * Set by parser to 1 for key frames and 0 for non-key frames. + * It is initialized to -1, so if the parser doesn't set this flag, + * old-style fallback using FF_I_TYPE picture type as key frames + * will be used. + */ + int key_frame; + + /** + * Time difference in stream time base units from the pts of this + * packet to the point at which the output from the decoder has converged + * independent from the availability of previous frames. That is, the + * frames are virtually identical no matter if decoding started from + * the very first frame or from this keyframe. + * Is AV_NOPTS_VALUE if unknown. + * This field is not the display duration of the current frame. + * + * The purpose of this field is to allow seeking in streams that have no + * keyframes in the conventional sense. It corresponds to the + * recovery point SEI in H.264 and match_time_delta in NUT. It is also + * essential for some types of subtitle streams to ensure that all + * subtitles are correctly displayed after seeking. + */ + int64_t convergence_duration; + + // Timestamp generation support: + /** + * Synchronization point for start of timestamp generation. + * + * Set to >0 for sync point, 0 for no sync point and <0 for undefined + * (default). + * + * For example, this corresponds to presence of H.264 buffering period + * SEI message. + */ + int dts_sync_point; + + /** + * Offset of the current timestamp against last timestamp sync point in + * units of AVCodecContext.time_base. + * + * Set to INT_MIN when dts_sync_point unused. Otherwise, it must + * contain a valid timestamp offset. + * + * Note that the timestamp of sync point has usually a nonzero + * dts_ref_dts_delta, which refers to the previous sync point. Offset of + * the next frame after timestamp sync point will be usually 1. + * + * For example, this corresponds to H.264 cpb_removal_delay. + */ + int dts_ref_dts_delta; + + /** + * Presentation delay of current frame in units of AVCodecContext.time_base. + * + * Set to INT_MIN when dts_sync_point unused. Otherwise, it must + * contain valid non-negative timestamp delta (presentation time of a frame + * must not lie in the past). + * + * This delay represents the difference between decoding and presentation + * time of the frame. + * + * For example, this corresponds to H.264 dpb_output_delay. + */ + int pts_dts_delta; + + /** + * Position of the packet in file. + * + * Analogous to cur_frame_pts/dts + */ + int64_t cur_frame_pos[AV_PARSER_PTS_NB]; + + /** + * Byte position of currently parsed frame in stream. + */ + int64_t pos; + + /** + * Previous frame byte position. + */ + int64_t last_pos; +} AVCodecParserContext; + +typedef struct AVCodecParser { + int codec_ids[5]; /* several codec IDs are permitted */ + int priv_data_size; + int (*parser_init)(AVCodecParserContext *s); + int (*parser_parse)(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size); + void (*parser_close)(AVCodecParserContext *s); + int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size); + struct AVCodecParser *next; +} AVCodecParser; + +AVCodecParser *av_parser_next(AVCodecParser *c); + +void av_register_codec_parser(AVCodecParser *parser); +AVCodecParserContext *av_parser_init(int codec_id); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +attribute_deprecated +int av_parser_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts); +#endif + +/** + * Parse a packet. + * + * @param s parser context. + * @param avctx codec context. + * @param poutbuf set to pointer to parsed buffer or NULL if not yet finished. + * @param poutbuf_size set to size of parsed buffer or zero if not yet finished. + * @param buf input buffer. + * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output). + * @param pts input presentation timestamp. + * @param dts input decoding timestamp. + * @param pos input byte position in stream. + * @return the number of bytes of the input bitstream used. + * + * Example: + * @code + * while(in_len){ + * len = av_parser_parse2(myparser, AVCodecContext, &data, &size, + * in_data, in_len, + * pts, dts, pos); + * in_data += len; + * in_len -= len; + * + * if(size) + * decode_frame(data, size); + * } + * @endcode + */ +int av_parser_parse2(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts, + int64_t pos); + +int av_parser_change(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); +void av_parser_close(AVCodecParserContext *s); + + +typedef struct AVBitStreamFilterContext { + void *priv_data; + struct AVBitStreamFilter *filter; + AVCodecParserContext *parser; + struct AVBitStreamFilterContext *next; +} AVBitStreamFilterContext; + + +typedef struct AVBitStreamFilter { + const char *name; + int priv_data_size; + int (*filter)(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); + void (*close)(AVBitStreamFilterContext *bsfc); + struct AVBitStreamFilter *next; +} AVBitStreamFilter; + +void av_register_bitstream_filter(AVBitStreamFilter *bsf); +AVBitStreamFilterContext *av_bitstream_filter_init(const char *name); +int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); +void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); + +AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f); + +/* memory */ + +/** + * Reallocates the given block if it is not large enough, otherwise it + * does nothing. + * + * @see av_realloc + */ +void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size); + +/** + * Allocates a buffer, reusing the given one if large enough. + * + * Contrary to av_fast_realloc the current buffer contents might not be + * preserved and on error the old buffer is freed, thus no special + * handling to avoid memleaks is necessary. + * + * @param ptr pointer to pointer to already allocated buffer, overwritten with pointer to new buffer + * @param size size of the buffer *ptr points to + * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and + * *size 0 if an error occurred. + */ +void av_fast_malloc(void *ptr, unsigned int *size, unsigned int min_size); + +/** + * Copy image 'src' to 'dst'. + */ +void av_picture_copy(AVPicture *dst, const AVPicture *src, + enum PixelFormat pix_fmt, int width, int height); + +/** + * Crop image top and left side. + */ +int av_picture_crop(AVPicture *dst, const AVPicture *src, + enum PixelFormat pix_fmt, int top_band, int left_band); + +/** + * Pad image. + */ +int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, enum PixelFormat pix_fmt, + int padtop, int padbottom, int padleft, int padright, int *color); + +/** + * Encodes extradata length to a buffer. Used by xiph codecs. + * + * @param s buffer to write to; must be at least (v/255+1) bytes long + * @param v size of extradata in bytes + * @return number of bytes written to the buffer. + */ +unsigned int av_xiphlacing(unsigned char *s, unsigned int v); + +/** + * Parses str and put in width_ptr and height_ptr the detected values. + * + * @return 0 in case of a successful parsing, a negative value otherwise + * @param[in] str the string to parse: it has to be a string in the format + * <width>x<height> or a valid video frame size abbreviation. + * @param[in,out] width_ptr pointer to the variable which will contain the detected + * frame width value + * @param[in,out] height_ptr pointer to the variable which will contain the detected + * frame height value + */ +int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str); + +/** + * Parses str and put in frame_rate the detected values. + * + * @return 0 in case of a successful parsing, a negative value otherwise + * @param[in] str the string to parse: it has to be a string in the format + * <frame_rate_num>/<frame_rate_den>, a float number or a valid video rate abbreviation + * @param[in,out] frame_rate pointer to the AVRational which will contain the detected + * frame rate + */ +int av_parse_video_frame_rate(AVRational *frame_rate, const char *str); + +/** + * Logs a generic warning message about a missing feature. This function is + * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) + * only, and would normally not be used by applications. + * @param[in] avc a pointer to an arbitrary struct of which the first field is + * a pointer to an AVClass struct + * @param[in] feature string containing the name of the missing feature + * @param[in] want_sample indicates if samples are wanted which exhibit this feature. + * If want_sample is non-zero, additional verbage will be added to the log + * message which tells the user how to report samples to the development + * mailing list. + */ +void av_log_missing_feature(void *avc, const char *feature, int want_sample); + +/** + * Logs a generic warning message asking for a sample. This function is + * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) + * only, and would normally not be used by applications. + * @param[in] avc a pointer to an arbitrary struct of which the first field is + * a pointer to an AVClass struct + * @param[in] msg string containing an optional message, or NULL if no message + */ +void av_log_ask_for_sample(void *avc, const char *msg); + +/** + * Registers the hardware accelerator hwaccel. + */ +void av_register_hwaccel(AVHWAccel *hwaccel); + +/** + * If hwaccel is NULL, returns the first registered hardware accelerator, + * if hwaccel is non-NULL, returns the next registered hardware accelerator + * after hwaccel, or NULL if hwaccel is the last one. + */ +AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel); + + +/** + * Lock operation used by lockmgr + */ +enum AVLockOp { + AV_LOCK_CREATE, ///< Create a mutex + AV_LOCK_OBTAIN, ///< Lock the mutex + AV_LOCK_RELEASE, ///< Unlock the mutex + AV_LOCK_DESTROY, ///< Free mutex resources +}; + +/** + * Register a user provided lock manager supporting the operations + * specified by AVLockOp. mutex points to a (void *) where the + * lockmgr should store/get a pointer to a user allocated mutex. It's + * NULL upon AV_LOCK_CREATE and != NULL for all other ops. + * + * @param cb User defined callback. Note: FFmpeg may invoke calls to this + * callback during the call to av_lockmgr_register(). + * Thus, the application must be prepared to handle that. + * If cb is set to NULL the lockmgr will be unregistered. + * Also note that during unregistration the previously registered + * lockmgr callback may also be invoked. + */ +int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)); + +#endif /* AVCODEC_AVCODEC_H */ diff --git a/include/libavcodec/avfft.h b/include/libavcodec/avfft.h new file mode 100644 index 00000000..623f0a33 --- /dev/null +++ b/include/libavcodec/avfft.h @@ -0,0 +1,99 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AVFFT_H +#define AVCODEC_AVFFT_H + +typedef float FFTSample; + +typedef struct FFTComplex { + FFTSample re, im; +} FFTComplex; + +typedef struct FFTContext FFTContext; + +/** + * Set up a complex FFT. + * @param nbits log2 of the length of the input array + * @param inverse if 0 perform the forward transform, if 1 perform the inverse + */ +FFTContext *av_fft_init(int nbits, int inverse); + +/** + * Do the permutation needed BEFORE calling ff_fft_calc(). + */ +void av_fft_permute(FFTContext *s, FFTComplex *z); + +/** + * Do a complex FFT with the parameters defined in av_fft_init(). The + * input data must be permuted before. No 1.0/sqrt(n) normalization is done. + */ +void av_fft_calc(FFTContext *s, FFTComplex *z); + +void av_fft_end(FFTContext *s); + +FFTContext *av_mdct_init(int nbits, int inverse, double scale); +void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input); +void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input); +void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input); +void av_mdct_end(FFTContext *s); + +/* Real Discrete Fourier Transform */ + +enum RDFTransformType { + DFT_R2C, + IDFT_C2R, + IDFT_R2C, + DFT_C2R, +}; + +typedef struct RDFTContext RDFTContext; + +/** + * Set up a real FFT. + * @param nbits log2 of the length of the input array + * @param trans the type of transform + */ +RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans); +void av_rdft_calc(RDFTContext *s, FFTSample *data); +void av_rdft_end(RDFTContext *s); + +/* Discrete Cosine Transform */ + +typedef struct DCTContext DCTContext; + +enum DCTTransformType { + DCT_II = 0, + DCT_III, + DCT_I, + DST_I, +}; + +/** + * Sets up DCT. + * @param nbits size of the input array: + * (1 << nbits) for DCT-II, DCT-III and DST-I + * (1 << nbits) + 1 for DCT-I + * + * @note the first element of the input of DST-I is ignored + */ +DCTContext *av_dct_init(int nbits, enum DCTTransformType type); +void av_dct_calc(DCTContext *s, FFTSample *data); +void av_dct_end (DCTContext *s); + +#endif /* AVCODEC_AVFFT_H */ diff --git a/include/libavcodec/dxva2.h b/include/libavcodec/dxva2.h new file mode 100644 index 00000000..5c5fe21e --- /dev/null +++ b/include/libavcodec/dxva2.h @@ -0,0 +1,68 @@ +/* + * DXVA2 HW acceleration + * + * copyright (c) 2009 Laurent Aimar + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DXVA_H +#define AVCODEC_DXVA_H + +#include <stdint.h> + +#include <dxva2api.h> + +/** + * This structure is used to provides the necessary configurations and data + * to the DXVA2 FFmpeg HWAccel implementation. + * + * The application must make it available as AVCodecContext.hwaccel_context. + */ +struct dxva_context { + /** + * DXVA2 decoder object + */ + IDirectXVideoDecoder *decoder; + + /** + * DXVA2 configuration used to create the decoder + */ + const DXVA2_ConfigPictureDecode *cfg; + + /** + * The number of surface in the surface array + */ + unsigned surface_count; + + /** + * The array of Direct3D surfaces used to create the decoder + */ + LPDIRECT3DSURFACE9 *surface; + + /** + * A bit field configuring the workarounds needed for using the decoder + */ + uint64_t workaround; + + /** + * Private to the FFmpeg AVHWAccel implementation + */ + unsigned report_id; +}; + +#endif /* AVCODEC_DXVA_H */ diff --git a/include/libavcodec/opt.h b/include/libavcodec/opt.h new file mode 100644 index 00000000..55ca4ea6 --- /dev/null +++ b/include/libavcodec/opt.h @@ -0,0 +1,211 @@ +/* + * AVOptions + * copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_OPT_H +#define AVCODEC_OPT_H + +/** + * @file + * AVOptions + */ + +#include "libavutil/rational.h" +#include "avcodec.h" + +enum AVOptionType{ + FF_OPT_TYPE_FLAGS, + FF_OPT_TYPE_INT, + FF_OPT_TYPE_INT64, + FF_OPT_TYPE_DOUBLE, + FF_OPT_TYPE_FLOAT, + FF_OPT_TYPE_STRING, + FF_OPT_TYPE_RATIONAL, + FF_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length + FF_OPT_TYPE_CONST=128, +}; + +/** + * AVOption + */ +typedef struct AVOption { + const char *name; + + /** + * short English help text + * @todo What about other languages? + */ + const char *help; + + /** + * The offset relative to the context structure where the option + * value is stored. It should be 0 for named constants. + */ + int offset; + enum AVOptionType type; + + /** + * the default value for scalar options + */ + double default_val; + double min; ///< minimum valid value for the option + double max; ///< maximum valid value for the option + + int flags; +#define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding +#define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding +#define AV_OPT_FLAG_METADATA 4 ///< some data extracted or inserted into the file like title, comment, ... +#define AV_OPT_FLAG_AUDIO_PARAM 8 +#define AV_OPT_FLAG_VIDEO_PARAM 16 +#define AV_OPT_FLAG_SUBTITLE_PARAM 32 +//FIXME think about enc-audio, ... style flags + + /** + * The logical unit to which the option belongs. Non-constant + * options and corresponding named constants share the same + * unit. May be NULL. + */ + const char *unit; +} AVOption; + +/** + * AVOption2. + * THIS IS NOT PART OF THE API/ABI YET! + * This is identical to AVOption except that default_val was replaced by + * an union, it should be compatible with AVOption on normal platforms. + */ +typedef struct AVOption2 { + const char *name; + + /** + * short English help text + * @todo What about other languages? + */ + const char *help; + + /** + * The offset relative to the context structure where the option + * value is stored. It should be 0 for named constants. + */ + int offset; + enum AVOptionType type; + + /** + * the default value for scalar options + */ + union { + double dbl; + const char *str; + } default_val; + + double min; ///< minimum valid value for the option + double max; ///< maximum valid value for the option + + int flags; +/* +#define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding +#define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding +#define AV_OPT_FLAG_METADATA 4 ///< some data extracted or inserted into the file like title, comment, ... +#define AV_OPT_FLAG_AUDIO_PARAM 8 +#define AV_OPT_FLAG_VIDEO_PARAM 16 +#define AV_OPT_FLAG_SUBTITLE_PARAM 32 +*/ +//FIXME think about enc-audio, ... style flags + + /** + * The logical unit to which the option belongs. Non-constant + * options and corresponding named constants share the same + * unit. May be NULL. + */ + const char *unit; +} AVOption2; + + +/** + * Looks for an option in obj. Looks only for the options which + * have the flags set as specified in mask and flags (that is, + * for which it is the case that opt->flags & mask == flags). + * + * @param[in] obj a pointer to a struct whose first element is a + * pointer to an AVClass + * @param[in] name the name of the option to look for + * @param[in] unit the unit of the option to look for, or any if NULL + * @return a pointer to the option found, or NULL if no option + * has been found + */ +const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int mask, int flags); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * @see av_set_string2() + */ +attribute_deprecated const AVOption *av_set_string(void *obj, const char *name, const char *val); + +/** + * @return a pointer to the AVOption corresponding to the field set or + * NULL if no matching AVOption exists, or if the value val is not + * valid + * @see av_set_string3() + */ +attribute_deprecated const AVOption *av_set_string2(void *obj, const char *name, const char *val, int alloc); +#endif + +/** + * Sets the field of obj with the given name to value. + * + * @param[in] obj A struct whose first element is a pointer to an + * AVClass. + * @param[in] name the name of the field to set + * @param[in] val The value to set. If the field is not of a string + * type, then the given string is parsed. + * SI postfixes and some named scalars are supported. + * If the field is of a numeric type, it has to be a numeric or named + * scalar. Behavior with more than one scalar and +- infix operators + * is undefined. + * If the field is of a flags type, it has to be a sequence of numeric + * scalars or named flags separated by '+' or '-'. Prefixing a flag + * with '+' causes it to be set without affecting the other flags; + * similarly, '-' unsets a flag. + * @param[out] o_out if non-NULL put here a pointer to the AVOption + * found + * @param alloc when 1 then the old value will be av_freed() and the + * new av_strduped() + * when 0 then no av_free() nor av_strdup() will be used + * @return 0 if the value has been set, or an AVERROR code in case of + * error: + * AVERROR(ENOENT) if no matching option exists + * AVERROR(ERANGE) if the value is out of range + * AVERROR(EINVAL) if the value is not valid + */ +int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out); + +const AVOption *av_set_double(void *obj, const char *name, double n); +const AVOption *av_set_q(void *obj, const char *name, AVRational n); +const AVOption *av_set_int(void *obj, const char *name, int64_t n); +double av_get_double(void *obj, const char *name, const AVOption **o_out); +AVRational av_get_q(void *obj, const char *name, const AVOption **o_out); +int64_t av_get_int(void *obj, const char *name, const AVOption **o_out); +const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len); +const AVOption *av_next_option(void *obj, const AVOption *last); +int av_opt_show(void *obj, void *av_log_obj); +void av_opt_set_defaults(void *s); +void av_opt_set_defaults2(void *s, int mask, int flags); + +#endif /* AVCODEC_OPT_H */ diff --git a/include/libavcodec/vaapi.h b/include/libavcodec/vaapi.h new file mode 100644 index 00000000..07568a47 --- /dev/null +++ b/include/libavcodec/vaapi.h @@ -0,0 +1,167 @@ +/* + * Video Acceleration API (shared data between FFmpeg and the video player) + * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1 + * + * Copyright (C) 2008-2009 Splitted-Desktop Systems + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VAAPI_H +#define AVCODEC_VAAPI_H + +#include <stdint.h> + +/** + * \defgroup VAAPI_Decoding VA API Decoding + * \ingroup Decoder + * @{ + */ + +/** + * This structure is used to share data between the FFmpeg library and + * the client video application. + * This shall be zero-allocated and available as + * AVCodecContext.hwaccel_context. All user members can be set once + * during initialization or through each AVCodecContext.get_buffer() + * function call. In any case, they must be valid prior to calling + * decoding functions. + */ +struct vaapi_context { + /** + * Window system dependent data + * + * - encoding: unused + * - decoding: Set by user + */ + void *display; + + /** + * Configuration ID + * + * - encoding: unused + * - decoding: Set by user + */ + uint32_t config_id; + + /** + * Context ID (video decode pipeline) + * + * - encoding: unused + * - decoding: Set by user + */ + uint32_t context_id; + + /** + * VAPictureParameterBuffer ID + * + * - encoding: unused + * - decoding: Set by libavcodec + */ + uint32_t pic_param_buf_id; + + /** + * VAIQMatrixBuffer ID + * + * - encoding: unused + * - decoding: Set by libavcodec + */ + uint32_t iq_matrix_buf_id; + + /** + * VABitPlaneBuffer ID (for VC-1 decoding) + * + * - encoding: unused + * - decoding: Set by libavcodec + */ + uint32_t bitplane_buf_id; + + /** + * Slice parameter/data buffer IDs + * + * - encoding: unused + * - decoding: Set by libavcodec + */ + uint32_t *slice_buf_ids; + + /** + * Number of effective slice buffer IDs to send to the HW + * + * - encoding: unused + * - decoding: Set by libavcodec + */ + unsigned int n_slice_buf_ids; + + /** + * Size of pre-allocated slice_buf_ids + * + * - encoding: unused + * - decoding: Set by libavcodec + */ + unsigned int slice_buf_ids_alloc; + + /** + * Pointer to VASliceParameterBuffers + * + * - encoding: unused + * - decoding: Set by libavcodec + */ + void *slice_params; + + /** + * Size of a VASliceParameterBuffer element + * + * - encoding: unused + * - decoding: Set by libavcodec + */ + unsigned int slice_param_size; + + /** + * Size of pre-allocated slice_params + * + * - encoding: unused + * - decoding: Set by libavcodec + */ + unsigned int slice_params_alloc; + + /** + * Number of slices currently filled in + * + * - encoding: unused + * - decoding: Set by libavcodec + */ + unsigned int slice_count; + + /** + * Pointer to slice data buffer base + * - encoding: unused + * - decoding: Set by libavcodec + */ + const uint8_t *slice_data; + + /** + * Current size of slice data + * + * - encoding: unused + * - decoding: Set by libavcodec + */ + uint32_t slice_data_size; +}; + +/* @} */ + +#endif /* AVCODEC_VAAPI_H */ diff --git a/include/libavcodec/vdpau.h b/include/libavcodec/vdpau.h new file mode 100644 index 00000000..a8fa4d38 --- /dev/null +++ b/include/libavcodec/vdpau.h @@ -0,0 +1,89 @@ +/* + * The Video Decode and Presentation API for UNIX (VDPAU) is used for + * hardware-accelerated decoding of MPEG-1/2, H.264 and VC-1. + * + * Copyright (C) 2008 NVIDIA + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VDPAU_H +#define AVCODEC_VDPAU_H + +/** + * \defgroup Decoder VDPAU Decoder and Renderer + * + * VDPAU hardware acceleration has two modules + * - VDPAU decoding + * - VDPAU presentation + * + * The VDPAU decoding module parses all headers using FFmpeg + * parsing mechanisms and uses VDPAU for the actual decoding. + * + * As per the current implementation, the actual decoding + * and rendering (API calls) are done as part of the VDPAU + * presentation (vo_vdpau.c) module. + * + * @{ + * \defgroup VDPAU_Decoding VDPAU Decoding + * \ingroup Decoder + * @{ + */ + +#include <vdpau/vdpau.h> +#include <vdpau/vdpau_x11.h> + +/** \brief The videoSurface is used for rendering. */ +#define FF_VDPAU_STATE_USED_FOR_RENDER 1 + +/** + * \brief The videoSurface is needed for reference/prediction. + * The codec manipulates this. + */ +#define FF_VDPAU_STATE_USED_FOR_REFERENCE 2 + +/** + * \brief This structure is used as a callback between the FFmpeg + * decoder (vd_) and presentation (vo_) module. + * This is used for defining a video frame containing surface, + * picture parameter, bitstream information etc which are passed + * between the FFmpeg decoder and its clients. + */ +struct vdpau_render_state { + VdpVideoSurface surface; ///< Used as rendered surface, never changed. + + int state; ///< Holds FF_VDPAU_STATE_* values. + + /** picture parameter information for all supported codecs */ + union VdpPictureInfo { + VdpPictureInfoH264 h264; + VdpPictureInfoMPEG1Or2 mpeg; + VdpPictureInfoVC1 vc1; + VdpPictureInfoMPEG4Part2 mpeg4; + } info; + + /** Describe size/location of the compressed video data. + Set to 0 when freeing bitstream_buffers. */ + int bitstream_buffers_allocated; + int bitstream_buffers_used; + /** The user is responsible for freeing this buffer using av_freep(). */ + VdpBitstreamBuffer *bitstream_buffers; +}; + +/* @}*/ + +#endif /* AVCODEC_VDPAU_H */ diff --git a/include/libavcodec/xvmc.h b/include/libavcodec/xvmc.h new file mode 100644 index 00000000..01f84b28 --- /dev/null +++ b/include/libavcodec/xvmc.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2003 Ivan Kalvachev + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_XVMC_H +#define AVCODEC_XVMC_H + +#include <X11/extensions/XvMC.h> + +#include "avcodec.h" + +#if LIBAVCODEC_VERSION_MAJOR < 53 +#define AV_XVMC_STATE_DISPLAY_PENDING 1 /** the surface should be shown, the video driver manipulates this */ +#define AV_XVMC_STATE_PREDICTION 2 /** the surface is needed for prediction, the codec manipulates this */ +#define AV_XVMC_STATE_OSD_SOURCE 4 /** the surface is needed for subpicture rendering */ +#endif +#define AV_XVMC_ID 0x1DC711C0 /**< special value to ensure that regular pixel routines haven't corrupted the struct + the number is 1337 speak for the letters IDCT MCo (motion compensation) */ + +struct xvmc_pix_fmt { + /** The field contains the special constant value AV_XVMC_ID. + It is used as a test that the application correctly uses the API, + and that there is no corruption caused by pixel routines. + - application - set during initialization + - libavcodec - unchanged + */ + int xvmc_id; + + /** Pointer to the block array allocated by XvMCCreateBlocks(). + The array has to be freed by XvMCDestroyBlocks(). + Each group of 64 values represents one data block of differential + pixel information (in MoCo mode) or coefficients for IDCT. + - application - set the pointer during initialization + - libavcodec - fills coefficients/pixel data into the array + */ + short* data_blocks; + + /** Pointer to the macroblock description array allocated by + XvMCCreateMacroBlocks() and freed by XvMCDestroyMacroBlocks(). + - application - set the pointer during initialization + - libavcodec - fills description data into the array + */ + XvMCMacroBlock* mv_blocks; + + /** Number of macroblock descriptions that can be stored in the mv_blocks + array. + - application - set during initialization + - libavcodec - unchanged + */ + int allocated_mv_blocks; + + /** Number of blocks that can be stored at once in the data_blocks array. + - application - set during initialization + - libavcodec - unchanged + */ + int allocated_data_blocks; + + /** Indicates that the hardware would interpret data_blocks as IDCT + coefficients and perform IDCT on them. + - application - set during initialization + - libavcodec - unchanged + */ + int idct; + + /** In MoCo mode it indicates that intra macroblocks are assumed to be in + unsigned format; same as the XVMC_INTRA_UNSIGNED flag. + - application - set during initialization + - libavcodec - unchanged + */ + int unsigned_intra; + + /** Pointer to the surface allocated by XvMCCreateSurface(). + It has to be freed by XvMCDestroySurface() on application exit. + It identifies the frame and its state on the video hardware. + - application - set during initialization + - libavcodec - unchanged + */ + XvMCSurface* p_surface; + +/** Set by the decoder before calling ff_draw_horiz_band(), + needed by the XvMCRenderSurface function. */ +//@{ + /** Pointer to the surface used as past reference + - application - unchanged + - libavcodec - set + */ + XvMCSurface* p_past_surface; + + /** Pointer to the surface used as future reference + - application - unchanged + - libavcodec - set + */ + XvMCSurface* p_future_surface; + + /** top/bottom field or frame + - application - unchanged + - libavcodec - set + */ + unsigned int picture_structure; + + /** XVMC_SECOND_FIELD - 1st or 2nd field in the sequence + - application - unchanged + - libavcodec - set + */ + unsigned int flags; +//}@ + + /** Number of macroblock descriptions in the mv_blocks array + that have already been passed to the hardware. + - application - zeroes it on get_buffer(). + A successful ff_draw_horiz_band() may increment it + with filled_mb_block_num or zero both. + - libavcodec - unchanged + */ + int start_mv_blocks_num; + + /** Number of new macroblock descriptions in the mv_blocks array (after + start_mv_blocks_num) that are filled by libavcodec and have to be + passed to the hardware. + - application - zeroes it on get_buffer() or after successful + ff_draw_horiz_band(). + - libavcodec - increment with one of each stored MB + */ + int filled_mv_blocks_num; + + /** Number of the the next free data block; one data block consists of + 64 short values in the data_blocks array. + All blocks before this one have already been claimed by placing their + position into the corresponding block description structure field, + that are part of the mv_blocks array. + - application - zeroes it on get_buffer(). + A successful ff_draw_horiz_band() may zero it together + with start_mb_blocks_num. + - libavcodec - each decoded macroblock increases it by the number + of coded blocks it contains. + */ + int next_free_data_block_num; + +/** extensions may be placed here */ +#if LIBAVCODEC_VERSION_MAJOR < 53 +//@{ + /** State flags used to work around limitations in the MPlayer video system. + 0 - Surface is not used. + 1 - Surface is still held in application to be displayed or is + still visible. + 2 - Surface is still held in libavcodec buffer for prediction. + */ + int state; + + /** pointer to the surface where the subpicture is rendered */ + void* p_osd_target_surface_render; +//}@ +#endif +}; + +#endif /* AVCODEC_XVMC_H */ diff --git a/include/libavformat/avformat.h b/include/libavformat/avformat.h new file mode 100644 index 00000000..dbd22bb8 --- /dev/null +++ b/include/libavformat/avformat.h @@ -0,0 +1,1369 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFORMAT_AVFORMAT_H +#define AVFORMAT_AVFORMAT_H + +#define LIBAVFORMAT_VERSION_MAJOR 52 +#define LIBAVFORMAT_VERSION_MINOR 64 +#define LIBAVFORMAT_VERSION_MICRO 2 + +#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ + LIBAVFORMAT_VERSION_MINOR, \ + LIBAVFORMAT_VERSION_MICRO) +#define LIBAVFORMAT_VERSION AV_VERSION(LIBAVFORMAT_VERSION_MAJOR, \ + LIBAVFORMAT_VERSION_MINOR, \ + LIBAVFORMAT_VERSION_MICRO) +#define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT + +#define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION) + +/** + * I return the LIBAVFORMAT_VERSION_INT constant. You got + * a fucking problem with that, douchebag? + */ +unsigned avformat_version(void); + +/** + * Returns the libavformat build-time configuration. + */ +const char *avformat_configuration(void); + +/** + * Returns the libavformat license. + */ +const char *avformat_license(void); + +#include <time.h> +#include <stdio.h> /* FILE */ +#include "libavcodec/avcodec.h" + +#include "avio.h" + +struct AVFormatContext; + + +/* + * Public Metadata API. + * The metadata API allows libavformat to export metadata tags to a client + * application using a sequence of key/value pairs. Like all strings in FFmpeg, + * metadata must be stored as UTF-8 encoded Unicode. Note that metadata + * exported by demuxers isn't checked to be valid UTF-8 in most cases. + * Important concepts to keep in mind: + * 1. Keys are unique; there can never be 2 tags with the same key. This is + * also meant semantically, i.e., a demuxer should not knowingly produce + * several keys that are literally different but semantically identical. + * E.g., key=Author5, key=Author6. In this example, all authors must be + * placed in the same tag. + * 2. Metadata is flat, not hierarchical; there are no subtags. If you + * want to store, e.g., the email address of the child of producer Alice + * and actor Bob, that could have key=alice_and_bobs_childs_email_address. + * 3. Several modifiers can be applied to the tag name. This is done by + * appending a dash character ('-') and the modifier name in the order + * they appear in the list below -- e.g. foo-eng-sort, not foo-sort-eng. + * a) language -- a tag whose value is localized for a particular language + * is appended with the ISO 639-2/B 3-letter language code. + * For example: Author-ger=Michael, Author-eng=Mike + * The original/default language is in the unqualified "Author" tag. + * A demuxer should set a default if it sets any translated tag. + * b) sorting -- a modified version of a tag that should be used for + * sorting will have '-sort' appended. E.g. artist="The Beatles", + * artist-sort="Beatles, The". + * + * 4. Tag names are normally exported exactly as stored in the container to + * allow lossless remuxing to the same format. For container-independent + * handling of metadata, av_metadata_conv() can convert it to ffmpeg generic + * format. Follows a list of generic tag names: + * + * album -- name of the set this work belongs to + * album_artist -- main creator of the set/album, if different from artist. + * e.g. "Various Artists" for compilation albums. + * artist -- main creator of the work + * comment -- any additional description of the file. + * composer -- who composed the work, if different from artist. + * copyright -- name of copyright holder. + * date -- date when the work was created, preferably in ISO 8601. + * disc -- number of a subset, e.g. disc in a multi-disc collection. + * encoder -- name/settings of the software/hardware that produced the file. + * encoded_by -- person/group who created the file. + * filename -- original name of the file. + * genre -- <self-evident>. + * language -- main language in which the work is performed, preferably + * in ISO 639-2 format. + * performer -- artist who performed the work, if different from artist. + * E.g for "Also sprach Zarathustra", artist would be "Richard + * Strauss" and performer "London Philharmonic Orchestra". + * publisher -- name of the label/publisher. + * title -- name of the work. + * track -- number of this work in the set, can be in form current/total. + */ + +#define AV_METADATA_MATCH_CASE 1 +#define AV_METADATA_IGNORE_SUFFIX 2 +#define AV_METADATA_DONT_STRDUP_KEY 4 +#define AV_METADATA_DONT_STRDUP_VAL 8 +#define AV_METADATA_DONT_OVERWRITE 16 ///< Don't overwrite existing tags. + +typedef struct { + char *key; + char *value; +}AVMetadataTag; + +typedef struct AVMetadata AVMetadata; +typedef struct AVMetadataConv AVMetadataConv; + +/** + * Gets a metadata element with matching key. + * @param prev Set to the previous matching element to find the next. + * If set to NULL the first matching element is returned. + * @param flags Allows case as well as suffix-insensitive comparisons. + * @return Found tag or NULL, changing key or value leads to undefined behavior. + */ +AVMetadataTag * +av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int flags); + +#if LIBAVFORMAT_VERSION_MAJOR == 52 +/** + * Sets the given tag in m, overwriting an existing tag. + * @param key tag key to add to m (will be av_strduped) + * @param value tag value to add to m (will be av_strduped) + * @return >= 0 on success otherwise an error code <0 + * @deprecated Use av_metadata_set2() instead. + */ +attribute_deprecated int av_metadata_set(AVMetadata **pm, const char *key, const char *value); +#endif + +/** + * Sets the given tag in m, overwriting an existing tag. + * @param key tag key to add to m (will be av_strduped depending on flags) + * @param value tag value to add to m (will be av_strduped depending on flags) + * @return >= 0 on success otherwise an error code <0 + */ +int av_metadata_set2(AVMetadata **pm, const char *key, const char *value, int flags); + +/** + * Converts all the metadata sets from ctx according to the source and + * destination conversion tables. If one of the tables is NULL, then + * tags are converted to/from ffmpeg generic tag names. + * @param d_conv destination tags format conversion table + * @param s_conv source tags format conversion table + */ +void av_metadata_conv(struct AVFormatContext *ctx,const AVMetadataConv *d_conv, + const AVMetadataConv *s_conv); + +/** + * Frees all the memory allocated for an AVMetadata struct. + */ +void av_metadata_free(AVMetadata **m); + + +/* packet functions */ + + +/** + * Allocates and reads the payload of a packet and initializes its + * fields with default values. + * + * @param pkt packet + * @param size desired payload size + * @return >0 (read size) if OK, AVERROR_xxx otherwise + */ +int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size); + + +/*************************************************/ +/* fractional numbers for exact pts handling */ + +/** + * The exact value of the fractional number is: 'val + num / den'. + * num is assumed to be 0 <= num < den. + */ +typedef struct AVFrac { + int64_t val, num, den; +} AVFrac; + +/*************************************************/ +/* input/output formats */ + +struct AVCodecTag; + +/** This structure contains the data a format has to probe a file. */ +typedef struct AVProbeData { + const char *filename; + unsigned char *buf; /**< Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. */ + int buf_size; /**< Size of buf except extra allocated bytes */ +} AVProbeData; + +#define AVPROBE_SCORE_MAX 100 ///< maximum score, half of that is used for file-extension-based detection +#define AVPROBE_PADDING_SIZE 32 ///< extra allocated bytes at the end of the probe buffer + +typedef struct AVFormatParameters { + AVRational time_base; + int sample_rate; + int channels; + int width; + int height; + enum PixelFormat pix_fmt; + int channel; /**< Used to select DV channel. */ + const char *standard; /**< TV standard, NTSC, PAL, SECAM */ + unsigned int mpeg2ts_raw:1; /**< Force raw MPEG-2 transport stream output, if possible. */ + unsigned int mpeg2ts_compute_pcr:1; /**< Compute exact PCR for each transport + stream packet (only meaningful if + mpeg2ts_raw is TRUE). */ + unsigned int initial_pause:1; /**< Do not begin to play the stream + immediately (RTSP only). */ + unsigned int prealloced_context:1; +#if LIBAVFORMAT_VERSION_INT < (53<<16) + enum CodecID video_codec_id; + enum CodecID audio_codec_id; +#endif +} AVFormatParameters; + +//! Demuxer will use url_fopen, no opened file should be provided by the caller. +#define AVFMT_NOFILE 0x0001 +#define AVFMT_NEEDNUMBER 0x0002 /**< Needs '%d' in filename. */ +#define AVFMT_SHOW_IDS 0x0008 /**< Show format stream IDs numbers. */ +#define AVFMT_RAWPICTURE 0x0020 /**< Format wants AVPicture structure for + raw picture data. */ +#define AVFMT_GLOBALHEADER 0x0040 /**< Format wants global header. */ +#define AVFMT_NOTIMESTAMPS 0x0080 /**< Format does not need / have any timestamps. */ +#define AVFMT_GENERIC_INDEX 0x0100 /**< Use generic index building code. */ +#define AVFMT_TS_DISCONT 0x0200 /**< Format allows timestamp discontinuities. */ +#define AVFMT_VARIABLE_FPS 0x0400 /**< Format allows variable fps. */ +#define AVFMT_NODIMENSIONS 0x0800 /**< Format does not need width/height */ + +typedef struct AVOutputFormat { + const char *name; + /** + * Descriptive name for the format, meant to be more human-readable + * than name. You should use the NULL_IF_CONFIG_SMALL() macro + * to define it. + */ + const char *long_name; + const char *mime_type; + const char *extensions; /**< comma-separated filename extensions */ + /** size of private data so that it can be allocated in the wrapper */ + int priv_data_size; + /* output support */ + enum CodecID audio_codec; /**< default audio codec */ + enum CodecID video_codec; /**< default video codec */ + int (*write_header)(struct AVFormatContext *); + int (*write_packet)(struct AVFormatContext *, AVPacket *pkt); + int (*write_trailer)(struct AVFormatContext *); + /** can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER */ + int flags; + /** Currently only used to set pixel format if not YUV420P. */ + int (*set_parameters)(struct AVFormatContext *, AVFormatParameters *); + int (*interleave_packet)(struct AVFormatContext *, AVPacket *out, + AVPacket *in, int flush); + + /** + * List of supported codec_id-codec_tag pairs, ordered by "better + * choice first". The arrays are all terminated by CODEC_ID_NONE. + */ + const struct AVCodecTag * const *codec_tag; + + enum CodecID subtitle_codec; /**< default subtitle codec */ + + const AVMetadataConv *metadata_conv; + + /* private fields */ + struct AVOutputFormat *next; +} AVOutputFormat; + +typedef struct AVInputFormat { + const char *name; + /** + * Descriptive name for the format, meant to be more human-readable + * than name. You should use the NULL_IF_CONFIG_SMALL() macro + * to define it. + */ + const char *long_name; + /** Size of private data so that it can be allocated in the wrapper. */ + int priv_data_size; + /** + * Tell if a given file has a chance of being parsed as this format. + * The buffer provided is guaranteed to be AVPROBE_PADDING_SIZE bytes + * big so you do not have to check for that unless you need more. + */ + int (*read_probe)(AVProbeData *); + /** Read the format header and initialize the AVFormatContext + structure. Return 0 if OK. 'ap' if non-NULL contains + additional parameters. Only used in raw format right + now. 'av_new_stream' should be called to create new streams. */ + int (*read_header)(struct AVFormatContext *, + AVFormatParameters *ap); + /** Read one packet and put it in 'pkt'. pts and flags are also + set. 'av_new_stream' can be called only if the flag + AVFMTCTX_NOHEADER is used. + @return 0 on success, < 0 on error. + When returning an error, pkt must not have been allocated + or must be freed before returning */ + int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); + /** Close the stream. The AVFormatContext and AVStreams are not + freed by this function */ + int (*read_close)(struct AVFormatContext *); + +#if LIBAVFORMAT_VERSION_MAJOR < 53 + /** + * Seek to a given timestamp relative to the frames in + * stream component stream_index. + * @param stream_index Must not be -1. + * @param flags Selects which direction should be preferred if no exact + * match is available. + * @return >= 0 on success (but not necessarily the new offset) + */ + int (*read_seek)(struct AVFormatContext *, + int stream_index, int64_t timestamp, int flags); +#endif + /** + * Gets the next timestamp in stream[stream_index].time_base units. + * @return the timestamp or AV_NOPTS_VALUE if an error occurred + */ + int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index, + int64_t *pos, int64_t pos_limit); + /** Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER. */ + int flags; + /** If extensions are defined, then no probe is done. You should + usually not use extension format guessing because it is not + reliable enough */ + const char *extensions; + /** General purpose read-only value that the format can use. */ + int value; + + /** Starts/resumes playing - only meaningful if using a network-based format + (RTSP). */ + int (*read_play)(struct AVFormatContext *); + + /** Pauses playing - only meaningful if using a network-based format + (RTSP). */ + int (*read_pause)(struct AVFormatContext *); + + const struct AVCodecTag * const *codec_tag; + + /** + * Seeks to timestamp ts. + * Seeking will be done so that the point from which all active streams + * can be presented successfully will be closest to ts and within min/max_ts. + * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. + */ + int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); + + const AVMetadataConv *metadata_conv; + + /* private fields */ + struct AVInputFormat *next; +} AVInputFormat; + +enum AVStreamParseType { + AVSTREAM_PARSE_NONE, + AVSTREAM_PARSE_FULL, /**< full parsing and repack */ + AVSTREAM_PARSE_HEADERS, /**< Only parse headers, do not repack. */ + AVSTREAM_PARSE_TIMESTAMPS, /**< full parsing and interpolation of timestamps for frames not starting on a packet boundary */ +}; + +typedef struct AVIndexEntry { + int64_t pos; + int64_t timestamp; +#define AVINDEX_KEYFRAME 0x0001 + int flags:2; + int size:30; //Yeah, trying to keep the size of this small to reduce memory requirements (it is 24 vs. 32 bytes due to possible 8-byte alignment). + int min_distance; /**< Minimum distance between this and the previous keyframe, used to avoid unneeded searching. */ +} AVIndexEntry; + +#define AV_DISPOSITION_DEFAULT 0x0001 +#define AV_DISPOSITION_DUB 0x0002 +#define AV_DISPOSITION_ORIGINAL 0x0004 +#define AV_DISPOSITION_COMMENT 0x0008 +#define AV_DISPOSITION_LYRICS 0x0010 +#define AV_DISPOSITION_KARAOKE 0x0020 + +/** + * Stream structure. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVStream) must not be used outside libav*. + */ +typedef struct AVStream { + int index; /**< stream index in AVFormatContext */ + int id; /**< format-specific stream ID */ + AVCodecContext *codec; /**< codec context */ + /** + * Real base framerate of the stream. + * This is the lowest framerate with which all timestamps can be + * represented accurately (it is the least common multiple of all + * framerates in the stream). Note, this value is just a guess! + * For example, if the time base is 1/90000 and all frames have either + * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1. + */ + AVRational r_frame_rate; + void *priv_data; + + /* internal data used in av_find_stream_info() */ + int64_t first_dts; + /** encoding: pts generation when outputting stream */ + struct AVFrac pts; + + /** + * This is the fundamental unit of time (in seconds) in terms + * of which frame timestamps are represented. For fixed-fps content, + * time base should be 1/framerate and timestamp increments should be 1. + */ + AVRational time_base; + int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */ + /* ffmpeg.c private use */ + int stream_copy; /**< If set, just copy stream. */ + enum AVDiscard discard; ///< Selects which packets can be discarded at will and do not need to be demuxed. + //FIXME move stuff to a flags field? + /** Quality, as it has been removed from AVCodecContext and put in AVVideoFrame. + * MN: dunno if that is the right place for it */ + float quality; + /** + * Decoding: pts of the first frame of the stream, in stream time base. + * Only set this if you are absolutely 100% sure that the value you set + * it to really is the pts of the first frame. + * This may be undefined (AV_NOPTS_VALUE). + * @note The ASF header does NOT contain a correct start_time the ASF + * demuxer must NOT set this. + */ + int64_t start_time; + /** + * Decoding: duration of the stream, in stream time base. + * If a source file does not specify a duration, but does specify + * a bitrate, this value will be estimated from bitrate and file size. + */ + int64_t duration; + +#if LIBAVFORMAT_VERSION_INT < (53<<16) + char language[4]; /** ISO 639-2/B 3-letter language code (empty string if undefined) */ +#endif + + /* av_read_frame() support */ + enum AVStreamParseType need_parsing; + struct AVCodecParserContext *parser; + + int64_t cur_dts; + int last_IP_duration; + int64_t last_IP_pts; + /* av_seek_frame() support */ + AVIndexEntry *index_entries; /**< Only used if the format does not + support seeking natively. */ + int nb_index_entries; + unsigned int index_entries_allocated_size; + + int64_t nb_frames; ///< number of frames in this stream if known or 0 + +#if LIBAVFORMAT_VERSION_INT < (53<<16) + int64_t unused[4+1]; + + char *filename; /**< source filename of the stream */ +#endif + + int disposition; /**< AV_DISPOSITION_* bit field */ + + AVProbeData probe_data; +#define MAX_REORDER_DELAY 16 + int64_t pts_buffer[MAX_REORDER_DELAY+1]; + + /** + * sample aspect ratio (0 if unknown) + * - encoding: Set by user. + * - decoding: Set by libavformat. + */ + AVRational sample_aspect_ratio; + + AVMetadata *metadata; + + /* av_read_frame() support */ + const uint8_t *cur_ptr; + int cur_len; + AVPacket cur_pkt; + + // Timestamp generation support: + /** + * Timestamp corresponding to the last dts sync point. + * + * Initialized when AVCodecParserContext.dts_sync_point >= 0 and + * a DTS is received from the underlying container. Otherwise set to + * AV_NOPTS_VALUE by default. + */ + int64_t reference_dts; + + /** + * Number of packets to buffer for codec probing + * NOT PART OF PUBLIC API + */ +#define MAX_PROBE_PACKETS 2500 + int probe_packets; + + /** + * last packet in packet_buffer for this stream when muxing. + * used internally, NOT PART OF PUBLIC API, dont read or write from outside of libav* + */ + struct AVPacketList *last_in_packet_buffer; + + /** + * Average framerate + */ + AVRational avg_frame_rate; + + /** + * Number of frames that have been demuxed during av_find_stream_info() + */ + int codec_info_nb_frames; +} AVStream; + +#define AV_PROGRAM_RUNNING 1 + +/** + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVProgram) must not be used outside libav*. + */ +typedef struct AVProgram { + int id; +#if LIBAVFORMAT_VERSION_INT < (53<<16) + char *provider_name; ///< network name for DVB streams + char *name; ///< service name for DVB streams +#endif + int flags; + enum AVDiscard discard; ///< selects which program to discard and which to feed to the caller + unsigned int *stream_index; + unsigned int nb_stream_indexes; + AVMetadata *metadata; +} AVProgram; + +#define AVFMTCTX_NOHEADER 0x0001 /**< signal that no header is present + (streams are added dynamically) */ + +typedef struct AVChapter { + int id; ///< unique ID to identify the chapter + AVRational time_base; ///< time base in which the start/end timestamps are specified + int64_t start, end; ///< chapter start/end time in time_base units +#if LIBAVFORMAT_VERSION_INT < (53<<16) + char *title; ///< chapter title +#endif + AVMetadata *metadata; +} AVChapter; + +#if LIBAVFORMAT_VERSION_MAJOR < 53 +#define MAX_STREAMS 20 +#else +#define MAX_STREAMS 100 +#endif + +/** + * Format I/O context. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVFormatContext) must not be used outside libav*. + */ +typedef struct AVFormatContext { + const AVClass *av_class; /**< Set by avformat_alloc_context. */ + /* Can only be iformat or oformat, not both at the same time. */ + struct AVInputFormat *iformat; + struct AVOutputFormat *oformat; + void *priv_data; + ByteIOContext *pb; + unsigned int nb_streams; + AVStream *streams[MAX_STREAMS]; + char filename[1024]; /**< input or output filename */ + /* stream info */ + int64_t timestamp; +#if LIBAVFORMAT_VERSION_INT < (53<<16) + char title[512]; + char author[512]; + char copyright[512]; + char comment[512]; + char album[512]; + int year; /**< ID3 year, 0 if none */ + int track; /**< track number, 0 if none */ + char genre[32]; /**< ID3 genre */ +#endif + + int ctx_flags; /**< Format-specific flags, see AVFMTCTX_xx */ + /* private data for pts handling (do not modify directly). */ + /** This buffer is only needed when packets were already buffered but + not decoded, for example to get the codec parameters in MPEG + streams. */ + struct AVPacketList *packet_buffer; + + /** Decoding: position of the first frame of the component, in + AV_TIME_BASE fractional seconds. NEVER set this value directly: + It is deduced from the AVStream values. */ + int64_t start_time; + /** Decoding: duration of the stream, in AV_TIME_BASE fractional + seconds. Only set this value if you know none of the individual stream + durations and also dont set any of them. This is deduced from the + AVStream values if not set. */ + int64_t duration; + /** decoding: total file size, 0 if unknown */ + int64_t file_size; + /** Decoding: total stream bitrate in bit/s, 0 if not + available. Never set it directly if the file_size and the + duration are known as FFmpeg can compute it automatically. */ + int bit_rate; + + /* av_read_frame() support */ + AVStream *cur_st; +#if LIBAVFORMAT_VERSION_INT < (53<<16) + const uint8_t *cur_ptr_deprecated; + int cur_len_deprecated; + AVPacket cur_pkt_deprecated; +#endif + + /* av_seek_frame() support */ + int64_t data_offset; /** offset of the first packet */ + int index_built; + + int mux_rate; + unsigned int packet_size; + int preload; + int max_delay; + +#define AVFMT_NOOUTPUTLOOP -1 +#define AVFMT_INFINITEOUTPUTLOOP 0 + /** number of times to loop output in formats that support it */ + int loop_output; + + int flags; +#define AVFMT_FLAG_GENPTS 0x0001 ///< Generate missing pts even if it requires parsing future frames. +#define AVFMT_FLAG_IGNIDX 0x0002 ///< Ignore index. +#define AVFMT_FLAG_NONBLOCK 0x0004 ///< Do not block when reading packets from input. +#define AVFMT_FLAG_IGNDTS 0x0008 ///< Ignore DTS on frames that contain both DTS & PTS +#define AVFMT_FLAG_NOFILLIN 0x0010 ///< Do not infer any values from other values, just return what is stored in the container +#define AVFMT_FLAG_NOPARSE 0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled +#define AVFMT_FLAG_RTP_HINT 0x0040 ///< Add RTP hinting to the output file + + int loop_input; + /** decoding: size of data to probe; encoding: unused. */ + unsigned int probesize; + + /** + * Maximum time (in AV_TIME_BASE units) during which the input should + * be analyzed in av_find_stream_info(). + */ + int max_analyze_duration; + + const uint8_t *key; + int keylen; + + unsigned int nb_programs; + AVProgram **programs; + + /** + * Forced video codec_id. + * Demuxing: Set by user. + */ + enum CodecID video_codec_id; + /** + * Forced audio codec_id. + * Demuxing: Set by user. + */ + enum CodecID audio_codec_id; + /** + * Forced subtitle codec_id. + * Demuxing: Set by user. + */ + enum CodecID subtitle_codec_id; + + /** + * Maximum amount of memory in bytes to use for the index of each stream. + * If the index exceeds this size, entries will be discarded as + * needed to maintain a smaller size. This can lead to slower or less + * accurate seeking (depends on demuxer). + * Demuxers for which a full in-memory index is mandatory will ignore + * this. + * muxing : unused + * demuxing: set by user + */ + unsigned int max_index_size; + + /** + * Maximum amount of memory in bytes to use for buffering frames + * obtained from realtime capture devices. + */ + unsigned int max_picture_buffer; + + unsigned int nb_chapters; + AVChapter **chapters; + + /** + * Flags to enable debugging. + */ + int debug; +#define FF_FDEBUG_TS 0x0001 + + /** + * Raw packets from the demuxer, prior to parsing and decoding. + * This buffer is used for buffering packets until the codec can + * be identified, as parsing cannot be done without knowing the + * codec. + */ + struct AVPacketList *raw_packet_buffer; + struct AVPacketList *raw_packet_buffer_end; + + struct AVPacketList *packet_buffer_end; + + AVMetadata *metadata; + + /** + * Remaining size available for raw_packet_buffer, in bytes. + * NOT PART OF PUBLIC API + */ +#define RAW_PACKET_BUFFER_SIZE 2500000 + int raw_packet_buffer_remaining_size; + + /** + * Start time of the stream in real world time, in microseconds + * since the unix epoch (00:00 1st January 1970). That is, pts=0 + * in the stream was captured at this real world time. + * - encoding: Set by user. + * - decoding: Unused. + */ + int64_t start_time_realtime; +} AVFormatContext; + +typedef struct AVPacketList { + AVPacket pkt; + struct AVPacketList *next; +} AVPacketList; + +#if LIBAVFORMAT_VERSION_INT < (53<<16) +extern AVInputFormat *first_iformat; +extern AVOutputFormat *first_oformat; +#endif + +/** + * If f is NULL, returns the first registered input format, + * if f is non-NULL, returns the next registered input format after f + * or NULL if f is the last one. + */ +AVInputFormat *av_iformat_next(AVInputFormat *f); + +/** + * If f is NULL, returns the first registered output format, + * if f is non-NULL, returns the next registered output format after f + * or NULL if f is the last one. + */ +AVOutputFormat *av_oformat_next(AVOutputFormat *f); + +enum CodecID av_guess_image2_codec(const char *filename); + +/* XXX: Use automatic init with either ELF sections or C file parser */ +/* modules. */ + +/* utils.c */ +void av_register_input_format(AVInputFormat *format); +void av_register_output_format(AVOutputFormat *format); +#if LIBAVFORMAT_VERSION_MAJOR < 53 +attribute_deprecated AVOutputFormat *guess_stream_format(const char *short_name, + const char *filename, + const char *mime_type); + +/** + * @deprecated Use av_guess_format() instead. + */ +attribute_deprecated AVOutputFormat *guess_format(const char *short_name, + const char *filename, + const char *mime_type); +#endif + +/** + * Returns the output format in the list of registered output formats + * which best matches the provided parameters, or returns NULL if + * there is no match. + * + * @param short_name if non-NULL checks if short_name matches with the + * names of the registered formats + * @param filename if non-NULL checks if filename terminates with the + * extensions of the registered formats + * @param mime_type if non-NULL checks if mime_type matches with the + * MIME type of the registered formats + */ +AVOutputFormat *av_guess_format(const char *short_name, + const char *filename, + const char *mime_type); + +/** + * Guesses the codec ID based upon muxer and filename. + */ +enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name, + const char *filename, const char *mime_type, + enum AVMediaType type); + +/** + * Sends a nice hexadecimal dump of a buffer to the specified file stream. + * + * @param f The file stream pointer where the dump should be sent to. + * @param buf buffer + * @param size buffer size + * + * @see av_hex_dump_log, av_pkt_dump, av_pkt_dump_log + */ +void av_hex_dump(FILE *f, uint8_t *buf, int size); + +/** + * Sends a nice hexadecimal dump of a buffer to the log. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message, lower values signifying + * higher importance. + * @param buf buffer + * @param size buffer size + * + * @see av_hex_dump, av_pkt_dump, av_pkt_dump_log + */ +void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size); + +/** + * Sends a nice dump of a packet to the specified file stream. + * + * @param f The file stream pointer where the dump should be sent to. + * @param pkt packet to dump + * @param dump_payload True if the payload must be displayed, too. + */ +void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload); + +/** + * Sends a nice dump of a packet to the log. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message, lower values signifying + * higher importance. + * @param pkt packet to dump + * @param dump_payload True if the payload must be displayed, too. + */ +void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload); + +/** + * Initializes libavformat and registers all the muxers, demuxers and + * protocols. If you do not call this function, then you can select + * exactly which formats you want to support. + * + * @see av_register_input_format() + * @see av_register_output_format() + * @see av_register_protocol() + */ +void av_register_all(void); + +/** + * Gets the CodecID for the given codec tag tag. + * If no codec id is found returns CODEC_ID_NONE. + * + * @param tags list of supported codec_id-codec_tag pairs, as stored + * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag + */ +enum CodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag); + +/** + * Gets the codec tag for the given codec id id. + * If no codec tag is found returns 0. + * + * @param tags list of supported codec_id-codec_tag pairs, as stored + * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag + */ +unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum CodecID id); + +/* media file input */ + +/** + * Finds AVInputFormat based on the short name of the input format. + */ +AVInputFormat *av_find_input_format(const char *short_name); + +/** + * Guesses the file format. + * + * @param is_opened Whether the file is already opened; determines whether + * demuxers with or without AVFMT_NOFILE are probed. + */ +AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened); + +/** + * Guesses the file format. + * + * @param is_opened Whether the file is already opened; determines whether + * demuxers with or without AVFMT_NOFILE are probed. + * @param score_max A probe score larger that this is required to accept a + * detection, the variable is set to the actual detection + * score afterwards. + * If the score is <= AVPROBE_SCORE_MAX / 4 it is recommended + * to retry with a larger probe buffer. + */ +AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max); + +/** + * Allocates all the structures needed to read an input stream. + * This does not open the needed codecs for decoding the stream[s]. + */ +int av_open_input_stream(AVFormatContext **ic_ptr, + ByteIOContext *pb, const char *filename, + AVInputFormat *fmt, AVFormatParameters *ap); + +/** + * Opens a media file as input. The codecs are not opened. Only the file + * header (if present) is read. + * + * @param ic_ptr The opened media file handle is put here. + * @param filename filename to open + * @param fmt If non-NULL, force the file format to use. + * @param buf_size optional buffer size (zero if default is OK) + * @param ap Additional parameters needed when opening the file + * (NULL if default). + * @return 0 if OK, AVERROR_xxx otherwise + */ +int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, + AVInputFormat *fmt, + int buf_size, + AVFormatParameters *ap); + +#if LIBAVFORMAT_VERSION_MAJOR < 53 +/** + * @deprecated Use avformat_alloc_context() instead. + */ +attribute_deprecated AVFormatContext *av_alloc_format_context(void); +#endif + +/** + * Allocates an AVFormatContext. + * Can be freed with av_free() but do not forget to free everything you + * explicitly allocated as well! + */ +AVFormatContext *avformat_alloc_context(void); + +/** + * Reads packets of a media file to get stream information. This + * is useful for file formats with no headers such as MPEG. This + * function also computes the real framerate in case of MPEG-2 repeat + * frame mode. + * The logical file position is not changed by this function; + * examined packets may be buffered for later processing. + * + * @param ic media file handle + * @return >=0 if OK, AVERROR_xxx on error + * @todo Let the user decide somehow what information is needed so that + * we do not waste time getting stuff the user does not need. + */ +int av_find_stream_info(AVFormatContext *ic); + +/** + * Reads a transport packet from a media file. + * + * This function is obsolete and should never be used. + * Use av_read_frame() instead. + * + * @param s media file handle + * @param pkt is filled + * @return 0 if OK, AVERROR_xxx on error + */ +int av_read_packet(AVFormatContext *s, AVPacket *pkt); + +/** + * Returns the next frame of a stream. + * + * The returned packet is valid + * until the next av_read_frame() or until av_close_input_file() and + * must be freed with av_free_packet. For video, the packet contains + * exactly one frame. For audio, it contains an integer number of + * frames if each frame has a known fixed size (e.g. PCM or ADPCM + * data). If the audio frames have a variable size (e.g. MPEG audio), + * then it contains one frame. + * + * pkt->pts, pkt->dts and pkt->duration are always set to correct + * values in AVStream.time_base units (and guessed if the format cannot + * provide them). pkt->pts can be AV_NOPTS_VALUE if the video format + * has B-frames, so it is better to rely on pkt->dts if you do not + * decompress the payload. + * + * @return 0 if OK, < 0 on error or end of file + */ +int av_read_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * Seeks to the keyframe at timestamp. + * 'timestamp' in 'stream_index'. + * @param stream_index If stream_index is (-1), a default + * stream is selected, and timestamp is automatically converted + * from AV_TIME_BASE units to the stream specific time_base. + * @param timestamp Timestamp in AVStream.time_base units + * or, if no stream is specified, in AV_TIME_BASE units. + * @param flags flags which select direction and seeking mode + * @return >= 0 on success + */ +int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, + int flags); + +/** + * Seeks to timestamp ts. + * Seeking will be done so that the point from which all active streams + * can be presented successfully will be closest to ts and within min/max_ts. + * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. + * + * If flags contain AVSEEK_FLAG_BYTE, then all timestamps are in bytes and + * are the file position (this may not be supported by all demuxers). + * If flags contain AVSEEK_FLAG_FRAME, then all timestamps are in frames + * in the stream with stream_index (this may not be supported by all demuxers). + * Otherwise all timestamps are in units of the stream selected by stream_index + * or if stream_index is -1, in AV_TIME_BASE units. + * If flags contain AVSEEK_FLAG_ANY, then non-keyframes are treated as + * keyframes (this may not be supported by all demuxers). + * + * @param stream_index index of the stream which is used as time base reference + * @param min_ts smallest acceptable timestamp + * @param ts target timestamp + * @param max_ts largest acceptable timestamp + * @param flags flags + * @return >=0 on success, error code otherwise + * + * @NOTE This is part of the new seek API which is still under construction. + * Thus do not use this yet. It may change at any time, do not expect + * ABI compatibility yet! + */ +int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); + +/** + * Starts playing a network-based stream (e.g. RTSP stream) at the + * current position. + */ +int av_read_play(AVFormatContext *s); + +/** + * Pauses a network-based stream (e.g. RTSP stream). + * + * Use av_read_play() to resume it. + */ +int av_read_pause(AVFormatContext *s); + +/** + * Frees a AVFormatContext allocated by av_open_input_stream. + * @param s context to free + */ +void av_close_input_stream(AVFormatContext *s); + +/** + * Closes a media file (but not its codecs). + * + * @param s media file handle + */ +void av_close_input_file(AVFormatContext *s); + +/** + * Adds a new stream to a media file. + * + * Can only be called in the read_header() function. If the flag + * AVFMTCTX_NOHEADER is in the format context, then new streams + * can be added in read_packet too. + * + * @param s media file handle + * @param id file-format-dependent stream ID + */ +AVStream *av_new_stream(AVFormatContext *s, int id); +AVProgram *av_new_program(AVFormatContext *s, int id); + +/** + * Adds a new chapter. + * This function is NOT part of the public API + * and should ONLY be used by demuxers. + * + * @param s media file handle + * @param id unique ID for this chapter + * @param start chapter start time in time_base units + * @param end chapter end time in time_base units + * @param title chapter title + * + * @return AVChapter or NULL on error + */ +AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, + int64_t start, int64_t end, const char *title); + +/** + * Sets the pts for a given stream. + * + * @param s stream + * @param pts_wrap_bits number of bits effectively used by the pts + * (used for wrap control, 33 is the value for MPEG) + * @param pts_num numerator to convert to seconds (MPEG: 1) + * @param pts_den denominator to convert to seconds (MPEG: 90000) + */ +void av_set_pts_info(AVStream *s, int pts_wrap_bits, + unsigned int pts_num, unsigned int pts_den); + +#define AVSEEK_FLAG_BACKWARD 1 ///< seek backward +#define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes +#define AVSEEK_FLAG_ANY 4 ///< seek to any frame, even non-keyframes +#define AVSEEK_FLAG_FRAME 8 ///< seeking based on frame number + +int av_find_default_stream_index(AVFormatContext *s); + +/** + * Gets the index for a specific timestamp. + * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond + * to the timestamp which is <= the requested one, if backward + * is 0, then it will be >= + * if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise + * @return < 0 if no such timestamp could be found + */ +int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags); + +/** + * Ensures the index uses less memory than the maximum specified in + * AVFormatContext.max_index_size by discarding entries if it grows + * too large. + * This function is not part of the public API and should only be called + * by demuxers. + */ +void ff_reduce_index(AVFormatContext *s, int stream_index); + +/** + * Adds an index entry into a sorted list. Updates the entry if the list + * already contains it. + * + * @param timestamp timestamp in the time base of the given stream + */ +int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, + int size, int distance, int flags); + +/** + * Does a binary search using av_index_search_timestamp() and + * AVCodec.read_timestamp(). + * This is not supposed to be called directly by a user application, + * but by demuxers. + * @param target_ts target timestamp in the time base of the given stream + * @param stream_index stream number + */ +int av_seek_frame_binary(AVFormatContext *s, int stream_index, + int64_t target_ts, int flags); + +/** + * Updates cur_dts of all streams based on the given timestamp and AVStream. + * + * Stream ref_st unchanged, others set cur_dts in their native time base. + * Only needed for timestamp wrapping or if (dts not set and pts!=dts). + * @param timestamp new dts expressed in time_base of param ref_st + * @param ref_st reference stream giving time_base of param timestamp + */ +void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp); + +/** + * Does a binary search using read_timestamp(). + * This is not supposed to be called directly by a user application, + * but by demuxers. + * @param target_ts target timestamp in the time base of the given stream + * @param stream_index stream number + */ +int64_t av_gen_search(AVFormatContext *s, int stream_index, + int64_t target_ts, int64_t pos_min, + int64_t pos_max, int64_t pos_limit, + int64_t ts_min, int64_t ts_max, + int flags, int64_t *ts_ret, + int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )); + +/** media file output */ +int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap); + +/** + * Allocates the stream private data and writes the stream header to an + * output media file. + * + * @param s media file handle + * @return 0 if OK, AVERROR_xxx on error + */ +int av_write_header(AVFormatContext *s); + +/** + * Writes a packet to an output media file. + * + * The packet shall contain one audio or video frame. + * The packet must be correctly interleaved according to the container + * specification, if not then av_interleaved_write_frame must be used. + * + * @param s media file handle + * @param pkt The packet, which contains the stream_index, buf/buf_size, + dts/pts, ... + * @return < 0 on error, = 0 if OK, 1 if end of stream wanted + */ +int av_write_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * Writes a packet to an output media file ensuring correct interleaving. + * + * The packet must contain one audio or video frame. + * If the packets are already correctly interleaved, the application should + * call av_write_frame() instead as it is slightly faster. It is also important + * to keep in mind that completely non-interleaved input will need huge amounts + * of memory to interleave with this, so it is preferable to interleave at the + * demuxer level. + * + * @param s media file handle + * @param pkt The packet, which contains the stream_index, buf/buf_size, + dts/pts, ... + * @return < 0 on error, = 0 if OK, 1 if end of stream wanted + */ +int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * Interleaves a packet per dts in an output media file. + * + * Packets with pkt->destruct == av_destruct_packet will be freed inside this + * function, so they cannot be used after it. Note that calling av_free_packet() + * on them is still safe. + * + * @param s media file handle + * @param out the interleaved packet will be output here + * @param in the input packet + * @param flush 1 if no further packets are available as input and all + * remaining packets should be output + * @return 1 if a packet was output, 0 if no packet could be output, + * < 0 if an error occurred + */ +int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, + AVPacket *pkt, int flush); + +/** + * Writes the stream trailer to an output media file and frees the + * file private data. + * + * May only be called after a successful call to av_write_header. + * + * @param s media file handle + * @return 0 if OK, AVERROR_xxx on error + */ +int av_write_trailer(AVFormatContext *s); + +void dump_format(AVFormatContext *ic, + int index, + const char *url, + int is_output); + +#if LIBAVFORMAT_VERSION_MAJOR < 53 +/** + * Parses width and height out of string str. + * @deprecated Use av_parse_video_frame_size instead. + */ +attribute_deprecated int parse_image_size(int *width_ptr, int *height_ptr, + const char *str); + +/** + * Converts framerate from a string to a fraction. + * @deprecated Use av_parse_video_frame_rate instead. + */ +attribute_deprecated int parse_frame_rate(int *frame_rate, int *frame_rate_base, + const char *arg); +#endif + +/** + * Parses datestr and returns a corresponding number of microseconds. + * @param datestr String representing a date or a duration. + * - If a date the syntax is: + * @code + * [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]} + * @endcode + * Time is local time unless Z is appended, in which case it is + * interpreted as UTC. + * If the year-month-day part is not specified it takes the current + * year-month-day. + * Returns the number of microseconds since 1st of January, 1970 up to + * the time of the parsed date or INT64_MIN if datestr cannot be + * successfully parsed. + * - If a duration the syntax is: + * @code + * [-]HH[:MM[:SS[.m...]]] + * [-]S+[.m...] + * @endcode + * Returns the number of microseconds contained in a time interval + * with the specified duration or INT64_MIN if datestr cannot be + * successfully parsed. + * @param duration Flag which tells how to interpret datestr, if + * not zero datestr is interpreted as a duration, otherwise as a + * date. + */ +int64_t parse_date(const char *datestr, int duration); + +/** Gets the current time in microseconds. */ +int64_t av_gettime(void); + +/* ffm-specific for ffserver */ +#define FFM_PACKET_SIZE 4096 +int64_t ffm_read_write_index(int fd); +int ffm_write_write_index(int fd, int64_t pos); +void ffm_set_write_index(AVFormatContext *s, int64_t pos, int64_t file_size); + +/** + * Attempts to find a specific tag in a URL. + * + * syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. + * Return 1 if found. + */ +int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info); + +/** + * Returns in 'buf' the path with '%d' replaced by a number. + * + * Also handles the '%0nd' format where 'n' is the total number + * of digits and '%%'. + * + * @param buf destination buffer + * @param buf_size destination buffer size + * @param path numbered sequence string + * @param number frame number + * @return 0 if OK, -1 on format error + */ +int av_get_frame_filename(char *buf, int buf_size, + const char *path, int number); + +/** + * Checks whether filename actually is a numbered sequence generator. + * + * @param filename possible numbered sequence string + * @return 1 if a valid numbered sequence string, 0 otherwise + */ +int av_filename_number_test(const char *filename); + +/** + * Generates an SDP for an RTP session. + * + * @param ac array of AVFormatContexts describing the RTP streams. If the + * array is composed by only one context, such context can contain + * multiple AVStreams (one AVStream per RTP stream). Otherwise, + * all the contexts in the array (an AVCodecContext per RTP stream) + * must contain only one AVStream. + * @param n_files number of AVCodecContexts contained in ac + * @param buff buffer where the SDP will be stored (must be allocated by + * the caller) + * @param size the size of the buffer + * @return 0 if OK, AVERROR_xxx on error + */ +int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size); + +/** + * Returns a positive value if the given filename has one of the given + * extensions, 0 otherwise. + * + * @param extensions a comma-separated list of filename extensions + */ +int av_match_ext(const char *filename, const char *extensions); + +#endif /* AVFORMAT_AVFORMAT_H */ diff --git a/include/libavformat/avio.h b/include/libavformat/avio.h new file mode 100644 index 00000000..9ffe9356 --- /dev/null +++ b/include/libavformat/avio.h @@ -0,0 +1,525 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef AVFORMAT_AVIO_H +#define AVFORMAT_AVIO_H + +/** + * @file + * unbuffered I/O operations + * + * @warning This file has to be considered an internal but installed + * header, so it should not be directly included in your projects. + */ + +#include <stdint.h> + +#include "libavutil/common.h" + +/* unbuffered I/O */ + +/** + * URL Context. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(URLContext) must not be used outside libav*. + */ +typedef struct URLContext { +#if LIBAVFORMAT_VERSION_MAJOR >= 53 + const AVClass *av_class; ///< information for av_log(). Set by url_open(). +#endif + struct URLProtocol *prot; + int flags; + int is_streamed; /**< true if streamed (no seek possible), default = false */ + int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */ + void *priv_data; + char *filename; /**< specified URL */ +} URLContext; + +typedef struct URLPollEntry { + URLContext *handle; + int events; + int revents; +} URLPollEntry; + +#define URL_RDONLY 0 +#define URL_WRONLY 1 +#define URL_RDWR 2 + +typedef int URLInterruptCB(void); + +/** + * Creates an URLContext for accessing to the resource indicated by + * url, and opens it using the URLProtocol up. + * + * @param puc pointer to the location where, in case of success, the + * function puts the pointer to the created URLContext + * @param flags flags which control how the resource indicated by url + * is to be opened + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + */ +int url_open_protocol (URLContext **puc, struct URLProtocol *up, + const char *url, int flags); + +/** + * Creates an URLContext for accessing to the resource indicated by + * url, and opens it. + * + * @param puc pointer to the location where, in case of success, the + * function puts the pointer to the created URLContext + * @param flags flags which control how the resource indicated by url + * is to be opened + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + */ +int url_open(URLContext **h, const char *url, int flags); + +/** + * Reads up to size bytes from the resource accessed by h, and stores + * the read bytes in buf. + * + * @return The number of bytes actually read, or a negative value + * corresponding to an AVERROR code in case of error. A value of zero + * indicates that it is not possible to read more from the accessed + * resource (except if the value of the size argument is also zero). + */ +int url_read(URLContext *h, unsigned char *buf, int size); + +/** + * Read as many bytes as possible (up to size), calling the + * read function multiple times if necessary. + * Will also retry if the read function returns AVERROR(EAGAIN). + * This makes special short-read handling in applications + * unnecessary, if the return value is < size then it is + * certain there was either an error or the end of file was reached. + */ +int url_read_complete(URLContext *h, unsigned char *buf, int size); +int url_write(URLContext *h, unsigned char *buf, int size); + +/** + * Changes the position that will be used by the next read/write + * operation on the resource accessed by h. + * + * @param pos specifies the new position to set + * @param whence specifies how pos should be interpreted, it must be + * one of SEEK_SET (seek from the beginning), SEEK_CUR (seek from the + * current position), SEEK_END (seek from the end), or AVSEEK_SIZE + * (return the filesize of the requested resource, pos is ignored). + * @return a negative value corresponding to an AVERROR code in case + * of failure, or the resulting file position, measured in bytes from + * the beginning of the file. You can use this feature together with + * SEEK_CUR to read the current file position. + */ +int64_t url_seek(URLContext *h, int64_t pos, int whence); + +/** + * Closes the resource accessed by the URLContext h, and frees the + * memory used by it. + * + * @return a negative value if an error condition occurred, 0 + * otherwise + */ +int url_close(URLContext *h); + +/** + * Returns a non-zero value if the resource indicated by url + * exists, 0 otherwise. + */ +int url_exist(const char *url); + +int64_t url_filesize(URLContext *h); + +/** + * Return the file descriptor associated with this URL. For RTP, this + * will return only the RTP file descriptor, not the RTCP file descriptor. + * To get both, use rtp_get_file_handles(). + * + * @return the file descriptor associated with this URL, or <0 on error. + */ +int url_get_file_handle(URLContext *h); + +/** + * Return the maximum packet size associated to packetized file + * handle. If the file is not packetized (stream like HTTP or file on + * disk), then 0 is returned. + * + * @param h file handle + * @return maximum packet size in bytes + */ +int url_get_max_packet_size(URLContext *h); +void url_get_filename(URLContext *h, char *buf, int buf_size); + +/** + * The callback is called in blocking functions to test regulary if + * asynchronous interruption is needed. AVERROR(EINTR) is returned + * in this case by the interrupted function. 'NULL' means no interrupt + * callback is given. + */ +void url_set_interrupt_cb(URLInterruptCB *interrupt_cb); + +/* not implemented */ +int url_poll(URLPollEntry *poll_table, int n, int timeout); + +/** + * Pause and resume playing - only meaningful if using a network streaming + * protocol (e.g. MMS). + * @param pause 1 for pause, 0 for resume + */ +int av_url_read_pause(URLContext *h, int pause); + +/** + * Seek to a given timestamp relative to some component stream. + * Only meaningful if using a network streaming protocol (e.g. MMS.). + * @param stream_index The stream index that the timestamp is relative to. + * If stream_index is (-1) the timestamp should be in AV_TIME_BASE + * units from the beginning of the presentation. + * If a stream_index >= 0 is used and the protocol does not support + * seeking based on component streams, the call will fail with ENOTSUP. + * @param timestamp timestamp in AVStream.time_base units + * or if there is no stream specified then in AV_TIME_BASE units. + * @param flags Optional combination of AVSEEK_FLAG_BACKWARD, AVSEEK_FLAG_BYTE + * and AVSEEK_FLAG_ANY. The protocol may silently ignore + * AVSEEK_FLAG_BACKWARD and AVSEEK_FLAG_ANY, but AVSEEK_FLAG_BYTE will + * fail with ENOTSUP if used and not supported. + * @return >= 0 on success + * @see AVInputFormat::read_seek + */ +int64_t av_url_read_seek(URLContext *h, int stream_index, + int64_t timestamp, int flags); + +/** + * Passing this as the "whence" parameter to a seek function causes it to + * return the filesize without seeking anywhere. Supporting this is optional. + * If it is not supported then the seek function will return <0. + */ +#define AVSEEK_SIZE 0x10000 + +/** + * Oring this flag as into the "whence" parameter to a seek function causes it to + * seek by any means (like reopening and linear reading) or other normally unreasonble + * means that can be extreemly slow. + * This may be ignored by the seek code. + */ +#define AVSEEK_FORCE 0x20000 + +typedef struct URLProtocol { + const char *name; + int (*url_open)(URLContext *h, const char *url, int flags); + int (*url_read)(URLContext *h, unsigned char *buf, int size); + int (*url_write)(URLContext *h, unsigned char *buf, int size); + int64_t (*url_seek)(URLContext *h, int64_t pos, int whence); + int (*url_close)(URLContext *h); + struct URLProtocol *next; + int (*url_read_pause)(URLContext *h, int pause); + int64_t (*url_read_seek)(URLContext *h, int stream_index, + int64_t timestamp, int flags); + int (*url_get_file_handle)(URLContext *h); +} URLProtocol; + +#if LIBAVFORMAT_VERSION_MAJOR < 53 +extern URLProtocol *first_protocol; +#endif + +extern URLInterruptCB *url_interrupt_cb; + +/** + * If protocol is NULL, returns the first registered protocol, + * if protocol is non-NULL, returns the next registered protocol after protocol, + * or NULL if protocol is the last one. + */ +URLProtocol *av_protocol_next(URLProtocol *p); + +#if LIBAVFORMAT_VERSION_MAJOR < 53 +/** + * @deprecated Use av_register_protocol() instead. + */ +attribute_deprecated int register_protocol(URLProtocol *protocol); +#endif + +/** + * Registers the URLProtocol protocol. + */ +int av_register_protocol(URLProtocol *protocol); + +/** + * Bytestream IO Context. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(ByteIOContext) must not be used outside libav*. + */ +typedef struct { + unsigned char *buffer; + int buffer_size; + unsigned char *buf_ptr, *buf_end; + void *opaque; + int (*read_packet)(void *opaque, uint8_t *buf, int buf_size); + int (*write_packet)(void *opaque, uint8_t *buf, int buf_size); + int64_t (*seek)(void *opaque, int64_t offset, int whence); + int64_t pos; /**< position in the file of the current buffer */ + int must_flush; /**< true if the next seek should flush */ + int eof_reached; /**< true if eof reached */ + int write_flag; /**< true if open for writing */ + int is_streamed; + int max_packet_size; + unsigned long checksum; + unsigned char *checksum_ptr; + unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size); + int error; ///< contains the error code or 0 if no error happened + int (*read_pause)(void *opaque, int pause); + int64_t (*read_seek)(void *opaque, int stream_index, + int64_t timestamp, int flags); +} ByteIOContext; + +int init_put_byte(ByteIOContext *s, + unsigned char *buffer, + int buffer_size, + int write_flag, + void *opaque, + int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), + int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), + int64_t (*seek)(void *opaque, int64_t offset, int whence)); +ByteIOContext *av_alloc_put_byte( + unsigned char *buffer, + int buffer_size, + int write_flag, + void *opaque, + int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), + int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), + int64_t (*seek)(void *opaque, int64_t offset, int whence)); + +void put_byte(ByteIOContext *s, int b); +void put_buffer(ByteIOContext *s, const unsigned char *buf, int size); +void put_le64(ByteIOContext *s, uint64_t val); +void put_be64(ByteIOContext *s, uint64_t val); +void put_le32(ByteIOContext *s, unsigned int val); +void put_be32(ByteIOContext *s, unsigned int val); +void put_le24(ByteIOContext *s, unsigned int val); +void put_be24(ByteIOContext *s, unsigned int val); +void put_le16(ByteIOContext *s, unsigned int val); +void put_be16(ByteIOContext *s, unsigned int val); +void put_tag(ByteIOContext *s, const char *tag); + +void put_strz(ByteIOContext *s, const char *buf); + +/** + * fseek() equivalent for ByteIOContext. + * @return new position or AVERROR. + */ +int64_t url_fseek(ByteIOContext *s, int64_t offset, int whence); + +/** + * Skip given number of bytes forward. + * @param offset number of bytes + */ +void url_fskip(ByteIOContext *s, int64_t offset); + +/** + * ftell() equivalent for ByteIOContext. + * @return position or AVERROR. + */ +int64_t url_ftell(ByteIOContext *s); + +/** + * Gets the filesize. + * @return filesize or AVERROR + */ +int64_t url_fsize(ByteIOContext *s); + +/** + * feof() equivalent for ByteIOContext. + * @return non zero if and only if end of file + */ +int url_feof(ByteIOContext *s); + +int url_ferror(ByteIOContext *s); + +int av_url_read_fpause(ByteIOContext *h, int pause); +int64_t av_url_read_fseek(ByteIOContext *h, int stream_index, + int64_t timestamp, int flags); + +#define URL_EOF (-1) +/** @note return URL_EOF (-1) if EOF */ +int url_fgetc(ByteIOContext *s); + +/** @warning currently size is limited */ +#ifdef __GNUC__ +int url_fprintf(ByteIOContext *s, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); +#else +int url_fprintf(ByteIOContext *s, const char *fmt, ...); +#endif + +/** @note unlike fgets, the EOL character is not returned and a whole + line is parsed. return NULL if first char read was EOF */ +char *url_fgets(ByteIOContext *s, char *buf, int buf_size); + +void put_flush_packet(ByteIOContext *s); + + +/** + * Reads size bytes from ByteIOContext into buf. + * @return number of bytes read or AVERROR + */ +int get_buffer(ByteIOContext *s, unsigned char *buf, int size); + +/** + * Reads size bytes from ByteIOContext into buf. + * This reads at most 1 packet. If that is not enough fewer bytes will be + * returned. + * @return number of bytes read or AVERROR + */ +int get_partial_buffer(ByteIOContext *s, unsigned char *buf, int size); + +/** @note return 0 if EOF, so you cannot use it if EOF handling is + necessary */ +int get_byte(ByteIOContext *s); +unsigned int get_le24(ByteIOContext *s); +unsigned int get_le32(ByteIOContext *s); +uint64_t get_le64(ByteIOContext *s); +unsigned int get_le16(ByteIOContext *s); + +char *get_strz(ByteIOContext *s, char *buf, int maxlen); +unsigned int get_be16(ByteIOContext *s); +unsigned int get_be24(ByteIOContext *s); +unsigned int get_be32(ByteIOContext *s); +uint64_t get_be64(ByteIOContext *s); + +uint64_t ff_get_v(ByteIOContext *bc); + +static inline int url_is_streamed(ByteIOContext *s) +{ + return s->is_streamed; +} + +/** + * Creates and initializes a ByteIOContext for accessing the + * resource referenced by the URLContext h. + * @note When the URLContext h has been opened in read+write mode, the + * ByteIOContext can be used only for writing. + * + * @param s Used to return the pointer to the created ByteIOContext. + * In case of failure the pointed to value is set to NULL. + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + */ +int url_fdopen(ByteIOContext **s, URLContext *h); + +/** @warning must be called before any I/O */ +int url_setbufsize(ByteIOContext *s, int buf_size); +#if LIBAVFORMAT_VERSION_MAJOR < 53 +/** Reset the buffer for reading or writing. + * @note Will drop any data currently in the buffer without transmitting it. + * @param flags URL_RDONLY to set up the buffer for reading, or URL_WRONLY + * to set up the buffer for writing. */ +int url_resetbuf(ByteIOContext *s, int flags); +#endif + +/** + * Rewinds the ByteIOContext using the specified buffer containing the first buf_size bytes of the file. + * Used after probing to avoid seeking. + * Joins buf and s->buffer, taking any overlap into consideration. + * @note s->buffer must overlap with buf or they can't be joined and the function fails + * @note This function is NOT part of the public API + * + * @param s The read-only ByteIOContext to rewind + * @param buf The probe buffer containing the first buf_size bytes of the file + * @param buf_size The size of buf + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + */ +int ff_rewind_with_probe_data(ByteIOContext *s, unsigned char *buf, int buf_size); + +/** + * Creates and initializes a ByteIOContext for accessing the + * resource indicated by url. + * @note When the resource indicated by url has been opened in + * read+write mode, the ByteIOContext can be used only for writing. + * + * @param s Used to return the pointer to the created ByteIOContext. + * In case of failure the pointed to value is set to NULL. + * @param flags flags which control how the resource indicated by url + * is to be opened + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + */ +int url_fopen(ByteIOContext **s, const char *url, int flags); + +int url_fclose(ByteIOContext *s); +URLContext *url_fileno(ByteIOContext *s); + +/** + * Return the maximum packet size associated to packetized buffered file + * handle. If the file is not packetized (stream like http or file on + * disk), then 0 is returned. + * + * @param s buffered file handle + * @return maximum packet size in bytes + */ +int url_fget_max_packet_size(ByteIOContext *s); + +int url_open_buf(ByteIOContext **s, uint8_t *buf, int buf_size, int flags); + +/** return the written or read size */ +int url_close_buf(ByteIOContext *s); + +/** + * Open a write only memory stream. + * + * @param s new IO context + * @return zero if no error. + */ +int url_open_dyn_buf(ByteIOContext **s); + +/** + * Open a write only packetized memory stream with a maximum packet + * size of 'max_packet_size'. The stream is stored in a memory buffer + * with a big endian 4 byte header giving the packet size in bytes. + * + * @param s new IO context + * @param max_packet_size maximum packet size (must be > 0) + * @return zero if no error. + */ +int url_open_dyn_packet_buf(ByteIOContext **s, int max_packet_size); + +/** + * Return the written size and a pointer to the buffer. The buffer + * must be freed with av_free(). + * @param s IO context + * @param pbuffer pointer to a byte buffer + * @return the length of the byte buffer + */ +int url_close_dyn_buf(ByteIOContext *s, uint8_t **pbuffer); + +unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, + unsigned int len); +unsigned long get_checksum(ByteIOContext *s); +void init_checksum(ByteIOContext *s, + unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), + unsigned long checksum); + +/* udp.c */ +int udp_set_remote_url(URLContext *h, const char *uri); +int udp_get_local_port(URLContext *h); +#if (LIBAVFORMAT_VERSION_MAJOR <= 52) +int udp_get_file_handle(URLContext *h); +#endif + +#endif /* AVFORMAT_AVIO_H */ diff --git a/include/libavutil/adler32.h b/include/libavutil/adler32.h new file mode 100644 index 00000000..9626c805 --- /dev/null +++ b/include/libavutil/adler32.h @@ -0,0 +1,30 @@ +/* + * copyright (c) 2006 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ADLER32_H +#define AVUTIL_ADLER32_H + +#include <stdint.h> +#include "attributes.h" + +unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf, + unsigned int len) av_pure; + +#endif /* AVUTIL_ADLER32_H */ diff --git a/include/libavutil/attributes.h b/include/libavutil/attributes.h new file mode 100644 index 00000000..da45234c --- /dev/null +++ b/include/libavutil/attributes.h @@ -0,0 +1,113 @@ +/* + * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Macro definitions for various function/variable attributes + */ + +#ifndef AVUTIL_ATTRIBUTES_H +#define AVUTIL_ATTRIBUTES_H + +#ifdef __GNUC__ +# define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > x || __GNUC__ == x && __GNUC_MINOR__ >= y) +#else +# define AV_GCC_VERSION_AT_LEAST(x,y) 0 +#endif + +#ifndef av_always_inline +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_always_inline __attribute__((always_inline)) inline +#else +# define av_always_inline inline +#endif +#endif + +#ifndef av_noinline +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_noinline __attribute__((noinline)) +#else +# define av_noinline +#endif +#endif + +#ifndef av_pure +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_pure __attribute__((pure)) +#else +# define av_pure +#endif +#endif + +#ifndef av_const +#if AV_GCC_VERSION_AT_LEAST(2,6) +# define av_const __attribute__((const)) +#else +# define av_const +#endif +#endif + +#ifndef av_cold +#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,3) +# define av_cold __attribute__((cold)) +#else +# define av_cold +#endif +#endif + +#ifndef av_flatten +#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,1) +# define av_flatten __attribute__((flatten)) +#else +# define av_flatten +#endif +#endif + +#ifndef attribute_deprecated +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define attribute_deprecated __attribute__((deprecated)) +#else +# define attribute_deprecated +#endif +#endif + +#ifndef av_unused +#if defined(__GNUC__) +# define av_unused __attribute__((unused)) +#else +# define av_unused +#endif +#endif + +#ifndef av_uninit +#if defined(__GNUC__) && !defined(__ICC) +# define av_uninit(x) x=x +#else +# define av_uninit(x) x +#endif +#endif + +#ifdef __GNUC__ +# define av_builtin_constant_p __builtin_constant_p +#else +# define av_builtin_constant_p(x) 0 +#endif + +#endif /* AVUTIL_ATTRIBUTES_H */ diff --git a/include/libavutil/avconfig.h b/include/libavutil/avconfig.h new file mode 100644 index 00000000..b028bb4f --- /dev/null +++ b/include/libavutil/avconfig.h @@ -0,0 +1,5 @@ +/* Generated by ffconf */ +#ifndef AVUTIL_AVCONFIG_H +#define AVUTIL_AVCONFIG_H +#define AV_HAVE_BIGENDIAN 0 +#endif /* AVUTIL_AVCONFIG_H */ diff --git a/include/libavutil/avstring.h b/include/libavutil/avstring.h new file mode 100644 index 00000000..01c2391b --- /dev/null +++ b/include/libavutil/avstring.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2007 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AVSTRING_H +#define AVUTIL_AVSTRING_H + +#include <stddef.h> + +/** + * Return non-zero if pfx is a prefix of str. If it is, *ptr is set to + * the address of the first character in str after the prefix. + * + * @param str input string + * @param pfx prefix to test + * @param ptr updated if the prefix is matched inside str + * @return non-zero if the prefix matches, zero otherwise + */ +int av_strstart(const char *str, const char *pfx, const char **ptr); + +/** + * Return non-zero if pfx is a prefix of str independent of case. If + * it is, *ptr is set to the address of the first character in str + * after the prefix. + * + * @param str input string + * @param pfx prefix to test + * @param ptr updated if the prefix is matched inside str + * @return non-zero if the prefix matches, zero otherwise + */ +int av_stristart(const char *str, const char *pfx, const char **ptr); + +/** + * Locate the first case-independent occurrence in the string haystack + * of the string needle. A zero-length string needle is considered to + * match at the start of haystack. + * + * This function is a case-insensitive version of the standard strstr(). + * + * @param haystack string to search in + * @param needle string to search for + * @return pointer to the located match within haystack + * or a null pointer if no match + */ +char *av_stristr(const char *haystack, const char *needle); + +/** + * Copy the string src to dst, but no more than size - 1 bytes, and + * null-terminate dst. + * + * This function is the same as BSD strlcpy(). + * + * @param dst destination buffer + * @param src source string + * @param size size of destination buffer + * @return the length of src + * + * WARNING: since the return value is the length of src, src absolutely + * _must_ be a properly 0-terminated string, otherwise this will read beyond + * the end of the buffer and possibly crash. + */ +size_t av_strlcpy(char *dst, const char *src, size_t size); + +/** + * Append the string src to the string dst, but to a total length of + * no more than size - 1 bytes, and null-terminate dst. + * + * This function is similar to BSD strlcat(), but differs when + * size <= strlen(dst). + * + * @param dst destination buffer + * @param src source string + * @param size size of destination buffer + * @return the total length of src and dst + * + * WARNING: since the return value use the length of src and dst, these absolutely + * _must_ be a properly 0-terminated strings, otherwise this will read beyond + * the end of the buffer and possibly crash. + */ +size_t av_strlcat(char *dst, const char *src, size_t size); + +/** + * Append output to a string, according to a format. Never write out of + * the destination buffer, and always put a terminating 0 within + * the buffer. + * @param dst destination buffer (string to which the output is + * appended) + * @param size total size of the destination buffer + * @param fmt printf-compatible format string, specifying how the + * following parameters are used + * @return the length of the string that would have been generated + * if enough space had been available + */ +size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...); + +/** + * Convert a number to a av_malloced string. + */ +char *av_d2str(double d); + +#endif /* AVUTIL_AVSTRING_H */ diff --git a/include/libavutil/avutil.h b/include/libavutil/avutil.h new file mode 100644 index 00000000..e9e07b92 --- /dev/null +++ b/include/libavutil/avutil.h @@ -0,0 +1,89 @@ +/* + * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AVUTIL_H +#define AVUTIL_AVUTIL_H + +/** + * @file + * external API header + */ + + +#define AV_STRINGIFY(s) AV_TOSTRING(s) +#define AV_TOSTRING(s) #s + +#define AV_GLUE(a, b) a ## b +#define AV_JOIN(a, b) AV_GLUE(a, b) + +#define AV_PRAGMA(s) _Pragma(#s) + +#define AV_VERSION_INT(a, b, c) (a<<16 | b<<8 | c) +#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c +#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) + +#define LIBAVUTIL_VERSION_MAJOR 50 +#define LIBAVUTIL_VERSION_MINOR 15 +#define LIBAVUTIL_VERSION_MICRO 1 + +#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, \ + LIBAVUTIL_VERSION_MICRO) +#define LIBAVUTIL_VERSION AV_VERSION(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, \ + LIBAVUTIL_VERSION_MICRO) +#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT + +#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION) + +/** + * Returns the LIBAVUTIL_VERSION_INT constant. + */ +unsigned avutil_version(void); + +/** + * Returns the libavutil build-time configuration. + */ +const char *avutil_configuration(void); + +/** + * Returns the libavutil license. + */ +const char *avutil_license(void); + +enum AVMediaType { + AVMEDIA_TYPE_UNKNOWN = -1, + AVMEDIA_TYPE_VIDEO, + AVMEDIA_TYPE_AUDIO, + AVMEDIA_TYPE_DATA, + AVMEDIA_TYPE_SUBTITLE, + AVMEDIA_TYPE_ATTACHMENT, + AVMEDIA_TYPE_NB +}; + +#include "common.h" +#include "error.h" +#include "mathematics.h" +#include "rational.h" +#include "intfloat_readwrite.h" +#include "log.h" +#include "pixfmt.h" + +#endif /* AVUTIL_AVUTIL_H */ diff --git a/include/libavutil/base64.h b/include/libavutil/base64.h new file mode 100644 index 00000000..103860ef --- /dev/null +++ b/include/libavutil/base64.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_BASE64_H +#define AVUTIL_BASE64_H + +#include <stdint.h> + +/** + * Decodes the base64-encoded string in in and puts the decoded + * data in out. + * + * @param out_size size in bytes of the out buffer, it should be at + * least 3/4 of the length of in + * @return the number of bytes written, or a negative value in case of + * error + */ +int av_base64_decode(uint8_t *out, const char *in, int out_size); + +/** + * Encodes in base64 the data in in and puts the resulting string + * in out. + * + * @param out_size size in bytes of the out string, it should be at + * least ((in_size + 2) / 3) * 4 + 1 + * @param in_size size in bytes of the in buffer + * @return the string containing the encoded data, or NULL in case of + * error + */ +char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size); + +#endif /* AVUTIL_BASE64_H */ diff --git a/include/libavutil/common.h b/include/libavutil/common.h new file mode 100644 index 00000000..4aa00a99 --- /dev/null +++ b/include/libavutil/common.h @@ -0,0 +1,308 @@ +/* + * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * common internal and external API header + */ + +#ifndef AVUTIL_COMMON_H +#define AVUTIL_COMMON_H + +#include <ctype.h> +#include <errno.h> +#include <inttypes.h> +#include <limits.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "attributes.h" + +//rounded division & shift +#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b)) +/* assume b>0 */ +#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) +#define FFABS(a) ((a) >= 0 ? (a) : (-(a))) +#define FFSIGN(a) ((a) > 0 ? 1 : -1) + +#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c) +#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) +#define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c) + +#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) +#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) +#define FFALIGN(x, a) (((x)+(a)-1)&~((a)-1)) + +/* misc math functions */ +extern const uint8_t ff_log2_tab[256]; + +extern const uint8_t av_reverse[256]; + +static inline av_const int av_log2_c(unsigned int v) +{ + int n = 0; + if (v & 0xffff0000) { + v >>= 16; + n += 16; + } + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} + +static inline av_const int av_log2_16bit_c(unsigned int v) +{ + int n = 0; + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} + +#ifdef HAVE_AV_CONFIG_H +# include "config.h" +# include "intmath.h" +#endif + +#ifndef av_log2 +# define av_log2 av_log2_c +#endif +#ifndef av_log2_16bit +# define av_log2_16bit av_log2_16bit_c +#endif + +/** + * Clips a signed integer value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static inline av_const int av_clip(int a, int amin, int amax) +{ + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** + * Clips a signed integer value into the 0-255 range. + * @param a value to clip + * @return clipped value + */ +static inline av_const uint8_t av_clip_uint8(int a) +{ + if (a&(~0xFF)) return (-a)>>31; + else return a; +} + +/** + * Clips a signed integer value into the 0-65535 range. + * @param a value to clip + * @return clipped value + */ +static inline av_const uint16_t av_clip_uint16(int a) +{ + if (a&(~0xFFFF)) return (-a)>>31; + else return a; +} + +/** + * Clips a signed integer value into the -32768,32767 range. + * @param a value to clip + * @return clipped value + */ +static inline av_const int16_t av_clip_int16(int a) +{ + if ((a+0x8000) & ~0xFFFF) return (a>>31) ^ 0x7FFF; + else return a; +} + +/** + * Clips a signed 64-bit integer value into the -2147483648,2147483647 range. + * @param a value to clip + * @return clipped value + */ +static inline av_const int32_t av_clipl_int32(int64_t a) +{ + if ((a+0x80000000u) & ~UINT64_C(0xFFFFFFFF)) return (a>>63) ^ 0x7FFFFFFF; + else return a; +} + +/** + * Clips a float value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static inline av_const float av_clipf(float a, float amin, float amax) +{ + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** Computes ceil(log2(x)). + * @param x value used to compute ceil(log2(x)) + * @return computed ceiling of log2(x) + */ +static inline av_const int av_ceil_log2(int x) +{ + return av_log2((x - 1) << 1); +} + +#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24)) +#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24)) + +/*! + * \def GET_UTF8(val, GET_BYTE, ERROR) + * Converts a UTF-8 character (up to 4 bytes long) to its 32-bit UCS-4 encoded form + * \param val is the output and should be of type uint32_t. It holds the converted + * UCS-4 character and should be a left value. + * \param GET_BYTE gets UTF-8 encoded bytes from any proper source. It can be + * a function or a statement whose return value or evaluated value is of type + * uint8_t. It will be executed up to 4 times for values in the valid UTF-8 range, + * and up to 7 times in the general case. + * \param ERROR action that should be taken when an invalid UTF-8 byte is returned + * from GET_BYTE. It should be a statement that jumps out of the macro, + * like exit(), goto, return, break, or continue. + */ +#define GET_UTF8(val, GET_BYTE, ERROR)\ + val= GET_BYTE;\ + {\ + int ones= 7 - av_log2(val ^ 255);\ + if(ones==1)\ + ERROR\ + val&= 127>>ones;\ + while(--ones > 0){\ + int tmp= GET_BYTE - 128;\ + if(tmp>>6)\ + ERROR\ + val= (val<<6) + tmp;\ + }\ + } + +/*! + * \def GET_UTF16(val, GET_16BIT, ERROR) + * Converts a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form + * \param val is the output and should be of type uint32_t. It holds the converted + * UCS-4 character and should be a left value. + * \param GET_16BIT gets two bytes of UTF-16 encoded data converted to native endianness. + * It can be a function or a statement whose return value or evaluated value is of type + * uint16_t. It will be executed up to 2 times. + * \param ERROR action that should be taken when an invalid UTF-16 surrogate is + * returned from GET_BYTE. It should be a statement that jumps out of the macro, + * like exit(), goto, return, break, or continue. + */ +#define GET_UTF16(val, GET_16BIT, ERROR)\ + val = GET_16BIT;\ + {\ + unsigned int hi = val - 0xD800;\ + if (hi < 0x800) {\ + val = GET_16BIT - 0xDC00;\ + if (val > 0x3FFU || hi > 0x3FFU)\ + ERROR\ + val += (hi<<10) + 0x10000;\ + }\ + }\ + +/*! + * \def PUT_UTF8(val, tmp, PUT_BYTE) + * Converts a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long). + * \param val is an input-only argument and should be of type uint32_t. It holds + * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If + * val is given as a function it is executed only once. + * \param tmp is a temporary variable and should be of type uint8_t. It + * represents an intermediate value during conversion that is to be + * output by PUT_BYTE. + * \param PUT_BYTE writes the converted UTF-8 bytes to any proper destination. + * It could be a function or a statement, and uses tmp as the input byte. + * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be + * executed up to 4 times for values in the valid UTF-8 range and up to + * 7 times in the general case, depending on the length of the converted + * Unicode character. + */ +#define PUT_UTF8(val, tmp, PUT_BYTE)\ + {\ + int bytes, shift;\ + uint32_t in = val;\ + if (in < 0x80) {\ + tmp = in;\ + PUT_BYTE\ + } else {\ + bytes = (av_log2(in) + 4) / 5;\ + shift = (bytes - 1) * 6;\ + tmp = (256 - (256 >> bytes)) | (in >> shift);\ + PUT_BYTE\ + while (shift >= 6) {\ + shift -= 6;\ + tmp = 0x80 | ((in >> shift) & 0x3f);\ + PUT_BYTE\ + }\ + }\ + } + +/*! + * \def PUT_UTF16(val, tmp, PUT_16BIT) + * Converts a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes). + * \param val is an input-only argument and should be of type uint32_t. It holds + * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If + * val is given as a function it is executed only once. + * \param tmp is a temporary variable and should be of type uint16_t. It + * represents an intermediate value during conversion that is to be + * output by PUT_16BIT. + * \param PUT_16BIT writes the converted UTF-16 data to any proper destination + * in desired endianness. It could be a function or a statement, and uses tmp + * as the input byte. For example, PUT_BYTE could be "*output++ = tmp;" + * PUT_BYTE will be executed 1 or 2 times depending on input character. + */ +#define PUT_UTF16(val, tmp, PUT_16BIT)\ + {\ + uint32_t in = val;\ + if (in < 0x10000) {\ + tmp = in;\ + PUT_16BIT\ + } else {\ + tmp = 0xD800 | ((in - 0x10000) >> 10);\ + PUT_16BIT\ + tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\ + PUT_16BIT\ + }\ + }\ + + + +#include "mem.h" + +#ifdef HAVE_AV_CONFIG_H +# include "internal.h" +#endif /* HAVE_AV_CONFIG_H */ + +#endif /* AVUTIL_COMMON_H */ diff --git a/include/libavutil/crc.h b/include/libavutil/crc.h new file mode 100644 index 00000000..6c0baab5 --- /dev/null +++ b/include/libavutil/crc.h @@ -0,0 +1,44 @@ +/* + * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CRC_H +#define AVUTIL_CRC_H + +#include <stdint.h> +#include <stddef.h> +#include "attributes.h" + +typedef uint32_t AVCRC; + +typedef enum { + AV_CRC_8_ATM, + AV_CRC_16_ANSI, + AV_CRC_16_CCITT, + AV_CRC_32_IEEE, + AV_CRC_32_IEEE_LE, /*< reversed bitorder version of AV_CRC_32_IEEE */ + AV_CRC_MAX, /*< Not part of public API! Do not use outside libavutil. */ +}AVCRCId; + +int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size); +const AVCRC *av_crc_get_table(AVCRCId crc_id); +uint32_t av_crc(const AVCRC *ctx, uint32_t start_crc, const uint8_t *buffer, size_t length) av_pure; + +#endif /* AVUTIL_CRC_H */ + diff --git a/include/libavutil/error.h b/include/libavutil/error.h new file mode 100644 index 00000000..13a9a359 --- /dev/null +++ b/include/libavutil/error.h @@ -0,0 +1,72 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * error code definitions + */ + +#ifndef AVUTIL_ERROR_H +#define AVUTIL_ERROR_H + +#include <errno.h> +#include "avutil.h" + +/* error handling */ +#if EDOM > 0 +#define AVERROR(e) (-(e)) ///< Returns a negative error code from a POSIX error code, to return from library functions. +#define AVUNERROR(e) (-(e)) ///< Returns a POSIX error code from a library function error return value. +#else +/* Some platforms have E* and errno already negated. */ +#define AVERROR(e) (e) +#define AVUNERROR(e) (e) +#endif + +#if LIBAVUTIL_VERSION_MAJOR < 51 +#define AVERROR_INVALIDDATA AVERROR(EINVAL) ///< Invalid data found when processing input +#define AVERROR_IO AVERROR(EIO) ///< I/O error +#define AVERROR_NOENT AVERROR(ENOENT) ///< No such file or directory +#define AVERROR_NOFMT AVERROR(EILSEQ) ///< Unknown format +#define AVERROR_NOMEM AVERROR(ENOMEM) ///< Not enough memory +#define AVERROR_NOTSUPP AVERROR(ENOSYS) ///< Operation not supported +#define AVERROR_NUMEXPECTED AVERROR(EDOM) ///< Number syntax expected in filename +#define AVERROR_UNKNOWN AVERROR(EINVAL) ///< Unknown error +#endif + +#define AVERROR_EOF AVERROR(EPIPE) ///< End of file + +#define AVERROR_PATCHWELCOME (-MKTAG('P','A','W','E')) ///< Not yet implemented in FFmpeg, patches welcome + +#if LIBAVUTIL_VERSION_MAJOR > 50 +#define AVERROR_INVALIDDATA (-MKTAG('I','N','D','A')) ///< Invalid data found when processing input +#define AVERROR_NUMEXPECTED (-MKTAG('N','U','E','X')) ///< Number syntax expected in filename +#endif + +/** + * Puts a description of the AVERROR code errnum in errbuf. + * In case of failure the global variable errno is set to indicate the + * error. Even in case of failure av_strerror() will print a generic + * error message indicating the errnum provided to errbuf. + * + * @param errbuf_size the size in bytes of errbuf + * @return 0 on success, a negative value if a description for errnum + * cannot be found + */ +int av_strerror(int errnum, char *errbuf, size_t errbuf_size); + +#endif /* AVUTIL_ERROR_H */ diff --git a/include/libavutil/fifo.h b/include/libavutil/fifo.h new file mode 100644 index 00000000..fb1ed47f --- /dev/null +++ b/include/libavutil/fifo.h @@ -0,0 +1,116 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * a very simple circular buffer FIFO implementation + */ + +#ifndef AVUTIL_FIFO_H +#define AVUTIL_FIFO_H + +#include <stdint.h> + +typedef struct AVFifoBuffer { + uint8_t *buffer; + uint8_t *rptr, *wptr, *end; + uint32_t rndx, wndx; +} AVFifoBuffer; + +/** + * Initializes an AVFifoBuffer. + * @param size of FIFO + * @return AVFifoBuffer or NULL in case of memory allocation failure + */ +AVFifoBuffer *av_fifo_alloc(unsigned int size); + +/** + * Frees an AVFifoBuffer. + * @param *f AVFifoBuffer to free + */ +void av_fifo_free(AVFifoBuffer *f); + +/** + * Resets the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied. + * @param *f AVFifoBuffer to reset + */ +void av_fifo_reset(AVFifoBuffer *f); + +/** + * Returns the amount of data in bytes in the AVFifoBuffer, that is the + * amount of data you can read from it. + * @param *f AVFifoBuffer to read from + * @return size + */ +int av_fifo_size(AVFifoBuffer *f); + +/** + * Returns the amount of space in bytes in the AVFifoBuffer, that is the + * amount of data you can write into it. + * @param *f AVFifoBuffer to write into + * @return size + */ +int av_fifo_space(AVFifoBuffer *f); + +/** + * Feeds data from an AVFifoBuffer to a user-supplied callback. + * @param *f AVFifoBuffer to read from + * @param buf_size number of bytes to read + * @param *func generic read function + * @param *dest data destination + */ +int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int)); + +/** + * Feeds data from a user-supplied callback to an AVFifoBuffer. + * @param *f AVFifoBuffer to write to + * @param *src data source; non-const since it may be used as a + * modifiable context by the function defined in func + * @param size number of bytes to write + * @param *func generic write function; the first parameter is src, + * the second is dest_buf, the third is dest_buf_size. + * func must return the number of bytes written to dest_buf, or <= 0 to + * indicate no more data available to write. + * If func is NULL, src is interpreted as a simple byte array for source data. + * @return the number of bytes written to the FIFO + */ +int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int)); + +/** + * Resizes an AVFifoBuffer. + * @param *f AVFifoBuffer to resize + * @param size new AVFifoBuffer size in bytes + * @return <0 for failure, >=0 otherwise + */ +int av_fifo_realloc2(AVFifoBuffer *f, unsigned int size); + +/** + * Reads and discards the specified amount of data from an AVFifoBuffer. + * @param *f AVFifoBuffer to read from + * @param size amount of data to read in bytes + */ +void av_fifo_drain(AVFifoBuffer *f, int size); + +static inline uint8_t av_fifo_peek(AVFifoBuffer *f, int offs) +{ + uint8_t *ptr = f->rptr + offs; + if (ptr >= f->end) + ptr -= f->end - f->buffer; + return *ptr; +} +#endif /* AVUTIL_FIFO_H */ diff --git a/include/libavutil/intfloat_readwrite.h b/include/libavutil/intfloat_readwrite.h new file mode 100644 index 00000000..1b80fc6e --- /dev/null +++ b/include/libavutil/intfloat_readwrite.h @@ -0,0 +1,40 @@ +/* + * copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_INTFLOAT_READWRITE_H +#define AVUTIL_INTFLOAT_READWRITE_H + +#include <stdint.h> +#include "attributes.h" + +/* IEEE 80 bits extended float */ +typedef struct AVExtFloat { + uint8_t exponent[2]; + uint8_t mantissa[8]; +} AVExtFloat; + +double av_int2dbl(int64_t v) av_const; +float av_int2flt(int32_t v) av_const; +double av_ext2dbl(const AVExtFloat ext) av_const; +int64_t av_dbl2int(double d) av_const; +int32_t av_flt2int(float d) av_const; +AVExtFloat av_dbl2ext(double d) av_const; + +#endif /* AVUTIL_INTFLOAT_READWRITE_H */ diff --git a/include/libavutil/log.h b/include/libavutil/log.h new file mode 100644 index 00000000..1c3e4901 --- /dev/null +++ b/include/libavutil/log.h @@ -0,0 +1,123 @@ +/* + * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LOG_H +#define AVUTIL_LOG_H + +#include <stdarg.h> +#include "avutil.h" + +/** + * Describes the class of an AVClass context structure. That is an + * arbitrary struct of which the first field is a pointer to an + * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.). + */ +typedef struct { + /** + * The name of the class; usually it is the same name as the + * context structure type to which the AVClass is associated. + */ + const char* class_name; + + /** + * A pointer to a function which returns the name of a context + * instance ctx associated with the class. + */ + const char* (*item_name)(void* ctx); + + /** + * a pointer to the first option specified in the class if any or NULL + * + * @see av_set_default_options() + */ + const struct AVOption *option; + + /** + * LIBAVUTIL_VERSION with which this structure was created. + * This is used to allow fields to be added without requiring major + * version bumps everywhere. + */ + + int version; +} AVClass; + +/* av_log API */ + +#define AV_LOG_QUIET -8 + +/** + * Something went really wrong and we will crash now. + */ +#define AV_LOG_PANIC 0 + +/** + * Something went wrong and recovery is not possible. + * For example, no header was found for a format which depends + * on headers or an illegal combination of parameters is used. + */ +#define AV_LOG_FATAL 8 + +/** + * Something went wrong and cannot losslessly be recovered. + * However, not all future data is affected. + */ +#define AV_LOG_ERROR 16 + +/** + * Something somehow does not look correct. This may or may not + * lead to problems. An example would be the use of '-vstrict -2'. + */ +#define AV_LOG_WARNING 24 + +#define AV_LOG_INFO 32 +#define AV_LOG_VERBOSE 40 + +/** + * Stuff which is only useful for libav* developers. + */ +#define AV_LOG_DEBUG 48 + +/** + * Sends the specified message to the log if the level is less than or equal + * to the current av_log_level. By default, all logging messages are sent to + * stderr. This behavior can be altered by setting a different av_vlog callback + * function. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message, lower values signifying + * higher importance. + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @see av_vlog + */ +#ifdef __GNUC__ +void av_log(void*, int level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))); +#else +void av_log(void*, int level, const char *fmt, ...); +#endif + +void av_vlog(void*, int level, const char *fmt, va_list); +int av_log_get_level(void); +void av_log_set_level(int); +void av_log_set_callback(void (*)(void*, int, const char*, va_list)); +void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl); + +#endif /* AVUTIL_LOG_H */ diff --git a/include/libavutil/lzo.h b/include/libavutil/lzo.h new file mode 100644 index 00000000..6788054b --- /dev/null +++ b/include/libavutil/lzo.h @@ -0,0 +1,66 @@ +/* + * LZO 1x decompression + * copyright (c) 2006 Reimar Doeffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LZO_H +#define AVUTIL_LZO_H + +#include <stdint.h> + +/** \defgroup errflags Error flags returned by av_lzo1x_decode + * \{ */ +//! end of the input buffer reached before decoding finished +#define AV_LZO_INPUT_DEPLETED 1 +//! decoded data did not fit into output buffer +#define AV_LZO_OUTPUT_FULL 2 +//! a reference to previously decoded data was wrong +#define AV_LZO_INVALID_BACKPTR 4 +//! a non-specific error in the compressed bitstream +#define AV_LZO_ERROR 8 +/** \} */ + +#define AV_LZO_INPUT_PADDING 8 +#define AV_LZO_OUTPUT_PADDING 12 + +/** + * \brief Decodes LZO 1x compressed data. + * \param out output buffer + * \param outlen size of output buffer, number of bytes left are returned here + * \param in input buffer + * \param inlen size of input buffer, number of bytes left are returned here + * \return 0 on success, otherwise a combination of the error flags above + * + * Make sure all buffers are appropriately padded, in must provide + * AV_LZO_INPUT_PADDING, out must provide AV_LZO_OUTPUT_PADDING additional bytes. + */ +int av_lzo1x_decode(void *out, int *outlen, const void *in, int *inlen); + +/** + * \brief deliberately overlapping memcpy implementation + * \param dst destination buffer; must be padded with 12 additional bytes + * \param back how many bytes back we start (the initial size of the overlapping window) + * \param cnt number of bytes to copy, must be >= 0 + * + * cnt > back is valid, this will copy the bytes we just copied, + * thus creating a repeating pattern with a period length of back. + */ +void av_memcpy_backptr(uint8_t *dst, int back, int cnt); + +#endif /* AVUTIL_LZO_H */ diff --git a/include/libavutil/mathematics.h b/include/libavutil/mathematics.h new file mode 100644 index 00000000..e198aef8 --- /dev/null +++ b/include/libavutil/mathematics.h @@ -0,0 +1,98 @@ +/* + * copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MATHEMATICS_H +#define AVUTIL_MATHEMATICS_H + +#include <stdint.h> +#include <math.h> +#include "attributes.h" +#include "rational.h" + +#ifndef M_E +#define M_E 2.7182818284590452354 /* e */ +#endif +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 /* log_e 2 */ +#endif +#ifndef M_LN10 +#define M_LN10 2.30258509299404568402 /* log_e 10 */ +#endif +#ifndef M_LOG2_10 +#define M_LOG2_10 3.32192809488736234787 /* log_2 10 */ +#endif +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif +#ifndef M_SQRT1_2 +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ +#endif +#ifndef M_SQRT2 +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#endif +#ifndef NAN +#define NAN (0.0/0.0) +#endif +#ifndef INFINITY +#define INFINITY (1.0/0.0) +#endif + +enum AVRounding { + AV_ROUND_ZERO = 0, ///< Round toward zero. + AV_ROUND_INF = 1, ///< Round away from zero. + AV_ROUND_DOWN = 2, ///< Round toward -infinity. + AV_ROUND_UP = 3, ///< Round toward +infinity. + AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero. +}; + +/** + * Returns the greatest common divisor of a and b. + * If both a and b are 0 or either or both are <0 then behavior is + * undefined. + */ +int64_t av_const av_gcd(int64_t a, int64_t b); + +/** + * Rescales a 64-bit integer with rounding to nearest. + * A simple a*b/c isn't possible as it can overflow. + */ +int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const; + +/** + * Rescales a 64-bit integer with specified rounding. + * A simple a*b/c isn't possible as it can overflow. + */ +int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding) av_const; + +/** + * Rescales a 64-bit integer by 2 rational numbers. + */ +int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const; + +/** + * Compares 2 timestamps each in its own timebases. + * The result of the function is undefined if one of the timestamps + * is outside the int64_t range when represented in the others timebase. + * @return -1 if ts_a is before ts_b, 1 if ts_a is after ts_b or 0 if they represent the same position + */ +int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b); + + +#endif /* AVUTIL_MATHEMATICS_H */ diff --git a/include/libavutil/md5.h b/include/libavutil/md5.h new file mode 100644 index 00000000..969202a8 --- /dev/null +++ b/include/libavutil/md5.h @@ -0,0 +1,36 @@ +/* + * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MD5_H +#define AVUTIL_MD5_H + +#include <stdint.h> + +extern const int av_md5_size; + +struct AVMD5; + +void av_md5_init(struct AVMD5 *ctx); +void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, const int len); +void av_md5_final(struct AVMD5 *ctx, uint8_t *dst); +void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len); + +#endif /* AVUTIL_MD5_H */ + diff --git a/include/libavutil/mem.h b/include/libavutil/mem.h new file mode 100644 index 00000000..14887927 --- /dev/null +++ b/include/libavutil/mem.h @@ -0,0 +1,125 @@ +/* + * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * memory handling functions + */ + +#ifndef AVUTIL_MEM_H +#define AVUTIL_MEM_H + +#include "attributes.h" + +#if defined(__ICC) || defined(__SUNPRO_C) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v +#elif defined(__TI_COMPILER_VERSION__) + #define DECLARE_ALIGNED(n,t,v) \ + AV_PRAGMA(DATA_ALIGN(v,n)) \ + t __attribute__((aligned(n))) v + #define DECLARE_ASM_CONST(n,t,v) \ + AV_PRAGMA(DATA_ALIGN(v,n)) \ + static const t __attribute__((aligned(n))) v +#elif defined(__GNUC__) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_CONST(n,t,v) static const t attribute_used __attribute__ ((aligned (n))) v +#elif defined(_MSC_VER) + #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v +#else + #define DECLARE_ALIGNED(n,t,v) t v + #define DECLARE_ASM_CONST(n,t,v) static const t v +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,1) + #define av_malloc_attrib __attribute__((__malloc__)) +#else + #define av_malloc_attrib +#endif + +#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,3) + #define av_alloc_size(n) __attribute__((alloc_size(n))) +#else + #define av_alloc_size(n) +#endif + +/** + * Allocates a block of size bytes with alignment suitable for all + * memory accesses (including vectors if available on the CPU). + * @param size Size in bytes for the memory block to be allocated. + * @return Pointer to the allocated block, NULL if the block cannot + * be allocated. + * @see av_mallocz() + */ +void *av_malloc(unsigned int size) av_malloc_attrib av_alloc_size(1); + +/** + * Allocates or reallocates a block of memory. + * If ptr is NULL and size > 0, allocates a new block. If + * size is zero, frees the memory block pointed to by ptr. + * @param size Size in bytes for the memory block to be allocated or + * reallocated. + * @param ptr Pointer to a memory block already allocated with + * av_malloc(z)() or av_realloc() or NULL. + * @return Pointer to a newly reallocated block or NULL if the block + * cannot be reallocated or the function is used to free the memory block. + * @see av_fast_realloc() + */ +void *av_realloc(void *ptr, unsigned int size) av_alloc_size(2); + +/** + * Frees a memory block which has been allocated with av_malloc(z)() or + * av_realloc(). + * @param ptr Pointer to the memory block which should be freed. + * @note ptr = NULL is explicitly allowed. + * @note It is recommended that you use av_freep() instead. + * @see av_freep() + */ +void av_free(void *ptr); + +/** + * Allocates a block of size bytes with alignment suitable for all + * memory accesses (including vectors if available on the CPU) and + * zeroes all the bytes of the block. + * @param size Size in bytes for the memory block to be allocated. + * @return Pointer to the allocated block, NULL if it cannot be allocated. + * @see av_malloc() + */ +void *av_mallocz(unsigned int size) av_malloc_attrib av_alloc_size(1); + +/** + * Duplicates the string s. + * @param s string to be duplicated + * @return Pointer to a newly allocated string containing a + * copy of s or NULL if the string cannot be allocated. + */ +char *av_strdup(const char *s) av_malloc_attrib; + +/** + * Frees a memory block which has been allocated with av_malloc(z)() or + * av_realloc() and set the pointer pointing to it to NULL. + * @param ptr Pointer to the pointer to the memory block which should + * be freed. + * @see av_free() + */ +void av_freep(void *ptr); + +#endif /* AVUTIL_MEM_H */ diff --git a/include/libavutil/pixdesc.h b/include/libavutil/pixdesc.h new file mode 100644 index 00000000..8e4c85d7 --- /dev/null +++ b/include/libavutil/pixdesc.h @@ -0,0 +1,154 @@ +/* + * pixel format descriptor + * Copyright (c) 2009 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PIXDESC_H +#define AVUTIL_PIXDESC_H + +#include <inttypes.h> + +typedef struct AVComponentDescriptor{ + uint16_t plane :2; ///< which of the 4 planes contains the component + + /** + * Number of elements between 2 horizontally consecutive pixels minus 1. + * Elements are bits for bitstream formats, bytes otherwise. + */ + uint16_t step_minus1 :3; + + /** + * Number of elements before the component of the first pixel plus 1. + * Elements are bits for bitstream formats, bytes otherwise. + */ + uint16_t offset_plus1 :3; + uint16_t shift :3; ///< number of least significant bits that must be shifted away to get the value + uint16_t depth_minus1 :4; ///< number of bits in the component minus 1 +}AVComponentDescriptor; + +/** + * Descriptor that unambiguously describes how the bits of a pixel are + * stored in the up to 4 data planes of an image. It also stores the + * subsampling factors and number of components. + * + * @note This is separate of the colorspace (RGB, YCbCr, YPbPr, JPEG-style YUV + * and all the YUV variants) AVPixFmtDescriptor just stores how values + * are stored not what these values represent. + */ +typedef struct AVPixFmtDescriptor{ + const char *name; + uint8_t nb_components; ///< The number of components each pixel has, (1-4) + + /** + * Amount to shift the luma width right to find the chroma width. + * For YV12 this is 1 for example. + * chroma_width = -((-luma_width) >> log2_chroma_w) + * The note above is needed to ensure rounding up. + * This value only refers to the chroma components. + */ + uint8_t log2_chroma_w; ///< chroma_width = -((-luma_width )>>log2_chroma_w) + + /** + * Amount to shift the luma height right to find the chroma height. + * For YV12 this is 1 for example. + * chroma_height= -((-luma_height) >> log2_chroma_h) + * The note above is needed to ensure rounding up. + * This value only refers to the chroma components. + */ + uint8_t log2_chroma_h; + uint8_t flags; + + /** + * Parameters that describe how pixels are packed. If the format + * has chroma components, they must be stored in comp[1] and + * comp[2]. + */ + AVComponentDescriptor comp[4]; +}AVPixFmtDescriptor; + +#define PIX_FMT_BE 1 ///< Pixel format is big-endian. +#define PIX_FMT_PAL 2 ///< Pixel format has a palette in data[1], values are indexes in this palette. +#define PIX_FMT_BITSTREAM 4 ///< All values of a component are bit-wise packed end to end. +#define PIX_FMT_HWACCEL 8 ///< Pixel format is an HW accelerated format. + +/** + * The array of all the pixel format descriptors. + */ +extern const AVPixFmtDescriptor av_pix_fmt_descriptors[]; + +/** + * Reads a line from an image, and writes the values of the + * pixel format component c to dst. + * + * @param data the array containing the pointers to the planes of the image + * @param linesizes the array containing the linesizes of the image + * @param desc the pixel format descriptor for the image + * @param x the horizontal coordinate of the first pixel to read + * @param y the vertical coordinate of the first pixel to read + * @param w the width of the line to read, that is the number of + * values to write to dst + * @param read_pal_component if not zero and the format is a paletted + * format writes the values corresponding to the palette + * component c in data[1] to dst, rather than the palette indexes in + * data[0]. The behavior is undefined if the format is not paletted. + */ +void read_line(uint16_t *dst, const uint8_t *data[4], const int linesize[4], + const AVPixFmtDescriptor *desc, int x, int y, int c, int w, int read_pal_component); + +/** + * Writes the values from src to the pixel format component c of an + * image line. + * + * @param src array containing the values to write + * @param data the array containing the pointers to the planes of the + * image to write into. It is supposed to be zeroed. + * @param linesizes the array containing the linesizes of the image + * @param desc the pixel format descriptor for the image + * @param x the horizontal coordinate of the first pixel to write + * @param y the vertical coordinate of the first pixel to write + * @param w the width of the line to write, that is the number of + * values to write to the image line + */ +void write_line(const uint16_t *src, uint8_t *data[4], const int linesize[4], + const AVPixFmtDescriptor *desc, int x, int y, int c, int w); + +/** + * Returns the pixel format corresponding to name. + * + * If there is no pixel format with name name, then looks for a + * pixel format with the name corresponding to the native endian + * format of name. + * For example in a little-endian system, first looks for "gray16", + * then for "gray16le". + * + * Finally if no pixel format has been found, returns PIX_FMT_NONE. + */ +enum PixelFormat av_get_pix_fmt(const char *name); + +/** + * Returns the number of bits per pixel used by the pixel format + * described by pixdesc. + * + * The returned number of bits refers to the number of bits actually + * used for storing the pixel information, that is padding bits are + * not counted. + */ +int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc); + +#endif /* AVUTIL_PIXDESC_H */ diff --git a/include/libavutil/pixfmt.h b/include/libavutil/pixfmt.h new file mode 100644 index 00000000..d976f343 --- /dev/null +++ b/include/libavutil/pixfmt.h @@ -0,0 +1,163 @@ +/* + * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PIXFMT_H +#define AVUTIL_PIXFMT_H + +/** + * @file + * pixel format definitions + * + * @warning This file has to be considered an internal but installed + * header, so it should not be directly included in your projects. + */ + +#include "libavutil/avconfig.h" + +/** + * Pixel format. Notes: + * + * PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA + * color is put together as: + * (A << 24) | (R << 16) | (G << 8) | B + * This is stored as BGRA on little-endian CPU architectures and ARGB on + * big-endian CPUs. + * + * When the pixel format is palettized RGB (PIX_FMT_PAL8), the palettized + * image data is stored in AVFrame.data[0]. The palette is transported in + * AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is + * formatted the same as in PIX_FMT_RGB32 described above (i.e., it is + * also endian-specific). Note also that the individual RGB palette + * components stored in AVFrame.data[1] should be in the range 0..255. + * This is important as many custom PAL8 video codecs that were designed + * to run on the IBM VGA graphics adapter use 6-bit palette components. + * + * For all the 8bit per pixel formats, an RGB32 palette is in data[1] like + * for pal8. This palette is filled in automatically by the function + * allocating the picture. + * + * Note, make sure that all newly added big endian formats have pix_fmt&1==1 + * and that all newly added little endian formats have pix_fmt&1==0 + * this allows simpler detection of big vs little endian. + */ +enum PixelFormat { + PIX_FMT_NONE= -1, + PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) + PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr + PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB... + PIX_FMT_BGR24, ///< packed RGB 8:8:8, 24bpp, BGRBGR... + PIX_FMT_YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) + PIX_FMT_YUV444P, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) + PIX_FMT_YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) + PIX_FMT_YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) + PIX_FMT_GRAY8, ///< Y , 8bpp + PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb + PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb + PIX_FMT_PAL8, ///< 8 bit with PIX_FMT_RGB32 palette + PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG) + PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG) + PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG) + PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing + PIX_FMT_XVMC_MPEG2_IDCT, + PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 + PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 + PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) + PIX_FMT_BGR4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits + PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) + PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) + PIX_FMT_RGB4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits + PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) + PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) + PIX_FMT_NV21, ///< as above, but U and V bytes are swapped + + PIX_FMT_ARGB, ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB... + PIX_FMT_RGBA, ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA... + PIX_FMT_ABGR, ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR... + PIX_FMT_BGRA, ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA... + + PIX_FMT_GRAY16BE, ///< Y , 16bpp, big-endian + PIX_FMT_GRAY16LE, ///< Y , 16bpp, little-endian + PIX_FMT_YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) + PIX_FMT_YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG) + PIX_FMT_YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) + PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian + PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian + + PIX_FMT_RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian + PIX_FMT_RGB565LE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian + PIX_FMT_RGB555BE, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0 + PIX_FMT_RGB555LE, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0 + + PIX_FMT_BGR565BE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian + PIX_FMT_BGR565LE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian + PIX_FMT_BGR555BE, ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1 + PIX_FMT_BGR555LE, ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1 + + PIX_FMT_VAAPI_MOCO, ///< HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers + PIX_FMT_VAAPI_IDCT, ///< HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers + PIX_FMT_VAAPI_VLD, ///< HW decoding through VA API, Picture.data[3] contains a vaapi_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + + PIX_FMT_YUV420P16LE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + PIX_FMT_YUV420P16BE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + PIX_FMT_YUV422P16LE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + PIX_FMT_YUV422P16BE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + PIX_FMT_YUV444P16LE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + PIX_FMT_VDPAU_MPEG4, ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_DXVA2_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer + + PIX_FMT_RGB444BE, ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0 + PIX_FMT_RGB444LE, ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0 + PIX_FMT_BGR444BE, ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), big-endian, most significant bits to 1 + PIX_FMT_BGR444LE, ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), little-endian, most significant bits to 1 + PIX_FMT_Y400A, ///< 8bit gray, 8bit alpha + PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions +}; + +#if AV_HAVE_BIGENDIAN +# define PIX_FMT_NE(be, le) PIX_FMT_##be +#else +# define PIX_FMT_NE(be, le) PIX_FMT_##le +#endif + +#define PIX_FMT_RGB32 PIX_FMT_NE(ARGB, BGRA) +#define PIX_FMT_RGB32_1 PIX_FMT_NE(RGBA, ABGR) +#define PIX_FMT_BGR32 PIX_FMT_NE(ABGR, RGBA) +#define PIX_FMT_BGR32_1 PIX_FMT_NE(BGRA, ARGB) + +#define PIX_FMT_GRAY16 PIX_FMT_NE(GRAY16BE, GRAY16LE) +#define PIX_FMT_RGB48 PIX_FMT_NE(RGB48BE, RGB48LE) +#define PIX_FMT_RGB565 PIX_FMT_NE(RGB565BE, RGB565LE) +#define PIX_FMT_RGB555 PIX_FMT_NE(RGB555BE, RGB555LE) +#define PIX_FMT_RGB444 PIX_FMT_NE(RGB444BE, RGB444LE) +#define PIX_FMT_BGR565 PIX_FMT_NE(BGR565BE, BGR565LE) +#define PIX_FMT_BGR555 PIX_FMT_NE(BGR555BE, BGR555LE) +#define PIX_FMT_BGR444 PIX_FMT_NE(BGR444BE, BGR444LE) + +#define PIX_FMT_YUV420P16 PIX_FMT_NE(YUV420P16BE, YUV420P16LE) +#define PIX_FMT_YUV422P16 PIX_FMT_NE(YUV422P16BE, YUV422P16LE) +#define PIX_FMT_YUV444P16 PIX_FMT_NE(YUV444P16BE, YUV444P16LE) + +#endif /* AVUTIL_PIXFMT_H */ diff --git a/include/libavutil/rational.h b/include/libavutil/rational.h new file mode 100644 index 00000000..4d91f7ba --- /dev/null +++ b/include/libavutil/rational.h @@ -0,0 +1,129 @@ +/* + * rational numbers + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * rational numbers + * @author Michael Niedermayer <michaelni@gmx.at> + */ + +#ifndef AVUTIL_RATIONAL_H +#define AVUTIL_RATIONAL_H + +#include <stdint.h> +#include "attributes.h" + +/** + * rational number numerator/denominator + */ +typedef struct AVRational{ + int num; ///< numerator + int den; ///< denominator +} AVRational; + +/** + * Compares two rationals. + * @param a first rational + * @param b second rational + * @return 0 if a==b, 1 if a>b and -1 if a<b + */ +static inline int av_cmp_q(AVRational a, AVRational b){ + const int64_t tmp= a.num * (int64_t)b.den - b.num * (int64_t)a.den; + + if(tmp) return (tmp>>63)|1; + else return 0; +} + +/** + * Converts rational to double. + * @param a rational to convert + * @return (double) a + */ +static inline double av_q2d(AVRational a){ + return a.num / (double) a.den; +} + +/** + * Reduces a fraction. + * This is useful for framerate calculations. + * @param dst_num destination numerator + * @param dst_den destination denominator + * @param num source numerator + * @param den source denominator + * @param max the maximum allowed for dst_num & dst_den + * @return 1 if exact, 0 otherwise + */ +int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max); + +/** + * Multiplies two rationals. + * @param b first rational + * @param c second rational + * @return b*c + */ +AVRational av_mul_q(AVRational b, AVRational c) av_const; + +/** + * Divides one rational by another. + * @param b first rational + * @param c second rational + * @return b/c + */ +AVRational av_div_q(AVRational b, AVRational c) av_const; + +/** + * Adds two rationals. + * @param b first rational + * @param c second rational + * @return b+c + */ +AVRational av_add_q(AVRational b, AVRational c) av_const; + +/** + * Subtracts one rational from another. + * @param b first rational + * @param c second rational + * @return b-c + */ +AVRational av_sub_q(AVRational b, AVRational c) av_const; + +/** + * Converts a double precision floating point number to a rational. + * @param d double to convert + * @param max the maximum allowed numerator and denominator + * @return (AVRational) d + */ +AVRational av_d2q(double d, int max) av_const; + +/** + * @return 1 if q1 is nearer to q than q2, -1 if q2 is nearer + * than q1, 0 if they have the same distance. + */ +int av_nearer_q(AVRational q, AVRational q1, AVRational q2); + +/** + * Finds the nearest value in q_list to q. + * @param q_list an array of rationals terminated by {0, 0} + * @return the index of the nearest value found in the array + */ +int av_find_nearest_q_idx(AVRational q, const AVRational* q_list); + +#endif /* AVUTIL_RATIONAL_H */ diff --git a/include/libavutil/sha1.h b/include/libavutil/sha1.h new file mode 100644 index 00000000..cf7c4a65 --- /dev/null +++ b/include/libavutil/sha1.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_SHA1_H +#define AVUTIL_SHA1_H + +#include <stdint.h> + +extern const int av_sha1_size; + +struct AVSHA1; + +/** + * Initializes SHA-1 hashing. + * + * @param context pointer to the function context (of size av_sha_size) + * @deprecated use av_sha_init() instead + */ +void av_sha1_init(struct AVSHA1* context); + +/** + * Updates hash value. + * + * @param context hash function context + * @param data input data to update hash with + * @param len input data length + * @deprecated use av_sha_update() instead + */ +void av_sha1_update(struct AVSHA1* context, const uint8_t* data, unsigned int len); + +/** + * Finishes hashing and output digest value. + * + * @param context hash function context + * @param digest buffer where output digest value is stored + * @deprecated use av_sha_final() instead + */ +void av_sha1_final(struct AVSHA1* context, uint8_t digest[20]); + +#endif /* AVUTIL_SHA1_H */ diff --git a/include/mad.h b/include/mad.h new file mode 100644 index 00000000..9ef6cc8f --- /dev/null +++ b/include/mad.h @@ -0,0 +1,964 @@ +/* + * libmad - MPEG audio decoder 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 + * + * If you would like to negotiate alternate licensing terms, you may do + * so by contacting: Underbit Technologies, Inc. <info@underbit.com> + */ + +# ifdef __cplusplus +extern "C" { +# endif + +# define FPM_INTEL + + + +# define SIZEOF_INT 4 +# define SIZEOF_LONG 4 +# define SIZEOF_LONG_LONG 8 + + +/* Id: version.h,v 1.26 2004/01/23 09:41:33 rob Exp */ + +# ifndef LIBMAD_VERSION_H +# define LIBMAD_VERSION_H + +# define MAD_VERSION_MAJOR 0 +# define MAD_VERSION_MINOR 15 +# define MAD_VERSION_PATCH 1 +# define MAD_VERSION_EXTRA " (beta)" + +# define MAD_VERSION_STRINGIZE(str) #str +# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num) + +# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \ + MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \ + MAD_VERSION_STRING(MAD_VERSION_PATCH) \ + MAD_VERSION_EXTRA + +# define MAD_PUBLISHYEAR "2000-2004" +# define MAD_AUTHOR "Underbit Technologies, Inc." +# define MAD_EMAIL "info@underbit.com" + +extern char const mad_version[]; +extern char const mad_copyright[]; +extern char const mad_author[]; +extern char const mad_build[]; + +# endif + +/* Id: fixed.h,v 1.38 2004/02/17 02:02:03 rob Exp */ + +# ifndef LIBMAD_FIXED_H +# define LIBMAD_FIXED_H + +# if SIZEOF_INT >= 4 +typedef signed int mad_fixed_t; + +typedef signed int mad_fixed64hi_t; +typedef unsigned int mad_fixed64lo_t; +# else +typedef signed long mad_fixed_t; + +typedef signed long mad_fixed64hi_t; +typedef unsigned long mad_fixed64lo_t; +# endif + +# if defined(_MSC_VER) +# define mad_fixed64_t signed __int64 +# elif 1 || defined(__GNUC__) +# define mad_fixed64_t signed long long +# endif + +# if defined(FPM_FLOAT) +typedef double mad_sample_t; +# else +typedef mad_fixed_t mad_sample_t; +# endif + +/* + * Fixed-point format: 0xABBBBBBB + * A == whole part (sign + 3 bits) + * B == fractional part (28 bits) + * + * Values are signed two's complement, so the effective range is: + * 0x80000000 to 0x7fffffff + * -8.0 to +7.9999999962747097015380859375 + * + * The smallest representable value is: + * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9) + * + * 28 bits of fractional accuracy represent about + * 8.6 digits of decimal accuracy. + * + * Fixed-point numbers can be added or subtracted as normal + * integers, but multiplication requires shifting the 64-bit result + * from 56 fractional bits back to 28 (and rounding.) + * + * Changing the definition of MAD_F_FRACBITS is only partially + * supported, and must be done with care. + */ + +# define MAD_F_FRACBITS 28 + +# if MAD_F_FRACBITS == 28 +# define MAD_F(x) ((mad_fixed_t) (x##L)) +# else +# if MAD_F_FRACBITS < 28 +# warning "MAD_F_FRACBITS < 28" +# define MAD_F(x) ((mad_fixed_t) \ + (((x##L) + \ + (1L << (28 - MAD_F_FRACBITS - 1))) >> \ + (28 - MAD_F_FRACBITS))) +# elif MAD_F_FRACBITS > 28 +# error "MAD_F_FRACBITS > 28 not currently supported" +# define MAD_F(x) ((mad_fixed_t) \ + ((x##L) << (MAD_F_FRACBITS - 28))) +# endif +# endif + +# define MAD_F_MIN ((mad_fixed_t) -0x80000000L) +# define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL) + +# define MAD_F_ONE MAD_F(0x10000000) + +# define mad_f_tofixed(x) ((mad_fixed_t) \ + ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5)) +# define mad_f_todouble(x) ((double) \ + ((x) / (double) (1L << MAD_F_FRACBITS))) + +# define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS) +# define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1)) + /* (x should be positive) */ + +# define mad_f_fromint(x) ((x) << MAD_F_FRACBITS) + +# define mad_f_add(x, y) ((x) + (y)) +# define mad_f_sub(x, y) ((x) - (y)) + +# if defined(FPM_FLOAT) +# error "FPM_FLOAT not yet supported" + +# undef MAD_F +# define MAD_F(x) mad_f_todouble(x) + +# define mad_f_mul(x, y) ((x) * (y)) +# define mad_f_scale64 + +# undef ASO_ZEROCHECK + +# elif defined(FPM_64BIT) + +/* + * This version should be the most accurate if 64-bit types are supported by + * the compiler, although it may not be the most efficient. + */ +# if defined(OPT_ACCURACY) +# define mad_f_mul(x, y) \ + ((mad_fixed_t) \ + ((((mad_fixed64_t) (x) * (y)) + \ + (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS)) +# else +# define mad_f_mul(x, y) \ + ((mad_fixed_t) (((mad_fixed64_t) (x) * (y)) >> MAD_F_SCALEBITS)) +# endif + +# define MAD_F_SCALEBITS MAD_F_FRACBITS + +/* --- Intel --------------------------------------------------------------- */ + +# elif defined(FPM_INTEL) + +# if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4035) /* no return value */ +static __forceinline +mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) +{ + enum { + fracbits = MAD_F_FRACBITS + }; + + __asm { + mov eax, x + imul y + shrd eax, edx, fracbits + } + + /* implicit return of eax */ +} +# pragma warning(pop) + +# define mad_f_mul mad_f_mul_inline +# define mad_f_scale64 +# else +/* + * This Intel version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("imull %3" \ + : "=a" (lo), "=d" (hi) \ + : "%a" (x), "rm" (y) \ + : "cc") + +# if defined(OPT_ACCURACY) +/* + * This gives best accuracy but is not very fast. + */ +# define MAD_F_MLA(hi, lo, x, y) \ + ({ mad_fixed64hi_t __hi; \ + mad_fixed64lo_t __lo; \ + MAD_F_MLX(__hi, __lo, (x), (y)); \ + asm ("addl %2,%0\n\t" \ + "adcl %3,%1" \ + : "=rm" (lo), "=rm" (hi) \ + : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \ + : "cc"); \ + }) +# endif /* OPT_ACCURACY */ + +# if defined(OPT_ACCURACY) +/* + * Surprisingly, this is faster than SHRD followed by ADC. + */ +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed64hi_t __hi_; \ + mad_fixed64lo_t __lo_; \ + mad_fixed_t __result; \ + asm ("addl %4,%2\n\t" \ + "adcl %5,%3" \ + : "=rm" (__lo_), "=rm" (__hi_) \ + : "0" (lo), "1" (hi), \ + "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \ + : "cc"); \ + asm ("shrdl %3,%2,%1" \ + : "=rm" (__result) \ + : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) +# elif defined(OPT_INTEL) +/* + * Alternate Intel scaling that may or may not perform better. + */ +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("shrl %3,%1\n\t" \ + "shll %4,%2\n\t" \ + "orl %2,%1" \ + : "=rm" (__result) \ + : "0" (lo), "r" (hi), \ + "I" (MAD_F_SCALEBITS), "I" (32 - MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) +# else +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("shrdl %3,%2,%1" \ + : "=rm" (__result) \ + : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) +# endif /* OPT_ACCURACY */ + +# define MAD_F_SCALEBITS MAD_F_FRACBITS +# endif + +/* --- ARM ----------------------------------------------------------------- */ + +# elif defined(FPM_ARM) + +/* + * This ARM V4 version is as accurate as FPM_64BIT but much faster. The + * least significant bit is properly rounded at no CPU cycle cost! + */ +# if 1 +/* + * This is faster than the default implementation via MAD_F_MLX() and + * mad_f_scale64(). + */ +# define mad_f_mul(x, y) \ + ({ mad_fixed64hi_t __hi; \ + mad_fixed64lo_t __lo; \ + mad_fixed_t __result; \ + asm ("smull %0, %1, %3, %4\n\t" \ + "movs %0, %0, lsr %5\n\t" \ + "adc %2, %0, %1, lsl %6" \ + : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ + : "%r" (x), "r" (y), \ + "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) +# endif + +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("smull %0, %1, %2, %3" \ + : "=&r" (lo), "=&r" (hi) \ + : "%r" (x), "r" (y)) + +# define MAD_F_MLA(hi, lo, x, y) \ + asm ("smlal %0, %1, %2, %3" \ + : "+r" (lo), "+r" (hi) \ + : "%r" (x), "r" (y)) + +# define MAD_F_MLN(hi, lo) \ + asm ("rsbs %0, %2, #0\n\t" \ + "rsc %1, %3, #0" \ + : "=r" (lo), "=r" (hi) \ + : "0" (lo), "1" (hi) \ + : "cc") + +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("movs %0, %1, lsr %3\n\t" \ + "adc %0, %0, %2, lsl %4" \ + : "=&r" (__result) \ + : "r" (lo), "r" (hi), \ + "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) + +# define MAD_F_SCALEBITS MAD_F_FRACBITS + +/* --- MIPS ---------------------------------------------------------------- */ + +# elif defined(FPM_MIPS) + +/* + * This MIPS version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("mult %2,%3" \ + : "=l" (lo), "=h" (hi) \ + : "%r" (x), "r" (y)) + +# if defined(HAVE_MADD_ASM) +# define MAD_F_MLA(hi, lo, x, y) \ + asm ("madd %2,%3" \ + : "+l" (lo), "+h" (hi) \ + : "%r" (x), "r" (y)) +# elif defined(HAVE_MADD16_ASM) +/* + * This loses significant accuracy due to the 16-bit integer limit in the + * multiply/accumulate instruction. + */ +# define MAD_F_ML0(hi, lo, x, y) \ + asm ("mult %2,%3" \ + : "=l" (lo), "=h" (hi) \ + : "%r" ((x) >> 12), "r" ((y) >> 16)) +# define MAD_F_MLA(hi, lo, x, y) \ + asm ("madd16 %2,%3" \ + : "+l" (lo), "+h" (hi) \ + : "%r" ((x) >> 12), "r" ((y) >> 16)) +# define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo)) +# endif + +# if defined(OPT_SPEED) +# define mad_f_scale64(hi, lo) \ + ((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS))) +# define MAD_F_SCALEBITS MAD_F_FRACBITS +# endif + +/* --- SPARC --------------------------------------------------------------- */ + +# elif defined(FPM_SPARC) + +/* + * This SPARC V8 version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("smul %2, %3, %0\n\t" \ + "rd %%y, %1" \ + : "=r" (lo), "=r" (hi) \ + : "%r" (x), "rI" (y)) + +/* --- PowerPC ------------------------------------------------------------- */ + +# elif defined(FPM_PPC) + +/* + * This PowerPC version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + do { \ + asm ("mullw %0,%1,%2" \ + : "=r" (lo) \ + : "%r" (x), "r" (y)); \ + asm ("mulhw %0,%1,%2" \ + : "=r" (hi) \ + : "%r" (x), "r" (y)); \ + } \ + while (0) + +# if defined(OPT_ACCURACY) +/* + * This gives best accuracy but is not very fast. + */ +# define MAD_F_MLA(hi, lo, x, y) \ + ({ mad_fixed64hi_t __hi; \ + mad_fixed64lo_t __lo; \ + MAD_F_MLX(__hi, __lo, (x), (y)); \ + asm ("addc %0,%2,%3\n\t" \ + "adde %1,%4,%5" \ + : "=r" (lo), "=r" (hi) \ + : "%r" (lo), "r" (__lo), \ + "%r" (hi), "r" (__hi) \ + : "xer"); \ + }) +# endif + +# if defined(OPT_ACCURACY) +/* + * This is slower than the truncating version below it. + */ +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result, __round; \ + asm ("rotrwi %0,%1,%2" \ + : "=r" (__result) \ + : "r" (lo), "i" (MAD_F_SCALEBITS)); \ + asm ("extrwi %0,%1,1,0" \ + : "=r" (__round) \ + : "r" (__result)); \ + asm ("insrwi %0,%1,%2,0" \ + : "+r" (__result) \ + : "r" (hi), "i" (MAD_F_SCALEBITS)); \ + asm ("add %0,%1,%2" \ + : "=r" (__result) \ + : "%r" (__result), "r" (__round)); \ + __result; \ + }) +# else +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("rotrwi %0,%1,%2" \ + : "=r" (__result) \ + : "r" (lo), "i" (MAD_F_SCALEBITS)); \ + asm ("insrwi %0,%1,%2,0" \ + : "+r" (__result) \ + : "r" (hi), "i" (MAD_F_SCALEBITS)); \ + __result; \ + }) +# endif + +# define MAD_F_SCALEBITS MAD_F_FRACBITS + +/* --- Default ------------------------------------------------------------- */ + +# elif defined(FPM_DEFAULT) + +/* + * This version is the most portable but it loses significant accuracy. + * Furthermore, accuracy is biased against the second argument, so care + * should be taken when ordering operands. + * + * The scale factors are constant as this is not used with SSO. + * + * Pre-rounding is required to stay within the limits of compliance. + */ +# if defined(OPT_SPEED) +# define mad_f_mul(x, y) (((x) >> 12) * ((y) >> 16)) +# else +# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \ + (((y) + (1L << 15)) >> 16)) +# endif + +/* ------------------------------------------------------------------------- */ + +# else +# error "no FPM selected" +# endif + +/* default implementations */ + +# if !defined(mad_f_mul) +# define mad_f_mul(x, y) \ + ({ register mad_fixed64hi_t __hi; \ + register mad_fixed64lo_t __lo; \ + MAD_F_MLX(__hi, __lo, (x), (y)); \ + mad_f_scale64(__hi, __lo); \ + }) +# endif + +# if !defined(MAD_F_MLA) +# define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y))) +# define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y))) +# define MAD_F_MLN(hi, lo) ((lo) = -(lo)) +# define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo)) +# endif + +# if !defined(MAD_F_ML0) +# define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y)) +# endif + +# if !defined(MAD_F_MLN) +# define MAD_F_MLN(hi, lo) ((hi) = ((lo) = -(lo)) ? ~(hi) : -(hi)) +# endif + +# if !defined(MAD_F_MLZ) +# define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo)) +# endif + +# if !defined(mad_f_scale64) +# if defined(OPT_ACCURACY) +# define mad_f_scale64(hi, lo) \ + ((((mad_fixed_t) \ + (((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \ + ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1) +# else +# define mad_f_scale64(hi, lo) \ + ((mad_fixed_t) \ + (((hi) << (32 - MAD_F_SCALEBITS)) | \ + ((lo) >> MAD_F_SCALEBITS))) +# endif +# define MAD_F_SCALEBITS MAD_F_FRACBITS +# endif + +/* C routines */ + +mad_fixed_t mad_f_abs(mad_fixed_t); +mad_fixed_t mad_f_div(mad_fixed_t, mad_fixed_t); + +# endif + +/* Id: bit.h,v 1.12 2004/01/23 09:41:32 rob Exp */ + +# ifndef LIBMAD_BIT_H +# define LIBMAD_BIT_H + +struct mad_bitptr { + unsigned char const *byte; + unsigned short cache; + unsigned short left; +}; + +void mad_bit_init(struct mad_bitptr *, unsigned char const *); + +# define mad_bit_finish(bitptr) /* nothing */ + +unsigned int mad_bit_length(struct mad_bitptr const *, + struct mad_bitptr const *); + +# define mad_bit_bitsleft(bitptr) ((bitptr)->left) +unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *); + +void mad_bit_skip(struct mad_bitptr *, unsigned int); +unsigned long mad_bit_read(struct mad_bitptr *, unsigned int); +void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long); + +unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short); + +# endif + +/* Id: timer.h,v 1.16 2004/01/23 09:41:33 rob Exp */ + +# ifndef LIBMAD_TIMER_H +# define LIBMAD_TIMER_H + +typedef struct { + signed long seconds; /* whole seconds */ + unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */ +} mad_timer_t; + +extern mad_timer_t const mad_timer_zero; + +# define MAD_TIMER_RESOLUTION 352800000UL + +enum mad_units { + MAD_UNITS_HOURS = -2, + MAD_UNITS_MINUTES = -1, + MAD_UNITS_SECONDS = 0, + + /* metric units */ + + MAD_UNITS_DECISECONDS = 10, + MAD_UNITS_CENTISECONDS = 100, + MAD_UNITS_MILLISECONDS = 1000, + + /* audio sample units */ + + MAD_UNITS_8000_HZ = 8000, + MAD_UNITS_11025_HZ = 11025, + MAD_UNITS_12000_HZ = 12000, + + MAD_UNITS_16000_HZ = 16000, + MAD_UNITS_22050_HZ = 22050, + MAD_UNITS_24000_HZ = 24000, + + MAD_UNITS_32000_HZ = 32000, + MAD_UNITS_44100_HZ = 44100, + MAD_UNITS_48000_HZ = 48000, + + /* video frame/field units */ + + MAD_UNITS_24_FPS = 24, + MAD_UNITS_25_FPS = 25, + MAD_UNITS_30_FPS = 30, + MAD_UNITS_48_FPS = 48, + MAD_UNITS_50_FPS = 50, + MAD_UNITS_60_FPS = 60, + + /* CD audio frames */ + + MAD_UNITS_75_FPS = 75, + + /* video drop-frame units */ + + MAD_UNITS_23_976_FPS = -24, + MAD_UNITS_24_975_FPS = -25, + MAD_UNITS_29_97_FPS = -30, + MAD_UNITS_47_952_FPS = -48, + MAD_UNITS_49_95_FPS = -50, + MAD_UNITS_59_94_FPS = -60 +}; + +# define mad_timer_reset(timer) ((void) (*(timer) = mad_timer_zero)) + +int mad_timer_compare(mad_timer_t, mad_timer_t); + +# define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero) + +void mad_timer_negate(mad_timer_t *); +mad_timer_t mad_timer_abs(mad_timer_t); + +void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long); +void mad_timer_add(mad_timer_t *, mad_timer_t); +void mad_timer_multiply(mad_timer_t *, signed long); + +signed long mad_timer_count(mad_timer_t, enum mad_units); +unsigned long mad_timer_fraction(mad_timer_t, unsigned long); +void mad_timer_string(mad_timer_t, char *, char const *, + enum mad_units, enum mad_units, unsigned long); + +# endif + +/* Id: stream.h,v 1.20 2004/02/05 09:02:39 rob Exp */ + +# ifndef LIBMAD_STREAM_H +# define LIBMAD_STREAM_H + + +# define MAD_BUFFER_GUARD 8 +# define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD) + +enum mad_error { + MAD_ERROR_NONE = 0x0000, /* no error */ + + MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */ + MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */ + + MAD_ERROR_NOMEM = 0x0031, /* not enough memory */ + + MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */ + MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */ + MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */ + MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */ + MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */ + + MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */ + MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */ + MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */ + MAD_ERROR_BADMODE = 0x0222, /* bad bitrate/mode combination */ + MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */ + MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */ + MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */ + MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */ + MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */ + MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */ + MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */ + MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */ + MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */ +}; + +# define MAD_RECOVERABLE(error) ((error) & 0xff00) + +struct mad_stream { + unsigned char const *buffer; /* input bitstream buffer */ + unsigned char const *bufend; /* end of buffer */ + unsigned long skiplen; /* bytes to skip before next frame */ + + int sync; /* stream sync found */ + unsigned long freerate; /* free bitrate (fixed) */ + + unsigned char const *this_frame; /* start of current frame */ + unsigned char const *next_frame; /* start of next frame */ + struct mad_bitptr ptr; /* current processing bit pointer */ + + struct mad_bitptr anc_ptr; /* ancillary bits pointer */ + unsigned int anc_bitlen; /* number of ancillary bits */ + + unsigned char (*main_data)[MAD_BUFFER_MDLEN]; + /* Layer III main_data() */ + unsigned int md_len; /* bytes in main_data */ + + int options; /* decoding options (see below) */ + enum mad_error error; /* error code (see above) */ +}; + +enum { + MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */ + MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */ +# if 0 /* not yet implemented */ + MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */ + MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */ + MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */ +# endif +}; + +void mad_stream_init(struct mad_stream *); +void mad_stream_finish(struct mad_stream *); + +# define mad_stream_options(stream, opts) \ + ((void) ((stream)->options = (opts))) + +void mad_stream_buffer(struct mad_stream *, + unsigned char const *, unsigned long); +void mad_stream_skip(struct mad_stream *, unsigned long); + +int mad_stream_sync(struct mad_stream *); + +char const *mad_stream_errorstr(struct mad_stream const *); + +# endif + +/* Id: frame.h,v 1.20 2004/01/23 09:41:32 rob Exp */ + +# ifndef LIBMAD_FRAME_H +# define LIBMAD_FRAME_H + + +enum mad_layer { + MAD_LAYER_I = 1, /* Layer I */ + MAD_LAYER_II = 2, /* Layer II */ + MAD_LAYER_III = 3 /* Layer III */ +}; + +enum mad_mode { + MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */ + MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */ + MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */ + MAD_MODE_STEREO = 3 /* normal LR stereo */ +}; + +enum mad_emphasis { + MAD_EMPHASIS_NONE = 0, /* no emphasis */ + MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */ + MAD_EMPHASIS_CCITT_J_17 = 3, /* CCITT J.17 emphasis */ + MAD_EMPHASIS_RESERVED = 2 /* unknown emphasis */ +}; + +struct mad_header { + enum mad_layer layer; /* audio layer (1, 2, or 3) */ + enum mad_mode mode; /* channel mode (see above) */ + int mode_extension; /* additional mode info */ + enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ + + unsigned long bitrate; /* stream bitrate (bps) */ + unsigned int samplerate; /* sampling frequency (Hz) */ + + unsigned short crc_check; /* frame CRC accumulator */ + unsigned short crc_target; /* final target CRC checksum */ + + int flags; /* flags (see below) */ + int private_bits; /* private bits (see below) */ + + mad_timer_t duration; /* audio playing time of frame */ +}; + +struct mad_frame { + struct mad_header header; /* MPEG audio header */ + + int options; /* decoding options (from stream) */ + + mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */ + mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */ +}; + +# define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1) +# define MAD_NSBSAMPLES(header) \ + ((header)->layer == MAD_LAYER_I ? 12 : \ + (((header)->layer == MAD_LAYER_III && \ + ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36)) + +enum { + MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ + MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ + + MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ + MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ + MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ + MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ + + MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ + MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ + MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ + + MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ + MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ + MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ +}; + +enum { + MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ + MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ +}; + +void mad_header_init(struct mad_header *); + +# define mad_header_finish(header) /* nothing */ + +int mad_header_decode(struct mad_header *, struct mad_stream *); + +void mad_frame_init(struct mad_frame *); +void mad_frame_finish(struct mad_frame *); + +int mad_frame_decode(struct mad_frame *, struct mad_stream *); + +void mad_frame_mute(struct mad_frame *); + +# endif + +/* Id: synth.h,v 1.15 2004/01/23 09:41:33 rob Exp */ + +# ifndef LIBMAD_SYNTH_H +# define LIBMAD_SYNTH_H + + +struct mad_pcm { + unsigned int samplerate; /* sampling frequency (Hz) */ + unsigned short channels; /* number of channels */ + unsigned short length; /* number of samples per channel */ + mad_fixed_t samples[2][1152]; /* PCM output samples [ch][sample] */ +}; + +struct mad_synth { + mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ + /* [ch][eo][peo][s][v] */ + + unsigned int phase; /* current processing phase */ + + struct mad_pcm pcm; /* PCM output */ +}; + +/* single channel PCM selector */ +enum { + MAD_PCM_CHANNEL_SINGLE = 0 +}; + +/* dual channel PCM selector */ +enum { + MAD_PCM_CHANNEL_DUAL_1 = 0, + MAD_PCM_CHANNEL_DUAL_2 = 1 +}; + +/* stereo PCM selector */ +enum { + MAD_PCM_CHANNEL_STEREO_LEFT = 0, + MAD_PCM_CHANNEL_STEREO_RIGHT = 1 +}; + +void mad_synth_init(struct mad_synth *); + +# define mad_synth_finish(synth) /* nothing */ + +void mad_synth_mute(struct mad_synth *); + +void mad_synth_frame(struct mad_synth *, struct mad_frame const *); + +# endif + +/* Id: decoder.h,v 1.17 2004/01/23 09:41:32 rob Exp */ + +# ifndef LIBMAD_DECODER_H +# define LIBMAD_DECODER_H + + +enum mad_decoder_mode { + MAD_DECODER_MODE_SYNC = 0, + MAD_DECODER_MODE_ASYNC +}; + +enum mad_flow { + MAD_FLOW_CONTINUE = 0x0000, /* continue normally */ + MAD_FLOW_STOP = 0x0010, /* stop decoding normally */ + MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */ + MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */ +}; + +struct mad_decoder { + enum mad_decoder_mode mode; + + int options; + + struct { + long pid; + int in; + int out; + } async; + + struct { + struct mad_stream stream; + struct mad_frame frame; + struct mad_synth synth; + } *sync; + + void *cb_data; + + enum mad_flow (*input_func)(void *, struct mad_stream *); + enum mad_flow (*header_func)(void *, struct mad_header const *); + enum mad_flow (*filter_func)(void *, + struct mad_stream const *, struct mad_frame *); + enum mad_flow (*output_func)(void *, + struct mad_header const *, struct mad_pcm *); + enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); + enum mad_flow (*message_func)(void *, void *, unsigned int *); +}; + +void mad_decoder_init(struct mad_decoder *, void *, + enum mad_flow (*)(void *, struct mad_stream *), + enum mad_flow (*)(void *, struct mad_header const *), + enum mad_flow (*)(void *, + struct mad_stream const *, + struct mad_frame *), + enum mad_flow (*)(void *, + struct mad_header const *, + struct mad_pcm *), + enum mad_flow (*)(void *, + struct mad_stream *, + struct mad_frame *), + enum mad_flow (*)(void *, void *, unsigned int *)); +int mad_decoder_finish(struct mad_decoder *); + +# define mad_decoder_options(decoder, opts) \ + ((void) ((decoder)->options = (opts))) + +int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode); +int mad_decoder_message(struct mad_decoder *, void *, unsigned int *); + +# endif + +# ifdef __cplusplus +} +# endif diff --git a/include/neaacdec.h b/include/neaacdec.h new file mode 100644 index 00000000..a45f1d09 --- /dev/null +++ b/include/neaacdec.h @@ -0,0 +1,258 @@ +/* +** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding +** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com +** +** 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. +** +** Any non-GPL usage of this software or parts of this software is strictly +** forbidden. +** +** The "appropriate copyright message" mentioned in section 2c of the GPLv2 +** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" +** +** Commercial non-GPL licensing of this software is possible. +** For more info contact Nero AG through Mpeg4AAClicense@nero.com. +** +** $Id: neaacdec.h,v 1.13 2009/01/26 23:51:15 menno Exp $ +**/ + +#ifndef __NEAACDEC_H__ +#define __NEAACDEC_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#if 1 +/* MACROS FOR BACKWARDS COMPATIBILITY */ +/* structs */ +#define faacDecHandle NeAACDecHandle +#define faacDecConfiguration NeAACDecConfiguration +#define faacDecConfigurationPtr NeAACDecConfigurationPtr +#define faacDecFrameInfo NeAACDecFrameInfo +/* functions */ +#define faacDecGetErrorMessage NeAACDecGetErrorMessage +#define faacDecSetConfiguration NeAACDecSetConfiguration +#define faacDecGetCurrentConfiguration NeAACDecGetCurrentConfiguration +#define faacDecInit NeAACDecInit +#define faacDecInit2 NeAACDecInit2 +#define faacDecInitDRM NeAACDecInitDRM +#define faacDecPostSeekReset NeAACDecPostSeekReset +#define faacDecOpen NeAACDecOpen +#define faacDecClose NeAACDecClose +#define faacDecDecode NeAACDecDecode +#define AudioSpecificConfig NeAACDecAudioSpecificConfig +#endif + + +#ifdef _WIN32 + #pragma pack(push, 8) + #ifndef NEAACDECAPI + #define NEAACDECAPI __cdecl + #endif +#else + #ifndef NEAACDECAPI + #define NEAACDECAPI + #endif +#endif + +#define FAAD2_VERSION "2.7" + +/* object types for AAC */ +#define MAIN 1 +#define LC 2 +#define SSR 3 +#define LTP 4 +#define HE_AAC 5 +#define ER_LC 17 +#define ER_LTP 19 +#define LD 23 +#define DRM_ER_LC 27 /* special object type for DRM */ + +/* header types */ +#define RAW 0 +#define ADIF 1 +#define ADTS 2 +#define LATM 3 + +/* SBR signalling */ +#define NO_SBR 0 +#define SBR_UPSAMPLED 1 +#define SBR_DOWNSAMPLED 2 +#define NO_SBR_UPSAMPLED 3 + +/* library output formats */ +#define FAAD_FMT_16BIT 1 +#define FAAD_FMT_24BIT 2 +#define FAAD_FMT_32BIT 3 +#define FAAD_FMT_FLOAT 4 +#define FAAD_FMT_FIXED FAAD_FMT_FLOAT +#define FAAD_FMT_DOUBLE 5 + +/* Capabilities */ +#define LC_DEC_CAP (1<<0) /* Can decode LC */ +#define MAIN_DEC_CAP (1<<1) /* Can decode MAIN */ +#define LTP_DEC_CAP (1<<2) /* Can decode LTP */ +#define LD_DEC_CAP (1<<3) /* Can decode LD */ +#define ERROR_RESILIENCE_CAP (1<<4) /* Can decode ER */ +#define FIXED_POINT_CAP (1<<5) /* Fixed point */ + +/* Channel definitions */ +#define FRONT_CHANNEL_CENTER (1) +#define FRONT_CHANNEL_LEFT (2) +#define FRONT_CHANNEL_RIGHT (3) +#define SIDE_CHANNEL_LEFT (4) +#define SIDE_CHANNEL_RIGHT (5) +#define BACK_CHANNEL_LEFT (6) +#define BACK_CHANNEL_RIGHT (7) +#define BACK_CHANNEL_CENTER (8) +#define LFE_CHANNEL (9) +#define UNKNOWN_CHANNEL (0) + +/* DRM channel definitions */ +#define DRMCH_MONO 1 +#define DRMCH_STEREO 2 +#define DRMCH_SBR_MONO 3 +#define DRMCH_SBR_STEREO 4 +#define DRMCH_SBR_PS_STEREO 5 + + +/* A decode call can eat up to FAAD_MIN_STREAMSIZE bytes per decoded channel, + so at least so much bytes per channel should be available in this stream */ +#define FAAD_MIN_STREAMSIZE 768 /* 6144 bits/channel */ + + +typedef void *NeAACDecHandle; + +typedef struct mp4AudioSpecificConfig +{ + /* Audio Specific Info */ + unsigned char objectTypeIndex; + unsigned char samplingFrequencyIndex; + unsigned long samplingFrequency; + unsigned char channelsConfiguration; + + /* GA Specific Info */ + unsigned char frameLengthFlag; + unsigned char dependsOnCoreCoder; + unsigned short coreCoderDelay; + unsigned char extensionFlag; + unsigned char aacSectionDataResilienceFlag; + unsigned char aacScalefactorDataResilienceFlag; + unsigned char aacSpectralDataResilienceFlag; + unsigned char epConfig; + + char sbr_present_flag; + char forceUpSampling; + char downSampledSBR; +} mp4AudioSpecificConfig; + +typedef struct NeAACDecConfiguration +{ + unsigned char defObjectType; + unsigned long defSampleRate; + unsigned char outputFormat; + unsigned char downMatrix; + unsigned char useOldADTSFormat; + unsigned char dontUpSampleImplicitSBR; +} NeAACDecConfiguration, *NeAACDecConfigurationPtr; + +typedef struct NeAACDecFrameInfo +{ + unsigned long bytesconsumed; + unsigned long samples; + unsigned char channels; + unsigned char error; + unsigned long samplerate; + + /* SBR: 0: off, 1: on; upsample, 2: on; downsampled, 3: off; upsampled */ + unsigned char sbr; + + /* MPEG-4 ObjectType */ + unsigned char object_type; + + /* AAC header type; MP4 will be signalled as RAW also */ + unsigned char header_type; + + /* multichannel configuration */ + unsigned char num_front_channels; + unsigned char num_side_channels; + unsigned char num_back_channels; + unsigned char num_lfe_channels; + unsigned char channel_position[64]; + + /* PS: 0: off, 1: on */ + unsigned char ps; +} NeAACDecFrameInfo; + +char* NEAACDECAPI NeAACDecGetErrorMessage(unsigned char errcode); + +unsigned long NEAACDECAPI NeAACDecGetCapabilities(void); + +NeAACDecHandle NEAACDECAPI NeAACDecOpen(void); + +NeAACDecConfigurationPtr NEAACDECAPI NeAACDecGetCurrentConfiguration(NeAACDecHandle hDecoder); + +unsigned char NEAACDECAPI NeAACDecSetConfiguration(NeAACDecHandle hDecoder, + NeAACDecConfigurationPtr config); + +/* Init the library based on info from the AAC file (ADTS/ADIF) */ +long NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder, + unsigned char *buffer, + unsigned long buffer_size, + unsigned long *samplerate, + unsigned char *channels); + +/* Init the library using a DecoderSpecificInfo */ +char NEAACDECAPI NeAACDecInit2(NeAACDecHandle hDecoder, + unsigned char *pBuffer, + unsigned long SizeOfDecoderSpecificInfo, + unsigned long *samplerate, + unsigned char *channels); + +/* Init the library for DRM */ +char NEAACDECAPI NeAACDecInitDRM(NeAACDecHandle *hDecoder, unsigned long samplerate, + unsigned char channels); + +void NEAACDECAPI NeAACDecPostSeekReset(NeAACDecHandle hDecoder, long frame); + +void NEAACDECAPI NeAACDecClose(NeAACDecHandle hDecoder); + +void* NEAACDECAPI NeAACDecDecode(NeAACDecHandle hDecoder, + NeAACDecFrameInfo *hInfo, + unsigned char *buffer, + unsigned long buffer_size); + +void* NEAACDECAPI NeAACDecDecode2(NeAACDecHandle hDecoder, + NeAACDecFrameInfo *hInfo, + unsigned char *buffer, + unsigned long buffer_size, + void **sample_buffer, + unsigned long sample_buffer_size); + +char NEAACDECAPI NeAACDecAudioSpecificConfig(unsigned char *pBuffer, + unsigned long buffer_size, + mp4AudioSpecificConfig *mp4ASC); + +#ifdef _WIN32 + #pragma pack(pop) +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/include/ogg/Makefile.am b/include/ogg/Makefile.am new file mode 100644 index 00000000..142699d3 --- /dev/null +++ b/include/ogg/Makefile.am @@ -0,0 +1,6 @@ +## Process this file with automake to produce Makefile.in + +oggincludedir = $(includedir)/ogg + +ogginclude_HEADERS = ogg.h os_types.h +nodist_ogginclude_HEADERS = config_types.h diff --git a/include/ogg/config_types.h b/include/ogg/config_types.h new file mode 100644 index 00000000..496e900f --- /dev/null +++ b/include/ogg/config_types.h @@ -0,0 +1,11 @@ +#ifndef __CONFIG_TYPES_H__ +#define __CONFIG_TYPES_H__ + +/* these are filled in by configure */ +typedef int16_t ogg_int16_t; +typedef u_int16_t ogg_uint16_t; +typedef int32_t ogg_int32_t; +typedef u_int32_t ogg_uint32_t; +typedef int64_t ogg_int64_t; + +#endif diff --git a/include/ogg/config_types.h.in b/include/ogg/config_types.h.in new file mode 100644 index 00000000..568a001f --- /dev/null +++ b/include/ogg/config_types.h.in @@ -0,0 +1,11 @@ +#ifndef __CONFIG_TYPES_H__ +#define __CONFIG_TYPES_H__ + +/* these are filled in by configure */ +typedef @SIZE16@ ogg_int16_t; +typedef @USIZE16@ ogg_uint16_t; +typedef @SIZE32@ ogg_int32_t; +typedef @USIZE32@ ogg_uint32_t; +typedef @SIZE64@ ogg_int64_t; + +#endif diff --git a/include/ogg/ogg.h b/include/ogg/ogg.h new file mode 100644 index 00000000..ae0cfd53 --- /dev/null +++ b/include/ogg/ogg.h @@ -0,0 +1,208 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel libogg include + last mod: $Id: ogg.h 16051 2009-05-27 05:00:06Z xiphmont $ + + ********************************************************************/ +#ifndef _OGG_H +#define _OGG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stddef.h> +#include <ogg/os_types.h> + +typedef struct { + void *iov_base; + size_t iov_len; +} ogg_iovec_t; + +typedef struct { + long endbyte; + int endbit; + + unsigned char *buffer; + unsigned char *ptr; + long storage; +} oggpack_buffer; + +/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ + +typedef struct { + unsigned char *header; + long header_len; + unsigned char *body; + long body_len; +} ogg_page; + +/* ogg_stream_state contains the current encode/decode state of a logical + Ogg bitstream **********************************************************/ + +typedef struct { + unsigned char *body_data; /* bytes from packet bodies */ + long body_storage; /* storage elements allocated */ + long body_fill; /* elements stored; fill mark */ + long body_returned; /* elements of fill returned */ + + + int *lacing_vals; /* The values that will go to the segment table */ + ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact + this way, but it is simple coupled to the + lacing fifo */ + long lacing_storage; + long lacing_fill; + long lacing_packet; + long lacing_returned; + + unsigned char header[282]; /* working space for header encode */ + int header_fill; + + int e_o_s; /* set when we have buffered the last packet in the + logical bitstream */ + int b_o_s; /* set after we've written the initial page + of a logical bitstream */ + long serialno; + long pageno; + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a seperate abstraction + layer) also knows about the gap */ + ogg_int64_t granulepos; + +} ogg_stream_state; + +/* ogg_packet is used to encapsulate the data and metadata belonging + to a single raw Ogg/Vorbis packet *************************************/ + +typedef struct { + unsigned char *packet; + long bytes; + long b_o_s; + long e_o_s; + + ogg_int64_t granulepos; + + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a seperate abstraction + layer) also knows about the gap */ +} ogg_packet; + +typedef struct { + unsigned char *data; + int storage; + int fill; + int returned; + + int unsynced; + int headerbytes; + int bodybytes; +} ogg_sync_state; + +/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ + +extern void oggpack_writeinit(oggpack_buffer *b); +extern int oggpack_writecheck(oggpack_buffer *b); +extern void oggpack_writetrunc(oggpack_buffer *b,long bits); +extern void oggpack_writealign(oggpack_buffer *b); +extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpack_reset(oggpack_buffer *b); +extern void oggpack_writeclear(oggpack_buffer *b); +extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpack_look(oggpack_buffer *b,int bits); +extern long oggpack_look1(oggpack_buffer *b); +extern void oggpack_adv(oggpack_buffer *b,int bits); +extern void oggpack_adv1(oggpack_buffer *b); +extern long oggpack_read(oggpack_buffer *b,int bits); +extern long oggpack_read1(oggpack_buffer *b); +extern long oggpack_bytes(oggpack_buffer *b); +extern long oggpack_bits(oggpack_buffer *b); +extern unsigned char *oggpack_get_buffer(oggpack_buffer *b); + +extern void oggpackB_writeinit(oggpack_buffer *b); +extern int oggpackB_writecheck(oggpack_buffer *b); +extern void oggpackB_writetrunc(oggpack_buffer *b,long bits); +extern void oggpackB_writealign(oggpack_buffer *b); +extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpackB_reset(oggpack_buffer *b); +extern void oggpackB_writeclear(oggpack_buffer *b); +extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpackB_look(oggpack_buffer *b,int bits); +extern long oggpackB_look1(oggpack_buffer *b); +extern void oggpackB_adv(oggpack_buffer *b,int bits); +extern void oggpackB_adv1(oggpack_buffer *b); +extern long oggpackB_read(oggpack_buffer *b,int bits); +extern long oggpackB_read1(oggpack_buffer *b); +extern long oggpackB_bytes(oggpack_buffer *b); +extern long oggpackB_bits(oggpack_buffer *b); +extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); + +/* Ogg BITSTREAM PRIMITIVES: encoding **************************/ + +extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); +extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, + int count, long e_o_s, ogg_int64_t granulepos); +extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); + +/* Ogg BITSTREAM PRIMITIVES: decoding **************************/ + +extern int ogg_sync_init(ogg_sync_state *oy); +extern int ogg_sync_clear(ogg_sync_state *oy); +extern int ogg_sync_reset(ogg_sync_state *oy); +extern int ogg_sync_destroy(ogg_sync_state *oy); +extern int ogg_sync_check(ogg_sync_state *oy); + +extern char *ogg_sync_buffer(ogg_sync_state *oy, long size); +extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); +extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); +extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); +extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); +extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); + +/* Ogg BITSTREAM PRIMITIVES: general ***************************/ + +extern int ogg_stream_init(ogg_stream_state *os,int serialno); +extern int ogg_stream_clear(ogg_stream_state *os); +extern int ogg_stream_reset(ogg_stream_state *os); +extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); +extern int ogg_stream_destroy(ogg_stream_state *os); +extern int ogg_stream_check(ogg_stream_state *os); +extern int ogg_stream_eos(ogg_stream_state *os); + +extern void ogg_page_checksum_set(ogg_page *og); + +extern int ogg_page_version(const ogg_page *og); +extern int ogg_page_continued(const ogg_page *og); +extern int ogg_page_bos(const ogg_page *og); +extern int ogg_page_eos(const ogg_page *og); +extern ogg_int64_t ogg_page_granulepos(const ogg_page *og); +extern int ogg_page_serialno(const ogg_page *og); +extern long ogg_page_pageno(const ogg_page *og); +extern int ogg_page_packets(const ogg_page *og); + +extern void ogg_packet_clear(ogg_packet *op); + + +#ifdef __cplusplus +} +#endif + +#endif /* _OGG_H */ diff --git a/include/ogg/os_types.h b/include/ogg/os_types.h new file mode 100644 index 00000000..f6f8b381 --- /dev/null +++ b/include/ogg/os_types.h @@ -0,0 +1,148 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + last mod: $Id: os_types.h 16649 2009-10-25 00:49:58Z ds $ + + ********************************************************************/ +#ifndef _OS_TYPES_H +#define _OS_TYPES_H + +/* make it easy on the folks that want to compile the libs with a + different malloc than stdlib */ +#define _ogg_malloc malloc +#define _ogg_calloc calloc +#define _ogg_realloc realloc +#define _ogg_free free + +#if defined(_WIN32) + +# if defined(__CYGWIN__) +# include <stdint.h> + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + typedef uint64_t ogg_uint64_t; +# elif defined(__MINGW32__) +# include <sys/types.h> + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; +# elif defined(__MWERKS__) + typedef long long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; +# else + /* MSVC/Borland */ + typedef __int64 ogg_int64_t; + typedef __int32 ogg_int32_t; + typedef unsigned __int32 ogg_uint32_t; + typedef __int16 ogg_int16_t; + typedef unsigned __int16 ogg_uint16_t; +# endif + +#elif defined(__MACOS__) + +# include <sys/types.h> + typedef SInt16 ogg_int16_t; + typedef UInt16 ogg_uint16_t; + typedef SInt32 ogg_int32_t; + typedef UInt32 ogg_uint32_t; + typedef SInt64 ogg_int64_t; + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include <sys/types.h> + typedef int16_t ogg_int16_t; + typedef u_int16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef u_int32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined(__HAIKU__) + + /* Haiku */ +# include <sys/types.h> + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined(__BEOS__) + + /* Be */ +# include <inttypes.h> + typedef int16_t ogg_int16_t; + typedef u_int16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef u_int32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short ogg_int16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined(R5900) + + /* PS2 EE */ + typedef long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned ogg_uint32_t; + typedef short ogg_int16_t; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + +#elif defined(__TMS320C6X__) + + /* TI C64x compiler */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + +#else + +# include <sys/types.h> +# include <ogg/config_types.h> + +#endif + +#endif /* _OS_TYPES_H */ diff --git a/include/samplerate.h b/include/samplerate.h new file mode 100644 index 00000000..9651e635 --- /dev/null +++ b/include/samplerate.h @@ -0,0 +1,197 @@ +/* +** Copyright (C) 2002-2008 Erik de Castro Lopo <erikd@mega-nerd.com> +** +** 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. +*/ + +/* +** This code is part of Secret Rabibt Code aka libsamplerate. A commercial +** use license for this code is available, please see: +** http://www.mega-nerd.com/SRC/procedure.html +*/ + +/* +** API documentation is available here: +** http://www.mega-nerd.com/SRC/api.html +*/ + +#ifndef SAMPLERATE_H +#define SAMPLERATE_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Opaque data type SRC_STATE. */ +typedef struct SRC_STATE_tag SRC_STATE ; + +/* SRC_DATA is used to pass data to src_simple() and src_process(). */ +typedef struct +{ float *data_in, *data_out ; + + long input_frames, output_frames ; + long input_frames_used, output_frames_gen ; + + int end_of_input ; + + double src_ratio ; +} SRC_DATA ; + +/* SRC_CB_DATA is used with callback based API. */ +typedef struct +{ long frames ; + float *data_in ; +} SRC_CB_DATA ; + +/* +** User supplied callback function type for use with src_callback_new() +** and src_callback_read(). First parameter is the same pointer that was +** passed into src_callback_new(). Second parameter is pointer to a +** pointer. The user supplied callback function must modify *data to +** point to the start of the user supplied float array. The user supplied +** function must return the number of frames that **data points to. +*/ + +typedef long (*src_callback_t) (void *cb_data, float **data) ; + +/* +** Standard initialisation function : return an anonymous pointer to the +** internal state of the converter. Choose a converter from the enums below. +** Error returned in *error. +*/ + +SRC_STATE* src_new (int converter_type, int channels, int *error) ; + +/* +** Initilisation for callback based API : return an anonymous pointer to the +** internal state of the converter. Choose a converter from the enums below. +** The cb_data pointer can point to any data or be set to NULL. Whatever the +** value, when processing, user supplied function "func" gets called with +** cb_data as first parameter. +*/ + +SRC_STATE* src_callback_new (src_callback_t func, int converter_type, int channels, + int *error, void* cb_data) ; + +/* +** Cleanup all internal allocations. +** Always returns NULL. +*/ + +SRC_STATE* src_delete (SRC_STATE *state) ; + +/* +** Standard processing function. +** Returns non zero on error. +*/ + +int src_process (SRC_STATE *state, SRC_DATA *data) ; + +/* +** Callback based processing function. Read up to frames worth of data from +** the converter int *data and return frames read or -1 on error. +*/ +long src_callback_read (SRC_STATE *state, double src_ratio, long frames, float *data) ; + +/* +** Simple interface for performing a single conversion from input buffer to +** output buffer at a fixed conversion ratio. +** Simple interface does not require initialisation as it can only operate on +** a single buffer worth of audio. +*/ + +int src_simple (SRC_DATA *data, int converter_type, int channels) ; + +/* +** This library contains a number of different sample rate converters, +** numbered 0 through N. +** +** Return a string giving either a name or a more full description of each +** sample rate converter or NULL if no sample rate converter exists for +** the given value. The converters are sequentially numbered from 0 to N. +*/ + +const char *src_get_name (int converter_type) ; +const char *src_get_description (int converter_type) ; +const char *src_get_version (void) ; + +/* +** Set a new SRC ratio. This allows step responses +** in the conversion ratio. +** Returns non zero on error. +*/ + +int src_set_ratio (SRC_STATE *state, double new_ratio) ; + +/* +** Reset the internal SRC state. +** Does not modify the quality settings. +** Does not free any memory allocations. +** Returns non zero on error. +*/ + +int src_reset (SRC_STATE *state) ; + +/* +** Return TRUE if ratio is a valid conversion ratio, FALSE +** otherwise. +*/ + +int src_is_valid_ratio (double ratio) ; + +/* +** Return an error number. +*/ + +int src_error (SRC_STATE *state) ; + +/* +** Convert the error number into a string. +*/ +const char* src_strerror (int error) ; + +/* +** The following enums can be used to set the interpolator type +** using the function src_set_converter(). +*/ + +enum +{ + SRC_SINC_BEST_QUALITY = 0, + SRC_SINC_MEDIUM_QUALITY = 1, + SRC_SINC_FASTEST = 2, + SRC_ZERO_ORDER_HOLD = 3, + SRC_LINEAR = 4, +} ; + +/* +** Extra helper functions for converting from short to float and +** back again. +*/ + +void src_short_to_float_array (const short *in, float *out, int len) ; +void src_float_to_short_array (const float *in, short *out, int len) ; + +void src_int_to_float_array (const int *in, float *out, int len) ; +void src_float_to_int_array (const float *in, int *out, int len) ; + + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* SAMPLERATE_H */ + diff --git a/include/sndfile.h b/include/sndfile.h new file mode 100644 index 00000000..1b7e1f99 --- /dev/null +++ b/include/sndfile.h @@ -0,0 +1,665 @@ +/* +** Copyright (C) 1999-2010 Erik de Castro Lopo <erikd@mega-nerd.com> +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU Lesser General Public License as published by +** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. +** +** You should have received a copy of the GNU Lesser 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. +*/ + +/* +** sndfile.h -- system-wide definitions +** +** API documentation is in the doc/ directory of the source code tarball +** and at http://www.mega-nerd.com/libsndfile/api.html. +*/ + +#ifndef SNDFILE_H +#define SNDFILE_H + +/* This is the version 1.0.X header file. */ +#define SNDFILE_1 + +#include <stdio.h> +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* The following file types can be read and written. +** A file type would consist of a major type (ie SF_FORMAT_WAV) bitwise +** ORed with a minor type (ie SF_FORMAT_PCM). SF_FORMAT_TYPEMASK and +** SF_FORMAT_SUBMASK can be used to separate the major and minor file +** types. +*/ + +enum +{ /* Major formats. */ + SF_FORMAT_WAV = 0x010000, /* Microsoft WAV format (little endian default). */ + SF_FORMAT_AIFF = 0x020000, /* Apple/SGI AIFF format (big endian). */ + SF_FORMAT_AU = 0x030000, /* Sun/NeXT AU format (big endian). */ + SF_FORMAT_RAW = 0x040000, /* RAW PCM data. */ + SF_FORMAT_PAF = 0x050000, /* Ensoniq PARIS file format. */ + SF_FORMAT_SVX = 0x060000, /* Amiga IFF / SVX8 / SV16 format. */ + SF_FORMAT_NIST = 0x070000, /* Sphere NIST format. */ + SF_FORMAT_VOC = 0x080000, /* VOC files. */ + SF_FORMAT_IRCAM = 0x0A0000, /* Berkeley/IRCAM/CARL */ + SF_FORMAT_W64 = 0x0B0000, /* Sonic Foundry's 64 bit RIFF/WAV */ + SF_FORMAT_MAT4 = 0x0C0000, /* Matlab (tm) V4.2 / GNU Octave 2.0 */ + SF_FORMAT_MAT5 = 0x0D0000, /* Matlab (tm) V5.0 / GNU Octave 2.1 */ + SF_FORMAT_PVF = 0x0E0000, /* Portable Voice Format */ + SF_FORMAT_XI = 0x0F0000, /* Fasttracker 2 Extended Instrument */ + SF_FORMAT_HTK = 0x100000, /* HMM Tool Kit format */ + SF_FORMAT_SDS = 0x110000, /* Midi Sample Dump Standard */ + SF_FORMAT_AVR = 0x120000, /* Audio Visual Research */ + SF_FORMAT_WAVEX = 0x130000, /* MS WAVE with WAVEFORMATEX */ + SF_FORMAT_SD2 = 0x160000, /* Sound Designer 2 */ + SF_FORMAT_FLAC = 0x170000, /* FLAC lossless file format */ + SF_FORMAT_CAF = 0x180000, /* Core Audio File format */ + SF_FORMAT_WVE = 0x190000, /* Psion WVE format */ + SF_FORMAT_OGG = 0x200000, /* Xiph OGG container */ + SF_FORMAT_MPC2K = 0x210000, /* Akai MPC 2000 sampler */ + SF_FORMAT_RF64 = 0x220000, /* RF64 WAV file */ + + /* Subtypes from here on. */ + + SF_FORMAT_PCM_S8 = 0x0001, /* Signed 8 bit data */ + SF_FORMAT_PCM_16 = 0x0002, /* Signed 16 bit data */ + SF_FORMAT_PCM_24 = 0x0003, /* Signed 24 bit data */ + SF_FORMAT_PCM_32 = 0x0004, /* Signed 32 bit data */ + + SF_FORMAT_PCM_U8 = 0x0005, /* Unsigned 8 bit data (WAV and RAW only) */ + + SF_FORMAT_FLOAT = 0x0006, /* 32 bit float data */ + SF_FORMAT_DOUBLE = 0x0007, /* 64 bit float data */ + + SF_FORMAT_ULAW = 0x0010, /* U-Law encoded. */ + SF_FORMAT_ALAW = 0x0011, /* A-Law encoded. */ + SF_FORMAT_IMA_ADPCM = 0x0012, /* IMA ADPCM. */ + SF_FORMAT_MS_ADPCM = 0x0013, /* Microsoft ADPCM. */ + + SF_FORMAT_GSM610 = 0x0020, /* GSM 6.10 encoding. */ + SF_FORMAT_VOX_ADPCM = 0x0021, /* OKI / Dialogix ADPCM */ + + SF_FORMAT_G721_32 = 0x0030, /* 32kbs G721 ADPCM encoding. */ + SF_FORMAT_G723_24 = 0x0031, /* 24kbs G723 ADPCM encoding. */ + SF_FORMAT_G723_40 = 0x0032, /* 40kbs G723 ADPCM encoding. */ + + SF_FORMAT_DWVW_12 = 0x0040, /* 12 bit Delta Width Variable Word encoding. */ + SF_FORMAT_DWVW_16 = 0x0041, /* 16 bit Delta Width Variable Word encoding. */ + SF_FORMAT_DWVW_24 = 0x0042, /* 24 bit Delta Width Variable Word encoding. */ + SF_FORMAT_DWVW_N = 0x0043, /* N bit Delta Width Variable Word encoding. */ + + SF_FORMAT_DPCM_8 = 0x0050, /* 8 bit differential PCM (XI only) */ + SF_FORMAT_DPCM_16 = 0x0051, /* 16 bit differential PCM (XI only) */ + + SF_FORMAT_VORBIS = 0x0060, /* Xiph Vorbis encoding. */ + + /* Endian-ness options. */ + + SF_ENDIAN_FILE = 0x00000000, /* Default file endian-ness. */ + SF_ENDIAN_LITTLE = 0x10000000, /* Force little endian-ness. */ + SF_ENDIAN_BIG = 0x20000000, /* Force big endian-ness. */ + SF_ENDIAN_CPU = 0x30000000, /* Force CPU endian-ness. */ + + SF_FORMAT_SUBMASK = 0x0000FFFF, + SF_FORMAT_TYPEMASK = 0x0FFF0000, + SF_FORMAT_ENDMASK = 0x30000000 +} ; + +/* +** The following are the valid command numbers for the sf_command() +** interface. The use of these commands is documented in the file +** command.html in the doc directory of the source code distribution. +*/ + +enum +{ SFC_GET_LIB_VERSION = 0x1000, + SFC_GET_LOG_INFO = 0x1001, + SFC_GET_CURRENT_SF_INFO = 0x1002, + + + SFC_GET_NORM_DOUBLE = 0x1010, + SFC_GET_NORM_FLOAT = 0x1011, + SFC_SET_NORM_DOUBLE = 0x1012, + SFC_SET_NORM_FLOAT = 0x1013, + SFC_SET_SCALE_FLOAT_INT_READ = 0x1014, + SFC_SET_SCALE_INT_FLOAT_WRITE = 0x1015, + + SFC_GET_SIMPLE_FORMAT_COUNT = 0x1020, + SFC_GET_SIMPLE_FORMAT = 0x1021, + + SFC_GET_FORMAT_INFO = 0x1028, + + SFC_GET_FORMAT_MAJOR_COUNT = 0x1030, + SFC_GET_FORMAT_MAJOR = 0x1031, + SFC_GET_FORMAT_SUBTYPE_COUNT = 0x1032, + SFC_GET_FORMAT_SUBTYPE = 0x1033, + + SFC_CALC_SIGNAL_MAX = 0x1040, + SFC_CALC_NORM_SIGNAL_MAX = 0x1041, + SFC_CALC_MAX_ALL_CHANNELS = 0x1042, + SFC_CALC_NORM_MAX_ALL_CHANNELS = 0x1043, + SFC_GET_SIGNAL_MAX = 0x1044, + SFC_GET_MAX_ALL_CHANNELS = 0x1045, + + SFC_SET_ADD_PEAK_CHUNK = 0x1050, + SFC_SET_ADD_HEADER_PAD_CHUNK = 0x1051, + + SFC_UPDATE_HEADER_NOW = 0x1060, + SFC_SET_UPDATE_HEADER_AUTO = 0x1061, + + SFC_FILE_TRUNCATE = 0x1080, + + SFC_SET_RAW_START_OFFSET = 0x1090, + + SFC_SET_DITHER_ON_WRITE = 0x10A0, + SFC_SET_DITHER_ON_READ = 0x10A1, + + SFC_GET_DITHER_INFO_COUNT = 0x10A2, + SFC_GET_DITHER_INFO = 0x10A3, + + SFC_GET_EMBED_FILE_INFO = 0x10B0, + + SFC_SET_CLIPPING = 0x10C0, + SFC_GET_CLIPPING = 0x10C1, + + SFC_GET_INSTRUMENT = 0x10D0, + SFC_SET_INSTRUMENT = 0x10D1, + + SFC_GET_LOOP_INFO = 0x10E0, + + SFC_GET_BROADCAST_INFO = 0x10F0, + SFC_SET_BROADCAST_INFO = 0x10F1, + + SFC_GET_CHANNEL_MAP_INFO = 0x1100, + SFC_SET_CHANNEL_MAP_INFO = 0x1101, + + SFC_RAW_DATA_NEEDS_ENDSWAP = 0x1110, + + /* Support for Wavex Ambisonics Format */ + SFC_WAVEX_SET_AMBISONIC = 0x1200, + SFC_WAVEX_GET_AMBISONIC = 0x1201, + + SFC_SET_VBR_ENCODING_QUALITY = 0x1300, + + /* Following commands for testing only. */ + SFC_TEST_IEEE_FLOAT_REPLACE = 0x6001, + + /* + ** SFC_SET_ADD_* values are deprecated and will disappear at some + ** time in the future. They are guaranteed to be here up to and + ** including version 1.0.8 to avoid breakage of existng software. + ** They currently do nothing and will continue to do nothing. + */ + SFC_SET_ADD_DITHER_ON_WRITE = 0x1070, + SFC_SET_ADD_DITHER_ON_READ = 0x1071 +} ; + + +/* +** String types that can be set and read from files. Not all file types +** support this and even the file types which support one, may not support +** all string types. +*/ + +enum +{ SF_STR_TITLE = 0x01, + SF_STR_COPYRIGHT = 0x02, + SF_STR_SOFTWARE = 0x03, + SF_STR_ARTIST = 0x04, + SF_STR_COMMENT = 0x05, + SF_STR_DATE = 0x06, + SF_STR_ALBUM = 0x07, + SF_STR_LICENSE = 0x08, + SF_STR_TRACKNUMBER = 0x09, + SF_STR_GENRE = 0x10 +} ; + +/* +** Use the following as the start and end index when doing metadata +** transcoding. +*/ + +#define SF_STR_FIRST SF_STR_TITLE +#define SF_STR_LAST SF_STR_LICENSE + +enum +{ /* True and false */ + SF_FALSE = 0, + SF_TRUE = 1, + + /* Modes for opening files. */ + SFM_READ = 0x10, + SFM_WRITE = 0x20, + SFM_RDWR = 0x30, + + SF_AMBISONIC_NONE = 0x40, + SF_AMBISONIC_B_FORMAT = 0x41 +} ; + +/* Public error values. These are guaranteed to remain unchanged for the duration +** of the library major version number. +** There are also a large number of private error numbers which are internal to +** the library which can change at any time. +*/ + +enum +{ SF_ERR_NO_ERROR = 0, + SF_ERR_UNRECOGNISED_FORMAT = 1, + SF_ERR_SYSTEM = 2, + SF_ERR_MALFORMED_FILE = 3, + SF_ERR_UNSUPPORTED_ENCODING = 4 +} ; + + +/* Channel map values (used with SFC_SET/GET_CHANNEL_MAP). +*/ + +enum +{ SF_CHANNEL_MAP_INVALID = 0, + SF_CHANNEL_MAP_MONO = 1, + SF_CHANNEL_MAP_LEFT, /* Apple calls this 'Left' */ + SF_CHANNEL_MAP_RIGHT, /* Apple calls this 'Right' */ + SF_CHANNEL_MAP_CENTER, /* Apple calls this 'Center' */ + SF_CHANNEL_MAP_FRONT_LEFT, + SF_CHANNEL_MAP_FRONT_RIGHT, + SF_CHANNEL_MAP_FRONT_CENTER, + SF_CHANNEL_MAP_REAR_CENTER, /* Apple calls this 'Center Surround', Msft calls this 'Back Center' */ + SF_CHANNEL_MAP_REAR_LEFT, /* Apple calls this 'Left Surround', Msft calls this 'Back Left' */ + SF_CHANNEL_MAP_REAR_RIGHT, /* Apple calls this 'Right Surround', Msft calls this 'Back Right' */ + SF_CHANNEL_MAP_LFE, /* Apple calls this 'LFEScreen', Msft calls this 'Low Frequency' */ + SF_CHANNEL_MAP_FRONT_LEFT_OF_CENTER, /* Apple calls this 'Left Center' */ + SF_CHANNEL_MAP_FRONT_RIGHT_OF_CENTER, /* Apple calls this 'Right Center */ + SF_CHANNEL_MAP_SIDE_LEFT, /* Apple calls this 'Left Surround Direct' */ + SF_CHANNEL_MAP_SIDE_RIGHT, /* Apple calls this 'Right Surround Direct' */ + SF_CHANNEL_MAP_TOP_CENTER, /* Apple calls this 'Top Center Surround' */ + SF_CHANNEL_MAP_TOP_FRONT_LEFT, /* Apple calls this 'Vertical Height Left' */ + SF_CHANNEL_MAP_TOP_FRONT_RIGHT, /* Apple calls this 'Vertical Height Right' */ + SF_CHANNEL_MAP_TOP_FRONT_CENTER, /* Apple calls this 'Vertical Height Center' */ + SF_CHANNEL_MAP_TOP_REAR_LEFT, /* Apple and MS call this 'Top Back Left' */ + SF_CHANNEL_MAP_TOP_REAR_RIGHT, /* Apple and MS call this 'Top Back Right' */ + SF_CHANNEL_MAP_TOP_REAR_CENTER, /* Apple and MS call this 'Top Back Center' */ + + SF_CHANNEL_MAP_AMBISONIC_B_W, + SF_CHANNEL_MAP_AMBISONIC_B_X, + SF_CHANNEL_MAP_AMBISONIC_B_Y, + SF_CHANNEL_MAP_AMBISONIC_B_Z, + + SF_CHANNEL_MAP_MAX +} ; + + +/* A SNDFILE* pointer can be passed around much like stdio.h's FILE* pointer. */ + +typedef struct SNDFILE_tag SNDFILE ; + +/* The following typedef is system specific and is defined when libsndfile is +** compiled. sf_count_t can be one of loff_t (Linux), off_t (*BSD), off64_t +** (Solaris), __int64 (Win32) etc. On windows, we need to allow the same +** header file to be compiler by both GCC and the microsoft compiler. +*/ + +#if (defined (_MSCVER) || defined (_MSC_VER)) +typedef __int64 sf_count_t ; +#define SF_COUNT_MAX 0x7fffffffffffffffi64 +#else +typedef loff_t sf_count_t ; +#define SF_COUNT_MAX 0x7FFFFFFFFFFFFFFFLL +#endif + + +/* A pointer to a SF_INFO structure is passed to sf_open () and filled in. +** On write, the SF_INFO structure is filled in by the user and passed into +** sf_open (). +*/ + +struct SF_INFO +{ sf_count_t frames ; /* Used to be called samples. Changed to avoid confusion. */ + int samplerate ; + int channels ; + int format ; + int sections ; + int seekable ; +} ; + +typedef struct SF_INFO SF_INFO ; + +/* The SF_FORMAT_INFO struct is used to retrieve information about the sound +** file formats libsndfile supports using the sf_command () interface. +** +** Using this interface will allow applications to support new file formats +** and encoding types when libsndfile is upgraded, without requiring +** re-compilation of the application. +** +** Please consult the libsndfile documentation (particularly the information +** on the sf_command () interface) for examples of its use. +*/ + +typedef struct +{ int format ; + const char *name ; + const char *extension ; +} SF_FORMAT_INFO ; + +/* +** Enums and typedefs for adding dither on read and write. +** See the html documentation for sf_command(), SFC_SET_DITHER_ON_WRITE +** and SFC_SET_DITHER_ON_READ. +*/ + +enum +{ SFD_DEFAULT_LEVEL = 0, + SFD_CUSTOM_LEVEL = 0x40000000, + + SFD_NO_DITHER = 500, + SFD_WHITE = 501, + SFD_TRIANGULAR_PDF = 502 +} ; + +typedef struct +{ int type ; + double level ; + const char *name ; +} SF_DITHER_INFO ; + +/* Struct used to retrieve information about a file embedded within a +** larger file. See SFC_GET_EMBED_FILE_INFO. +*/ + +typedef struct +{ sf_count_t offset ; + sf_count_t length ; +} SF_EMBED_FILE_INFO ; + +/* +** Structs used to retrieve music sample information from a file. +*/ + +enum +{ /* + ** The loop mode field in SF_INSTRUMENT will be one of the following. + */ + SF_LOOP_NONE = 800, + SF_LOOP_FORWARD, + SF_LOOP_BACKWARD, + SF_LOOP_ALTERNATING +} ; + +typedef struct +{ int gain ; + char basenote, detune ; + char velocity_lo, velocity_hi ; + char key_lo, key_hi ; + int loop_count ; + + struct + { int mode ; + unsigned int start ; + unsigned int end ; + unsigned int count ; + } loops [16] ; /* make variable in a sensible way */ +} SF_INSTRUMENT ; + + + +/* Struct used to retrieve loop information from a file.*/ +typedef struct +{ + short time_sig_num ; /* any positive integer > 0 */ + short time_sig_den ; /* any positive power of 2 > 0 */ + int loop_mode ; /* see SF_LOOP enum */ + + int num_beats ; /* this is NOT the amount of quarter notes !!!*/ + /* a full bar of 4/4 is 4 beats */ + /* a full bar of 7/8 is 7 beats */ + + float bpm ; /* suggestion, as it can be calculated using other fields:*/ + /* file's lenght, file's sampleRate and our time_sig_den*/ + /* -> bpms are always the amount of _quarter notes_ per minute */ + + int root_key ; /* MIDI note, or -1 for None */ + int future [6] ; +} SF_LOOP_INFO ; + + +/* Struct used to retrieve broadcast (EBU) information from a file. +** Strongly (!) based on EBU "bext" chunk format used in Broadcast WAVE. +*/ +#define SF_BROADCAST_INFO_VAR(coding_hist_size) \ + struct \ + { char description [256] ; \ + char originator [32] ; \ + char originator_reference [32] ; \ + char origination_date [10] ; \ + char origination_time [8] ; \ + unsigned int time_reference_low ; \ + unsigned int time_reference_high ; \ + short version ; \ + char umid [64] ; \ + char reserved [190] ; \ + unsigned int coding_history_size ; \ + char coding_history [coding_hist_size] ; \ + } + +/* SF_BROADCAST_INFO is the above struct with coding_history field of 256 bytes. */ +typedef SF_BROADCAST_INFO_VAR (256) SF_BROADCAST_INFO ; + + +/* Virtual I/O functionality. */ + +typedef sf_count_t (*sf_vio_get_filelen) (void *user_data) ; +typedef sf_count_t (*sf_vio_seek) (sf_count_t offset, int whence, void *user_data) ; +typedef sf_count_t (*sf_vio_read) (void *ptr, sf_count_t count, void *user_data) ; +typedef sf_count_t (*sf_vio_write) (const void *ptr, sf_count_t count, void *user_data) ; +typedef sf_count_t (*sf_vio_tell) (void *user_data) ; + +struct SF_VIRTUAL_IO +{ sf_vio_get_filelen get_filelen ; + sf_vio_seek seek ; + sf_vio_read read ; + sf_vio_write write ; + sf_vio_tell tell ; +} ; + +typedef struct SF_VIRTUAL_IO SF_VIRTUAL_IO ; + + +/* Open the specified file for read, write or both. On error, this will +** return a NULL pointer. To find the error number, pass a NULL SNDFILE +** to sf_strerror (). +** All calls to sf_open() should be matched with a call to sf_close(). +*/ + +SNDFILE* sf_open (const char *path, int mode, SF_INFO *sfinfo) ; + + +/* Use the existing file descriptor to create a SNDFILE object. If close_desc +** is TRUE, the file descriptor will be closed when sf_close() is called. If +** it is FALSE, the descritor will not be closed. +** When passed a descriptor like this, the library will assume that the start +** of file header is at the current file offset. This allows sound files within +** larger container files to be read and/or written. +** On error, this will return a NULL pointer. To find the error number, pass a +** NULL SNDFILE to sf_strerror (). +** All calls to sf_open_fd() should be matched with a call to sf_close(). + +*/ + +SNDFILE* sf_open_fd (int fd, int mode, SF_INFO *sfinfo, int close_desc) ; + +SNDFILE* sf_open_virtual (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data) ; + + +/* sf_error () returns a error number which can be translated to a text +** string using sf_error_number(). +*/ + +int sf_error (SNDFILE *sndfile) ; + + +/* sf_strerror () returns to the caller a pointer to the current error message for +** the given SNDFILE. +*/ + +const char* sf_strerror (SNDFILE *sndfile) ; + + +/* sf_error_number () allows the retrieval of the error string for each internal +** error number. +** +*/ + +const char* sf_error_number (int errnum) ; + + +/* The following two error functions are deprecated but they will remain in the +** library for the forseeable future. The function sf_strerror() should be used +** in their place. +*/ + +int sf_perror (SNDFILE *sndfile) ; +int sf_error_str (SNDFILE *sndfile, char* str, size_t len) ; + + +/* Return TRUE if fields of the SF_INFO struct are a valid combination of values. */ + +int sf_command (SNDFILE *sndfile, int command, void *data, int datasize) ; + + +/* Return TRUE if fields of the SF_INFO struct are a valid combination of values. */ + +int sf_format_check (const SF_INFO *info) ; + + +/* Seek within the waveform data chunk of the SNDFILE. sf_seek () uses +** the same values for whence (SEEK_SET, SEEK_CUR and SEEK_END) as +** stdio.h function fseek (). +** An offset of zero with whence set to SEEK_SET will position the +** read / write pointer to the first data sample. +** On success sf_seek returns the current position in (multi-channel) +** samples from the start of the file. +** Please see the libsndfile documentation for moving the read pointer +** separately from the write pointer on files open in mode SFM_RDWR. +** On error all of these functions return -1. +*/ + +sf_count_t sf_seek (SNDFILE *sndfile, sf_count_t frames, int whence) ; + + +/* Functions for retrieving and setting string data within sound files. +** Not all file types support this features; AIFF and WAV do. For both +** functions, the str_type parameter must be one of the SF_STR_* values +** defined above. +** On error, sf_set_string() returns non-zero while sf_get_string() +** returns NULL. +*/ + +int sf_set_string (SNDFILE *sndfile, int str_type, const char* str) ; + +const char* sf_get_string (SNDFILE *sndfile, int str_type) ; + + +/* Return the library version string. */ + +const char * sf_version_string (void) ; + + +/* Functions for reading/writing the waveform data of a sound file. +*/ + +sf_count_t sf_read_raw (SNDFILE *sndfile, void *ptr, sf_count_t bytes) ; +sf_count_t sf_write_raw (SNDFILE *sndfile, const void *ptr, sf_count_t bytes) ; + + +/* Functions for reading and writing the data chunk in terms of frames. +** The number of items actually read/written = frames * number of channels. +** sf_xxxx_raw read/writes the raw data bytes from/to the file +** sf_xxxx_short passes data in the native short format +** sf_xxxx_int passes data in the native int format +** sf_xxxx_float passes data in the native float format +** sf_xxxx_double passes data in the native double format +** All of these read/write function return number of frames read/written. +*/ + +sf_count_t sf_readf_short (SNDFILE *sndfile, short *ptr, sf_count_t frames) ; +sf_count_t sf_writef_short (SNDFILE *sndfile, const short *ptr, sf_count_t frames) ; + +sf_count_t sf_readf_int (SNDFILE *sndfile, int *ptr, sf_count_t frames) ; +sf_count_t sf_writef_int (SNDFILE *sndfile, const int *ptr, sf_count_t frames) ; + +sf_count_t sf_readf_float (SNDFILE *sndfile, float *ptr, sf_count_t frames) ; +sf_count_t sf_writef_float (SNDFILE *sndfile, const float *ptr, sf_count_t frames) ; + +sf_count_t sf_readf_double (SNDFILE *sndfile, double *ptr, sf_count_t frames) ; +sf_count_t sf_writef_double (SNDFILE *sndfile, const double *ptr, sf_count_t frames) ; + + +/* Functions for reading and writing the data chunk in terms of items. +** Otherwise similar to above. +** All of these read/write function return number of items read/written. +*/ + +sf_count_t sf_read_short (SNDFILE *sndfile, short *ptr, sf_count_t items) ; +sf_count_t sf_write_short (SNDFILE *sndfile, const short *ptr, sf_count_t items) ; + +sf_count_t sf_read_int (SNDFILE *sndfile, int *ptr, sf_count_t items) ; +sf_count_t sf_write_int (SNDFILE *sndfile, const int *ptr, sf_count_t items) ; + +sf_count_t sf_read_float (SNDFILE *sndfile, float *ptr, sf_count_t items) ; +sf_count_t sf_write_float (SNDFILE *sndfile, const float *ptr, sf_count_t items) ; + +sf_count_t sf_read_double (SNDFILE *sndfile, double *ptr, sf_count_t items) ; +sf_count_t sf_write_double (SNDFILE *sndfile, const double *ptr, sf_count_t items) ; + + +/* Close the SNDFILE and clean up all memory allocations associated with this +** file. +** Returns 0 on success, or an error number. +*/ + +int sf_close (SNDFILE *sndfile) ; + + +/* If the file is opened SFM_WRITE or SFM_RDWR, call fsync() on the file +** to force the writing of data to disk. If the file is opened SFM_READ +** no action is taken. +*/ + +void sf_write_sync (SNDFILE *sndfile) ; + + + +/* The function sf_wchar_open() is Windows Only! +** Open a file passing in a Windows Unicode filename. Otherwise, this is +** the same as sf_open(). +** +** In order for this to work, you need to do the following: +** +** #include <windows.h> +** #define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1 +** #including <sndfile.h> +*/ + +#if ENABLE_SNDFILE_WINDOWS_PROTOTYPES +SNDFILE* sf_wchar_open (LPCWSTR wpath, int mode, SF_INFO *sfinfo) ; +#endif + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* SNDFILE_H */ + diff --git a/include/vorbis/Makefile.am b/include/vorbis/Makefile.am new file mode 100644 index 00000000..dbba34e5 --- /dev/null +++ b/include/vorbis/Makefile.am @@ -0,0 +1,7 @@ +## Process this file with automake to produce Makefile.in + +vorbisincludedir = $(includedir)/vorbis + +vorbisinclude_HEADERS = codec.h vorbisfile.h vorbisenc.h + + diff --git a/include/vorbis/codec.h b/include/vorbis/codec.h new file mode 100644 index 00000000..999aa335 --- /dev/null +++ b/include/vorbis/codec.h @@ -0,0 +1,243 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + + ******************************************************************** + + function: libvorbis codec headers + last mod: $Id: codec.h 17021 2010-03-24 09:29:41Z xiphmont $ + + ********************************************************************/ + +#ifndef _vorbis_codec_h_ +#define _vorbis_codec_h_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include <ogg/ogg.h> + +typedef struct vorbis_info{ + int version; + int channels; + long rate; + + /* The below bitrate declarations are *hints*. + Combinations of the three values carry the following implications: + + all three set to the same value: + implies a fixed rate bitstream + only nominal set: + implies a VBR stream that averages the nominal bitrate. No hard + upper/lower limit + upper and or lower set: + implies a VBR bitstream that obeys the bitrate limits. nominal + may also be set to give a nominal rate. + none set: + the coder does not care to speculate. + */ + + long bitrate_upper; + long bitrate_nominal; + long bitrate_lower; + long bitrate_window; + + void *codec_setup; +} vorbis_info; + +/* vorbis_dsp_state buffers the current vorbis audio + analysis/synthesis state. The DSP state belongs to a specific + logical bitstream ****************************************************/ +typedef struct vorbis_dsp_state{ + int analysisp; + vorbis_info *vi; + + float **pcm; + float **pcmret; + int pcm_storage; + int pcm_current; + int pcm_returned; + + int preextrapolate; + int eofflag; + + long lW; + long W; + long nW; + long centerW; + + ogg_int64_t granulepos; + ogg_int64_t sequence; + + ogg_int64_t glue_bits; + ogg_int64_t time_bits; + ogg_int64_t floor_bits; + ogg_int64_t res_bits; + + void *backend_state; +} vorbis_dsp_state; + +typedef struct vorbis_block{ + /* necessary stream state for linking to the framing abstraction */ + float **pcm; /* this is a pointer into local storage */ + oggpack_buffer opb; + + long lW; + long W; + long nW; + int pcmend; + int mode; + + int eofflag; + ogg_int64_t granulepos; + ogg_int64_t sequence; + vorbis_dsp_state *vd; /* For read-only access of configuration */ + + /* local storage to avoid remallocing; it's up to the mapping to + structure it */ + void *localstore; + long localtop; + long localalloc; + long totaluse; + struct alloc_chain *reap; + + /* bitmetrics for the frame */ + long glue_bits; + long time_bits; + long floor_bits; + long res_bits; + + void *internal; + +} vorbis_block; + +/* vorbis_block is a single block of data to be processed as part of +the analysis/synthesis stream; it belongs to a specific logical +bitstream, but is independent from other vorbis_blocks belonging to +that logical bitstream. *************************************************/ + +struct alloc_chain{ + void *ptr; + struct alloc_chain *next; +}; + +/* vorbis_info contains all the setup information specific to the + specific compression/decompression mode in progress (eg, + psychoacoustic settings, channel setup, options, codebook + etc). vorbis_info and substructures are in backends.h. +*********************************************************************/ + +/* the comments are not part of vorbis_info so that vorbis_info can be + static storage */ +typedef struct vorbis_comment{ + /* unlimited user comment fields. libvorbis writes 'libvorbis' + whatever vendor is set to in encode */ + char **user_comments; + int *comment_lengths; + int comments; + char *vendor; + +} vorbis_comment; + + +/* libvorbis encodes in two abstraction layers; first we perform DSP + and produce a packet (see docs/analysis.txt). The packet is then + coded into a framed OggSquish bitstream by the second layer (see + docs/framing.txt). Decode is the reverse process; we sync/frame + the bitstream and extract individual packets, then decode the + packet back into PCM audio. + + The extra framing/packetizing is used in streaming formats, such as + files. Over the net (such as with UDP), the framing and + packetization aren't necessary as they're provided by the transport + and the streaming layer is not used */ + +/* Vorbis PRIMITIVES: general ***************************************/ + +extern void vorbis_info_init(vorbis_info *vi); +extern void vorbis_info_clear(vorbis_info *vi); +extern int vorbis_info_blocksize(vorbis_info *vi,int zo); +extern void vorbis_comment_init(vorbis_comment *vc); +extern void vorbis_comment_add(vorbis_comment *vc, const char *comment); +extern void vorbis_comment_add_tag(vorbis_comment *vc, + const char *tag, const char *contents); +extern char *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count); +extern int vorbis_comment_query_count(vorbis_comment *vc, const char *tag); +extern void vorbis_comment_clear(vorbis_comment *vc); + +extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); +extern int vorbis_block_clear(vorbis_block *vb); +extern void vorbis_dsp_clear(vorbis_dsp_state *v); +extern double vorbis_granule_time(vorbis_dsp_state *v, + ogg_int64_t granulepos); + +extern const char *vorbis_version_string(void); + +/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/ + +extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op); +extern int vorbis_analysis_headerout(vorbis_dsp_state *v, + vorbis_comment *vc, + ogg_packet *op, + ogg_packet *op_comm, + ogg_packet *op_code); +extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op); + +extern int vorbis_bitrate_addblock(vorbis_block *vb); +extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, + ogg_packet *op); + +/* Vorbis PRIMITIVES: synthesis layer *******************************/ +extern int vorbis_synthesis_idheader(ogg_packet *op); +extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, + ogg_packet *op); + +extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_synthesis_restart(vorbis_dsp_state *v); +extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples); +extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); + +extern int vorbis_synthesis_halfrate(vorbis_info *v,int flag); +extern int vorbis_synthesis_halfrate_p(vorbis_info *v); + +/* Vorbis ERRORS and return codes ***********************************/ + +#define OV_FALSE -1 +#define OV_EOF -2 +#define OV_HOLE -3 + +#define OV_EREAD -128 +#define OV_EFAULT -129 +#define OV_EIMPL -130 +#define OV_EINVAL -131 +#define OV_ENOTVORBIS -132 +#define OV_EBADHEADER -133 +#define OV_EVERSION -134 +#define OV_ENOTAUDIO -135 +#define OV_EBADPACKET -136 +#define OV_EBADLINK -137 +#define OV_ENOSEEK -138 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/include/vorbis/vorbisenc.h b/include/vorbis/vorbisenc.h new file mode 100644 index 00000000..02332b50 --- /dev/null +++ b/include/vorbis/vorbisenc.h @@ -0,0 +1,436 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: vorbis encode-engine setup + last mod: $Id: vorbisenc.h 17021 2010-03-24 09:29:41Z xiphmont $ + + ********************************************************************/ + +/** \file + * Libvorbisenc is a convenient API for setting up an encoding + * environment using libvorbis. Libvorbisenc encapsulates the + * actions needed to set up the encoder properly. + */ + +#ifndef _OV_ENC_H_ +#define _OV_ENC_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "codec.h" + +/** + * This is the primary function within libvorbisenc for setting up managed + * bitrate modes. + * + * Before this function is called, the \ref vorbis_info + * struct should be initialized by using vorbis_info_init() from the libvorbis + * API. After encoding, vorbis_info_clear() should be called. + * + * The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set + * constraints for the encoded file. This function uses these settings to + * select the appropriate encoding mode and set it up. + * + * \param vi Pointer to an initialized \ref vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param max_bitrate Desired maximum bitrate (limit). -1 indicates unset. + * \param nominal_bitrate Desired average, or central, bitrate. -1 indicates unset. + * \param min_bitrate Desired minimum bitrate. -1 indicates unset. + * + * \return Zero for success, and negative values for failure. + * + * \retval 0 Success. + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with bitrate request. + */ +extern int vorbis_encode_init(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate); + +/** + * This function performs step-one of a three-step bitrate-managed encode + * setup. It functions similarly to the one-step setup performed by \ref + * vorbis_encode_init but allows an application to make further encode setup + * tweaks using \ref vorbis_encode_ctl before finally calling \ref + * vorbis_encode_setup_init to complete the setup process. + * + * Before this function is called, the \ref vorbis_info struct should be + * initialized by using vorbis_info_init() from the libvorbis API. After + * encoding, vorbis_info_clear() should be called. + * + * The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set + * constraints for the encoded file. This function uses these settings to + * select the appropriate encoding mode and set it up. + * + * \param vi Pointer to an initialized vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param max_bitrate Desired maximum bitrate (limit). -1 indicates unset. + * \param nominal_bitrate Desired average, or central, bitrate. -1 indicates unset. + * \param min_bitrate Desired minimum bitrate. -1 indicates unset. + * + * \return Zero for success, and negative for failure. + * + * \retval 0 Success + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with bitrate request. + */ +extern int vorbis_encode_setup_managed(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate); + +/** + * This function performs step-one of a three-step variable bitrate + * (quality-based) encode setup. It functions similarly to the one-step setup + * performed by \ref vorbis_encode_init_vbr() but allows an application to + * make further encode setup tweaks using \ref vorbis_encode_ctl() before + * finally calling \ref vorbis_encode_setup_init to complete the setup + * process. + * + * Before this function is called, the \ref vorbis_info struct should be + * initialized by using \ref vorbis_info_init() from the libvorbis API. After + * encoding, vorbis_info_clear() should be called. + * + * \param vi Pointer to an initialized vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param quality Desired quality level, currently from -0.1 to 1.0 (lo to hi). + * + * \return Zero for success, and negative values for failure. + * + * \retval 0 Success + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with quality level request. + */ +extern int vorbis_encode_setup_vbr(vorbis_info *vi, + long channels, + long rate, + + float quality + ); + +/** + * This is the primary function within libvorbisenc for setting up variable + * bitrate ("quality" based) modes. + * + * + * Before this function is called, the vorbis_info struct should be + * initialized by using vorbis_info_init() from the libvorbis API. After + * encoding, vorbis_info_clear() should be called. + * + * \param vi Pointer to an initialized vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param base_quality Desired quality level, currently from -0.1 to 1.0 (lo to hi). + * + * + * \return Zero for success, or a negative number for failure. + * + * \retval 0 Success + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with quality level request. + */ +extern int vorbis_encode_init_vbr(vorbis_info *vi, + long channels, + long rate, + + float base_quality + ); + +/** + * This function performs the last stage of three-step encoding setup, as + * described in the API overview under managed bitrate modes. + * + * Before this function is called, the \ref vorbis_info struct should be + * initialized by using vorbis_info_init() from the libvorbis API, one of + * \ref vorbis_encode_setup_managed() or \ref vorbis_encode_setup_vbr() called to + * initialize the high-level encoding setup, and \ref vorbis_encode_ctl() + * called if necessary to make encoding setup changes. + * vorbis_encode_setup_init() finalizes the highlevel encoding structure into + * a complete encoding setup after which the application may make no further + * setup changes. + * + * After encoding, vorbis_info_clear() should be called. + * + * \param vi Pointer to an initialized \ref vorbis_info struct. + * + * \return Zero for success, and negative values for failure. + * + * \retval 0 Success. + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * + * \retval OV_EINVAL Attempt to use vorbis_encode_setup_init() without first + * calling one of vorbis_encode_setup_managed() or vorbis_encode_setup_vbr() to + * initialize the high-level encoding setup + * + */ +extern int vorbis_encode_setup_init(vorbis_info *vi); + +/** + * This function implements a generic interface to miscellaneous encoder + * settings similar to the classic UNIX 'ioctl()' system call. Applications + * may use vorbis_encode_ctl() to query or set bitrate management or quality + * mode details by using one of several \e request arguments detailed below. + * vorbis_encode_ctl() must be called after one of + * vorbis_encode_setup_managed() or vorbis_encode_setup_vbr(). When used + * to modify settings, \ref vorbis_encode_ctl() must be called before \ref + * vorbis_encode_setup_init(). + * + * \param vi Pointer to an initialized vorbis_info struct. + * + * \param number Specifies the desired action; See \ref encctlcodes "the list + * of available requests". + * + * \param arg void * pointing to a data structure matching the request + * argument. + * + * \retval 0 Success. Any further return information (such as the result of a + * query) is placed into the storage pointed to by *arg. + * + * \retval OV_EINVAL Invalid argument, or an attempt to modify a setting after + * calling vorbis_encode_setup_init(). + * + * \retval OV_EIMPL Unimplemented or unknown request + */ +extern int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg); + +/** + * \deprecated This is a deprecated interface. Please use vorbis_encode_ctl() + * with the \ref ovectl_ratemanage2_arg struct and \ref + * OV_ECTL_RATEMANAGE2_GET and \ref OV_ECTL_RATEMANAGE2_SET calls in new code. + * + * The \ref ovectl_ratemanage_arg structure is used with vorbis_encode_ctl() + * and the \ref OV_ECTL_RATEMANAGE_GET, \ref OV_ECTL_RATEMANAGE_SET, \ref + * OV_ECTL_RATEMANAGE_AVG, \ref OV_ECTL_RATEMANAGE_HARD calls in order to + * query and modify specifics of the encoder's bitrate management + * configuration. +*/ +struct ovectl_ratemanage_arg { + int management_active; /**< nonzero if bitrate management is active*/ +/** hard lower limit (in kilobits per second) below which the stream bitrate + will never be allowed for any given bitrate_hard_window seconds of time.*/ + long bitrate_hard_min; +/** hard upper limit (in kilobits per second) above which the stream bitrate + will never be allowed for any given bitrate_hard_window seconds of time.*/ + long bitrate_hard_max; +/** the window period (in seconds) used to regulate the hard bitrate minimum + and maximum*/ + double bitrate_hard_window; +/** soft lower limit (in kilobits per second) below which the average bitrate + tracker will start nudging the bitrate higher.*/ + long bitrate_av_lo; +/** soft upper limit (in kilobits per second) above which the average bitrate + tracker will start nudging the bitrate lower.*/ + long bitrate_av_hi; +/** the window period (in seconds) used to regulate the average bitrate + minimum and maximum.*/ + double bitrate_av_window; +/** Regulates the relative centering of the average and hard windows; in + libvorbis 1.0 and 1.0.1, the hard window regulation overlapped but + followed the average window regulation. In libvorbis 1.1 a bit-reservoir + interface replaces the old windowing interface; the older windowing + interface is simulated and this field has no effect.*/ + double bitrate_av_window_center; +}; + +/** + * \name struct ovectl_ratemanage2_arg + * + * The ovectl_ratemanage2_arg structure is used with vorbis_encode_ctl() and + * the OV_ECTL_RATEMANAGE2_GET and OV_ECTL_RATEMANAGE2_SET calls in order to + * query and modify specifics of the encoder's bitrate management + * configuration. + * +*/ +struct ovectl_ratemanage2_arg { + int management_active; /**< nonzero if bitrate management is active */ +/** Lower allowed bitrate limit in kilobits per second */ + long bitrate_limit_min_kbps; +/** Upper allowed bitrate limit in kilobits per second */ + long bitrate_limit_max_kbps; + long bitrate_limit_reservoir_bits; /**<Size of the bitrate reservoir in bits */ +/** Regulates the bitrate reservoir's preferred fill level in a range from 0.0 + * to 1.0; 0.0 tries to bank bits to buffer against future bitrate spikes, 1.0 + * buffers against future sudden drops in instantaneous bitrate. Default is + * 0.1 + */ + double bitrate_limit_reservoir_bias; +/** Average bitrate setting in kilobits per second */ + long bitrate_average_kbps; +/** Slew rate limit setting for average bitrate adjustment; sets the minimum + * time in seconds the bitrate tracker may swing from one extreme to the + * other when boosting or damping average bitrate. + */ + double bitrate_average_damping; +}; + + +/** + * \name vorbis_encode_ctl() codes + * + * \anchor encctlcodes + * + * These values are passed as the \c number parameter of vorbis_encode_ctl(). + * The type of the referent of that function's \c arg pointer depends on these + * codes. + */ +/*@{*/ + +/** + * Query the current encoder bitrate management setting. + * + *Argument: <tt>struct ovectl_ratemanage2_arg *</tt> + * + * Used to query the current encoder bitrate management setting. Also used to + * initialize fields of an ovectl_ratemanage2_arg structure for use with + * \ref OV_ECTL_RATEMANAGE2_SET. + */ +#define OV_ECTL_RATEMANAGE2_GET 0x14 + +/** + * Set the current encoder bitrate management settings. + * + * Argument: <tt>struct ovectl_ratemanage2_arg *</tt> + * + * Used to set the current encoder bitrate management settings to the values + * listed in the ovectl_ratemanage2_arg. Passing a NULL pointer will disable + * bitrate management. +*/ +#define OV_ECTL_RATEMANAGE2_SET 0x15 + +/** + * Returns the current encoder hard-lowpass setting (kHz) in the double + * pointed to by arg. + * + * Argument: <tt>double *</tt> +*/ +#define OV_ECTL_LOWPASS_GET 0x20 + +/** + * Sets the encoder hard-lowpass to the value (kHz) pointed to by arg. Valid + * lowpass settings range from 2 to 99. + * + * Argument: <tt>double *</tt> +*/ +#define OV_ECTL_LOWPASS_SET 0x21 + +/** + * Returns the current encoder impulse block setting in the double pointed + * to by arg. + * + * Argument: <tt>double *</tt> +*/ +#define OV_ECTL_IBLOCK_GET 0x30 + +/** + * Sets the impulse block bias to the the value pointed to by arg. + * + * Argument: <tt>double *</tt> + * + * Valid range is -15.0 to 0.0 [default]. A negative impulse block bias will + * direct to encoder to use more bits when incoding short blocks that contain + * strong impulses, thus improving the accuracy of impulse encoding. + */ +#define OV_ECTL_IBLOCK_SET 0x31 + +/** + * Returns the current encoder coupling setting in the int pointed + * to by arg. + * + * Argument: <tt>int *</tt> +*/ +#define OV_ECTL_COUPLING_GET 0x40 + +/** + * Enables/disables channel coupling in multichannel encoding according to arg. + * + * Argument: <tt>int *</tt> + * + * Zero disables channel coupling for multichannel inputs, nonzer enables + * channel coupling. Setting has no effect on monophonic encoding or + * multichannel counts that do not offer coupling. At present, coupling is + * available for stereo and 5.1 encoding. + */ +#define OV_ECTL_COUPLING_SET 0x41 + + /* deprecated rate management supported only for compatibility */ + +/** + * Old interface to querying bitrate management settings. + * + * Deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_GET instead. + * + * Argument: <tt>struct ovectl_ratemanage_arg *</tt> + */ +#define OV_ECTL_RATEMANAGE_GET 0x10 +/** + * Old interface to modifying bitrate management settings. + * + * deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + * + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead. + * + * Argument: <tt>struct ovectl_ratemanage_arg *</tt> + */ +#define OV_ECTL_RATEMANAGE_SET 0x11 +/** + * Old interface to setting average-bitrate encoding mode. + * + * Deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + * + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead. + * + * Argument: <tt>struct ovectl_ratemanage_arg *</tt> + */ +#define OV_ECTL_RATEMANAGE_AVG 0x12 +/** + * Old interface to setting bounded-bitrate encoding modes. + * + * deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + * + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead. + * + * Argument: <tt>struct ovectl_ratemanage_arg *</tt> + */ +#define OV_ECTL_RATEMANAGE_HARD 0x13 + +/*@}*/ + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/include/vorbis/vorbisfile.h b/include/vorbis/vorbisfile.h new file mode 100644 index 00000000..a865cd09 --- /dev/null +++ b/include/vorbis/vorbisfile.h @@ -0,0 +1,206 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + last mod: $Id: vorbisfile.h 17021 2010-03-24 09:29:41Z xiphmont $ + + ********************************************************************/ + +#ifndef _OV_FILE_H_ +#define _OV_FILE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include <stdio.h> +#include "codec.h" + +/* The function prototypes for the callbacks are basically the same as for + * the stdio functions fread, fseek, fclose, ftell. + * The one difference is that the FILE * arguments have been replaced with + * a void * - this is to be used as a pointer to whatever internal data these + * functions might need. In the stdio case, it's just a FILE * cast to a void * + * + * If you use other functions, check the docs for these functions and return + * the right values. For seek_func(), you *MUST* return -1 if the stream is + * unseekable + */ +typedef struct { + size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); + int (*seek_func) (void *datasource, ogg_int64_t offset, int whence); + int (*close_func) (void *datasource); + long (*tell_func) (void *datasource); +} ov_callbacks; + +#ifndef OV_EXCLUDE_STATIC_CALLBACKS + +/* a few sets of convenient callbacks, especially for use under + * Windows where ov_open_callbacks() should always be used instead of + * ov_open() to avoid problems with incompatible crt.o version linking + * issues. */ + +static int _ov_header_fseek_wrap(FILE *f,ogg_int64_t off,int whence){ + if(f==NULL)return(-1); + +#ifdef __MINGW32__ + return fseeko64(f,off,whence); +#elif defined (_WIN32) + return _fseeki64(f,off,whence); +#else + return fseek(f,off,whence); +#endif +} + +/* These structs below (OV_CALLBACKS_DEFAULT etc) are defined here as + * static data. That means that every file which includes this header + * will get its own copy of these structs whether it uses them or + * not unless it #defines OV_EXCLUDE_STATIC_CALLBACKS. + * These static symbols are essential on platforms such as Windows on + * which several different versions of stdio support may be linked to + * by different DLLs, and we need to be certain we know which one + * we're using (the same one as the main application). + */ + +static ov_callbacks OV_CALLBACKS_DEFAULT = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap, + (int (*)(void *)) fclose, + (long (*)(void *)) ftell +}; + +static ov_callbacks OV_CALLBACKS_NOCLOSE = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap, + (int (*)(void *)) NULL, + (long (*)(void *)) ftell +}; + +static ov_callbacks OV_CALLBACKS_STREAMONLY = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) NULL, + (int (*)(void *)) fclose, + (long (*)(void *)) NULL +}; + +static ov_callbacks OV_CALLBACKS_STREAMONLY_NOCLOSE = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) NULL, + (int (*)(void *)) NULL, + (long (*)(void *)) NULL +}; + +#endif + +#define NOTOPEN 0 +#define PARTOPEN 1 +#define OPENED 2 +#define STREAMSET 3 +#define INITSET 4 + +typedef struct OggVorbis_File { + void *datasource; /* Pointer to a FILE *, etc. */ + int seekable; + ogg_int64_t offset; + ogg_int64_t end; + ogg_sync_state oy; + + /* If the FILE handle isn't seekable (eg, a pipe), only the current + stream appears */ + int links; + ogg_int64_t *offsets; + ogg_int64_t *dataoffsets; + long *serialnos; + ogg_int64_t *pcmlengths; /* overloaded to maintain binary + compatibility; x2 size, stores both + beginning and end values */ + vorbis_info *vi; + vorbis_comment *vc; + + /* Decoding working state local storage */ + ogg_int64_t pcm_offset; + int ready_state; + long current_serialno; + int current_link; + + double bittrack; + double samptrack; + + ogg_stream_state os; /* take physical pages, weld into a logical + stream of packets */ + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + ov_callbacks callbacks; + +} OggVorbis_File; + + +extern int ov_clear(OggVorbis_File *vf); +extern int ov_fopen(char *path,OggVorbis_File *vf); +extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); +extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf, + char *initial, long ibytes, ov_callbacks callbacks); + +extern int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); +extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf, + char *initial, long ibytes, ov_callbacks callbacks); +extern int ov_test_open(OggVorbis_File *vf); + +extern long ov_bitrate(OggVorbis_File *vf,int i); +extern long ov_bitrate_instant(OggVorbis_File *vf); +extern long ov_streams(OggVorbis_File *vf); +extern long ov_seekable(OggVorbis_File *vf); +extern long ov_serialnumber(OggVorbis_File *vf,int i); + +extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i); +extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i); +extern double ov_time_total(OggVorbis_File *vf,int i); + +extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page(OggVorbis_File *vf,double pos); + +extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek_lap(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos); + +extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf); +extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf); +extern double ov_time_tell(OggVorbis_File *vf); + +extern vorbis_info *ov_info(OggVorbis_File *vf,int link); +extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link); + +extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples, + int *bitstream); +extern long ov_read_filter(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream, + void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param); +extern long ov_read(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream); +extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2); + +extern int ov_halfrate(OggVorbis_File *vf,int flag); +extern int ov_halfrate_p(OggVorbis_File *vf); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/include/wavpack.h b/include/wavpack.h new file mode 100644 index 00000000..fe66dcbc --- /dev/null +++ b/include/wavpack.h @@ -0,0 +1,302 @@ +//////////////////////////////////////////////////////////////////////////// +// **** WAVPACK **** // +// Hybrid Lossless Wavefile Compressor // +// Copyright (c) 1998 - 2006 Conifer Software. // +// All Rights Reserved. // +// Distributed under the BSD Software License (see license.txt) // +//////////////////////////////////////////////////////////////////////////// + +// wavpack.h + +#ifndef WAVPACK_H +#define WAVPACK_H + +// This header file contains all the definitions required to use the +// functions in "wputils.c" to read and write WavPack files and streams. + +#include <sys/types.h> + +#if defined(_WIN32) && !defined(__MINGW32__) +#include <stdlib.h> +typedef unsigned __int64 uint64_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int8 uint8_t; +typedef __int64 int64_t; +typedef __int32 int32_t; +typedef __int16 int16_t; +typedef __int8 int8_t; +typedef float float32_t; +#else +#include <inttypes.h> +#endif + +// RIFF / wav header formats (these occur at the beginning of both wav files +// and pre-4.0 WavPack files that are not in the "raw" mode). Generally, an +// application using the library to read or write WavPack files will not be +// concerned with any of these. + +typedef struct { + char ckID [4]; + uint32_t ckSize; + char formType [4]; +} RiffChunkHeader; + +typedef struct { + char ckID [4]; + uint32_t ckSize; +} ChunkHeader; + +#define ChunkHeaderFormat "4L" + +typedef struct { + unsigned short FormatTag, NumChannels; + uint32_t SampleRate, BytesPerSecond; + unsigned short BlockAlign, BitsPerSample; + unsigned short cbSize, ValidBitsPerSample; + int32_t ChannelMask; + unsigned short SubFormat; + char GUID [14]; +} WaveHeader; + +#define WaveHeaderFormat "SSLLSSSSLS" + +// This is the ONLY structure that occurs in WavPack files (as of version +// 4.0), and is the preamble to every block in both the .wv and .wvc +// files (in little-endian format). Normally, this structure has no use +// to an application using the library to read or write WavPack files, +// but if an application needs to manually parse WavPack files then this +// would be used (with appropriate endian correction). + +typedef struct { + char ckID [4]; + uint32_t ckSize; + short version; + unsigned char track_no, index_no; + uint32_t total_samples, block_index, block_samples, flags, crc; +} WavpackHeader; + +#define WavpackHeaderFormat "4LS2LLLLL" + +// or-values for WavpackHeader.flags +#define BYTES_STORED 3 // 1-4 bytes/sample +#define MONO_FLAG 4 // not stereo +#define HYBRID_FLAG 8 // hybrid mode +#define JOINT_STEREO 0x10 // joint stereo +#define CROSS_DECORR 0x20 // no-delay cross decorrelation +#define HYBRID_SHAPE 0x40 // noise shape (hybrid mode only) +#define FLOAT_DATA 0x80 // ieee 32-bit floating point data + +#define INT32_DATA 0x100 // special extended int handling +#define HYBRID_BITRATE 0x200 // bitrate noise (hybrid mode only) +#define HYBRID_BALANCE 0x400 // balance noise (hybrid stereo mode only) + +#define INITIAL_BLOCK 0x800 // initial block of multichannel segment +#define FINAL_BLOCK 0x1000 // final block of multichannel segment + +#define SHIFT_LSB 13 +#define SHIFT_MASK (0x1fL << SHIFT_LSB) + +#define MAG_LSB 18 +#define MAG_MASK (0x1fL << MAG_LSB) + +#define SRATE_LSB 23 +#define SRATE_MASK (0xfL << SRATE_LSB) + +#define FALSE_STEREO 0x40000000 // block is stereo, but data is mono + +#define IGNORED_FLAGS 0x18000000 // reserved, but ignore if encountered +#define NEW_SHAPING 0x20000000 // use IIR filter for negative shaping +#define UNKNOWN_FLAGS 0x80000000 // also reserved, but refuse decode if + // encountered + +#define MONO_DATA (MONO_FLAG | FALSE_STEREO) + +#define MIN_STREAM_VERS 0x402 // lowest stream version we'll decode +#define MAX_STREAM_VERS 0x410 // highest stream version we'll decode or encode +#define CUR_STREAM_VERS 0x407 // stream version we are writing now + +// These are the mask bit definitions for the metadata chunk id byte (see format.txt) + +#define ID_UNIQUE 0x3f +#define ID_OPTIONAL_DATA 0x20 +#define ID_ODD_SIZE 0x40 +#define ID_LARGE 0x80 + +#define ID_DUMMY 0x0 +#define ID_ENCODER_INFO 0x1 +#define ID_DECORR_TERMS 0x2 +#define ID_DECORR_WEIGHTS 0x3 +#define ID_DECORR_SAMPLES 0x4 +#define ID_ENTROPY_VARS 0x5 +#define ID_HYBRID_PROFILE 0x6 +#define ID_SHAPING_WEIGHTS 0x7 +#define ID_FLOAT_INFO 0x8 +#define ID_INT32_INFO 0x9 +#define ID_WV_BITSTREAM 0xa +#define ID_WVC_BITSTREAM 0xb +#define ID_WVX_BITSTREAM 0xc +#define ID_CHANNEL_INFO 0xd + +#define ID_RIFF_HEADER (ID_OPTIONAL_DATA | 0x1) +#define ID_RIFF_TRAILER (ID_OPTIONAL_DATA | 0x2) +#define ID_REPLAY_GAIN (ID_OPTIONAL_DATA | 0x3) // never used (APEv2) +#define ID_CUESHEET (ID_OPTIONAL_DATA | 0x4) // never used (APEv2) +#define ID_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0x5) +#define ID_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x6) +#define ID_SAMPLE_RATE (ID_OPTIONAL_DATA | 0x7) + +///////////////////////// WavPack Configuration /////////////////////////////// + +// This external structure is used during encode to provide configuration to +// the encoding engine and during decoding to provide fle information back to +// the higher level functions. Not all fields are used in both modes. + +typedef struct { + float bitrate, shaping_weight; + int bits_per_sample, bytes_per_sample; + int qmode, flags, xmode, num_channels, float_norm_exp; + int32_t block_samples, extra_flags, sample_rate, channel_mask; + unsigned char md5_checksum [16], md5_read; + int num_tag_strings; + char **tag_strings; +} WavpackConfig; + +#define CONFIG_HYBRID_FLAG 8 // hybrid mode +#define CONFIG_JOINT_STEREO 0x10 // joint stereo +#define CONFIG_HYBRID_SHAPE 0x40 // noise shape (hybrid mode only) +#define CONFIG_FAST_FLAG 0x200 // fast mode +#define CONFIG_HIGH_FLAG 0x800 // high quality mode +#define CONFIG_VERY_HIGH_FLAG 0x1000 // very high +#define CONFIG_BITRATE_KBPS 0x2000 // bitrate is kbps, not bits / sample +#define CONFIG_SHAPE_OVERRIDE 0x8000 // shaping mode specified +#define CONFIG_JOINT_OVERRIDE 0x10000 // joint-stereo mode specified +#define CONFIG_DYNAMIC_SHAPING 0x20000 // dynamic noise shaping +#define CONFIG_CREATE_EXE 0x40000 // create executable +#define CONFIG_CREATE_WVC 0x80000 // create correction file +#define CONFIG_OPTIMIZE_WVC 0x100000 // maximize bybrid compression +#define CONFIG_CALC_NOISE 0x800000 // calc noise in hybrid mode +#define CONFIG_EXTRA_MODE 0x2000000 // extra processing mode +#define CONFIG_SKIP_WVX 0x4000000 // no wvx stream w/ floats & big ints +#define CONFIG_MD5_CHECKSUM 0x8000000 // store MD5 signature +#define CONFIG_MERGE_BLOCKS 0x10000000 // merge blocks of equal redundancy (for lossyWAV) +#define CONFIG_PAIR_UNDEF_CHANS 0x20000000 // encode undefined channels in stereo pairs +#define CONFIG_OPTIMIZE_MONO 0x80000000 // optimize for mono streams posing as stereo + +////////////// Callbacks used for reading & writing WavPack streams ////////// + +typedef struct { + int32_t (*read_bytes)(void *id, void *data, int32_t bcount); + uint32_t (*get_pos)(void *id); + int (*set_pos_abs)(void *id, uint32_t pos); + int (*set_pos_rel)(void *id, int32_t delta, int mode); + int (*push_back_byte)(void *id, int c); + uint32_t (*get_length)(void *id); + int (*can_seek)(void *id); + + // this callback is for writing edited tags only + int32_t (*write_bytes)(void *id, void *data, int32_t bcount); +} WavpackStreamReader; + +typedef int (*WavpackBlockOutput)(void *id, void *data, int32_t bcount); + +//////////////////////////// function prototypes ///////////////////////////// + +// Note: See wputils.c sourcecode for descriptions for using these functions. + +typedef void WavpackContext; + +#ifdef __cplusplus +extern "C" { +#endif + +WavpackContext *WavpackOpenFileInputEx (WavpackStreamReader *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset); +WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int flags, int norm_offset); + +#define OPEN_WVC 0x1 // open/read "correction" file +#define OPEN_TAGS 0x2 // read ID3v1 / APEv2 tags (seekable file) +#define OPEN_WRAPPER 0x4 // make audio wrapper available (i.e. RIFF) +#define OPEN_2CH_MAX 0x8 // open multichannel as stereo (no downmix) +#define OPEN_NORMALIZE 0x10 // normalize floating point data to +/- 1.0 +#define OPEN_STREAMING 0x20 // "streaming" mode blindly unpacks blocks + // w/o regard to header file position info +#define OPEN_EDIT_TAGS 0x40 // allow editing of tags + +int WavpackGetMode (WavpackContext *wpc); + +#define MODE_WVC 0x1 +#define MODE_LOSSLESS 0x2 +#define MODE_HYBRID 0x4 +#define MODE_FLOAT 0x8 +#define MODE_VALID_TAG 0x10 +#define MODE_HIGH 0x20 +#define MODE_FAST 0x40 +#define MODE_EXTRA 0x80 // extra mode used, see MODE_XMODE for possible level +#define MODE_APETAG 0x100 +#define MODE_SFX 0x200 +#define MODE_VERY_HIGH 0x400 +#define MODE_MD5 0x800 +#define MODE_XMODE 0x7000 // mask for extra level (1-6, 0=unknown) +#define MODE_DNS 0x8000 + +char *WavpackGetErrorMessage (WavpackContext *wpc); +int WavpackGetVersion (WavpackContext *wpc); +uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t samples); +uint32_t WavpackGetNumSamples (WavpackContext *wpc); +uint32_t WavpackGetSampleIndex (WavpackContext *wpc); +int WavpackGetNumErrors (WavpackContext *wpc); +int WavpackLossyBlocks (WavpackContext *wpc); +int WavpackSeekSample (WavpackContext *wpc, uint32_t sample); +WavpackContext *WavpackCloseFile (WavpackContext *wpc); +uint32_t WavpackGetSampleRate (WavpackContext *wpc); +int WavpackGetBitsPerSample (WavpackContext *wpc); +int WavpackGetBytesPerSample (WavpackContext *wpc); +int WavpackGetNumChannels (WavpackContext *wpc); +int WavpackGetChannelMask (WavpackContext *wpc); +int WavpackGetReducedChannels (WavpackContext *wpc); +int WavpackGetFloatNormExp (WavpackContext *wpc); +int WavpackGetMD5Sum (WavpackContext *wpc, unsigned char data [16]); +uint32_t WavpackGetWrapperBytes (WavpackContext *wpc); +unsigned char *WavpackGetWrapperData (WavpackContext *wpc); +void WavpackFreeWrapper (WavpackContext *wpc); +void WavpackSeekTrailingWrapper (WavpackContext *wpc); +double WavpackGetProgress (WavpackContext *wpc); +uint32_t WavpackGetFileSize (WavpackContext *wpc); +double WavpackGetRatio (WavpackContext *wpc); +double WavpackGetAverageBitrate (WavpackContext *wpc, int count_wvc); +double WavpackGetInstantBitrate (WavpackContext *wpc); +int WavpackGetNumTagItems (WavpackContext *wpc); +int WavpackGetTagItem (WavpackContext *wpc, const char *item, char *value, int size); +int WavpackGetTagItemIndexed (WavpackContext *wpc, int index, char *item, int size); +int WavpackGetNumBinaryTagItems (WavpackContext *wpc); +int WavpackGetBinaryTagItem (WavpackContext *wpc, const char *item, char *value, int size); +int WavpackGetBinaryTagItemIndexed (WavpackContext *wpc, int index, char *item, int size); +int WavpackAppendTagItem (WavpackContext *wpc, const char *item, const char *value, int vsize); +int WavpackAppendBinaryTagItem (WavpackContext *wpc, const char *item, const char *value, int vsize); +int WavpackDeleteTagItem (WavpackContext *wpc, const char *item); +int WavpackWriteTag (WavpackContext *wpc); + +WavpackContext *WavpackOpenFileOutput (WavpackBlockOutput blockout, void *wv_id, void *wvc_id); +int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_t total_samples); +int WavpackAddWrapper (WavpackContext *wpc, void *data, uint32_t bcount); +int WavpackStoreMD5Sum (WavpackContext *wpc, unsigned char data [16]); +int WavpackPackInit (WavpackContext *wpc); +int WavpackPackSamples (WavpackContext *wpc, int32_t *sample_buffer, uint32_t sample_count); +int WavpackFlushSamples (WavpackContext *wpc); +void WavpackUpdateNumSamples (WavpackContext *wpc, void *first_block); +void *WavpackGetWrapperLocation (void *first_block, uint32_t *size); +double WavpackGetEncodedNoise (WavpackContext *wpc, double *peak); + +void WavpackFloatNormalize (int32_t *values, int32_t num_values, int delta_exp); + +void WavpackLittleEndianToNative (void *data, char *format); +void WavpackNativeToLittleEndian (void *data, char *format); + +uint32_t WavpackGetLibraryVersion (void); +const char *WavpackGetLibraryVersionString (void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/zconf.h b/include/zconf.h new file mode 100644 index 00000000..b2343874 --- /dev/null +++ b/include/zconf.h @@ -0,0 +1,428 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# define uncompress z_uncompress +# define zError z_zError +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# define gzFile z_gzFile +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include <windows.h> + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 1 /* was set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef STDC +# include <sys/types.h> /* for off_t */ +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include <unistd.h> /* for SEEK_* and off_t */ +# ifdef VMS +# include <unixio.h> /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define z_off64_t off64_t +#else +# define z_off64_t z_off_t +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/include/zlib.h b/include/zlib.h new file mode 100644 index 00000000..bfbba83e --- /dev/null +++ b/include/zlib.h @@ -0,0 +1,1613 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.5, April 19th, 2010 + + Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.5" +#define ZLIB_VERNUM 0x1250 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 5 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all the uncompressed data. (The size + of the uncompressed data may have been saved by the compressor for this + purpose.) The next operation on this stream must be inflateEnd to deallocate + the decompression state. The use of Z_FINISH is never required, but can be + used to inform inflate that a faster approach may be used for the single + inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK or Z_TREES is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any call + of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been + found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the + success case, the application may save the current current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef voidp gzFile; /* opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) Also "a" + can be used instead of "w" to request that the gzip stream that will be + written be appended to the file. "+" will result in an error, since reading + and writing to the same gzip file is not supported. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file was not in gzip format, gzread copies the given number of + bytes into the buffer. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream, or failing that, reading the rest + of the input file directly without decompression. The entire input file + will be read if gzread is called until it returns less than the requested + len. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. This state can change from + false to true while reading the input file if the end of a gzip stream is + reached, but is followed by data that is not another gzip stream. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the for the crc. Pre- and post-conditioning (one's + complement) is performed within this function so it shouldn't be done by the + application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# ifdef _LARGEFILE64_SOURCE + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/lib-x86-32/libFLAC.a b/lib-x86-32/libFLAC.a Binary files differnew file mode 100644 index 00000000..f9329aee --- /dev/null +++ b/lib-x86-32/libFLAC.a diff --git a/lib-x86-32/libavcodec.a b/lib-x86-32/libavcodec.a Binary files differnew file mode 100644 index 00000000..6e429f4a --- /dev/null +++ b/lib-x86-32/libavcodec.a diff --git a/lib-x86-32/libavcore.a b/lib-x86-32/libavcore.a Binary files differnew file mode 100644 index 00000000..650b57ed --- /dev/null +++ b/lib-x86-32/libavcore.a diff --git a/lib-x86-32/libavformat.a b/lib-x86-32/libavformat.a Binary files differnew file mode 100644 index 00000000..a7adafee --- /dev/null +++ b/lib-x86-32/libavformat.a diff --git a/lib-x86-32/libavutil.a b/lib-x86-32/libavutil.a Binary files differnew file mode 100644 index 00000000..e53d807c --- /dev/null +++ b/lib-x86-32/libavutil.a diff --git a/lib-x86-32/libcddb.a b/lib-x86-32/libcddb.a Binary files differnew file mode 100644 index 00000000..fed07ff6 --- /dev/null +++ b/lib-x86-32/libcddb.a diff --git a/lib-x86-32/libcdio.a b/lib-x86-32/libcdio.a Binary files differnew file mode 100644 index 00000000..c491a18e --- /dev/null +++ b/lib-x86-32/libcdio.a diff --git a/lib-x86-32/libcurl.a b/lib-x86-32/libcurl.a Binary files differnew file mode 100644 index 00000000..94a7d5a7 --- /dev/null +++ b/lib-x86-32/libcurl.a diff --git a/lib-x86-32/libdbus-1.a b/lib-x86-32/libdbus-1.a Binary files differnew file mode 100644 index 00000000..956ae037 --- /dev/null +++ b/lib-x86-32/libdbus-1.a diff --git a/lib-x86-32/libexpat.a b/lib-x86-32/libexpat.a Binary files differnew file mode 100644 index 00000000..7ce1fecc --- /dev/null +++ b/lib-x86-32/libexpat.a diff --git a/lib-x86-32/libfaad.a b/lib-x86-32/libfaad.a Binary files differnew file mode 100644 index 00000000..b1bbf9ab --- /dev/null +++ b/lib-x86-32/libfaad.a diff --git a/lib-x86-32/libidn.a b/lib-x86-32/libidn.a Binary files differnew file mode 100644 index 00000000..a0829f79 --- /dev/null +++ b/lib-x86-32/libidn.a diff --git a/lib-x86-32/libiso9660.a b/lib-x86-32/libiso9660.a Binary files differnew file mode 100644 index 00000000..3259699e --- /dev/null +++ b/lib-x86-32/libiso9660.a diff --git a/lib-x86-32/libmad.a b/lib-x86-32/libmad.a Binary files differnew file mode 100644 index 00000000..b9b86f27 --- /dev/null +++ b/lib-x86-32/libmad.a diff --git a/lib-x86-32/libogg.a b/lib-x86-32/libogg.a Binary files differnew file mode 100644 index 00000000..99bf4df0 --- /dev/null +++ b/lib-x86-32/libogg.a diff --git a/lib-x86-32/libopencore-amrnb.a b/lib-x86-32/libopencore-amrnb.a Binary files differnew file mode 100644 index 00000000..7ce4236c --- /dev/null +++ b/lib-x86-32/libopencore-amrnb.a diff --git a/lib-x86-32/libopencore-amrwb.a b/lib-x86-32/libopencore-amrwb.a Binary files differnew file mode 100644 index 00000000..64cef81b --- /dev/null +++ b/lib-x86-32/libopencore-amrwb.a diff --git a/lib-x86-32/libsamplerate.a b/lib-x86-32/libsamplerate.a Binary files differnew file mode 100644 index 00000000..9a1e284c --- /dev/null +++ b/lib-x86-32/libsamplerate.a diff --git a/lib-x86-32/libsndfile.a b/lib-x86-32/libsndfile.a Binary files differnew file mode 100644 index 00000000..855328d2 --- /dev/null +++ b/lib-x86-32/libsndfile.a diff --git a/lib-x86-32/libudf.a b/lib-x86-32/libudf.a Binary files differnew file mode 100644 index 00000000..f76f210e --- /dev/null +++ b/lib-x86-32/libudf.a diff --git a/lib-x86-32/libvorbis.a b/lib-x86-32/libvorbis.a Binary files differnew file mode 100644 index 00000000..5b54022a --- /dev/null +++ b/lib-x86-32/libvorbis.a diff --git a/lib-x86-32/libvorbisenc.a b/lib-x86-32/libvorbisenc.a Binary files differnew file mode 100644 index 00000000..c4ef087e --- /dev/null +++ b/lib-x86-32/libvorbisenc.a diff --git a/lib-x86-32/libvorbisfile.a b/lib-x86-32/libvorbisfile.a Binary files differnew file mode 100644 index 00000000..70315863 --- /dev/null +++ b/lib-x86-32/libvorbisfile.a diff --git a/lib-x86-32/libwavpack.a b/lib-x86-32/libwavpack.a Binary files differnew file mode 100644 index 00000000..a18683f0 --- /dev/null +++ b/lib-x86-32/libwavpack.a diff --git a/lib-x86-32/libz.a b/lib-x86-32/libz.a Binary files differnew file mode 100644 index 00000000..00810f6e --- /dev/null +++ b/lib-x86-32/libz.a @@ -54,10 +54,7 @@ #include "conf.h" #include "volume.h" #include "plugins.h" - -#ifndef PATH_MAX -#define PATH_MAX 1024 /* max # of characters in a path name */ -#endif +#include "common.h" #ifndef PREFIX #error PREFIX must be defined @@ -67,12 +64,18 @@ #define USE_ABSTRACT_NAME 0 #endif -//#define trace(...) { fprintf(stderr, __VA_ARGS__); } -#define trace(fmt,...) +#define trace(...) { fprintf(stderr, __VA_ARGS__); } +//#define trace(fmt,...) + // some common global variables -char confdir[1024]; // $HOME/.config -char dbconfdir[1024]; // $HOME/.config/deadbeef +char sys_install_path[PATH_MAX]; // see deadbeef->get_prefix +char confdir[PATH_MAX]; // $HOME/.config +char dbconfdir[PATH_MAX]; // $HOME/.config/deadbeef +char dbinstalldir[PATH_MAX]; // see deadbeef->get_prefix +char dbdocdir[PATH_MAX]; // see deadbeef->get_doc_dir +char dbplugindir[PATH_MAX]; // see deadbeef->get_plugin_dir +char dbpixmapdir[PATH_MAX]; // see deadbeef->get_pixmap_dir // client-side commandline support // -1 error, program must exit with error code -1 @@ -532,11 +535,45 @@ main (int argc, char *argv[]) { bind_textdomain_codeset (PACKAGE, "UTF-8"); textdomain (PACKAGE); #endif - fprintf (stderr, "starting deadbeef " VERSION "\n"); + fprintf (stderr, "starting deadbeef " VERSION "%s\n", PORTABLE ? " [portable build]" : ""); srand (time (NULL)); #ifdef __linux__ prctl (PR_SET_NAME, "deadbeef-main", 0, 0, 0, 0); #endif + +#if PORTABLE + strcpy (dbinstalldir, argv[0]); + char *e = dbinstalldir + strlen (dbinstalldir); + while (e >= dbinstalldir && *e != '/') { + e--; + } + *e = 0; + if (snprintf (confdir, sizeof (confdir), "%s/config", dbinstalldir) > sizeof (confdir)) { + fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); + return -1; + } + + strcpy (dbconfdir, confdir); + + if (snprintf (dbdocdir, sizeof (dbdocdir), "%s/doc", dbinstalldir) > sizeof (dbdocdir)) { + fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); + return -1; + } + if (snprintf (dbplugindir, sizeof (dbplugindir), "%s/plugins", dbinstalldir) > sizeof (dbplugindir)) { + fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); + return -1; + } + if (snprintf (dbpixmapdir, sizeof (dbpixmapdir), "%s/pixmaps", dbinstalldir) > sizeof (dbpixmapdir)) { + fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); + return -1; + } + trace ("installdir: %s\n", dbinstalldir); + trace ("confdir: %s\n", confdir); + trace ("docdir: %s\n", dbdocdir); + trace ("plugindir: %s\n", dbplugindir); + mkdir (dbplugindir, 0755); + trace ("pixmapdir: %s\n", dbpixmapdir); +#else char *homedir = getenv ("HOME"); if (!homedir) { fprintf (stderr, "unable to find home directory. stopping.\n"); @@ -556,11 +593,25 @@ main (int argc, char *argv[]) { return -1; } } - mkdir (confdir, 0755); if (snprintf (dbconfdir, sizeof (dbconfdir), "%s/deadbeef", confdir) > sizeof (dbconfdir)) { fprintf (stderr, "fatal: out of memory while configuring\n"); return -1; } + mkdir (confdir, 0755); + if (snprintf (dbdocdir, sizeof (dbdocdir), "%s", DOCDIR) > sizeof (dbdocdir)) { + fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); + return -1; + } + if (snprintf (dbplugindir, sizeof (dbplugindir), "%s/deadbeef", LIBDIR) > sizeof (dbplugindir)) { + fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); + return -1; + } + if (snprintf (dbpixmapdir, sizeof (dbpixmapdir), "%s/share/deadbeef/pixmaps", PREFIX) > sizeof (dbpixmapdir)) { + fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); + return -1; + } +#endif + mkdir (dbconfdir, 0755); char cmdline[2048]; @@ -682,7 +733,9 @@ main (int argc, char *argv[]) { conf_load (); // required by some plugins at startup volume_set_db (conf_get_float ("playback.volume", 0)); // volume need to be initialized before plugins start messagepump_init (); // required to push messages while handling commandline - plug_load_all (); // required to add files to playlist from commandline + if (plug_load_all ()) { // required to add files to playlist from commandline + exit (-1); + } pl_load_all (); plt_set_curr (conf_get_int ("playlist.current", 0)); @@ -88,8 +88,13 @@ static DB_functions_t deadbeef_api = { .streamer_get_apx_bitrate = streamer_get_apx_bitrate, .streamer_get_current_fileinfo = streamer_get_current_fileinfo, .streamer_get_current_playlist = streamer_get_current_playlist, - // process control + // folders .get_config_dir = plug_get_config_dir, + .get_prefix = plug_get_prefix, + .get_doc_dir = plug_get_doc_dir, + .get_plugin_dir = plug_get_plugin_dir, + .get_pixmap_dir = plug_get_pixmap_dir, + // process control .quit = plug_quit, // threading .thread_start = thread_start, @@ -271,6 +276,26 @@ plug_get_config_dir (void) { return dbconfdir; } +const char * +plug_get_prefix (void) { + return dbinstalldir; +} + +const char * +plug_get_doc_dir (void) { + return dbdocdir; +} + +const char * +plug_get_plugin_dir (void) { + return dbplugindir; +} + +const char * +plug_get_pixmap_dir (void) { + return dbpixmapdir; +} + void plug_volume_set_db (float db) { volume_set_db (db); @@ -570,7 +595,7 @@ plug_load_all (void) { const char *conf_blacklist_plugins = conf_get_str ("blacklist_plugins", ""); trace ("plug: mutex_create\n"); mutex = mutex_create (); - const char *dirname = LIBDIR "/deadbeef"; + const char *dirname = deadbeef->get_plugin_dir (); struct dirent **namelist = NULL; char *xdg_local_home = getenv ("XDG_LOCAL_HOME"); @@ -618,8 +643,8 @@ plug_load_all (void) { int i; for (i = 0; i < n; i++) { - // no hidden files - while (namelist[i]->d_name[0] != '.') + // skip hidden files and fallback plugins + while (namelist[i]->d_name[0] != '.' && !strstr (namelist[i]->d_name, ".fallback.")) { int l = strlen (namelist[i]->d_name); if (l < 3) { @@ -658,7 +683,16 @@ plug_load_all (void) { void *handle = dlopen (fullname, RTLD_NOW); if (!handle) { trace ("dlopen error: %s\n", dlerror ()); - break; + strcpy (fullname + strlen(fullname) - 3, ".fallback.so"); + trace ("trying %s...\n", fullname); + handle = dlopen (fullname, RTLD_NOW); + if (!handle) { + trace ("dlopen error: %s\n", dlerror ()); + break; + } + else { + fprintf (stderr, "successfully started fallback plugin %s\n", fullname); + } } d_name[l-3] = 0; strcat (d_name, "_load"); @@ -113,6 +113,14 @@ plug_volume_set_amp (float amp); const char * plug_get_config_dir (void); +const char * +plug_get_prefix (void); +const char * +plug_get_doc_dir (void); +const char * +plug_get_plugin_dir (void); +const char * +plug_get_pixmap_dir (void); int plug_activate (DB_plugin_t *plug, int activate); diff --git a/plugins/aac/aac.c b/plugins/aac/aac.c index f7925b82..25143849 100644 --- a/plugins/aac/aac.c +++ b/plugins/aac/aac.c @@ -1123,8 +1123,8 @@ static const char *filetypes[] = { "RAW AAC", "MP4 AAC", NULL }; // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "aac", .plugin.name = "AAC decoder based on FAAD2", diff --git a/plugins/adplug/Makefile.am b/plugins/adplug/Makefile.am index a75f38b5..393f2d59 100644 --- a/plugins/adplug/Makefile.am +++ b/plugins/adplug/Makefile.am @@ -5,11 +5,12 @@ adlibdir = $(libdir)/$(PACKAGE) pkglib_LTLIBRARIES = adplug.la AM_CFLAGS = $(CFLAGS) -std=c99 -I$(adplugpath)/adplug -I$(adplugpath)/libbinio +adplug_la_LDFLAGS = -module -nostdlib -lsupc++ -AM_CPPFLAGS = $(CXXFLAGS) -Dstricmp=strcasecmp -DVERSION=\"2.1\" -I$(adplugpath)/adplug -I$(adplugpath)/libbinio +AM_CPPFLAGS = $(CXXFLAGS) -Dstricmp=strcasecmp -DVERSION=\"2.1\" -I$(adplugpath)/adplug -I$(adplugpath)/libbinio -fno-exceptions -fno-rtti -nostdlib -fno-unwind-tables -adplug_la_SOURCES = adplug-db.cpp\ - plugin.c\ +adplug_la_SOURCES = plugin.c\ + adplug-db.cpp\ libbinio/binfile.h\ libbinio/binio.h\ libbinio/binstr.h\ @@ -134,5 +135,4 @@ adplug_la_SOURCES = adplug-db.cpp\ # adplug/database.cpp # adplug/database.h -adplug_la_LDFLAGS = -module endif diff --git a/plugins/adplug/adplug-db.cpp b/plugins/adplug/adplug-db.cpp index 567d55ca..a7b1f6b2 100644 --- a/plugins/adplug/adplug-db.cpp +++ b/plugins/adplug/adplug-db.cpp @@ -31,6 +31,18 @@ //#define trace(...) { fprintf (stderr, __VA_ARGS__); } #define trace(fmt,...) +int _Unwind_Resume_or_Rethrow; +int _Unwind_RaiseException; +int _Unwind_GetLanguageSpecificData; +int _Unwind_Resume; +int _Unwind_DeleteException; +int _Unwind_GetTextRelBase; +int _Unwind_SetIP; +int _Unwind_GetDataRelBase; +int _Unwind_GetRegionStart; +int _Unwind_SetGR; +int _Unwind_GetIPInfo; + extern "C" { extern DB_decoder_t adplug_plugin; diff --git a/plugins/adplug/plugin.c b/plugins/adplug/plugin.c index c4e8e04c..80acc38d 100644 --- a/plugins/adplug/plugin.c +++ b/plugins/adplug/plugin.c @@ -47,8 +47,8 @@ adplug_stop (void); // define plugin interface DB_decoder_t adplug_plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "adplug", .plugin.name = "Adplug player", diff --git a/plugins/alsa/alsa.c b/plugins/alsa/alsa.c index 96d7645b..65178e55 100644 --- a/plugins/alsa/alsa.c +++ b/plugins/alsa/alsa.c @@ -668,8 +668,8 @@ static const char settings_dlg[] = // define plugin interface static DB_output_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.nostop = 1, .plugin.type = DB_PLUGIN_OUTPUT, .plugin.name = "ALSA output plugin", diff --git a/plugins/ao/plugin.c b/plugins/ao/plugin.c index 2e29c4e0..f54a0417 100644 --- a/plugins/ao/plugin.c +++ b/plugins/ao/plugin.c @@ -336,8 +336,8 @@ aoplug_stop (void) { static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "psf", .plugin.name = "Audio Overload plugin", diff --git a/plugins/artwork/artwork.c b/plugins/artwork/artwork.c index 3257f619..34bac6dd 100644 --- a/plugins/artwork/artwork.c +++ b/plugins/artwork/artwork.c @@ -17,7 +17,7 @@ //#define trace(...) { fprintf(stderr, __VA_ARGS__); } #define trace(...) -#define DEFAULT_COVER_PATH (PREFIX "/share/deadbeef/pixmaps/noartwork.jpg") +static char default_cover[PATH_MAX]; #define DEFAULT_FILEMASK "*cover*.jpg;*front*.jpg" static DB_artwork_plugin_t plugin; @@ -42,12 +42,16 @@ static volatile int terminate; static volatile int clear_queue; static intptr_t tid; -int artwork_enable_embedded; -int artwork_enable_local; -int artwork_enable_lfm; -int artwork_enable_aao; -time_t artwork_reset_time; -char artwork_filemask[200]; +static int artwork_enable_embedded; +static int artwork_enable_local; +static int artwork_enable_lfm; +static int artwork_enable_aao; +static time_t artwork_reset_time; +static char artwork_filemask[200]; + +static const char *get_default_cover (void) { + return default_cover; +} void make_cache_dir_path (char *path, int size, const char *album, const char *artist) { @@ -569,11 +573,11 @@ get_album_art (const char *fname, const char *artist, const char *album, artwork if (!*artist || !*album) { //give up - return strdup (DEFAULT_COVER_PATH); + return strdup (get_default_cover ()); } if (!deadbeef->is_local_file (fname)) { - return strdup (DEFAULT_COVER_PATH); + return strdup (get_default_cover ()); } make_cache_path (path, sizeof (path), album, artist); @@ -587,7 +591,7 @@ get_album_art (const char *fname, const char *artist, const char *album, artwork trace ("reloading cached file %s\n", path); unlink (path); queue_add (fname, artist, album, callback, user_data); - return strdup (DEFAULT_COVER_PATH); + return strdup (get_default_cover ()); } // trace ("found %s in cache, resettime %" PRId64 ", filetime %" PRId64 ", time %" PRId64 "\n", path, artwork_reset_time, stat_buf.st_mtime, tm); @@ -595,7 +599,7 @@ get_album_art (const char *fname, const char *artist, const char *album, artwork } queue_add (fname, artist, album, callback, user_data); - return strdup (DEFAULT_COVER_PATH); + return strdup (get_default_cover ()); } DB_plugin_t * @@ -667,6 +671,13 @@ artwork_on_configchanged (DB_event_t *ev, uintptr_t data) { static int artwork_plugin_start (void) { + const char *def_art = deadbeef->conf_get_str ("gtkui.nocover_pixmap", NULL); + if (!def_art) { + snprintf (default_cover, sizeof (default_cover), "%s/noartwork.jpg", deadbeef->get_pixmap_dir ()); + } + else { + strcpy (default_cover, def_art); + } terminate = 0; artwork_enable_embedded = deadbeef->conf_get_int ("artwork.enable_embedded", 1); @@ -723,10 +734,13 @@ static const char settings_dlg[] = "property \"Fetch from last.fm\" checkbox artwork.enable_lastfm 0;\n" "property \"Fetch from albumart.org\" checkbox artwork.enable_albumartorg 0;\n" ; + // define plugin interface static DB_artwork_plugin_t plugin = { .plugin.plugin.api_vmajor = DB_API_VERSION_MAJOR, .plugin.plugin.api_vminor = DB_API_VERSION_MINOR, + .plugin.plugin.version_major = 1, + .plugin.plugin.version_minor = 0, .plugin.plugin.type = DB_PLUGIN_MISC, .plugin.plugin.id = "cover_loader", .plugin.plugin.name = "Album Artwork", @@ -739,4 +753,5 @@ static DB_artwork_plugin_t plugin = { .plugin.plugin.configdialog = settings_dlg, .get_album_art = get_album_art, .reset = artwork_reset, + .get_default_cover = get_default_cover, }; diff --git a/plugins/artwork/artwork.h b/plugins/artwork/artwork.h index ab0fead6..ed5357df 100644 --- a/plugins/artwork/artwork.h +++ b/plugins/artwork/artwork.h @@ -14,6 +14,7 @@ typedef struct { // this has to be called to clear queue on exit, before caller terminates // `fast=1' means "don't wait, just flush queue" void (*reset) (int fast); + const char *(*get_default_cover) (void); } DB_artwork_plugin_t; #endif /*__ARTWORK_H*/ diff --git a/plugins/cdda/cdda.c b/plugins/cdda/cdda.c index b83dc5bb..e69adfa7 100644 --- a/plugins/cdda/cdda.c +++ b/plugins/cdda/cdda.c @@ -580,12 +580,12 @@ static const char settings_dlg[] = // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "cda", .plugin.name = "Audio CD player", - .plugin.descr = "Audio CD plugins using libcdio and libcddb", + .plugin.descr = "Audio CD plugin using libcdio and libcddb", .plugin.author = "Viktor Semykin, Alexey Yakovenko", .plugin.email = "thesame.ml@gmail.com, waker@users.sourceforge.net", .plugin.website = "http://deadbeef.sf.net", diff --git a/plugins/dca/dcaplug.c b/plugins/dca/dcaplug.c index 9d7f251f..bcd782a1 100644 --- a/plugins/dca/dcaplug.c +++ b/plugins/dca/dcaplug.c @@ -644,8 +644,8 @@ dts_stop (void) { // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "dts", .plugin.name = "dts decoder", diff --git a/plugins/dumb/cdumb.c b/plugins/dumb/cdumb.c index b8189eeb..b3f6bb2a 100644 --- a/plugins/dumb/cdumb.c +++ b/plugins/dumb/cdumb.c @@ -815,8 +815,8 @@ static const char settings_dlg[] = // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "stddumb", .plugin.name = "DUMB module player", diff --git a/plugins/ffap/ffap.c b/plugins/ffap/ffap.c index deaa06dc..c65e4fc9 100644 --- a/plugins/ffap/ffap.c +++ b/plugins/ffap/ffap.c @@ -1899,8 +1899,8 @@ static const char *filetypes[] = { "APE", NULL }; // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "ffap", .plugin.name = "Monkey's Audio (APE) decoder", diff --git a/plugins/ffmpeg/ChangeLog b/plugins/ffmpeg/ChangeLog new file mode 100644 index 00000000..f3179866 --- /dev/null +++ b/plugins/ffmpeg/ChangeLog @@ -0,0 +1,5 @@ +version 1.2 + Added AMR support via libopencore + +version 1.1 + Switched to ffmpeg commit 25472 diff --git a/plugins/ffmpeg/ffmpeg.c b/plugins/ffmpeg/ffmpeg.c index f27e403b..89917c83 100644 --- a/plugins/ffmpeg/ffmpeg.c +++ b/plugins/ffmpeg/ffmpeg.c @@ -55,7 +55,7 @@ static DB_decoder_t plugin; static DB_functions_t *deadbeef; -static const char * exts[] = { "m4a", "wma", "aa3", "oma", "ac3", "vqf", NULL }; +static const char * exts[] = { "m4a", "wma", "aa3", "oma", "ac3", "vqf", "amr", NULL }; enum { FT_ALAC = 0, @@ -63,10 +63,11 @@ enum { FT_ATRAC3 = 2, FT_VQF = 3, FT_AC3 = 4, + FT_AMR = 5, FT_UNKNOWN = 5 }; -static const char *filetypes[] = { "ALAC", "WMA", "ATRAC3", "VQF", "AC3", "FFMPEG (unknown)", NULL }; +static const char *filetypes[] = { "ALAC", "WMA", "ATRAC3", "VQF", "AC3", "AMR", "FFMPEG (unknown)", NULL }; #define FF_PROTOCOL_NAME "deadbeef" @@ -169,6 +170,9 @@ ffmpeg_init (DB_fileinfo_t *_info, DB_playItem_t *it) { else if (strcasestr (info->codec->name, "ac3")) { it->filetype = filetypes[FT_AC3]; } + else if (strcasestr (info->codec->name, "amr")) { + it->filetype = filetypes[FT_AMR]; + } else { it->filetype = filetypes[FT_UNKNOWN]; } @@ -714,8 +718,8 @@ ffmpeg_read_metadata (DB_playItem_t *it) { // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 2, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "ffmpeg", .plugin.name = "FFMPEG audio player", diff --git a/plugins/flac/flac.c b/plugins/flac/flac.c index 00cdf598..1de1f443 100644 --- a/plugins/flac/flac.c +++ b/plugins/flac/flac.c @@ -837,8 +837,8 @@ static const char *filetypes[] = { "FLAC", "OggFLAC", NULL }; // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "stdflac", .plugin.name = "FLAC decoder", diff --git a/plugins/gme/Makefile.am b/plugins/gme/Makefile.am index 61351f9c..ed815899 100644 --- a/plugins/gme/Makefile.am +++ b/plugins/gme/Makefile.am @@ -112,8 +112,8 @@ game-music-emu-0.5.5/gme/Ym2413_Emu.h\ game-music-emu-0.5.5/gme/Ym2612_Emu.h\ game-music-emu-0.5.5/gme/gme_types.h -gme_la_LDFLAGS = -module +gme_la_LDFLAGS = -module -nostdlib -lsupc++ -gme_la_LIBADD = $(LDADD) -lstdc++ AM_CFLAGS = $(CFLAGS) -I$(gmepath) -std=c99 -DGME_VERSION_055 +AM_CPPFLAGS = $(CXXFLAGS) -fno-exceptions -fno-rtti -nostdlib -fno-unwind-tables endif diff --git a/plugins/gme/cgme.c b/plugins/gme/cgme.c index 5d2920f0..1d4bdaed 100644 --- a/plugins/gme/cgme.c +++ b/plugins/gme/cgme.c @@ -21,6 +21,18 @@ #include "gme/gme.h" #include "../../deadbeef.h" +int _Unwind_Resume_or_Rethrow; +int _Unwind_RaiseException; +int _Unwind_GetLanguageSpecificData; +int _Unwind_Resume; +int _Unwind_DeleteException; +int _Unwind_GetTextRelBase; +int _Unwind_SetIP; +int _Unwind_GetDataRelBase; +int _Unwind_GetRegionStart; +int _Unwind_SetGR; +int _Unwind_GetIPInfo; + //#define trace(...) { fprintf(stderr, __VA_ARGS__); } #define trace(fmt,...) @@ -241,8 +253,8 @@ static const char settings_dlg[] = // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "stdgme", .plugin.name = "Game_Music_Emu decoder", diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.cpp index fa9bc4b1..fb56f5dc 100644 --- a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.cpp +++ b/plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.cpp @@ -90,7 +90,7 @@ void Sap_Apu::reset( Sap_Apu_Impl* new_impl ) memset( &oscs [i], 0, offsetof (osc_t,output) ); } -inline void Sap_Apu::calc_periods() +void Sap_Apu::calc_periods() { // 15/64 kHz clock int divider = 28; diff --git a/plugins/gtkui/Makefile.am b/plugins/gtkui/Makefile.am index 609917ed..55557ad8 100644 --- a/plugins/gtkui/Makefile.am +++ b/plugins/gtkui/Makefile.am @@ -1,10 +1,7 @@ if HAVE_GTKUI gtkuidir = $(libdir)/$(PACKAGE) -pkglib_LTLIBRARIES = gtkui.la - gtkui_VALASOURCES = ddbequalizer.vala ddbseekbar.vala ddbcellrenderertextmultiline.vala gtkui_VALABUILTSOURCES = $(gtkui_VALASOURCES:.vala=.c) ddbequalizer.h ddbseekbar.h ddbcellrenderertextmultiline.h - if MAINTAINER_MODE BUILT_SOURCES = vala.stamp vala.stamp: $(gtkui_VALASOURCES) @@ -12,10 +9,13 @@ vala.stamp: $(gtkui_VALASOURCES) $(VALAC) -C -H ddbequalizer.h --library ddbequalizer gtkui.vapi --pkg=gtk+-2.0 ddbequalizer.vala $(VALAC) -C -H ddbseekbar.h --library ddbseekbar gtkui.vapi --pkg=gtk+-2.0 ddbseekbar.vala touch $@ + +CLEANFILES = \ + $(BUILT_SOURCES) \ + $(gtkui_VALABUILTSOURCES) endif -gtkui_la_SOURCES = $(gtkui_VALABUILTSOURCES)\ - gtkui.c gtkui.h\ +GTKUI_SOURCES = gtkui.c gtkui.h\ callbacks.c interface.c support.c callbacks.h interface.h support.h\ ddblistview.c ddblistview.h\ mainplaylist.c mainplaylist.h\ @@ -34,16 +34,31 @@ gtkui_la_SOURCES = $(gtkui_VALABUILTSOURCES)\ eq.c eq.h\ actions.c actions.h +EXTRA_DIST = $(gtkui_VALASOURCES) deadbeef.glade + +if PORTABLE +pkglib_LTLIBRARIES = gtkui.la gtkui.fallback.la +else +pkglib_LTLIBRARIES = gtkui.la +endif + +# normal lib +gtkui_la_SOURCES = $(gtkui_VALABUILTSOURCES) $(GTKUI_SOURCES) gtkui_la_LDFLAGS = -module +gtkui_la_LIBADD = $(LDADD) $(GTKUI_DEPS_LIBS) +gtkui_la_CFLAGS = -std=c99 $(GTKUI_DEPS_CFLAGS) -gtkui_la_LIBADD = $(LDADD) $(GTKUI_DEPS_LIBS) $(NOTIFY_DEPS_LIBS) -AM_CFLAGS = -std=c99 $(GTKUI_DEPS_CFLAGS) $(NOTIFY_DEPS_CFLAGS) +# fallback lib +if PORTABLE +GTK_ROOT=../../../deadbeef-deps/gtk-debian/usr -EXTRA_DIST = $(gtkui_VALASOURCES) deadbeef.glade +gtkui_fallback_la_SOURCES = $(gtkui_VALABUILTSOURCES) $(GTKUI_SOURCES) +gtkui_fallback_la_LDFLAGS = -module + +gtkui_fallback_la_LIBADD = $(LDADD) -L$(GTK_ROOT)/lib $(GTK_ROOT)/lib/libgtk-x11-2.0.la $(GTK_ROOT)/lib/libgdk-x11-2.0.la $(GTK_ROOT)/lib/libpangoft2-1.0.la $(GTK_ROOT)/lib/libpangocairo-1.0.la $(GTK_ROOT)/lib/libgdk_pixbuf-2.0.la -lm $(GTK_ROOT)/lib/libcairo.la $(GTK_ROOT)/lib/libpango-1.0.la $(GTK_ROOT)/lib/libgobject-2.0.la $(GTK_ROOT)/lib/libgmodule-2.0.la $(GTK_ROOT)/lib/libgthread-2.0.la -lrt $(GTK_ROOT)/lib/libglib-2.0.la + +gtkui_fallback_la_CFLAGS = -std=c99 -I $(GTK_ROOT)/include -I $(GTK_ROOT)/lib/gtk-2.0/include -I $(GTK_ROOT)/include/glib-2.0 -I $(GTK_ROOT)/include/gtk-2.0 -I $(GTK_ROOT)/include/cairo -I $(GTK_ROOT)/lib/glib-2.0/include/ -I $(GTK_ROOT)/include/pango-1.0 -I $(GTK_ROOT)/include/atk-1.0 -DULTRA_COMPATIBLE=1 -if MAINTAINER_MODE -CLEANFILES = \ - $(BUILT_SOURCES) \ - $(gtkui_VALABUILTSOURCES) endif + endif diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c index dd26a422..84a585ee 100644 --- a/plugins/gtkui/callbacks.c +++ b/plugins/gtkui/callbacks.c @@ -689,7 +689,7 @@ on_help1_activate (GtkMenuItem *menuitem, gpointer user_data) { char fname[PATH_MAX]; - snprintf (fname, sizeof (fname), DOCDIR "/%s", _("help.txt")); + snprintf (fname, sizeof (fname), "%s/%s", deadbeef->get_doc_dir (), _("help.txt")); show_info_window (fname, _("Help"), &helpwindow); } @@ -702,7 +702,7 @@ on_about1_activate (GtkMenuItem *menuitem, char s[200]; snprintf (s, sizeof (s), _("About DeaDBeeF %s"), VERSION); char fname[PATH_MAX]; - snprintf (fname, sizeof (fname), DOCDIR "/%s", "about.txt"); + snprintf (fname, sizeof (fname), "%s/%s", deadbeef->get_doc_dir (), "about.txt"); show_info_window (fname, s, &aboutwindow); } @@ -715,7 +715,7 @@ on_changelog1_activate (GtkMenuItem *menuitem, char s[200]; snprintf (s, sizeof (s), _("DeaDBeeF %s ChangeLog"), VERSION); char fname[PATH_MAX]; - snprintf (fname, sizeof (fname), DOCDIR "/%s", "ChangeLog"); + snprintf (fname, sizeof (fname), "%s/%s", deadbeef->get_doc_dir (), "ChangeLog"); show_info_window (fname, s, &changelogwindow); } @@ -726,7 +726,7 @@ on_gpl1_activate (GtkMenuItem *menuitem, gpointer user_data) { char fname[PATH_MAX]; - snprintf (fname, sizeof (fname), DOCDIR "/%s", "COPYING.GPLv2"); + snprintf (fname, sizeof (fname), "%s/%s", deadbeef->get_doc_dir (), "COPYING.GPLv2"); show_info_window (fname, "GNU GENERAL PUBLIC LICENSE Version 2", &gplwindow); } @@ -737,7 +737,7 @@ on_lgpl1_activate (GtkMenuItem *menuitem, gpointer user_data) { char fname[PATH_MAX]; - snprintf (fname, sizeof (fname), DOCDIR "/%s", "COPYING.LGPLv2.1"); + snprintf (fname, sizeof (fname), "%s/%s", deadbeef->get_doc_dir (), "COPYING.LGPLv2.1"); show_info_window (fname, "GNU LESSER GENERAL PUBLIC LICENSE Version 2.1", &lgplwindow); } @@ -1079,7 +1079,7 @@ on_translators1_activate (GtkMenuItem *menuitem, char s[200]; snprintf (s, sizeof (s), _("DeaDBeeF Translators")); char fname[PATH_MAX]; - snprintf (fname, sizeof (fname), DOCDIR "/%s", "translators.txt"); + snprintf (fname, sizeof (fname), "%s/%s", deadbeef->get_doc_dir (), "translators.txt"); show_info_window (fname, s, &translatorswindow); } diff --git a/plugins/gtkui/coverart.c b/plugins/gtkui/coverart.c index 9a42172a..0a8865a1 100644 --- a/plugins/gtkui/coverart.c +++ b/plugins/gtkui/coverart.c @@ -26,8 +26,6 @@ #include "../artwork/artwork.h" #include "gtkui.h" -#define DEFAULT_COVER_PATH (PREFIX "/share/deadbeef/pixmaps/noartwork.jpg") - //#define trace(...) { fprintf(stderr, __VA_ARGS__); } #define trace(...) @@ -156,12 +154,13 @@ loading_thread (void *none) { g_error_free (error); error = NULL; } - if (stat (DEFAULT_COVER_PATH, &stat_buf) < 0) { + const char *defpath = coverart_plugin->get_default_cover (); + if (stat (defpath, &stat_buf) < 0) { trace ("failed to stat file %s\n", queue->fname); } - pixbuf = gdk_pixbuf_new_from_file_at_scale (DEFAULT_COVER_PATH, queue->width, queue->width, TRUE, &error); + pixbuf = gdk_pixbuf_new_from_file_at_scale (defpath, queue->width, queue->width, TRUE, &error); if (!pixbuf) { - fprintf (stderr, "gdk_pixbuf_new_from_file_at_scale %s %d failed, error: %s\n", DEFAULT_COVER_PATH, queue->width, error->message); + fprintf (stderr, "gdk_pixbuf_new_from_file_at_scale %s %d failed, error: %s\n", defpath, queue->width, error->message); } } if (error) { diff --git a/plugins/gtkui/ddblistview.c b/plugins/gtkui/ddblistview.c index 89a27cff..8fce3463 100644 --- a/plugins/gtkui/ddblistview.c +++ b/plugins/gtkui/ddblistview.c @@ -2268,7 +2268,9 @@ ddb_listview_header_motion_notify_event (GtkWidget *widget, ev_x = event->x; ev_y = event->y; ev_state = event->state; +#if GTK_CHECK_VERSION(2,12,0) && !defined(ULTRA_COMPATIBLE) gdk_event_request_motions (event); +#endif if ((ev_state & GDK_BUTTON1_MASK) && ps->header_prepare) { if (gtk_drag_check_threshold (widget, ev_x, ps->prev_header_x, 0, 0)) { @@ -2630,7 +2632,9 @@ ddb_listview_motion_notify_event (GtkWidget *widget, { int x = event->x; int y = event->y; +#if GTK_CHECK_VERSION(2,12,0) && !defined(ULTRA_COMPATIBLE) gdk_event_request_motions (event); +#endif DdbListview *ps = DDB_LISTVIEW (g_object_get_data (G_OBJECT (widget), "owner")); ddb_listview_list_mousemove (ps, event, x, y); return FALSE; diff --git a/plugins/gtkui/ddbtabstrip.c b/plugins/gtkui/ddbtabstrip.c index ea7905c7..90f440dd 100644 --- a/plugins/gtkui/ddbtabstrip.c +++ b/plugins/gtkui/ddbtabstrip.c @@ -879,7 +879,9 @@ on_tabstrip_motion_notify_event (GtkWidget *widget, ev_x = event->x; ev_y = event->y; ev_state = event->state; +#if GTK_CHECK_VERSION(2,12,0) && !defined(ULTRA_COMPATIBLE) gdk_event_request_motions (event); +#endif if ((ev_state & GDK_BUTTON1_MASK) && ts->prepare) { if (gtk_drag_check_threshold (widget, ev_x, ts->prev_x, 0, 0)) { ts->prepare = 0; diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c index 35da1527..06ceb756 100644 --- a/plugins/gtkui/gtkui.c +++ b/plugins/gtkui/gtkui.c @@ -223,7 +223,7 @@ update_songinfo (gpointer ctx) { void set_tray_tooltip (const char *text) { if (trayicon) { -#if (GTK_MINOR_VERSION < 16) +#if !GTK_CHECK_VERSION(2,16,0) || defined(ULTRA_COMPATIBLE) gtk_status_icon_set_tooltip (trayicon, text); #else gtk_status_icon_set_tooltip_text (trayicon, text); @@ -292,7 +292,7 @@ mainwin_toggle_visible (void) { } } -#if GTK_MINOR_VERSION<=14 +#if !GTK_CHECK_VERSION(2,14,0) || defined(ULTRA_COMPATIBLE) gboolean on_trayicon_activate (GtkWidget *widget, @@ -583,12 +583,19 @@ gtkui_update_status_icon (gpointer unused) { icon_name = icon_is_builtin ? "deadbeef" : icon_name; } - trayicon = gtk_status_icon_new_from_icon_name(icon_name); + if (!gtk_icon_theme_has_icon(theme, icon_name)) { + char iconpath[1024]; + snprintf (iconpath, sizeof (iconpath), "%s/deadbeef.png", deadbeef->get_prefix ()); + trayicon = gtk_status_icon_new_from_file(iconpath); + } + else { + trayicon = gtk_status_icon_new_from_icon_name(icon_name); + } if (hide_tray_icon) { g_object_set (trayicon, "visible", FALSE, NULL); } -#if GTK_MINOR_VERSION <= 14 +#if !GTK_CHECK_VERSION(2,14,0) || defined(ULTRA_COMPATIBLE) g_signal_connect ((gpointer)trayicon, "activate", G_CALLBACK (on_trayicon_activate), NULL); #else g_signal_connect ((gpointer)trayicon, "scroll_event", G_CALLBACK (on_trayicon_scroll_event), NULL); @@ -900,7 +907,8 @@ void gtkui_thread (void *ctx) { // let's start some gtk g_thread_init (NULL); - add_pixmap_directory (PREFIX "/share/deadbeef/pixmaps"); +// add_pixmap_directory (PREFIX "/share/deadbeef/pixmaps"); + add_pixmap_directory (deadbeef->get_pixmap_dir ()); gdk_threads_init (); gdk_threads_enter (); @@ -918,7 +926,13 @@ gtkui_thread (void *ctx) { mainwin = create_mainwin (); gtkpl_init (); +#if PORTABLE + char iconpath[1024]; + snprintf (iconpath, sizeof (iconpath), "%s/deadbeef.png", deadbeef->get_prefix ()); + gtk_window_set_icon_from_file (GTK_WINDOW (mainwin), iconpath, NULL); +#else gtk_window_set_icon_name (GTK_WINDOW (mainwin), "deadbeef"); +#endif { int x = deadbeef->conf_get_int ("mainwin.geometry.x", 40); @@ -1093,6 +1107,8 @@ gtkui_playlist_set_curr (int playlist) { static int gtkui_start (void) { + fprintf (stderr, "gtkui plugin compiled for gtk version: %d.%d.%d\n", GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION); + // gtk must be running in separate thread gtk_initialized = 0; gtk_tid = deadbeef->thread_start (gtkui_thread, NULL); @@ -1207,8 +1223,8 @@ static const char settings_dlg[] = // define plugin interface static DB_gui_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.nostop = 1, .plugin.type = DB_PLUGIN_MISC, .plugin.name = "Standard GTK2 user interface", diff --git a/plugins/gtkui/gtkui.h b/plugins/gtkui/gtkui.h index 53db09af..7cb2dff4 100644 --- a/plugins/gtkui/gtkui.h +++ b/plugins/gtkui/gtkui.h @@ -25,12 +25,20 @@ #include <gtk/gtk.h> +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + +#if defined(ULTRA_COMPATIBLE) +#warning compiling for compatibility with gtk <2.14 +#endif + // workaround to make older gtk compatible with vala codegen -#if !GTK_CHECK_VERSION(2,14,0) +#if !GTK_CHECK_VERSION(2,14,0) || defined(ULTRA_COMPATIBLE) #define gtk_widget_get_window(widget) ((widget)->window) #endif -#if !GTK_CHECK_VERSION(2,18,0) +#if !GTK_CHECK_VERSION(2,18,0) || defined(ULTRA_COMPATIBLE) #define gtk_widget_set_has_window(widget, has_window) \ if (has_window) GTK_WIDGET_UNSET_FLAGS (widget, GTK_NO_WINDOW); \ else GTK_WIDGET_SET_FLAGS (widget, GTK_NO_WINDOW); @@ -39,7 +47,7 @@ #define gtk_widget_get_has_window(widget) (!GTK_WIDGET_NO_WINDOW(widget)) #endif -#if !GTK_CHECK_VERSION(2,20,0) +#if !GTK_CHECK_VERSION(2,20,0) || defined(ULTRA_COMPATIBLE) #define gtk_widget_get_realized(widget) (GTK_WIDGET_REALIZED(widget)) #endif diff --git a/plugins/hotkeys/hotkeys.c b/plugins/hotkeys/hotkeys.c index 2be24387..906fb74c 100644 --- a/plugins/hotkeys/hotkeys.c +++ b/plugins/hotkeys/hotkeys.c @@ -693,6 +693,8 @@ hotkeys_get_actions (DB_playItem_t *it) static DB_hotkeys_plugin_t plugin = { .misc.plugin.api_vmajor = DB_API_VERSION_MAJOR, .misc.plugin.api_vminor = DB_API_VERSION_MINOR, + .misc.plugin.version_major = 1, + .misc.plugin.version_minor = 0, .misc.plugin.type = DB_PLUGIN_MISC, .misc.plugin.id = "hotkeys", .misc.plugin.name = "Global hotkeys support", diff --git a/plugins/lastfm/lastfm.c b/plugins/lastfm/lastfm.c index 4a234e8f..5ebe1745 100644 --- a/plugins/lastfm/lastfm.c +++ b/plugins/lastfm/lastfm.c @@ -902,8 +902,8 @@ static const char settings_dlg[] = // define plugin interface static DB_misc_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_MISC, .plugin.name = "last.fm scrobbler", .plugin.descr = "sends played songs information to your last.fm account", diff --git a/plugins/mms/mmsplug.c b/plugins/mms/mmsplug.c index 4ad57832..5f484273 100644 --- a/plugins/mms/mmsplug.c +++ b/plugins/mms/mmsplug.c @@ -110,8 +110,8 @@ static const char *scheme_names[] = { "mms://", "mmsh://", NULL }; static DB_vfs_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_VFS, .plugin.name = "mms vfs", .plugin.descr = "MMS streaming plugin based on libmms", diff --git a/plugins/mpgmad/mpgmad.c b/plugins/mpgmad/mpgmad.c index 13544238..03ddbc91 100644 --- a/plugins/mpgmad/mpgmad.c +++ b/plugins/mpgmad/mpgmad.c @@ -1234,8 +1234,8 @@ static const char *exts[] = { // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "stdmpg", .plugin.name = "MPEG decoder", diff --git a/plugins/mpris/Makefile.am b/plugins/mpris/Makefile.am new file mode 100644 index 00000000..da59d242 --- /dev/null +++ b/plugins/mpris/Makefile.am @@ -0,0 +1,8 @@ +if HAVE_MPRIS +mprisdir = $(libdir)/$(PACKAGE) +pkglib_LTLIBRARIES = mpris.la +AM_CFLAGS = $(CFLAGS) $(MPRIS_DEPS_CFLAGS) -std=c99 +mpris_la_SOURCES = mpris.c mpris-spec.h +mpris_la_LDFLAGS = -module +mpris_la_LIBADD = $(LDADD) $(MPRIS_DEPS_LIBS) +endif diff --git a/plugins/mpris/mpris-spec.h b/plugins/mpris/mpris-spec.h new file mode 100644 index 00000000..dba8f542 --- /dev/null +++ b/plugins/mpris/mpris-spec.h @@ -0,0 +1,91 @@ +#define MPRIS_BUS_NAME_PREFIX "org.mpris.MediaPlayer2" +#define MPRIS_OBJECT_NAME "/org/mpris/MediaPlayer2" + +#define MPRIS_ROOT_INTERFACE "org.mpris.MediaPlayer2" +#define MPRIS_PLAYER_INTERFACE "org.mpris.MediaPlayer2.Player" +#define MPRIS_TRACKLIST_INTERFACE "org.mpris.MediaPlayer2.TrackList" + +const char *mpris_introspection_xml = + "<node>" + " <interface name='org.mpris.MediaPlayer2'>" + " <method name='Raise'/>" + " <method name='Quit'/>" + " <property name='CanQuit' type='b' access='read'/>" + " <property name='CanRaise' type='b' access='read'/>" + " <property name='HasTrackList' type='b' access='read'/>" + " <property name='Identity' type='s' access='read'/>" + " <property name='DesktopEntry' type='s' access='read'/>" + " <property name='SupportedUriSchemes' type='as' access='read'/>" + " <property name='SupportedMimeTypes' type='as' access='read'/>" + " </interface>" + " <interface name='org.mpris.MediaPlayer2.Player'>" + " <method name='Next'/>" + " <method name='Previous'/>" + " <method name='Pause'/>" + " <method name='PlayPause'/>" + " <method name='Stop'/>" + " <method name='Play'/>" + " <method name='Seek'>" + " <arg direction='in' name='Offset' type='x'/>" + " </method>" + " <method name='SetPosition'>" + " <arg direction='in' name='TrackId' type='o'/>" + " <arg direction='in' name='Position' type='x'/>" + " </method>" + " <method name='OpenUri'>" + " <arg direction='in' name='Uri' type='s'/>" + " </method>" + " <signal name='Seeked'>" + " <arg name='Position' type='x'/>" + " </signal>" + " <property name='PlaybackStatus' type='s' access='read'/>" + " <property name='LoopStatus' type='s' access='readwrite'/>" + " <property name='Rate' type='d' access='readwrite'/>" + " <property name='Shuffle' type='b' access='readwrite'/>" + " <property name='Metadata' type='a{sv}' access='read'/>" + " <property name='Volume' type='d' access='readwrite'/>" + " <property name='Position' type='x' access='read'/>" + " <property name='MinimumRate' type='d' access='read'/>" + " <property name='MaximumRate' type='d' access='read'/>" + " <property name='CanGoNext' type='b' access='read'/>" + " <property name='CanGoPrevious' type='b' access='read'/>" + " <property name='CanPlay' type='b' access='read'/>" + " <property name='CanPause' type='b' access='read'/>" + " <property name='CanSeek' type='b' access='read'/>" + " <property name='CanControl' type='b' access='read'/>" + " </interface>" + " <interface name='org.mpris.MediaPlayer2.TrackList'>" + " <method name='GetTracksMetadata'>" + " <arg direction='in' name='TrackIds' type='ao'/>" + " <arg direction='out' name='Metadata' type='aa{sv}'/>" + " </method>" + " <method name='AddTrack'>" + " <arg direction='in' name='Uri' type='s'/>" + " <arg direction='in' name='AfterTrack' type='o'/>" + " <arg direction='in' name='SetAsCurrent' type='b'/>" + " </method>" + " <method name='RemoveTrack'>" + " <arg direction='in' name='TrackId' type='o'/>" + " </method>" + " <method name='GoTo'>" + " <arg direction='in' name='TrackId' type='o'/>" + " </method>" + " <signal name='TrackListReplaced'>" + " <arg name='Tracks' type='ao'/>" + " <arg name='CurrentTrack' type='o'/>" + " </signal>" + " <signal name='TrackAdded'>" + " <arg name='Metadata' type='a{sv}'/>" + " <arg name='AfterTrack' type='o'/>" + " </signal>" + " <signal name='TrackRemoved'>" + " <arg name='TrackId' type='o'/>" + " </signal>" + " <signal name='TrackMetadataChanged'>" + " <arg name='TrackId' type='o'/>" + " <arg name='Metadata' type='a{sv}'/>" + " </signal>" + " <property name='Tracks' type='ao' access='read'/>" + " <property name='CanEditTracks' type='b' access='read'/>" + " </interface>" + "</node>"; diff --git a/plugins/mpris/mpris.c b/plugins/mpris/mpris.c new file mode 100644 index 00000000..040de84c --- /dev/null +++ b/plugins/mpris/mpris.c @@ -0,0 +1,1310 @@ +/* + Sound Menu plugin for DeaDBeeF + Copyright (C) 2010 Robert Y <Decatf@gmail.com> + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <time.h> +#include <gio/gio.h> +//#include <libindicate/server.h> + +#include <deadbeef/deadbeef.h> +#include "../artwork/artwork.h" + +#include "mpris-spec.h" + +#define trace(...) +#define ENTRY_OBJECT_PATH_PREFIX "/org/mpris/MediaPlayer2/Track/" +#define DESKTOP_FILE "/usr/share/applications/deadbeef.desktop" + +static DB_dsp_t plugin; +DB_functions_t *deadbeef; + +static short enabled = 0; +DB_artwork_plugin_t *coverart_plugin = NULL; + +//static IndicateServer *indicate_server; +static GDBusConnection *connection; +static guint name_own_id; +static guint root_id; +static guint player_id; + +static GHashTable *player_property_changes = NULL; +static guint player_property_emit_id = 0; +uintptr_t hash_table_mtx; +uintptr_t emit_id_mtx; + +double prev_track_pos; + + +static gboolean check_can_go_next(); +static gboolean check_can_go_prev(); +void cover_avail_callback (const char *fname, const char *artist, const char *album, void *user_data); + + +/* MPRIS root interface */ +static void +handle_root_method_call (GDBusConnection *connection, + const char *sender, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer *user_data) +{ + if (g_strcmp0 (object_path, MPRIS_OBJECT_NAME) != 0 || + g_strcmp0 (interface_name, MPRIS_ROOT_INTERFACE) != 0) { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_NOT_SUPPORTED, + "Method %s.%s not supported", + interface_name, + method_name); + return; + } + + if (g_strcmp0 (method_name, "Raise") == 0) { + /* TODO: need way to talk to gtkui plugin */ + g_dbus_method_invocation_return_value (invocation, NULL); + } else if (g_strcmp0 (method_name, "Quit") == 0) { + deadbeef->quit(); + g_dbus_method_invocation_return_value (invocation, NULL); + } else { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_NOT_SUPPORTED, + "Method %s.%s not supported", + interface_name, + method_name); + } +} + +static GVariant * +get_root_property (GDBusConnection *connection, + const char *sender, + const char *object_path, + const char *interface_name, + const char *property_name, + GError **error, + gpointer *user_data) +{ + if (g_strcmp0 (object_path, MPRIS_OBJECT_NAME) != 0 || + g_strcmp0 (interface_name, MPRIS_ROOT_INTERFACE) != 0) { + g_set_error (error, + G_DBUS_ERROR, + G_DBUS_ERROR_NOT_SUPPORTED, + "Property %s.%s not supported", + interface_name, + property_name); + return NULL; + } + + if (g_strcmp0 (property_name, "CanQuit") == 0) { + return g_variant_new_boolean (TRUE); + } else if (g_strcmp0 (property_name, "CanRaise") == 0) { + return g_variant_new_boolean (FALSE); + } else if (g_strcmp0 (property_name, "HasTrackList") == 0) { + return g_variant_new_boolean (FALSE); + } else if (g_strcmp0 (property_name, "Identity") == 0) { + return g_variant_new_string ("DeaDBeef audio player"); + } else if (g_strcmp0 (property_name, "DesktopEntry") == 0) { + return g_variant_new_string(DESKTOP_FILE); + } else if (g_strcmp0 (property_name, "SupportedUriSchemes") == 0) { + /* need some way to fetch these values */ + const char *fake_supported_schemes[] = { + "file", "http", "cdda", "smb", "sftp", NULL + }; + return g_variant_new_strv (fake_supported_schemes, -1); + } else if (g_strcmp0 (property_name, "SupportedMimeTypes") == 0) { + const char *fake_supported_mimetypes[] = { + "application/ogg", "audio/x-vorbis+ogg", "audio/x-flac", "audio/mpeg", NULL + }; + return g_variant_new_strv (fake_supported_mimetypes, -1); + } + + g_set_error (error, + G_DBUS_ERROR, + G_DBUS_ERROR_NOT_SUPPORTED, + "Property %s.%s not supported", + interface_name, + property_name); + return NULL; +} + +static const GDBusInterfaceVTable root_vtable = +{ + (GDBusInterfaceMethodCallFunc) handle_root_method_call, + (GDBusInterfaceGetPropertyFunc) get_root_property, + NULL +}; + + +/* MPRIS player interface */ + +static void +playpause () { + DB_output_t *output = NULL; + int state = -1; + + output = deadbeef->get_output(); + if (output == NULL) { + //printf ("[mpris] playpause(): Could not get output\n"); + return; + } + + state = output->state(); + + if (state == OUTPUT_STATE_STOPPED) { + deadbeef->playback_play(); + } + else if (state == OUTPUT_STATE_PLAYING) { + deadbeef->playback_pause(); + } + else if (state == OUTPUT_STATE_PAUSED) { + deadbeef->playback_play(); + } + else { + printf ("[mpris] playpause(): Error\n"); + } +} + +static void +seek (gint64 offset) +{ + DB_playItem_t *play_item = NULL; + play_item = deadbeef->streamer_get_playing_track (); + if (play_item == NULL) { + //printf ("[mpris] seek(): No play item\n"); + return; + } + + // Play position in seconds + float playpos = deadbeef->streamer_get_playpos(); + float newpos = playpos+(offset/G_USEC_PER_SEC); + + if (newpos < 0) { + newpos = 0.f; + } else if (newpos > play_item->playtime) { + deadbeef->playback_next(); + return; + } + + deadbeef->pl_item_unref(play_item); + deadbeef->streamer_seek (newpos); +} + +static GVariant * +get_playback_status (void) +{ + GVariant *v = NULL; + DB_output_t *output = NULL; + int state = -1; + + output = deadbeef->get_output(); + if (output == NULL) { + printf ("[mpris] get_playback_status: Could not get output\n"); + return v; + } + + state = output->state(); + + if (state == OUTPUT_STATE_STOPPED) { + v = g_variant_new_string ("Stopped"); + //printf ("[mpris] get_playback_status: Stopped\n"); + } + else if (state == OUTPUT_STATE_PLAYING) { + v = g_variant_new_string ("Playing"); + //printf ("[mpris] get_playback_status: Playing\n"); + } + else if (state == OUTPUT_STATE_PAUSED) { + v = g_variant_new_string ("Paused"); + //printf ("[mpris] get_playback_status: Paused\n"); + } + else { + //printf ("[mpris] get_playback_status: Error\n"); + } + + return v; +} + +static GVariant * +get_loop_status (void) +{ + GVariant *v = NULL; + int loop_mode; + loop_mode = deadbeef->conf_get_int ("playback.loop", 0); + + if (loop_mode == PLAYBACK_MODE_NOLOOP) { + //printf ("[mpris] get_loop_status: None\n"); + v = g_variant_new_string ("None"); + } + else if (loop_mode == PLAYBACK_MODE_LOOP_ALL) { + //printf ("[mpris] get_loop_status: Playlist\n"); + v = g_variant_new_string ("Playlist"); + } + else if (loop_mode == PLAYBACK_MODE_LOOP_SINGLE) { + //printf ("[mpris] get_loop_status: Track\n"); + v = g_variant_new_string ("Track"); + } + + return v; +} + +static gboolean +set_loop_status (GVariant *value) +{ + gchar *loop_status; + g_variant_get (value, "s", &loop_status); + + if (g_strcmp0 (loop_status, "None") == 0) { + deadbeef->conf_set_int ("playback.loop", PLAYBACK_MODE_NOLOOP); + return TRUE; + } else if (g_strcmp0 (loop_status, "Playlist") == 0) { + deadbeef->conf_set_int ("playback.loop", PLAYBACK_MODE_LOOP_ALL); + return TRUE; + } else if (g_strcmp0 (loop_status, "Track") == 0) { + deadbeef->conf_set_int ("playback.loop", PLAYBACK_MODE_LOOP_SINGLE); + return TRUE; + } + return FALSE; +} + +static GVariant * +get_shuffle (void) +{ + GVariant *v = NULL; + int shuffle_mode; + shuffle_mode = deadbeef->conf_get_int ("playback.order", 0); + + if (shuffle_mode == PLAYBACK_ORDER_LINEAR) { + //printf ("[mpris] get_shuffle: None\n"); + v = g_variant_new_boolean (FALSE); + } + else if (shuffle_mode == PLAYBACK_ORDER_SHUFFLE) { + //printf ("[mpris] get_shuffle: Playlist\n"); + v = g_variant_new_boolean (TRUE); + } + else if (shuffle_mode == PLAYBACK_ORDER_RANDOM) { + //printf ("[mpris] get_shuffle: Track\n"); + v = g_variant_new_boolean (TRUE); + } + + return v; +} + +static gboolean +set_shuffle (GVariant *value) +{ + gboolean shuffle; + g_variant_get (value, "b", &shuffle); + + if (shuffle == FALSE) { + deadbeef->conf_set_int ("playback.order",PLAYBACK_ORDER_LINEAR); + } else { + deadbeef->conf_set_int ("playback.order", PLAYBACK_ORDER_SHUFFLE); + } + + return TRUE; +} + +static GVariant * +get_metadata (void) +{ + GVariantBuilder *b; + DB_playItem_t *play_item = NULL; + + b = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + + play_item = deadbeef->streamer_get_playing_track (); + if (play_item == NULL) { + //printf ("[mpris] get_metadata: No play item\n"); + return g_variant_builder_end (b);; + } + + char buf[200]; + int buf_size = sizeof(buf); + + gchar *trackid_str; + deadbeef->pl_format_title (play_item, -1, buf, buf_size, DB_COLUMN_FILENUMBER, NULL); + trackid_str = g_strdup_printf(ENTRY_OBJECT_PATH_PREFIX "%s", buf); + //printf ("[mpris] get_metadata: trackid %s\n", trackid_str); + g_variant_builder_add (b, "{sv}", "mpris:trackid", g_variant_new("s", trackid_str)); + g_free(trackid_str); + + gchar *title_str; + deadbeef->pl_format_title (play_item, -1, buf, buf_size, -1, "%t"); + title_str = g_strdup_printf("%s", buf); + //printf ("[mpris] get_metadata: title_str %s\n", title_str); + g_variant_builder_add (b, "{sv}", "xesam:title", g_variant_new("s", title_str)); + g_free(title_str); + + gchar *artist_str; + deadbeef->pl_format_title (play_item, -1, buf, buf_size, -1, "%a"); + artist_str = g_strdup_printf("%s", buf); + //printf ("[mpris] get_metadata: artist_str %s\n", artist_str); + const char *artist_strv[] = {artist_str, NULL}; + g_variant_builder_add (b, "{sv}", "xesam:artist", g_variant_new_strv (artist_strv, -1)); + + + gchar *albumartist_str; + deadbeef->pl_format_title (play_item, -1, buf, buf_size, -1, "%B"); + albumartist_str = g_strdup_printf("%s", buf); + //printf ("[mpris] get_metadata: albumartist_str %s\n", albumartist_str); + const char *albumartist_strv[] = {albumartist_str, NULL}; + g_variant_builder_add (b, "{sv}", "xesam:albumArtist", g_variant_new_strv (albumartist_strv, -1)); + g_free(albumartist_str); + + gchar *album_str; + deadbeef->pl_format_title (play_item, -1, buf, buf_size, -1, "%b"); + album_str = g_strdup_printf("%s", buf); + //printf ("[mpris] get_metadata: album_str %s\n", album_str); + g_variant_builder_add (b, "{sv}", "xesam:album", g_variant_new("s", album_str)); + + if (coverart_plugin != NULL) { + gchar *image_fname = coverart_plugin->get_album_art (play_item->fname, + artist_str, + album_str, + cover_avail_callback, NULL); + g_free(artist_str); + g_free(album_str); + if (image_fname) { + gchar *art_str = g_strjoin (NULL, "file://", image_fname, NULL); + g_variant_builder_add (b, "{sv}", "mpris:artUrl", g_variant_new("s", art_str)); + //printf ("[mpris] get_metadata: image_fname %s\n", art_str); + g_free (image_fname); + g_free (art_str); + } + } + + gchar *track_num_str; + deadbeef->pl_format_title (play_item, -1, buf, buf_size, -1, "%n"); + track_num_str = g_strdup_printf("%s", buf); + gint64 track_num = g_ascii_strtoll (track_num_str, NULL, 10); + //printf ("[mpris] get_metadata: tracknum %ld\n", (long int) track_num); + g_variant_builder_add (b, "{sv}", "xesam:trackNumber", g_variant_new("x", track_num)); + g_free(track_num_str); + + gint64 length = play_item->playtime * G_USEC_PER_SEC; + //printf ("[mpris] get_metadata: length %ld\n", (long int) length); + g_variant_builder_add (b, "{sv}", "mpris:length", g_variant_new("x", length)); + + gchar *genre_str; + deadbeef->pl_format_title (play_item, -1, buf, buf_size, -1, "%g"); + genre_str = g_strdup_printf("%s", buf); + //printf ("[mpris] get_metadata: genre_str %s\n", genre_str); + const char *genre_strv[] = {genre_str, NULL}; + g_variant_builder_add (b, "{sv}", "xesam:genre", g_variant_new_strv (genre_strv, -1)); + g_free(genre_str); + + gchar *comment_str; + deadbeef->pl_format_title (play_item, -1, buf, buf_size, -1, "%c"); + comment_str = g_strdup_printf("%s", buf); + //printf ("[mpris] get_metadata: comment_str %s\n", comment_str); + const char *comment_strv[] = {comment_str, NULL}; + g_variant_builder_add (b, "{sv}", "xesam:comment", g_variant_new_strv (comment_strv, -1)); + g_free(comment_str); + + deadbeef->pl_item_unref(play_item); + //printf ("[mpris] get_metadata: done\n"); + + return g_variant_builder_end (b); +} + +static GVariant * +get_position (void) +{ + GVariant *v = NULL; + + DB_playItem_t *play_item = NULL; + play_item = deadbeef->streamer_get_playing_track (); + if (play_item == NULL) { + //printf ("[mpris] get_position: No play item\n"); + return v; + } + + deadbeef->pl_item_unref(play_item); + + float playpos = deadbeef->streamer_get_playpos(); + return g_variant_new_int64 (playpos*G_USEC_PER_SEC); +} + +void +set_position (const gchar* track_id, gint64 position) +{ + DB_playItem_t *play_item = NULL; + play_item = deadbeef->streamer_get_playing_track (); + if (play_item == NULL) { + //printf ("[mpris] set_position: No play item\n"); + return; + } + + gint64 play_time = play_item->playtime*G_USEC_PER_SEC; + if (position > play_time) + return; + + char *trackid_str; + trackid_str = g_strdup_printf(ENTRY_OBJECT_PATH_PREFIX "%s", play_item->fname); + if (g_strcmp0(trackid_str, track_id) != 0) { + g_free(trackid_str); + return; + } + g_free(trackid_str); + deadbeef->pl_item_unref(play_item); + + deadbeef->streamer_seek((float)position/G_USEC_PER_SEC); +} + +static GVariant * +get_canplay (void) +{ + DB_playItem_t *play_item = NULL; + play_item = deadbeef->streamer_get_playing_track (); + if (play_item == NULL) { + return g_variant_new_boolean(FALSE); + } + deadbeef->pl_item_unref(play_item); + + return g_variant_new_boolean(TRUE); +} + +static GVariant * +get_canpause (void) +{ + DB_playItem_t *play_item = NULL; + play_item = deadbeef->streamer_get_playing_track (); + if (play_item == NULL) { + return g_variant_new_boolean(FALSE); + } + deadbeef->pl_item_unref(play_item); + + DB_output_t *output = NULL; + output = deadbeef->get_output(); + if (output != NULL) { + if (output->state == OUTPUT_STATE_STOPPED) { + return g_variant_new_boolean(FALSE); + } + } + //else printf ("[mpris] get_canpause: Could not get output\n"); + + return g_variant_new_boolean(TRUE); +} + + +/// +// PropertiesChanged signal +/// +/* +static void +emit_property_change (const gchar *name, GVariant *value) +{ + GError *error = NULL; + GVariantBuilder *properties; + GVariant *properties_changed = NULL; + const char *invalidated[] = { NULL }; + + properties = g_variant_builder_new (G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add (properties, "{sv}", name, value); + + properties_changed = g_variant_new ("(sa{sv}^as)", + MPRIS_PLAYER_INTERFACE, + properties, + invalidated); + g_variant_builder_unref (properties); + + g_dbus_connection_emit_signal (connection, + NULL, + MPRIS_OBJECT_NAME, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + properties_changed, + &error); + + if (error != NULL) { + printf ("[mpris] Unable to send MPRIS property changes: %s", error->message); + g_clear_error (&error); + } + //printf ("[mpris] Sent property change: %s\n", name); +} +*/ + +static gboolean +emit_player_properties (gpointer data) +{ + //printf ("[mpris] emit_player_properties\n"); + + GError *error = NULL; + GVariantBuilder *properties; + GVariant *properties_changed = NULL; + const char *invalidated[] = { NULL }; + GHashTableIter iter; + gpointer propname, propvalue; + + + deadbeef->mutex_lock(hash_table_mtx); + properties = g_variant_builder_new (G_VARIANT_TYPE("a{sv}")); + g_hash_table_iter_init (&iter, player_property_changes); + while (g_hash_table_iter_next (&iter, &propname, &propvalue)) { + g_variant_builder_add (properties, "{sv}", propname, propvalue); + } + g_hash_table_destroy (player_property_changes); + player_property_changes = NULL; + deadbeef->mutex_unlock(hash_table_mtx); + + properties_changed = g_variant_new ("(sa{sv}^as)", + MPRIS_PLAYER_INTERFACE, + properties, + invalidated); + g_variant_builder_unref (properties); + + g_dbus_connection_emit_signal (connection, + NULL, + MPRIS_OBJECT_NAME, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + properties_changed, + &error); + + deadbeef->mutex_lock(emit_id_mtx); + player_property_emit_id = 0; + deadbeef->mutex_unlock(emit_id_mtx); + + if (error != NULL) { + printf ("[mpris] Unable to send MPRIS property changes: %s", error->message); + g_clear_error (&error); + } + + //printf ("[mpris] emit_player_properties: done %d\n", player_property_emit_id); + + return FALSE; +} + + +static void +add_property_change (const gchar *property, GVariant *value) +{ + //printf ("[mpris] add_property_change\n"); + + deadbeef->mutex_lock(hash_table_mtx); + if (player_property_changes == NULL) { + player_property_changes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + } + g_hash_table_insert (player_property_changes, g_strdup (property), value); + deadbeef->mutex_unlock(hash_table_mtx); + + if (player_property_emit_id == 0) { + deadbeef->mutex_lock(emit_id_mtx); + player_property_emit_id = g_idle_add ((GSourceFunc)emit_player_properties, NULL); + //printf ("[mpris] add_property_change: done\n"); + deadbeef->mutex_unlock(emit_id_mtx); + + return; + } + + //printf ("[mpris] add_property_change: source exists %d\n", player_property_emit_id); +} + + +// Events from DeaDBeef + +/* + PlaybackStatus: Working + LoopStatus: need event on playback.loop config change + Rate: not supported + Shuffle: need event on playback.order config change + Metadata: Working + Volume: Working(?) + MinimumRate: not supported + MaximumRate: not supported + CanGoNext: check&emit value on song start + CanGoPrevious: check&emit value on song start + CanPlay: not implemented + CanPause: dunno how to check this + CanSeek: dunno how to check this +*/ + +static int +db_paused (DB_event_t *ev, uintptr_t data) +{ + //printf ("[mpris] db_paused: PlaybackStatus\n"); + //emit_property_change ("PlaybackStatus", get_playback_status()); + add_property_change ("PlaybackStatus", get_playback_status()); + return 0; +} + +static int +db_track_info_changed (DB_event_t *ev, uintptr_t data) +{ + + //printf ("[mpris] db_track_info_changed\n"); + GVariant *v = NULL; + DB_output_t *output = NULL; + int state = -1; + + // Playback state change + output = deadbeef->get_output(); + if (output == NULL) { + //printf ("[mpris] db_track_info_changed(): Could not get output\n"); + return 0; + } + + state = output->state(); + if (state == OUTPUT_STATE_STOPPED) { + v = g_variant_new_string ("Stopped"); + //printf ("[mpris] db_track_info_changed: Stopped\n"); + } + else if (state == OUTPUT_STATE_PLAYING) { + v = g_variant_new_string ("Playing"); + //printf ("[mpris] db_track_info_changed: Playing\n"); + } + else if (state == OUTPUT_STATE_PAUSED) { + v = g_variant_new_string ("Paused"); + //printf ("[mpris] db_track_info_changed: Paused\n"); + } + else { + //printf ("[mpris] db_track_info_changed: Error\n"); + } + //printf ("[mpris] db_track_info_changed: PlaybackStatus\n"); + //emit_property_change ("PlaybackStatus", v); + add_property_change ("PlaybackStatus", v); + + // Seek + + // A change of greater than 1 second from the + // previous track position is considered a seek. + // (including the time change from track changes) + DB_playItem_t *play_item = NULL; + play_item = deadbeef->streamer_get_playing_track (); + if (play_item != NULL) { + + float playpos = deadbeef->streamer_get_playpos(); + float diff = playpos - prev_track_pos; + if (diff > 1.f || diff < -1.f) { + //printf ("[mpris] db_track_info_changed(): Seeked: %f\n", diff); + + GError *error = NULL; + g_dbus_connection_emit_signal (connection, + NULL, + MPRIS_OBJECT_NAME, + MPRIS_PLAYER_INTERFACE, + "Seeked", + g_variant_new ("(x)", (int)(deadbeef->streamer_get_playpos())*G_USEC_PER_SEC), + &error); + if (error != NULL) { + g_warning ("[mpris] Unable to set MPRIS Seeked signal: %s", error->message); + g_clear_error (&error); + } + } + deadbeef->pl_item_unref(play_item); + } + + + // Metadata changes + v = get_metadata(); + if (v != NULL) { + //emit_property_change ("Metadata", v); + add_property_change ("Metadata", v); + } + else { + printf ("[mpris] db_track_info_changed: no track\n"); + } + + return 0; +} + +static int +db_song_changed (DB_event_t *ev, uintptr_t data) +{ +/* + printf ("[mpris] db_song_changed\n"); + GVariant *v = NULL; + v = get_metadata(); + if (v != NULL) { + emit_property_change ("Metadata", v); + } +*/ + return 0; +} + +static int +db_song_started (DB_event_t *ev, uintptr_t data) +{ + //printf ("[mpris] db_song_started\n"); + + GVariant *v = NULL; + v = get_metadata(); + if (v != NULL) { + //emit_property_change ("Metadata", v); + add_property_change ("Metadata", v); + } + + gboolean can_go_next = check_can_go_next(); + //emit_property_change ("CanGoNext", g_variant_new_boolean(can_go_next)); + add_property_change ("CanGoNext", g_variant_new_boolean(can_go_next)); + + gboolean can_go_prev = check_can_go_prev(); + //emit_property_change ("CanGoPrev", g_variant_new_boolean(can_go_prev)); + add_property_change ("CanGoPrev", g_variant_new_boolean(can_go_prev)); + + return 0; +} + +static int +db_song_finished (DB_event_t *ev, uintptr_t data) +{ + //printf ("[mpris] db_song_finished\n"); +/* + GVariant *v = NULL; + v = get_metadata(); + if (v != NULL) { + emit_property_change ("Metadata", v); + } +*/ + return 0; +} + +static int +db_volume_changed (DB_event_t *ev, uintptr_t data) +{ + gdouble volume = deadbeef->volume_get_amp(); + if (volume < 0) + volume = 0; + //emit_property_change ("Volume", g_variant_new_double (volume)); + add_property_change ("Volume", g_variant_new_double (volume)); + printf ("[mpris] db_volume_changed: Volume %lf\n", volume); + return 0; +} + +static int +db_frameupdate (DB_event_t *ev, uintptr_t data) +{ + + DB_playItem_t *play_item = NULL; + play_item = deadbeef->streamer_get_playing_track (); + if (play_item != NULL) { + prev_track_pos = deadbeef->streamer_get_playpos(); + deadbeef->pl_item_unref(play_item); + } + return 0; +} + +static int +db_playlist_switched (DB_event_t *ev, uintptr_t data) +{ + //printf ("[mpris] db_playlist_switched\n"); + return 0; +} + +static int +db_activate (DB_event_t *ev, uintptr_t data) +{ + printf ("[mpris] db_activate()\n"); + return 0; +} + +// non callback emit helper functions +static gboolean +check_can_go_next() { + + + int loop_mode = deadbeef->conf_get_int ("playback.loop", 0); + if (loop_mode == PLAYBACK_MODE_NOLOOP) { + int playlist_size = deadbeef->pl_getcount(deadbeef->plt_get_curr()); + + // Check if playlist is on last track + DB_playItem_t *play_item = NULL; + play_item = deadbeef->streamer_get_playing_track (); + if (play_item == NULL) { + deadbeef->pl_item_unref(play_item); + return FALSE; + } + + int pl_current = deadbeef->pl_get_idx_of(play_item); + if (pl_current == playlist_size) { + deadbeef->pl_item_unref(play_item); + return FALSE; + } + deadbeef->pl_item_unref(play_item); + //printf ("[mpris] check_cangonext() plt count: %d plt current: %d\n", playlist_size, pl_current); + } + + return TRUE; +} + +static gboolean +check_can_go_prev() { + + int loop_mode = deadbeef->conf_get_int ("playback.loop", 0); + if (loop_mode == PLAYBACK_MODE_NOLOOP) { + // Check if playlist is on first track + DB_playItem_t *play_item = NULL; + play_item = deadbeef->streamer_get_playing_track (); + if (play_item == NULL) { + return FALSE; + } + + int pl_current = deadbeef->pl_get_idx_of(play_item); + if (pl_current == 0) { + deadbeef->pl_item_unref(play_item); + return TRUE; + } + deadbeef->pl_item_unref(play_item); + //printf ("[mpris] check_cangoprev() plt current: %d\n", pl_current); + } + return TRUE; +} + +// Artwork plugin callback +void cover_avail_callback (const char *fname, const char *artist, const char *album, void *user_data) { + //printf ("[mpris] cover_avail_callback\n"); + GVariant *v = get_metadata(); + //emit_property_change ("Metadata", v); + add_property_change ("Metadata", v); +} + + +/// +// MediaPlayer2.Player handlers +/// +static void +handle_result (GDBusMethodInvocation *invocation) +{ + g_dbus_method_invocation_return_error_literal (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Unknown error"); +} + +static void +handle_player_method_call (GDBusConnection *connection, + const char *sender, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer *user_data) +{ + + if (g_strcmp0 (object_path, MPRIS_OBJECT_NAME) != 0 || + g_strcmp0 (interface_name, MPRIS_PLAYER_INTERFACE) != 0) { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_NOT_SUPPORTED, + "Method %s.%s not supported", + interface_name, + method_name); + return; + } + + if (g_strcmp0 (method_name, "Next") == 0) { + deadbeef->playback_next(); + handle_result (invocation); + } else if (g_strcmp0 (method_name, "Previous") == 0) { + deadbeef->playback_prev(); + handle_result (invocation); + } else if (g_strcmp0 (method_name, "PlayPause") == 0) { + playpause(); + handle_result (invocation); + } else if (g_strcmp0 (method_name, "Stop") == 0) { + deadbeef->playback_stop(); + handle_result (invocation); + } else if (g_strcmp0 (method_name, "Play") == 0) { + deadbeef->playback_play(); + handle_result (invocation); + } else if (g_strcmp0 (method_name, "Seek") == 0) { + gint64 offset; + g_variant_get (parameters, "(x)", &offset); + seek (offset); + handle_result (invocation); + } else if (g_strcmp0 (method_name, "SetPosition") == 0) { + gint64 position; + const gchar *track_id; + g_variant_get (parameters, "&ox", &track_id, &position); + set_position (track_id, position); + handle_result (invocation); + } else if (g_strcmp0 (method_name, "OpenUri") == 0) { + /* TODO: implement this */ + const char *uri; + g_variant_get (parameters, "(&s)", &uri); + + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_NOT_SUPPORTED, + "Method %s.%s not supported", + interface_name, + method_name); + + } else { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_NOT_SUPPORTED, + "Method %s.%s not supported", + interface_name, + method_name); + } +} + +static GVariant * +get_player_property (GDBusConnection *connection, + const char *sender, + const char *object_path, + const char *interface_name, + const char *property_name, + GError **error, + gpointer *user_data) +{ + + //printf ("[mpris] get_player_property\n"); + if (g_strcmp0 (property_name, "PlaybackStatus") == 0) { + return get_playback_status(); + } else if (g_strcmp0 (property_name, "LoopStatus") == 0) { + return get_loop_status (); + } else if (g_strcmp0 (property_name, "Rate") == 0) { + return g_variant_new_double (1.0); + } else if (g_strcmp0 (property_name, "Shuffle") == 0) { + return get_shuffle (); + } else if (g_strcmp0 (property_name, "Metadata") == 0) { + //printf ("[mpris] get_player_property: Metadata\n"); + return get_metadata (); + } else if (g_strcmp0 (property_name, "Volume") == 0) { + gdouble volume = deadbeef->volume_get_amp(); + return g_variant_new_double(volume); + } else if (g_strcmp0 (property_name, "Position") == 0) { + return get_position(); + } else if (g_strcmp0 (property_name, "MinimumRate") == 0) { + return g_variant_new_double (1.0); + } else if (g_strcmp0 (property_name, "MaximumRate") == 0) { + return g_variant_new_double (1.0); + } else if (g_strcmp0 (property_name, "CanGoNext") == 0) { + return g_variant_new_boolean (TRUE); + } else if (g_strcmp0 (property_name, "CanGoPrevious") == 0) { + return g_variant_new_boolean (TRUE); + } else if (g_strcmp0 (property_name, "CanPlay") == 0) { + return get_canplay(); + } else if (g_strcmp0 (property_name, "CanPause") == 0) { + return get_canpause(); + } else if (g_strcmp0 (property_name, "CanSeek") == 0) { + /* Not sure how to check if a track is seekable + return true anyways */ + return g_variant_new_boolean(TRUE); + } else if (g_strcmp0 (property_name, "CanControl") == 0) { + return g_variant_new_boolean(TRUE); + } + + g_set_error (error, + G_DBUS_ERROR, + G_DBUS_ERROR_NOT_SUPPORTED, + "Property %s.%s not supported", + interface_name, + property_name); + return NULL; +} + +static gboolean +set_player_property (GDBusConnection *connection, + const char *sender, + const char *object_path, + const char *interface_name, + const char *property_name, + GVariant *value, + GError **error, + gpointer *user_data) +{ + + if (g_strcmp0 (object_path, MPRIS_OBJECT_NAME) != 0 || + g_strcmp0 (interface_name, MPRIS_PLAYER_INTERFACE) != 0) { + g_set_error (error, + G_DBUS_ERROR, + G_DBUS_ERROR_NOT_SUPPORTED, + "%s:%s not supported", + object_path, + interface_name); + return FALSE; + } + + if (g_strcmp0 (property_name, "LoopStatus") == 0) { + return set_loop_status(value); + } else if (g_strcmp0 (property_name, "Rate") == 0) { + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "[mpris] Can't modify playback rate"); + return FALSE; + } else if (g_strcmp0 (property_name, "Shuffle") == 0) { + set_shuffle (value); + return TRUE; + } else if (g_strcmp0 (property_name, "Volume") == 0) { + gdouble volume; + volume = g_variant_get_double (value); + if (volume < 0) volume = 0; + deadbeef->volume_set_amp((float)volume); + printf ("[mpris] set_player_property: volume %lf\n", volume); + return TRUE; + } + + g_set_error (error, + G_DBUS_ERROR, + G_DBUS_ERROR_NOT_SUPPORTED, + "Property %s.%s not supported", + interface_name, + property_name); + return FALSE; +} + +static const GDBusInterfaceVTable player_vtable = +{ + (GDBusInterfaceMethodCallFunc) handle_player_method_call, + (GDBusInterfaceGetPropertyFunc) get_player_property, + (GDBusInterfaceSetPropertyFunc) set_player_property, +}; + + +/* DeaDBeef plugin */ + +static void +name_acquired_cb (GDBusConnection *connection, const char *name, gpointer *user_data) +{ + trace ("[mpris] Successfully acquired dbus name %s\n", name); +} + +static void +name_lost_cb (GDBusConnection *connection, const char *name, gpointer *user_data) +{ + trace ("[mpris] Lost dbus name %s\n", name); +} + +static gboolean +mpris_begin () +{ +// indicate_server = indicate_server_ref_default (); +// indicate_server_set_type (indicate_server, "music.deadbeef"); +// indicate_server_set_desktop_file (indicate_server, DESKTOP_FILE); +// indicate_server_show (indicate_server); + + GError *error = NULL; + GDBusInterfaceInfo *ifaceinfo; + GDBusNodeInfo *node_info; + + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + if (error != NULL) { + g_warning ("[mpris] Unnable to connect to D-Bus session bus: %s", error->message); + return FALSE; + } + + // Introspection data + node_info = g_dbus_node_info_new_for_xml (mpris_introspection_xml, &error); + if (error != NULL) { + g_warning ("[mpris] Unnable to read MPRIS interface specification: %s", error->message); + return -1; + } + + // Root interface + ifaceinfo = g_dbus_node_info_lookup_interface (node_info, MPRIS_ROOT_INTERFACE); + root_id = g_dbus_connection_register_object (connection, + MPRIS_OBJECT_NAME, + ifaceinfo, + &root_vtable, + NULL, + NULL, + &error); + if (error != NULL) { + g_warning ("[mpris] Unnable to register MPRIS root interface: %s", error->message); + return FALSE; + } + + // Player interface + ifaceinfo = g_dbus_node_info_lookup_interface (node_info, MPRIS_PLAYER_INTERFACE); + player_id = g_dbus_connection_register_object (connection, + MPRIS_OBJECT_NAME, + ifaceinfo, + &player_vtable, + NULL, + NULL, + &error); + if (error != NULL) { + g_warning ("[mpris] Unable to register MPRIS player interface: %s", error->message); + g_error_free (error); + return FALSE; + } + + name_own_id = g_bus_own_name (G_BUS_TYPE_SESSION, + MPRIS_BUS_NAME_PREFIX ".deadbeef", + G_BUS_NAME_OWNER_FLAGS_NONE, + NULL, + (GBusNameAcquiredCallback) name_acquired_cb, + (GBusNameLostCallback) name_lost_cb, + NULL, + NULL); + + + // DeaDBeef event callbacks + deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_PAUSED, DB_CALLBACK (db_paused), 0); + deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_TRACKINFOCHANGED, DB_CALLBACK (db_track_info_changed), 0); + deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_SONGCHANGED, DB_CALLBACK (db_song_changed), 0); + deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_SONGSTARTED, DB_CALLBACK (db_song_started), 0); + deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_SONGFINISHED, DB_CALLBACK (db_song_finished), 0); + deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_VOLUMECHANGED, DB_CALLBACK (db_volume_changed), 0); + deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_ACTIVATE, DB_CALLBACK (db_activate), 0); + deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_PLAYLISTSWITCH, DB_CALLBACK (db_playlist_switched), 0); + deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_FRAMEUPDATE, DB_CALLBACK (db_frameupdate), 0); + + // + player_property_changes = NULL; + player_property_emit_id = 0; + hash_table_mtx = deadbeef->mutex_create(); + emit_id_mtx = deadbeef->mutex_create(); + + //printf ("[mpris] begin %d\n", name_own_id); + return TRUE; +} + +static void +mpris_end () +{ + if (coverart_plugin) { + //coverart_plugin->plugin.plugin.stop (); + coverart_plugin = NULL; + } + deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_PAUSED, DB_CALLBACK (db_paused), 0); + deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_TRACKINFOCHANGED, DB_CALLBACK (db_track_info_changed), 0); + deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_SONGCHANGED, DB_CALLBACK (db_song_changed), 0); + deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_SONGSTARTED, DB_CALLBACK (db_song_started), 0); + deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_SONGFINISHED, DB_CALLBACK (db_song_finished), 0); + deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_VOLUMECHANGED, DB_CALLBACK (db_volume_changed), 0); + deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_ACTIVATE, DB_CALLBACK (db_activate), 0); + deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_PLAYLISTSWITCH, DB_CALLBACK (db_playlist_switched), 0); + deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_FRAMEUPDATE, DB_CALLBACK (db_frameupdate), 0); + + if (root_id != 0) { + g_dbus_connection_unregister_object (connection, root_id); + root_id = 0; + } + + if (player_id != 0) { + g_dbus_connection_unregister_object (connection, player_id); + player_id = 0; + } + + if (name_own_id != 0) { + g_bus_unown_name (name_own_id); + name_own_id = 0; + } + +// indicate_server_hide (indicate_server); + + deadbeef->mutex_lock(emit_id_mtx); + if (player_property_emit_id != 0) { + g_source_remove (player_property_emit_id); + player_property_emit_id = 0; + } + deadbeef->mutex_unlock(emit_id_mtx); + deadbeef->mutex_free (emit_id_mtx); + + deadbeef->mutex_lock(hash_table_mtx); + if (player_property_changes != NULL) { + g_hash_table_destroy (player_property_changes); + player_property_changes = NULL; + } + deadbeef->mutex_unlock(hash_table_mtx); + deadbeef->mutex_free (hash_table_mtx); + + //printf ("[mpris] end\n"); +} + + +static int +mpris_connect (void) { + //printf ("[mpris] mpris_connect\n"); + DB_plugin_t **plugins = deadbeef->plug_get_list (); + for (int i = 0; plugins[i]; i++) { + DB_plugin_t *p = plugins[i]; + if (p->id && !g_strcmp0 (p->id, "cover_loader")) { + trace ("gtkui: found cover-art loader plugin\n"); + coverart_plugin = (DB_artwork_plugin_t *)p; + break; + } + } + return FALSE; +} + +static int +mpris_on_configchanged (DB_event_t *ev, uintptr_t data) { + int e = deadbeef->conf_get_int ("mpris.enable", 0); + //printf ("[mpris] configchanged(): enable %d\n", e); + if (e != enabled) { + if (e) { + mpris_begin (); + mpris_connect (); + db_track_info_changed (NULL, 0); + } else { + mpris_end (); + } + enabled = e; + } + return 0; +} + +static int +mpris_plugin_start (void) { + + deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (mpris_on_configchanged), 0); + + int e = deadbeef->conf_get_int ("mpris.enable", 0); + if (e != enabled) { + enabled = e; + if (enabled == 1) { + mpris_begin (); + } + } + + return 0; +} + +static int +mpris_plugin_stop (void) { + + deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (mpris_on_configchanged), 0); + + if (enabled == 1) { + mpris_end (); + } + + return 0; +} + +static const char settings_dlg[] = + "property \"Enable\" checkbox mpris.enable 0;\n" +; + +static DB_dsp_t plugin = { + .plugin.api_vmajor = DB_API_VERSION_MAJOR, + .plugin.api_vminor = DB_API_VERSION_MINOR, + .plugin.type = DB_PLUGIN_MISC, + .plugin.id = "mpris", + .plugin.name = "MPRIS", + .plugin.descr = "MPRIS", + .plugin.author = "Robert Y", + .plugin.email = "Decatf@gmail.com", + .plugin.website = "http://deadbeef.sf.net", + .plugin.start = mpris_plugin_start, + .plugin.stop = mpris_plugin_stop, + .plugin.configdialog = settings_dlg, + .plugin.connect = mpris_connect, +}; + +DB_plugin_t * +mpris_load (DB_functions_t *api) { + deadbeef = api; + return DB_PLUGIN (&plugin); +} diff --git a/plugins/musepack/musepack.c b/plugins/musepack/musepack.c index 69d18027..b89126f5 100644 --- a/plugins/musepack/musepack.c +++ b/plugins/musepack/musepack.c @@ -512,8 +512,8 @@ static const char *filetypes[] = { "MusePack", NULL }; // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "musepack", .plugin.name = "MusePack decoder", diff --git a/plugins/notify/notify.c b/plugins/notify/notify.c index 196a0e76..dd946062 100644 --- a/plugins/notify/notify.c +++ b/plugins/notify/notify.c @@ -253,7 +253,7 @@ DB_misc_t plugin = { .plugin.version_minor = 0, .plugin.id = "notify", .plugin.name = "OSD Notify", - .plugin.descr = "notification daemon OSD", + .plugin.descr = "Displays notifications on track changes using system notification daemon", .plugin.author = "Alexey Yakovenko", .plugin.email = "waker@users.sourceforge.net", .plugin.website = "http://deadbeef.sourceforge.net", diff --git a/plugins/nullout/nullout.c b/plugins/nullout/nullout.c index 8720de6d..9df5d9d5 100644 --- a/plugins/nullout/nullout.c +++ b/plugins/nullout/nullout.c @@ -220,8 +220,8 @@ nullout_load (DB_functions_t *api) { // define plugin interface static DB_output_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.nostop = 1, .plugin.type = DB_PLUGIN_OUTPUT, .plugin.name = "null output plugin", diff --git a/plugins/oss/oss.c b/plugins/oss/oss.c index 52c417fa..15ed7fb2 100644 --- a/plugins/oss/oss.c +++ b/plugins/oss/oss.c @@ -297,8 +297,8 @@ oss_load (DB_functions_t *api) { // define plugin interface static DB_output_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.nostop = 0, .plugin.type = DB_PLUGIN_OUTPUT, .plugin.id = "oss", diff --git a/plugins/shellexec/Makefile.am b/plugins/shellexec/Makefile.am index 65d6a5b8..212f6a0b 100644 --- a/plugins/shellexec/Makefile.am +++ b/plugins/shellexec/Makefile.am @@ -4,6 +4,6 @@ pkglib_LTLIBRARIES = shellexec.la shellexec_la_SOURCES = shellexec.c shellexec_la_LDFLAGS = -module -shellexec_la_LIBADD = $(LDADD) $(HOTKEYS_LIBS) +shellexec_la_LIBADD = $(LDADD) AM_CFLAGS = $(CFLAGS) -std=c99 endif diff --git a/plugins/shellexec/shellexec.c b/plugins/shellexec/shellexec.c index e8298cab..03b3dfc4 100644 --- a/plugins/shellexec/shellexec.c +++ b/plugins/shellexec/shellexec.c @@ -200,6 +200,8 @@ shx_start () static DB_misc_t plugin = { .plugin.api_vmajor = DB_API_VERSION_MAJOR, .plugin.api_vminor = DB_API_VERSION_MINOR, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_MISC, .plugin.id = "shellexec", .plugin.name = "Shell commands", diff --git a/plugins/shn/shn.c b/plugins/shn/shn.c index 1d44f6e8..28fb8bd7 100644 --- a/plugins/shn/shn.c +++ b/plugins/shn/shn.c @@ -1792,8 +1792,8 @@ static const char settings_dlg[] = // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "shn", .plugin.name = "SHN player", diff --git a/plugins/sid/Makefile.am b/plugins/sid/Makefile.am index 38caa014..f5408088 100644 --- a/plugins/sid/Makefile.am +++ b/plugins/sid/Makefile.am @@ -103,9 +103,9 @@ sidplay-libs/libsidplay/src/kernal.bin\ sidplay-libs/libsidplay/src/psiddrv.bin\ sidplay-libs/libsidplay/src/poweron.bin -sid_la_LIBADD = -lstdc++ -sid_la_LDFLAGS = -module +sid_la_LDFLAGS = -module -nostdlib -lsupc++ AM_CFLAGS = $(CFLAGS) -std=c99 -I$(sidpath)/libsidplay/include -I$(sidpath)/builders/resid-builder/include -fPIC -AM_CPPFLAGS = $(CXXFLAGS) -DHAVE_UNIX -I$(sidpath) -I$(sidpath)/unix -I$(sidpath)/libsidplay -I$(sidpath)/libsidplay/include -I$(sidpath)/libsidplay/include/sidplay -I$(sidpath)/libsidutils/include/sidplay/utils -I$(sidpath)/builders/resid-builder/include/sidplay/builders -I$(sidpath)/builders/resid-builder/include -DHAVE_STRCASECMP -DHAVE_STRNCASECMP +AM_CPPFLAGS = $(CXXFLAGS) -DHAVE_UNIX -I$(sidpath) -I$(sidpath)/unix -I$(sidpath)/libsidplay -I$(sidpath)/libsidplay/include -I$(sidpath)/libsidplay/include/sidplay -I$(sidpath)/libsidutils/include/sidplay/utils -I$(sidpath)/builders/resid-builder/include/sidplay/builders -I$(sidpath)/builders/resid-builder/include -DHAVE_STRCASECMP -DHAVE_STRNCASECMP -fno-exceptions -fno-rtti -fno-unwind-tables + endif diff --git a/plugins/sid/csid.cpp b/plugins/sid/csid.cpp index ccb2ecb3..57035291 100644 --- a/plugins/sid/csid.cpp +++ b/plugins/sid/csid.cpp @@ -34,6 +34,18 @@ #include "../../deadbeef.h" #include "csid.h" +int _Unwind_Resume_or_Rethrow; +int _Unwind_RaiseException; +int _Unwind_GetLanguageSpecificData; +int _Unwind_Resume; +int _Unwind_DeleteException; +int _Unwind_GetTextRelBase; +int _Unwind_SetIP; +int _Unwind_GetDataRelBase; +int _Unwind_GetRegionStart; +int _Unwind_SetGR; +int _Unwind_GetIPInfo; + extern DB_decoder_t sid_plugin; //#define trace(...) { fprintf(stderr, __VA_ARGS__); } diff --git a/plugins/sid/plugin.c b/plugins/sid/plugin.c index 9a2e9a27..f2df0c62 100644 --- a/plugins/sid/plugin.c +++ b/plugins/sid/plugin.c @@ -31,8 +31,8 @@ static const char settings_dlg[] = DB_decoder_t sid_plugin = { DB_PLUGIN_SET_API_VERSION .plugin.type = DB_PLUGIN_DECODER, - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.name = "SID decoder", .plugin.descr = "SID player based on libsidplay2", .plugin.author = "Alexey Yakovenko", diff --git a/plugins/sndfile/sndfile.c b/plugins/sndfile/sndfile.c index ab1d1ee9..f19083ba 100644 --- a/plugins/sndfile/sndfile.c +++ b/plugins/sndfile/sndfile.c @@ -312,8 +312,8 @@ static const char *filetypes[] = { "WAV", NULL }; // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "sndfile", .plugin.name = "pcm player", diff --git a/plugins/supereq/Equ.cpp b/plugins/supereq/Equ.cpp index f53b99d1..4411dbd9 100644 --- a/plugins/supereq/Equ.cpp +++ b/plugins/supereq/Equ.cpp @@ -4,6 +4,18 @@ #include <assert.h>
#include "paramlist.hpp"
+int _Unwind_Resume_or_Rethrow;
+int _Unwind_RaiseException;
+int _Unwind_GetLanguageSpecificData;
+int _Unwind_Resume;
+int _Unwind_DeleteException;
+int _Unwind_GetTextRelBase;
+int _Unwind_SetIP;
+int _Unwind_GetDataRelBase;
+int _Unwind_GetRegionStart;
+int _Unwind_SetGR;
+int _Unwind_GetIPInfo;
+
typedef float REAL;
void rfft(int n,int isign,REAL x[]);
diff --git a/plugins/supereq/Makefile.am b/plugins/supereq/Makefile.am index 0fffd6d6..eecade68 100644 --- a/plugins/supereq/Makefile.am +++ b/plugins/supereq/Makefile.am @@ -3,7 +3,9 @@ supereqdir = $(libdir)/$(PACKAGE) pkglib_LTLIBRARIES = supereq.la supereq_la_SOURCES = supereq.c supereq.h Equ.cpp Fftsg_fl.cpp paramlist.hpp -supereq_la_LDFLAGS = -module +AM_CPPFLAGS = $(CXXFLAGS) -fno-exceptions -fno-rtti -nostdlib -fno-unwind-tables + +supereq_la_LDFLAGS = -module -nostdlib -lsupc++ supereq_la_LIBADD = $(LDADD) AM_CFLAGS = -std=c99 diff --git a/plugins/supereq/supereq.c b/plugins/supereq/supereq.c index af4000fd..577af84a 100644 --- a/plugins/supereq/supereq.c +++ b/plugins/supereq/supereq.c @@ -212,6 +212,8 @@ supereq_enabled (void) { static DB_supereq_dsp_t plugin = { .dsp.plugin.api_vmajor = DB_API_VERSION_MAJOR, .dsp.plugin.api_vminor = DB_API_VERSION_MINOR, + .dsp.plugin.version_major = 1, + .dsp.plugin.version_minor = 0, .dsp.plugin.type = DB_PLUGIN_DSP, .dsp.plugin.id = "supereq", .dsp.plugin.name = "SuperEQ", diff --git a/plugins/tta/ttaplug.c b/plugins/tta/ttaplug.c index 196df859..948969e1 100644 --- a/plugins/tta/ttaplug.c +++ b/plugins/tta/ttaplug.c @@ -313,8 +313,8 @@ static const char *filetypes[] = { "TTA", NULL }; // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "tta", .plugin.name = "tta decoder", diff --git a/plugins/vfs_curl/Makefile.am b/plugins/vfs_curl/Makefile.am index 95794831..4c69c51f 100644 --- a/plugins/vfs_curl/Makefile.am +++ b/plugins/vfs_curl/Makefile.am @@ -4,6 +4,6 @@ pkglib_LTLIBRARIES = vfs_curl.la vfs_curl_la_SOURCES = vfs_curl.c vfs_curl_la_LDFLAGS = -module -vfs_curl_la_LIBADD = $(LDADD) $(CURL_LIBS) +vfs_curl_la_LIBADD = $(LDADD) $(VFS_CURL_LIBS) AM_CFLAGS = $(CFLAGS) -std=c99 endif diff --git a/plugins/vfs_curl/vfs_curl.c b/plugins/vfs_curl/vfs_curl.c index 048f964e..9f7a6fc0 100644 --- a/plugins/vfs_curl/vfs_curl.c +++ b/plugins/vfs_curl/vfs_curl.c @@ -896,8 +896,8 @@ static const char *scheme_names[] = { "http://", "ftp://", NULL }; // standard stdio vfs static DB_vfs_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_VFS, .plugin.id = "vfs_curl", .plugin.name = "cURL vfs", diff --git a/plugins/vorbis/vorbis.c b/plugins/vorbis/vorbis.c index fc0afe9e..91f933e5 100644 --- a/plugins/vorbis/vorbis.c +++ b/plugins/vorbis/vorbis.c @@ -694,8 +694,8 @@ static const char *filetypes[] = { "OggVorbis", NULL }; // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "stdogg", .plugin.name = "OggVorbis decoder", diff --git a/plugins/vtx/vtx.c b/plugins/vtx/vtx.c index 3e4ed6b9..2267f706 100644 --- a/plugins/vtx/vtx.c +++ b/plugins/vtx/vtx.c @@ -293,8 +293,8 @@ vtx_stop (void) { // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "vtx", .plugin.name = "VTX decoder", diff --git a/plugins/wavpack/wavpack.c b/plugins/wavpack/wavpack.c index e1eb4787..72cc7e3c 100644 --- a/plugins/wavpack/wavpack.c +++ b/plugins/wavpack/wavpack.c @@ -442,12 +442,12 @@ static const char *filetypes[] = { "wv", NULL }; // define plugin interface static DB_decoder_t plugin = { DB_PLUGIN_SET_API_VERSION - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.type = DB_PLUGIN_DECODER, .plugin.id = "wv", .plugin.name = "WavPack decoder", - .plugin.descr = ".wv player using libwavpack", + .plugin.descr = "WavPack (.wv, .iso.wv) player using libwavpack", .plugin.author = "Alexey Yakovenko", .plugin.email = "waker@users.sourceforge.net", .plugin.website = "http://deadbeef.sf.net", diff --git a/plugins/wildmidi/wildmidiplug.c b/plugins/wildmidi/wildmidiplug.c index e9c976b3..ccb0978a 100644 --- a/plugins/wildmidi/wildmidiplug.c +++ b/plugins/wildmidi/wildmidiplug.c @@ -186,8 +186,8 @@ static const char settings_dlg[] = DB_decoder_t wmidi_plugin = { DB_PLUGIN_SET_API_VERSION .plugin.type = DB_PLUGIN_DECODER, - .plugin.version_major = 0, - .plugin.version_minor = 1, + .plugin.version_major = 1, + .plugin.version_minor = 0, .plugin.name = "WildMidi player", .plugin.descr = "MIDI player based on WildMidi library", .plugin.author = "Alexey Yakovenko", diff --git a/insertlicense.sh b/scripts/insertlicense.sh index b046a61c..b046a61c 100755 --- a/insertlicense.sh +++ b/scripts/insertlicense.sh diff --git a/scripts/pluginstall.sh b/scripts/pluginstall.sh new file mode 100644 index 00000000..cb296fac --- /dev/null +++ b/scripts/pluginstall.sh @@ -0,0 +1,36 @@ +./scripts/portable_postbuild.sh + +#sudo cp ./deadbeef /usr/local/bin/ +#sudo cp ./plugins/nullout/.libs/nullout.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/cdda/.libs/cdda.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/flac/.libs/flac.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/alsa/.libs/alsa.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/mpgmad/.libs/mpgmad.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/hotkeys/.libs/hotkeys.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/vtx/.libs/vtx.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/ffap/.libs/ffap.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/wavpack/.libs/wavpack.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/vorbis/.libs/vorbis.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/oss/.libs/oss.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/vfs_curl/.libs/vfs_curl.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/ffmpeg/.libs/ffmpeg.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/lastfm/.libs/lastfm.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/sid/.libs/sid.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/adplug/.libs/adplug.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/gtkui/.libs/gtkui.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/sndfile/.libs/sndfile.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/pulse/.libs/pulse.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/artwork/.libs/artwork.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/supereq/.libs/supereq.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/gme/.libs/gme.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/dumb/.libs/dumb.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/notify/.libs/notify.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/musepack/.libs/musepack.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/wildmidi/.libs/wildmidi.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/tta/.libs/tta.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/dca/.libs/dca.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/aac/.libs/aac.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/mms/.libs/mms.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/shn/.libs/shn.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/ao/.libs/ao.so /usr/local/lib/deadbeef/ +#sudo cp ./plugins/shellexec/.libs/shellexec.so /usr/local/lib/deadbeef/ diff --git a/scripts/portable_build.sh b/scripts/portable_build.sh new file mode 100755 index 00000000..e973993b --- /dev/null +++ b/scripts/portable_build.sh @@ -0,0 +1,17 @@ +#!/bin/sh +VERSION=`cat PORTABLE_VERSION | perl -ne 'chomp and print'` +ORIGIN=`pwd | perl -ne 'chomp and print'` +export APBUILD_STATIC_LIBGCC=1 + +CC=$ORIGIN/tools/apbuild/apgcc CXX=$ORIGIN/tools/apbuild/apgcc ./configure --enable-portable --disable-pulse --disable-mpris --enable-maintainer-mode --disable-nls +sed -i 's/-lstdc++ -lm -lgcc_s -lc -lgcc_s/-lm -lc/g' libtool +make clean +make -j9 + +echo "building pluginfo tool..." +cd tools/pluginfo +make +cd ../../ + +./portable_postbuild.sh + diff --git a/scripts/portable_package.sh b/scripts/portable_package.sh new file mode 100755 index 00000000..bf292789 --- /dev/null +++ b/scripts/portable_package.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +# package for distribution +VERSION=`cat PORTABLE_VERSION | perl -ne 'chomp and print'` +BUILD=`cat PORTABLE_BUILD | perl -ne 'chomp and print'` + +# main distro +SRCDIR=deadbeef-$VERSION-portable +PLUGDIR=$SRCDIR/plugins +DOCDIR=$SRCDIR/doc +PIXMAPDIR=$SRCDIR/pixmaps + +mkdir -p portable_out/build 2>/dev/null +rm portable_out/* 2>/dev/null +rm portable_out/build/* 2>/dev/null + +tar jcvf portable_out/build/deadbeef-$VERSION-portable-build$BUILD.tar.bz2\ + $SRCDIR/deadbeef\ + $SRCDIR/deadbeef.png\ + $DOCDIR\ + $PLUGDIR/alsa.so\ + $PLUGDIR/oss.so\ + $PLUGDIR/vfs_curl.so\ + $PLUGDIR/artwork.so\ + $PLUGDIR/gtkui.so\ + $PLUGDIR/gtkui.fallback.so\ + $PLUGDIR/hotkeys.so\ + $PLUGDIR/cdda.so\ + $PLUGDIR/mpgmad.so\ + $PLUGDIR/vorbis.so\ + $PLUGDIR/wavpack.so\ + $PLUGDIR/flac.so\ + $PLUGDIR/ffap.so\ + $PLUGDIR/musepack.so\ + $PLUGDIR/notify.so\ + $PLUGDIR/sndfile.so\ + $PLUGDIR/supereq.so\ + $PLUGDIR/tta.so\ + $PIXMAPDIR + +# plugins +cd $PLUGDIR + +plugtable=../../../deadbeef-web/web/plugins-autogen.mkd +echo "<table><tr><th>Name</th><th>Version</th><th>Size</th><th>For Deadbeef</th><th>Description</th><th>Author(s)</th></tr>" >$plugtable + +PLUGINFO=../../tools/pluginfo/pluginfo + +for i in *.so ; do + plugname=`basename $i .so` + echo $plugname + + version="" + $PLUGINFO ./$i >./temp.sh + RET=$? + if [ "$RET" = "0" ]; then + source ./temp.sh + rm ./temp.sh + if [[ -n $version ]]; then + echo "$plugname version $version" + else + echo "$plugname version not found" + fi + fname=../../portable_out/deadbeef-$VERSION-portable-$plugname-$version.tar.bz2 + tar jcvf $fname $i + fsize=$(stat -c%s "$fname") + + # add some markdown + echo "<tr><td><a href="http://sourceforge.net/projects/deadbeef/files/portable/$VERSION/deadbeef-$VERSION-portable-$plugname-$version.tar.bz2/download">$name ($plugname)</a></td><td>$version</td><td>$fsize</td><td>$VERSION</td><td>$descr</td><td>$author ($email, $website)</td></tr>" >>$plugtable + fi +done +echo "</table>" >>$plugtable +cd ../../ + diff --git a/scripts/portable_postbuild.sh b/scripts/portable_postbuild.sh new file mode 100755 index 00000000..5deb7045 --- /dev/null +++ b/scripts/portable_postbuild.sh @@ -0,0 +1,64 @@ +#!/bin/sh +VERSION=`cat PORTABLE_VERSION | perl -ne 'chomp and print'` +OUTDIR=deadbeef-$VERSION-portable +PLUGDIR=$OUTDIR/plugins +DOCDIR=$OUTDIR/doc +PIXMAPDIR=$OUTDIR/pixmaps +mkdir -p $PLUGDIR +mkdir -p $DOCDIR +mkdir -p $PIXMAPDIR + +cp ./deadbeef ./deadbeef-$VERSION-portable/ +cp ./plugins/nullout/.libs/nullout.so $PLUGDIR/ +cp ./plugins/cdda/.libs/cdda.so $PLUGDIR/ +cp ./plugins/flac/.libs/flac.so $PLUGDIR/ +cp ./plugins/alsa/.libs/alsa.so $PLUGDIR/ +cp ./plugins/mpgmad/.libs/mpgmad.so $PLUGDIR/ +cp ./plugins/hotkeys/.libs/hotkeys.so $PLUGDIR/ +cp ./plugins/vtx/.libs/vtx.so $PLUGDIR/ +cp ./plugins/ffap/.libs/ffap.so $PLUGDIR/ +cp ./plugins/ffmpeg/.libs/ffmpeg.so $PLUGDIR/ +cp ./plugins/wavpack/.libs/wavpack.so $PLUGDIR/ +cp ./plugins/vorbis/.libs/vorbis.so $PLUGDIR/ +cp ./plugins/oss/.libs/oss.so $PLUGDIR/ +cp ./plugins/vfs_curl/.libs/vfs_curl.so $PLUGDIR/ +cp ./plugins/lastfm/.libs/lastfm.so $PLUGDIR/ +cp ./plugins/sid/.libs/sid.so $PLUGDIR/ +cp ./plugins/adplug/.libs/adplug.so $PLUGDIR/ +cp ./plugins/gtkui/.libs/gtkui.so $PLUGDIR/ +cp ./plugins/gtkui/.libs/gtkui.fallback.so $PLUGDIR/ +cp ./plugins/sndfile/.libs/sndfile.so $PLUGDIR/ +cp ./plugins/artwork/.libs/artwork.so $PLUGDIR/ +cp ./plugins/supereq/.libs/supereq.so $PLUGDIR/ +cp ./plugins/gme/.libs/gme.so $PLUGDIR/ +cp ./plugins/dumb/.libs/dumb.so $PLUGDIR/ +cp ./plugins/notify/.libs/notify.so $PLUGDIR/ +cp ./plugins/musepack/.libs/musepack.so $PLUGDIR/ +cp ./plugins/wildmidi/.libs/wildmidi.so $PLUGDIR/ +cp ./plugins/tta/.libs/tta.so $PLUGDIR/ +cp ./plugins/dca/.libs/dca.so $PLUGDIR/ +cp ./plugins/aac/.libs/aac.so $PLUGDIR/ +cp ./plugins/mms/.libs/mms.so $PLUGDIR/ +cp ./plugins/shn/.libs/shn.so $PLUGDIR/ +cp ./plugins/ao/.libs/ao.so $PLUGDIR/ +cp ./plugins/shellexec/.libs/shellexec.so $PLUGDIR/ + +#pixmaps +cp ./pixmaps/pause_16.png $PIXMAPDIR/ +cp ./pixmaps/play_16.png $PIXMAPDIR/ +cp ./pixmaps/buffering_16.png $PIXMAPDIR/ +cp ./pixmaps/noartwork.jpg $PIXMAPDIR/ + +# docs +cp ./ChangeLog $DOCDIR/ +cp ./help.txt $DOCDIR/ +cp ./COPYING.GPLv2 $DOCDIR/ +cp ./about.txt $DOCDIR/ +cp ./translators.txt $DOCDIR/ + +# icon +cp ./icons/32x32/deadbeef.png $OUTDIR/ + +# strip +strip --strip-unneeded ./deadbeef-$VERSION-portable/deadbeef +for i in $PLUGDIR/*.so ; do strip --strip-unneeded $i ; done diff --git a/scripts/portable_upload.sh b/scripts/portable_upload.sh new file mode 100755 index 00000000..482e66ea --- /dev/null +++ b/scripts/portable_upload.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +VERSION=`cat PORTABLE_VERSION | perl -ne 'chomp and print'` +BUILD=`cat PORTABLE_BUILD | perl -ne 'chomp and print'` + +UPLOAD_URI=waker,deadbeef@frs.sourceforge.net:/home/frs/project/d/de/deadbeef/portable/$VERSION/ + +scp portable_out/* $UPLOAD_URI/ +scp portable_out/build/* $UPLOAD_URI/ diff --git a/u8_gperf.sh b/scripts/u8_gperf.sh index 3ecffc3e..3ecffc3e 100755 --- a/u8_gperf.sh +++ b/scripts/u8_gperf.sh diff --git a/threading_pthread.c b/threading_pthread.c index 13d12b94..0705128c 100644 --- a/threading_pthread.c +++ b/threading_pthread.c @@ -21,6 +21,9 @@ #include <errno.h> #include <string.h> #include "threading.h" +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif intptr_t thread_start (void (*fn)(void *ctx), void *ctx) { @@ -69,12 +72,14 @@ thread_start_low_priority (void (*fn)(void *ctx), void *ctx) { fprintf (stderr, "pthread_create failed: %s\n", strerror (s)); return 0; } +#if !PORTABLE s = pthread_setschedprio (tid, minprio); if (s != 0) { fprintf (stderr, "pthread_setschedprio failed: %s\n", strerror (s)); pthread_cancel (tid); return 0; } +#endif s = pthread_attr_destroy (&attr); if (s != 0) { diff --git a/tools/apbuild/Apbuild/GCC.pm b/tools/apbuild/Apbuild/GCC.pm new file mode 100644 index 00000000..b4246148 --- /dev/null +++ b/tools/apbuild/Apbuild/GCC.pm @@ -0,0 +1,539 @@ +# Various gcc-related functions +package Apbuild::GCC; + +use strict; +use Apbuild::Utils; +use IPC::Open3; + + +######## Special constants; used for parsing GCC parameters ######## + +# Parameters that require an extra parameter +our $extraTypes = 'o|u|Xlinker|b|V|MF|MT|MQ|I|L|R|Wl,-rpath|isystem|D|x'; +# Linker parameters +our $linkerTypes = 'L|Wl|o$|l|s|n|R'; +# Files with these extensions are objects +our $staticLibTypes = 'a|al'; +our $objectTypes = "o|os|so(\\.\\d+)*|la|lo|$staticLibTypes"; +our $headerTypes = 'h|hpp'; +# Source file types +our $cTypes = 'c|C'; +our $cxxTypes = 'cpp|cxx|cc|c\+\+'; +our $srcTypes = "$cTypes|$cxxTypes"; + + +######## Methods ######## + +## +# Apbuild::GCC->new(gcc_command) +# gcc_command: The command for invoking GCC. +# +# Create a new Apbuild:GCC object. +sub new { + my ($class, $gcc) = @_; + my %self; + + $self{gcc} = $gcc; + $self{gcc_file} = checkCommand($gcc); + if (!defined $self{gcc_file}) { + error "$gcc: command not found\n"; + exit 127; + } + + # FIXME: should use gcc -print-search-paths. + $self{searchPaths} = ["/usr/lib", "/usr/local/lib"]; + foreach (reverse(split(/:/, $ENV{LIBRARY_PATH}))) { + push @{$self{searchPaths}}, $_; + } + + bless \%self, $class; + return \%self; +} + +## +# $gcc->capabilities() +# Returns: a hash with capabilities for this compiler. +# +# Check GCC's capabilities. This function will return +# a hash with the following keys: +# libgcc : Is 1 if gcc supports the parameter -{shared,static}-libgcc. +# as_needed: Is 1 if gcc's linker supports --as-needed. +# abi2 : Is 1 if gcc supports -fabi-version=2. +# +# This function takes care of caching results. +sub capabilities { + my ($self) = @_; + my (%capabilities, %cache); + + my $gcc = $self->{gcc}; + my $gcc_file = $self->{gcc_file}; + + # First, check the cache + my @stat = stat $gcc_file; + my $gcc_mtime = $stat[9]; + my $home = homeDir(); + if (-f "$home/.apbuild") { + parseDataFile("$home/.apbuild", \%cache); + if ($cache{version} != 2) { + # Cache file version incompatible; delete cache + %cache = (); + + } else { + if ($cache{"mtime_$gcc_file"} != $gcc_mtime) { + # Cache out of date for this compiler; update cache + delete $cache{"libgcc_$gcc_file"}; + delete $cache{"abi2_$gcc_file"}; + delete $cache{"as_needed_$gcc_file"}; + delete $cache{"hash_style_$gcc_file"}; + delete $cache{"stack_protector_$gcc_file"}; + delete $cache{"fortify_source_$gcc_file"}; + } + } + } + + my $lc_all = $ENV{LC_ALL}; + $ENV{LC_ALL} = 'C'; + + if (exists $cache{"libgcc_$gcc_file"} && exists $cache{"abi2_$gcc_file"}) { + $capabilities{libgcc} = $cache{"libgcc_$gcc_file"}; + $capabilities{abi2} = $cache{"abi2_$gcc_file"}; + + } else { + # Get output from 'gcc -v' + my ($r, $w, $e); + + my $pid = open3($w, $r, $e, $gcc_file, '-v'); + close $w if ($w); + close $e if ($e); + my @output = <$r>; + waitpid $pid, 0; + + # Check whether gcc >= 3.0 + my ($major, $minor) = $output[@output - 1] =~ /version ([0-9]+)\.([0-9]+)/; + if ($major >= 3) { + $capabilities{libgcc} = 1; + $cache{"libgcc_$gcc_file"} = 1; + } else { + $capabilities{libgcc} = 0; + $cache{"libgcc_$gcc_file"} = 0; + } + + if ($major > 3 || ($major >= 3 && $minor >= 4)) { + $capabilities{abi2} = 1; + $cache{"abi2_$gcc_file"} = 1; + } else { + $capabilities{abi2} = 0; + $cache{"abi2_$gcc_file"} = 0; + } + + $cache{"mtime_$gcc_file"} = $gcc_mtime; + } + + if (exists $cache{"as_needed_$gcc_file"}) { + $capabilities{as_needed} = $cache{"as_needed_$gcc_file"}; + + } else { + my ($r, $w, $e); + + my $pid = open3($w, $r, $e, $gcc_file, '-Wl,--help'); + close $w if ($w); + close $e if ($e); + local($/); + my $output = <$r>; + waitpid $pid, 0; + + if ($output =~ /--as-needed/) { + $capabilities{as_needed} = 1; + $cache{"as_needed_$gcc_file"} = 1; + } else { + $capabilities{as_needed} = 0; + $cache{"as_needed_$gcc_file"} = 0; + } + } + + if (exists $cache{"hash_style_$gcc_file"}) { + $capabilities{hash_style} = $cache{"hash_style_$gcc_file"}; + } else { + my ($r, $w, $e); + + my $pid = open3($w, $r, $e, $gcc_file, '-Wl,--help'); + close $w if ($w); + close $e if ($e); + local($/); + my $output = <$r>; + waitpid $pid, 0; + + if ($output =~ /--hash-style/) { + $capabilities{hash_style} = 1; + $cache{"hash_style_$gcc_file"} = 1; + } else { + $capabilities{hash_style} = 0; + $cache{"hash_style_$gcc_file"} = 0; + } + } + + if (exists $cache{"stack_protector_$gcc_file"}) { + $capabilities{stack_protector} = $cache{"stack_protector_$gcc_file"}; + } else { + # Get output from 'gcc -v' + my ($r, $w, $e); + + my $pid = open3($w, $r, $e, $gcc_file, '-v'); + close $w if ($w); + close $e if ($e); + my @output = <$r>; + waitpid $pid, 0; + + # Check whether gcc >= 3.0 + my ($major, $minor) = $output[@output - 1] =~ /version ([0-9]+)\.([0-9]+)/; + if ($major >= 4 && $minor >= 1) { + $capabilities{stack_protector} = 1; + $cache{"stack_protector_$gcc_file"} = 1; + } else { + $capabilities{stack_protector} = 0; + $cache{"stack_protector_$gcc_file"} = 0; + } + } + + if (exists $cache{"fortify_source_$gcc_file"}) { + $capabilities{fortify_source} = $cache{"fortify_source_$gcc_file"}; + } else { + # Get output from 'gcc -v' + my ($r, $w, $e); + + my $pid = open3($w, $r, $e, $gcc_file, '-v'); + close $w if ($w); + close $e if ($e); + my @output = <$r>; + waitpid $pid, 0; + + # Check whether gcc >= 4.1 + my ($major, $minor) = $output[@output - 1] =~ /version ([0-9]+)\.([0-9]+)/; + if ($major >= 4 && $minor >= 1) { + $capabilities{fortify_source} = 1; + $cache{"fortify_source_$gcc_file"} = 1; + } else { + $capabilities{fortify_source} = 0; + $cache{"fortify_source_$gcc_file"} = 0; + } + } + + if (defined $lc_all) { + $ENV{LC_ALL} = $lc_all; + } else { + delete $ENV{LC_ALL}; + } + + $cache{version} = 2; + writeDataFile("$home/.apbuild", \%cache); + return %capabilities; +} + + +## +# $gcc->command() +# +# Returns the GCC command associated with this Apbuild::GCC object. +sub command { + my ($self) = @_; + return $self->{gcc}; +} + + +## +# $gcc->foreach(args, callback) +# args: a reference to an array which contains GCC parameters. +# callback: the callback function which will be called in every iteration of the loop. +# +# Iterate through each GCC parameter. $callback will be called as follows: +# $callback->(type, args...); +# $type is the current parameter's type, either "param" or "file" (source file). +# args is an array of parameters. If this parameter is a parameter which excepts +# another parameter (such as -o, it expects a filename), then the expected +# parameter will also be passed to the callback function. +sub foreach { + my ($self, $args, $callback) = @_; + for (my $i = 0; $i < @{$args}; $i++) { + $_ = $args->[$i]; + if (/^-/ || /\.($objectTypes|$headerTypes)$/ || /.*\.so\.?$/) { + # Parameter + if (/^-($extraTypes)$/) { + # This parameter expects another parameter + $callback->("param", $_, $args->[$i + 1]); + $i++; + } else { + $callback->("param", $_); + } + + } else { + # File + $callback->("file", $_); + } + } +} + +## +# $gcc->splitParams(args, files, params) +# args: a reference to an array which contains GCC parameters. +# files: a reference to an array, or undef. +# params: a reference to an array, or undef. +# +# Parse GCC's parameters. Seperate files and arguments. +# A list of files will be stored in the array referenced to by $file, +# a list of non-file parameters will be stored in the array referenced to by $params. +sub splitParams { + my ($self, $args, $files, $params) = @_; + + my $callback = sub { + my $type = shift; + if ($type eq "param") { + push @{$params}, @_ if ($params); + } elsif ($type eq "file") { + push @{$files}, $_[0] if ($files); + } + }; + $self->foreach($args, $callback); +} + + +sub stripLinkerParams { + my ($self, $r_params, $linking) = @_; + my @params; + my $i = 0; + + my $callback = sub { + my $type = shift; + if ($type eq 'param' && $_[0] =~ /^-($linkerTypes)/) { + push @{$linking}, @_; + } else { + push @params, @_; + } + }; + $self->foreach($r_params, $callback); + @{$r_params} = @params; +} + + +sub addSearchPaths { + my ($self, $dir) = @_; + push @{$self->{searchPaths}}, $dir; +} + +# Parse $args and extract library search paths from it. +# Those paths, along with paths added by addSearchPaths(), +# will be appended to $paths. +sub getSearchPaths { + my ($self, $args, $paths) = @_; + + my $callback = sub { + my $type = shift; + return if ($type ne "param"); + + if ($_[0] eq "-L") { + push @{$paths}, $_[1]; + + } elsif ($_[0] =~ /^-L(.+)/ || $_[0] =~ /^--library-path=(.+)/) { + push @{$paths}, $1; + } + }; + $self->foreach($args, $callback); + + push @{$paths}, @{$self->{searchPaths}}; +} + + +## +# $gcc->isLibrary(arg, libname) +# +# Check whether $arg is a (dynamic) library argument. +# The base library name will be stored in $$libname. +sub isLibrary { + my ($self, $arg, $libname) = @_; + if ($arg =~ /^-l(.+)/ || $arg =~ /^--library=(.+)/ || $arg =~ /^(?:.*\/)?lib([^\/]+)\.so/) { + $$libname = $1 if ($libname); + return 1; + } else { + return 0; + } +} + +## +# $gcc->isObject(arg) +# +# Check whether $arg is an object. This includes static libraries. +sub isObject { + my ($self, $arg) = @_; + return $arg !~ /^-/ && $arg =~ /\.($objectTypes)$/; +} + +sub isStaticLib { + my ($self, $arg) = @_; + return $arg !~ /^-/ && $arg =~ /\.($staticLibTypes)$/; +} + +## +# $gcc->isSource(file) +# +# Checks whether $file is a source file. +sub isSource { + my ($self, $file) = @_; + return $file =~ /\.($srcTypes)$/; +} + +## +# $gcc->isCxxSource(file) +# +# Checks whether $file is a C++ source file. +sub isCxxSource { + my ($self, $file) = @_; + return $file =~ /\.($cxxTypes)$/; +} + + +# I wish I know how to explain what these functions do, but I can't. :( +# If you know a better way to name these, please do tell me. +sub sourceOrderIsImportant { + my ($self, $arg) = @_; + return $arg =~ /^-(x)$/; +} + +sub linkOrderIsImportant { + my ($self, $arg) = @_; + return $arg =~ /^-(Wl,--whole-archive|Wl,--no-whole-archive)$/; +} + +## +# $gcc->getOutputFile(args) +# args: a reference to an array which contains GCC parameters. +# Returns: a filename. +# +# Parse the GCC arguments and detect the output filename. +sub getOutputFile { + my ($gcc, $args) = @_; + my ($output, $compilingToObject, $source); + + my $callback = sub { + my $type = shift; + if ($type eq 'param' && $_[0] eq '-o') { + $output = $_[1]; + + } elsif ($type eq 'param' && $_[0] eq '-c') { + $compilingToObject = 1; + + } elsif ($type eq 'file' && $gcc->isSource($_[0])) { + $source = $_[0]; + } + }; + $gcc->foreach($args, $callback); + + if (defined $output) { + return $output; + } elsif ($compilingToObject) { + $source =~ s/\.[^.]*?$/.o/; + return $source; + } else { + return "a.out"; + } +} + +## +# $gcc->setOutputFile(args, new_output_file) +# args: a reference to an array which contains GCC parameters. +# new_output_file: the new output filename. +# +# Parse the GCC arguments and change the output filename. +# The array referenced by $args will be modified. +sub setOutputFile { + my ($gcc, $args, $new_output_file) = @_; + my (@newArgs, $changed); + + my $callback = sub { + my $type = shift; + + if ($type eq 'param' && $_[0] eq '-o') { + push @newArgs, "-o", $new_output_file; + $changed = 1; + + } else { + push @newArgs, @_; + } + }; + $gcc->foreach($args, $callback); + + if (!$changed) { + push @newArgs, "-o", $new_output_file if (!$changed); + } + @{$args} = @newArgs; +} + + +## +# $gcc->situation(args) +# args: a reference to an array which contains GCC arguments. +# Returns: 'compile', 'depcheck', 'compile and link', 'linking' or 'other'. +# +# Detect the situation in which the compiler is used. +# Basically, there are 5 situations in which the compiler is used: +# 1) Compilation (to an object file). +# 2) Linking. +# 3) Compilation and linking. +# 4) Dependancy checking with -M* or -E. +# 5) None of the above. Compiler is invoked with --help or something. +# Note that source files may also contain non-C/C++ files. +sub situation { + my ($self, $args) = @_; + + my $files = 0; + for (@{$args}) { + $files++ if (!(/^-/)); + } + + for (@{$args}) { + if (/^-c$/) { + # Situation 1 + return 'compile'; + } elsif (/^-M(|M|G)$/ || /^-E$/) { + # Situation 4 + return 'depcheck'; + } + } + + if ($files == 1) + { + my $i = 0; + for (@{$args}) + { + if (!(/^-/) && (/\.($headerTypes)$/)) + { + print($args->[$i], "\n"); + return 'precompiled header'; + } + $i++; + } + } + + my $i = 0; + for (@{$args}) { + if (!(/^-/) && !(/\.($objectTypes)$/)) { + if ($i > 0 && $args->[$i - 1] =~ /^-($extraTypes)$/) { + $i++; + next; + } else { + # Situation 3 + return 'compile and link'; + } + } + $i++; + } + + if ($files == 0) { + # Situation 5 + return 'other'; + } else { + # Situation 2 + return 'linking'; + } +} + + +1; diff --git a/tools/apbuild/Apbuild/Utils.pm b/tools/apbuild/Apbuild/Utils.pm new file mode 100644 index 00000000..a5089299 --- /dev/null +++ b/tools/apbuild/Apbuild/Utils.pm @@ -0,0 +1,195 @@ +package Apbuild::Utils; + +use strict; +use warnings; +use Exporter; +use base qw(Exporter); +use IO::Handle; +use IPC::Open2; +use POSIX; +use Cwd qw(abs_path); + + +our @EXPORT = qw(debug error checkCommand empty homeDir searchLib searchStaticLib soname run parseDataFile writeDataFile); +our $debugOpened = 0; + + +## +# debug(message) +# +# If the environment variable $APBUILD_DEBUG is set to 1, +# then print a debugging message to /dev/tty (not stdout or stderr). +sub debug { + return if (empty($ENV{APBUILD_DEBUG}) || !$ENV{APBUILD_DEBUG}); + + if (!$debugOpened) { + if (open DEBUG, '>/dev/tty') { + $debugOpened = 1; + } else { + return; + } + } + + my @args = split /\n/, "@_"; + foreach (@args) { + $_ = '# ' . $_; + $_ .= "\n"; + } + + print DEBUG "\033[1;33m"; + print DEBUG join '', @args; + print DEBUG "\033[0m"; + DEBUG->flush; +} + + +## +# error(message) +# +# Print an error message to stderr. It will be displayed in red. +sub error { + print STDERR "\033[1;31m"; + print STDERR $_[0]; + print STDERR "\033[0m"; + STDERR->flush; +} + + +## +# checkCommand(file) +# file: an command's filename. +# Returns: the full path to $file, or undef if $file is not a valid command. +# +# Checks whether $file is an executable which is in $PATH or the working directory. +# +# Example: +# checkCommand('gcc'); # Returns "/usr/bin/gcc" +sub checkCommand { + my ($file, $file2) = split / /, $_[0]; + $file = $file2 if ($file =~ /ccache/); + + return abs_path($file) if (-x $file); + foreach my $dir (split /:+/, $ENV{PATH}) { + if (-x "$dir/$file") { + return "$dir/$file"; + } + } + return undef; +} + +## +# empty(str) +# +# Checks whether $str is undefined or empty. +sub empty { + return !defined($_[0]) || $_[0] eq ''; +} + +## +# homeDir() +# +# Returns the user's home folder. +sub homeDir { + if (!$ENV{HOME}) { + my $user = getpwuid(POSIX::getuid()); + $ENV{HOME} = (getpwnam($user))[7]; + } + return $ENV{HOME}; +} + +## +# searchLib(basename, [extra_paths]) +# basename: the base name of the library. +# extra_paths: a reference to an array, which contains extra folders in which to look for the library. +# Returns: the absolute path to the library, or undef if not found. +# +# Get the absolute path of a (static or shared) library. +# +# Example: +# searchLib("libfoo.so.1"); # Returns "/usr/lib/libfoo.so.1" +sub searchLib { + my ($basename, $extra_paths) = @_; + + if ($extra_paths) { + foreach my $path (reverse(@{$extra_paths})) { + return "$path/$basename" if (-f "$path/$basename"); + } + } + foreach my $path ('/usr/local/lib', '/lib', '/usr/lib') { + return "$path/$basename" if (-f "$path/$basename"); + } + return undef; +} + +## +# soname(lib) +# lib: a filename to a shared library. +# Returns: the soname. +# +# Get the soname of the specified shared library by reading +# the SONAME section of the shared library file. +sub soname { + my ($lib) = @_; + my ($r, $w); + + if (open2($r, $w, 'objdump', '-p', $lib)) { + close $w; + my @lines = <$r>; + close $r; + + my ($soname) = grep {/SONAME/} @lines; + $soname =~ s/.*?SONAME[ \t]+//; + $soname =~ s/\n//gs; + return $soname; + + } else { + my ($soname) = $lib =~ /.*\/lib(.+)\.so/; + return $soname; + } +} + +## +# run(args...) +# Returns: the command's exit code. +# +# Run a command with system(). +sub run { + # split the first item in @_ into "words". The `printf ...` + # takes care of respecting ' and " quotes so we don't split a + # quoted string that contains whitespace. If $cmd itself + # contains \n, this will still go wrong. + my $cmd = shift @_; + my @words = `printf '%s\n' $cmd`; + chomp @words; + my $status = system(@words, @_); + return 127 if ($status == -1); + return $status / 256 if ($status != 0); + return 0; +} + +sub parseDataFile { + my ($file, $r_hash) = @_; + + %{$r_hash} = (); + return if (!open FILE, "< $file"); + foreach (<FILE>) { + next if (/^#/); + s/[\r\n]//g; + next if (length($_) == 0); + + my ($key, $value) = split / /, $_, 2; + $r_hash->{$key} = $value; + } + close FILE; +} + +sub writeDataFile { + my ($file, $r_hash) = @_; + return if (!open FILE, "> $file"); + foreach my $key (sort(keys %{$r_hash})) { + print FILE "$key $r_hash->{$key}\n"; + } + close FILE; +} + +1; diff --git a/tools/apbuild/BINARY-PORTABILITY-NOTES b/tools/apbuild/BINARY-PORTABILITY-NOTES new file mode 100644 index 00000000..9a34566a --- /dev/null +++ b/tools/apbuild/BINARY-PORTABILITY-NOTES @@ -0,0 +1,36 @@ +1) C++ ABI +The C++ ABI generated by GCC version 2.95, 2.96, 3.0, and 3.1.1 are +incompatible with each other. This means that, for examples, apps compiled +with GCC 2.95 cannot link to libraries compiled with GCC 3.2. + +GCC 3.4 is the latest ABI at the moment (April 2005). But the most widely +used ABI at the moment is the GCC 3.2 ABI. + +2) Symbol collisions, be aware of what libraries are implicitly linked in. +Imagine the following situation: +- foo contains the symbol foobar (a function). +- libbar contains a symbol with the same name, but is a totally different + function. +- foo is linked to libbar. +When foo tries to call foobar(), it's undefined whether it will call the +foobar() from it's own binary, or the one from libbar. Depending on what +those functions do, foo may crash or do something it isn't supposed to do. + +Solution: rtld features, -Bgroup. However, at this moment these are not +supported by glibc. Until they are, keep these in mind: +- You should mark all functions that you do not want to export (or show up + in the symbol table) as static. +- If you're a library, you should namespace all functions. +- Internal functions that are used within a library, but across multiple + .c files, should be prefixed by a _ or __. + +3) Linking against shared versions of X11 extension libs +Some X libraries, such as libXrender, are originally not shared libraries. +Distributions just created shared library versions to save memory. So +some distributions don't ship the shared versions at all. Apbuild +automatically statically links some of those X libraries (you can turn +this behavior off of course). + +4) Usage of sys_errlist + +5) Don't use TLS (the __thread keyword). diff --git a/tools/apbuild/ChangeLog b/tools/apbuild/ChangeLog new file mode 100644 index 00000000..fe1587ce --- /dev/null +++ b/tools/apbuild/ChangeLog @@ -0,0 +1,375 @@ +2009-03-13 Jan Niklas Hasse <jhasse@gmail.com> + + * apgcc: Use warn instead of print to display warnings. Thanks to Scott + Pakin for the patch. + +-------------------- 2.0.8 was released -------------------- + +2009-03-11 Jan Niklas Hasse <jhasse@gmail.com> + + * Apbuild/GCC.pm: Applied patch by Mike Lundy which fixes compiling of + libpng where apgcc detected a symbol list as precompiled header rather than + a depcheck. Fixes #118. + * apsymbols.h: New symbol list created on a GLIBC_2.9 machine by Mike + Lundy. Thanks! Fixes #117. + +2009-03-11 Jan Niklas Hasse <jhasse@gmail.com> + + * apgcc: Applied patch by Scott Pakin which shows a warning message when + a library in APBUILD_STATIC isn't found. + * Apbuild/GCC.pm: getSearchPaths: Correctly add the content of the list not + a reference. Also a patch by Scott Pakin, thanks! + +2009-03-10 Jan Niklas Hasse <jhasse@gmail.com> + + * apgcc: Applied patch by Scott Pakin which fixes statically compiling + of libuuid. + +-------------------- 2.0.7 was released -------------------- + +2008-11-10 Jan Niklas Hasse <jhasse@gmail.com> + + * Apbuild/GCC.pm: Check if FORTIFY_SOURCE is available. I'm not sure if + this really was introduced in gcc 4.1, but it should fix the the linker + errors in Ubuntu 8.10 and other new distros using this feature. + * apgcc: Add -U_FORTIFY_SOURCE to deactivate FORTIFY_SOURCE=2. + +2008-09-11 Jan Niklas Hasse <jhasse@gmail.com> + + * buildlist: Bump minimum GLibc version to 2.3 (from 2.2) + * apsymbols.h: update list to work with the new 2.3 glibc min version + (Patch from Taj, me and Isak, should fix #20) + * apgcc: Check if APBUILD_STATIC_X is definied to prevent warnings. + +2008-08-03 Jan Niklas Hasse <jhasse@gmail.com> + + * relaytool: Check if /dev/tty exists. Fixes #63 + +2008-08-03 Jan Niklas Hasse <jhasse@gmail.com> + + * apgcc: Don't statically link X11 libs by default. Fixes #61 + +-------------------- 2.0.6 was released -------------------- + +Sun Dec 30 19:17:03 UTC 2007 Taj Morton <tajmorton@gmail.com> + * relaytool: Apply patch from res in ticket #52. Now, if a lib cannot be relaytooled + for some reason, a stub that ensures libwhatever_is_present is defined will be + generated. + +Sun Sep 30 00:29:13 UTC 2007 Taj Morton <tajmorton@gmail.com> + * relaytool: When multi-linking, use the first SONAME passed to --multilink + as the name to use for the _is_present variable and _symbol_is_present function. + Fixes #37. + +Sat Sep 22 02:39:11 UTC 2007 Taj Morton <tajmorton@gmail.com> + * relaytool: Add --out-dir feature by user 'res' in ticket #50. + +2007-09-22 Isak Savo <isak.savo@gmail.com> + + * relaytool (arch_ptr_size): Use 'uname -m' instead of 'arch' to get + machine name. Patch from user 'res' in ticket #51 (ticket fixed by + this commit) + +Tue Aug 14 17:04:32 UTC 2007 Taj Morton <tajmorton@gmail.com> + * apgcc: Apply patch from Unfleshed One for precompiled header support. Fixes #32. + * Apbuild/GCC.pm: Apply patch from Unfleshed One from precompiled header and + SCons/Qt4 integration. Fixes #32. + +Tue Aug 14 16:51:30 UTC 2007 Taj Morton <tajmorton@gmail.com> + * relaytool: When running on unsupported arch, give correct + defines for lib_is_present and symbol_is_present. + +Mon Jul 9 23:22:21 UTC 2007 Curtis L. Knight <knighcl@gmail.com> + * apgcc: Update for 2.0.6 release. + * Makefile: Update for 2.0.6 release. + +-------------------- 2.0.5 was released -------------------- + +Mon Jun 4 02:03:06 UTC 2007 Taj Morton <tajmorton@gmail.com> + * apgcc: Append statically linked file's deps before adjusting + link line so that you can statically link the deps of the + libs you're statically linking (if that made any sense). + +Sat May 26 15:28:14 UTC 2007 Taj Morton <tajmorton@gmail.com> + * make-icons: Put icons into a directory called icons relative to + where make-icons was run from. Ask user for type so that icons get + put in correct subdirectory. + +Fri May 25 03:02:28 UTC 2007 Curtis L. Knight <knighcl@gmail.com> + * apgcc: Update for 2.0.5 release. + * Makefile: Update for 2.0.5 release. + +Wed May 23 00:45:48 UTC 2007 Taj Morton <tajmorton@gmail.com> + * apgcc: When statically linking, find the lib's DT_NEEDED entries + and link against them so we don't get linking errors. + +Thu May 17 20:38:11 UTC 2007 Taj Morton <tajmorton@gmail.com> + * relaytool: Use /bin/bash instead of /bin/sh so we can work on + Ubuntu (where sh -> dash). Thanks ACSpike. Add multilink support + to relaytool (TODO: document it better). + +-------------------- 2.0.4 was released -------------------- + +Sun Apr 8 11:22:23 UTC 2007 Curtis L. Knight <knighcl@gmail.com> + * apgcc: Update for 2.0.4 release. + * Makefile: Update for 2.0.4 release. + +Sat Mar 31 21:09:45 UTC 2007 Taj Morton <tajmorton@gmail.com> + * Apbuild/GCC.pm: Check if gcc supports -fstack-protector, + so it can be disabled. + * apgcc: If gcc supports -fstack-protector, disable it (it adds a + silent dependency on GLIBC 2.4). + * apsymbols.h: Rebuilt with GLIBC 2.4. Thanks to Chris Guirl for + rebuilding. + +Thu Mar 29 05:08:40 UTC 2007 Taj Morton <tajmorton@gmail.com> + * apgcc: Respect the $APBUILD_NO_STATIC_X variable (as + documented on website). This doesn't mean it's a good idea + to use this features. + +-------------------- 2.0.3 was released -------------------- + +Sun Dec 17 01:05:08 UTC 2006 Curtis L. Knight <knighcl@fastmail.fm> + * apgcc: Update for 2.0.3 release. + * Makefile: Update for 2.0.3 release. + +Sat Nov 25 23:20:07 UTC 2006 Taj Morton <tajmorton@gmail.com> + * Apbuild/GCC.pm: Detect if ld supports --hash-style so that we + can force both .gnu.hash and .hash to be generated on FC6. + * apgcc: If linker supports --hash-style, generate both .gnu.hash + and .hash sections so that binary works with linkers with support for + either type. By default, FC6 only generates .gnu.hash which makes its + binaries only work on systems with .gnu.hash. See: + http://fcp.surfsite.org/modules/newbb/viewtopic.php?topic_id=29929&forum=10&post_id=128939 + +-------------------- 2.0.2 was released -------------------- + +Thu Nov 2 22:53:33 UTC 2006 Taj Morton <tajmorton@gmail.com> + * apgcc: Allow people to replace -I flags passed to apgcc with ones from + $APBUILD_INCLUDE. For example /opt/kde/include=/home/taj/kde-includes/3.3 + replaces -I/opt/kde/include with -I/home/taj/kde-includes/3.3. This is only + useful for apps where include path order is important (amarok 1.4.3, see + comments for details). + +-------------------- 2.0.1 was released -------------------- + +Fri Oct 13 14:54:54 UTC 2006 Taj Morton <tajmorton@gmail.com> + * apgcc: Revert commit that "Just use[d] the multiple-file code for link and compile + in 1 command." This broke compiling main/libexec. Post 1.2 this code will get + better, I promise. :) + +Thu Oct 12 04:36:56 UTC 2006 Taj Morton <tajmorton@gmail.com> + * apgcc: [translateLibNames()]: Always find libstdc++ if compiling C++, force + use of the compilers libstdc++, instead of what libtool provides (which + is probably wrong when using your non-system g++). + +Mon Oct 9 00:57:48 UTC 2006 Taj Morton <tajmorton@gmail.com> + * apgcc: Remove special case with compiling and linking in 1 command with + 1 file. This code never called linkObjects() and so X libs were never + statically linked in. Just use the multiple-file code for link and compile in 1 + command. + [forceStatic()]: Link Xfixes if Xcursor is linked because sometimes Xcursor + depends on Xfixes (on Slack 11, xorg 6.9.0, at least). + +Sun Sep 24 22:38:50 UTC 2006 Taj Morton <tajmorton@gmail.com> + * apgcc: [rearrangeForAsNeeded()]: Put -lXRender at the end of the + link command. See + http://lists.sunsite.dk/cgi-bin/ezmlm-cgi?21:mss:5187:200609:lkfnloheeaingojmnemi + for details. + +2006-09-13 Isak Savo <isak.savo@gmail.com> + + * Makefile (PREFIX): Replaced bash specific '[[' testing with 'test' to work better with Ubuntu Edgy's 'dash' shell + +Thu Sep 7 19:10:53 UTC 2006 Taj Morton <tajmorton@gmail.com> + * apgcc: When compiling and linking in 1 command make sure + bogus deps are stripped. Note: I did not update the + double-compilation part of the code to have the fix because + it's dead code. + +Tue May 30 01:04:05 2006 Mike Hearn <mike@plan99.net> + + * relaytool: Add x64 support based on patch by Psyche. + Fix a couple of minor bugs and make the code flow better. + +Thu Apr 13 23:56:32 2006 Mike Hearn <mike@plan99.net> + + * apgcc (translateLibNames): Only drop libstdc++.so from the + arguments list when double compiling. This fixes the case + when libtool passes -nostdlib and then gives us a libstdc++ + directly. However it's kind of a hack and will need to be + changed to work properly with double compiling. + +2006-03-04 Hongli Lai <hongli@plan99.net> + + * apgcc: Apply patch by Francesco Montorsi. + This adds a new option APBUILD_RESOLVE_LIBPATH, which is a + space-seperated list of regular expressions which specify the + libraries whose path must be resolved into absolute paths. + This works around certain linking problems with static libraries, + when the order of the linking arguments is changed. + +2006-02-04 Peter Lund <firefly@diku.dk> + + * APBuild/GCC.pm: Fix double linking of .moc.o files + +2006-02-01 Peter Lund <firefly@diku.dk> + + * apgcc: Add support gcc-2.9x. + Minor comment/--help fixes. See + http://comments.gmane.org/gmane.comp.autopackage.devel/4408 + for more details + * APBuild/GCC.pm, APBuild/Utils.pm: Make apgcc work with ccache. + +2006-01-23 Peter Lund <firefly@diku.dk> + + * Makefile: Use eager notation (`:=') instead of `=' for var assignment. Add $(PROGS)-variable to hold all binary names. + + +2005-12-02 Hongli Lai <hongli@plan99.net> + * apgcc (rearrangeForAsNeeded): + Special case -lbfd and -liberty as they can cause link failures in + some cases. + +2005-11-30 Hongli Lai <hongli@plan99.net> + * apgcc: + Do not link to incorrect libstdc++ version: remove + /usr/lib/libstdc++.so.x from the arguments. + +2005-11-08 Hongli Lai <hongli@plan99.net> + * apgcc, Apbuild/GCC.pm, Apbuild/Utils.pm: + - Code cleanups. + - Fix C++ double compiling bugs: correctly set output filename + when -o is not given, surpress gcc output when double compiling. + +2005-11-07 Hongli Lai <hongli@plan99.net> + * apgcc (linkObjects): remove duplicate system() call which + does nothing good but breaks some libtool versions. + +2005-10-30 Jan Nieuwenhuizen <janneke@gnu.org> + + * Apbuild/GCC.pm (new): New member variable: searchPaths. Bugfix: + add LIBRARY_PATH to initialization. + (addSearchPaths): New function. + (getSearchPaths): Use searchPaths. + + * Apbuild/Utils.pm (searchLib): Bugfix: correct order of search + dirs. + + * apgcc (removeLibraries): Maintain searchPath for full .so name. + +October 16 2005 <hongli@plan99.net> + * apgcc: Correctly double compile C++ binaries during linking. + +September 28 2005 Hongli Lai <hongli@plan99.net> + * Support $APBUILD_NO_RPATH: don't add rpath entries. + Feature request by Andreas. + +September 3 2005 Hongli Lai <hongli@plan99.net> + * relaytool: support W, V and G symbols (experimental C++ support) + +August 5 2005 Hongli Lai <hongli@plan99.net> + * apgcc and GCC.pm: fixed an argument reordering bug. + * Makefile: add make-icons to distrbution. + +2005-08-02 Mike Hearn <mike@plan99.net> + * relaytool: Remove -include flags, if any. This makes relaytool + precompiled-header safe. + +2005-07-31 Mike Hearn <mike@plan99.net> + * relaytool.m4, relaytool: Optimization: use -ffunction-sections + and --gc-sections to eliminate unused jump slots + * relaytool: Don't break when CFLAGS is set + * relaytool: Optimization: only generate jump slots for exported + symbols from the library. + +July 30 2005 Hongli Lai <hongli@plan99.net> + * Apbuild/GCC.pm: Commit Joseph's patch: fix $gcc->isLibrary() + +2005-07-20 Mike Hearn <mike@plan99.net> + * Makefile (dist): Ship relaytool.m4, make extra scripts +x + * relaytool.m4: Big improvements to the way you integrate with + C/C++ build systems. + +July 9 2005 Hongli Lai <hongli@plan99.net> + * apgcc, Apbuild/GCC.pm (rearrangeForAsNeeded): + Fix rearrangement of objects: don't recognize parameters + (-Wl,foo.so) as objects. + +Thu Jun 16 22:43:55 2005 Mike Hearn <mike@navi.cx> + * make-icons: Add a script to generate icon theme dropins from an SVG + file, a convenient utility for developers + +May 31 2005 Hongli Lai <hongli@navi.cx> + * apgcc: Automatically compile C++ source files with two different + ABIs. By default, C++ files are compiled with ABI 1. Another + file with ABI 2 is stored as output.o.GCCABI2 + +May 16th 2005 Vincent Béron <vberon@mecano.gme.usherb.ca> + * relaytool: Keep only one copy of a given symbol per lib. + * relaytool: libdl won't ever be supported by relaytool, so skip it. + * relaytool: Add a --version option, reorganize a bit the rest of --help. + * relaytool: Allow generating a stub file for every library passed in args. + * relaytool: Skip generating a stub for libraries for which no functions + are called or no variables used. + * relaytool: Use proper quoting. + * relaytool: Support old nm versions + +May 15th 2005 Vincent Béron <vberon@mecano.gme.usherb.ca> + * relaytool: Allow relaytool to understand more than one --relay + parameter. + * relaytool: Enable (via --minimal-list) relaytool to only + generate the minimum list of symbols by looking which ones are + undefined in .o objects. + * relaytool: Use CFLAGS (if available) while compiling the stub file. + * relaytool: Use a shell function to do the same thing as + readlink -f as the latter isn't always understood by readlink. + * relaytool: Fix a typo in PPC C code. + +May 14th 2005 Vincent Béron <vberon@mecano.gme.usherb.ca> + * relaytool: Don't accidentally exclude all symbols with _init + or _fini in their names. + +April 16 2005 Hongli Lai <hongli@navi.cx> + * Add new tool 'scandeps' which makes it easier for you to find + your software's library dependancies. + * Improve documentation. + +April 15 2005 Hongli Lai <hongli@navi.cx> + * apgcc: add support for $APBUILD_INCLUDE, which allows you + to prepend any folder to the header search path. + * Improve documentation. + +Fri Apr 15 22:47:06 2005 Mike Hearn <mike@navi.cx> + * apsymbols.h: Update to glibc 2.3.5 + * buildlist: Don't spew so many errors + +April 10 2005 Hongli Lai <hongli@navi.cx> + * What? We have a ChangeLog? I didn't know that! + In the last 2 weeks I worked on these: + - Support for GCC 3.4+'s --as-needed, for smarter automatic bogus + dependancy stripping. + - Improved our own dependancy stripper. + - Big code cleanups. + +Tue Apr 5 02:14:49 2005 Mike Hearn <mike@navi.cx> + * relaytool.m4: Add an autoconf check for relaytool + +Mon Feb 14 00:37:46 2005 Mike Hearn <mike@navi.cx> + * relaytool: Add --no-replace option, fix misc bugs revealed by + actually using relaytool in a real app + +Fri Feb 11 23:49:24 2005 Mike Hearn <mike@navi.cx> + * relaytool: don't request PROT_EXEC permissions, they aren't + needed + +2004-06-06 Mike Hearn <mike@navi.cx> + * relaytool: make relaytool jump thunks NX safe by using mmap + rather than malloc. + + * relaytool: Fix ELF scoping of dummy symbols for variable + imports, so the definitions in the imported lib don't get + resolved to the dummies (not all libs are compiled -Bsymbolic) + + * relaytool: support partial maps + diff --git a/tools/apbuild/Makefile b/tools/apbuild/Makefile new file mode 100644 index 00000000..0b0441b4 --- /dev/null +++ b/tools/apbuild/Makefile @@ -0,0 +1,55 @@ +.PHONY: all install uninstall + +PREFIX:=$(shell test x"`id -u`" = "x0" && if test -f /usr/bin/apgcc; then echo /usr; else echo /usr/local; fi || echo ~/.local) +BINDIR:=$(PREFIX)/bin +PERLDIR:=$(PREFIX)/share/apbuild +INCLUDEDIR:=$(PREFIX)/include/apbuild +ACLOCALDIR:=$(PREFIX)/share/aclocal + +PACKAGE=apbuild +# Don't forget to bump the version in apgcc too. +VERSION=2.0.9 + +PROGS:=apgcc apg++ relaytool scandeps make-icons + +all: + @echo No compilation is required. To install, type 'make install'. + @echo "(Current prefix=$(PREFIX))" + +install: + mkdir -p $(BINDIR) + cp $(PROGS) $(BINDIR) + chmod +x $(BINDIR)/apgcc $(BINDIR)/apg++ $(BINDIR)/scandeps $(BINDIR)/make-icons $(BINDIR)/relaytool + mkdir -p $(PERLDIR)/Apbuild + cp Apbuild/*.pm $(PERLDIR)/Apbuild/ + mkdir -p $(INCLUDEDIR) + cp ctype.h apsymbols.h $(INCLUDEDIR) + mkdir -p $(ACLOCALDIR) + cp relaytool.m4 $(ACLOCALDIR) + echo >> $(INCLUDEDIR)/apsymbols.h + echo "/* apbuild version" $(VERSION) "*/" >> $(INCLUDEDIR)/apsymbols.h + @echo -------------- + @echo "Installation complete. Please read README for usage." + +uninstall: + rm -f $(addprefix $(BINDIR)/, $(PROGS)) + rm -f $(PERLDIR)/Apbuild/*.pm + rmdir $(PERLDIR)/Apbuild $(PERLDIR) + rm -f $(INCLUDEDIR)/ctype.h + rm -f $(INCLUDEDIR)/apsymbols.h + rm -f $(ACLOCALDIR)/relaytool.m4 + +distdir: + rm -rf $(PACKAGE)-$(VERSION) + mkdir $(PACKAGE)-$(VERSION) + cp -R BINARY-PORTABILITY-NOTES Makefile apsymbols.h ctype.h README $(PROGS) buildlist relaytool.m4 $(PACKAGE)-$(VERSION)/ + mkdir $(PACKAGE)-$(VERSION)/test-app + mkdir $(PACKAGE)-$(VERSION)/Apbuild + cp Apbuild/*.pm $(PACKAGE)-$(VERSION)/Apbuild/ + cp test-app/randomapp1.c $(PACKAGE)-$(VERSION)/test-app/ + +dist: distdir + rm -f $(PACKAGE)-$(VERSION).tar.gz + tar -cf $(PACKAGE)-$(VERSION).tar $(PACKAGE)-$(VERSION) + gzip --best $(PACKAGE)-$(VERSION).tar + rm -rf $(PACKAGE)-$(VERSION) diff --git a/tools/apbuild/README b/tools/apbuild/README new file mode 100644 index 00000000..9bc79658 --- /dev/null +++ b/tools/apbuild/README @@ -0,0 +1 @@ +Please read http://autopackage.org/aptools.html for documentation. diff --git a/tools/apbuild/apg++ b/tools/apbuild/apg++ new file mode 100755 index 00000000..30357b53 --- /dev/null +++ b/tools/apbuild/apg++ @@ -0,0 +1,10 @@ +#!/usr/bin/env perl +# Simple C++ wrapper for apgcc. + +use strict; +use FindBin; + +my $apgcc = "$FindBin::Bin/apgcc"; +$ENV{APBUILD_CXX_MODE} = 1; +my $a = do $apgcc; +die $@ if ($@); diff --git a/tools/apbuild/apgcc b/tools/apbuild/apgcc new file mode 100755 index 00000000..2aba0071 --- /dev/null +++ b/tools/apbuild/apgcc @@ -0,0 +1,1023 @@ +#!/usr/bin/env perl +# apbuild - a GCC wrapper for creating portable binaries +# Copyright (c) 2003,2004,2005 Hongli Lai +# Distributed under the GNU General Public License + +use warnings; +use strict; +use FindBin qw($RealBin); +use File::Spec; +use lib $RealBin; +use lib "$RealBin/../share/apbuild"; +use IPC::Open2; +use POSIX; +use Cwd; + +use Apbuild::GCC; +use Apbuild::Utils; + +# Don't forget to bump the version in Makefile too. +our $APBUILD_VERSION = "2.0.9"; + + +######## Initialization ######## + +# In C mode: +# $gcc is the default compiler. +# $gxx2 is not set. +# +# In C++ mode: +# $gcc is g++ 3.2. +# $gxx2 is g++ 3.4, and it might not be set. +# Double compiling is only enabled if both are set. +# +# Note that $APBUILD_CXX_MODE is an internal environment variable +# which should not be set by the user. +our ($gcc, $gxx2); + +if ($ENV{APBUILD_CXX_MODE}) { + # C++ support; user can: + # - Not set APBUILD_CXX1/2 at all -> use g++ as default, and don't double compile C++ sources. + # - Set APBUILD_CXX1 and APBUILD_CXX2 -> enable double compiling. + # - Set only APBUILD_CXX1 -> don't double compile. + # - Set only APBUILD_CXX2 -> use 'g++' as default for APBUILD_CXX1, and enable double compiling. + + if (empty($ENV{APBUILD_CXX1}) && empty($ENV{APBUILD_CXX2})) { + $gcc = new Apbuild::GCC('g++'); + + } elsif (!empty($ENV{APBUILD_CXX1}) && !empty($ENV{APBUILD_CXX2})) { + $gcc = new Apbuild::GCC($ENV{APBUILD_CXX1}); + $gxx2 = new Apbuild::GCC($ENV{APBUILD_CXX2}); + + } elsif (!empty($ENV{APBUILD_CXX1})) { + $gcc = new Apbuild::GCC($ENV{APBUILD_CXX1}); + + } elsif (!empty($ENV{APBUILD_CXX2})) { + $gcc = new Apbuild::GCC('g++'); + $gxx2 = new Apbuild::GCC($ENV{APBUILD_CXX2}); + } + +} else { + my $gcc_command = 'gcc'; + $gcc_command = $ENV{APBUILD_CC} if (!empty($ENV{APBUILD_CC})); + $gcc = new Apbuild::GCC($gcc_command); +} + + +our $appath; +our $libgcc = $ENV{APBUILD_STATIC_LIBGCC} ? '-static-libgcc' : '-shared-libgcc'; + +# Find out where apgcc is located and determine the apbuild header +# path relative to the apgcc script location. +$appath = $ENV{APBUILD_PATH} if (!empty($ENV{APBUILD_PATH})); +if (!defined $appath) { + $appath = $FindBin::Bin; + $appath =~ s/\/*$//g; + $appath =~ s/^(.*)\/.*?$/$1/; + $appath .= '/include/apbuild'; + if (! -f "$appath/apsymbols.h" && -f "$FindBin::Bin/apsymbols.h") { + $appath = $FindBin::Bin; + } +} + +# Special constants +our @linking = ('-Wl,--enable-new-dtags,--rpath,${ORIGIN}/../lib,--rpath,${ORIGIN}/../lib/autopackage'); +our @include = ("-I$appath", '-include', "$appath/apsymbols.h", "-DAPBUILD_VERSION=\"$APBUILD_VERSION\""); +our $extraTypes = $Apbuild::GCC::extraTypes; +our $srcTypes = $Apbuild::GCC::srcTypes; + + +@linking = () if ($ENV{APBUILD_NO_RPATH}); +if (!empty($ENV{APBUILD_INCLUDE})) { + foreach my $dir (split /:+/, $ENV{APBUILD_INCLUDE}) { + if ($dir =~ /=/) { + # allow people to force changing a path with oldpath=newpath, e.g.,: + # $echo $APBUILD_INCLUDE + # /opt/kde/include=/home/taj/kde-headers/kde-3.3.2/kde/include + # would change -I/opt/kde/include to my KDE 3.3 headers. + # this works around problems where the order of the include + # directories is important. Added for amarok 1.4.3 which has a + # header named scriptmanager.h. KDE also has a header named + # scriptmanager. Order of -I flags forces amarok header to be + # included. + my @splitpaths = split(/=/, $dir); + if (-d $splitpaths[1]) { + foreach (@ARGV) { + s/-I$splitpaths[0]$/-I$splitpaths[1]/g; + } + } + } + else { + push @include, "-I$dir" if (-d $dir); + } + } +} + +# Include the apbuild include folder, and all folders inside that folder. +if (opendir D, $appath) { + foreach my $dir (readdir D) { + if ($dir !~ /^\./ && -d "$appath/$dir") { + push @include, "-I$appath/$dir"; + } + } + closedir D; +} + +if (!empty($ENV{APBUILD_PROJECTNAME})) { + push @linking, '-Wl,--rpath,${ORIGIN}/../lib/' . $ENV{APBUILD_PROJECTNAME}; +} + + +our %capabilities = $gcc->capabilities; +if ($capabilities{hash_style}) { + # By default FC6 only generates a .gnu.hash section, not + # .hash (which is the only thing that FC5 and most other + # distros understand). + # Force generation of both sections if the linker supports it + # so that the binary will run on other systems. + # See http://fcp.surfsite.org/modules/newbb/viewtopic.php?topic_id=29929&forum=10&post_id=128939 + # for more details + push @linking, '-Wl,--hash-style=both'; +} + +if ($capabilities{stack_protector}) { + # gcc-4.1 introduced stack protection to help check for + # buffer overflows. This introduces a silent dependency on + # glibc 2.4 (__stack_chk_fail@@GLIBC_2.4) + # Not many people have glibc 2.4 yet, so disable it. + push @include, "-fno-stack-protector"; +} + +if ($capabilities{fortify_source}) { + # Some distros (e.g. Ubuntu 8.10) activate a bufferoverflow protection + # which is only available since glibc 2.3.4. Apbuild removes all symbols + # newer then 2.3, so this can't be used. + push @include, "-U_FORTIFY_SOURCE"; +} + +our %capabilities_gxx2; +%capabilities_gxx2 = $gxx2->capabilities if ($gxx2); +push @linking, $libgcc if ($capabilities{libgcc}); + + +############# Detect compilation situation ############# + +our $situation = $gcc->situation(\@ARGV); +if ($ENV{APBUILD_CXX_MODE}) { + debug "apg++ @ARGV\n"; +} else { + debug "apgcc @ARGV\n"; +} +debug "Situation: $situation\n"; + + +# Handle each situation +# Only situations that involve compiling or linking need to be treated specially +if ($situation eq 'compile') { + # Extract the parameters and files + my (@files, @params); + $gcc->splitParams(\@ARGV, \@files, \@params); + + # Compile each source file to an object file. + # Force GCC to compile C/C++ source files with older glibc symbols. + debug "\@files: is @files\n"; + foreach my $file (@files) { + if ($gxx2 && $gxx2->isCxxSource($file)) { + # This is a C++ source file. Compile the file twice with different ABIs. + my $src = $file; + my $old_gcc; + my %old_cap; + + compileSource($src, \@ARGV); + + $old_gcc = $gcc; + %old_cap = %capabilities; + $gcc = $gxx2; + %capabilities = %capabilities_gxx2; + + beginDoubleCompiling(); + compileSource($src, \@ARGV, '.GCCABI2'); + endDoubleCompiling(); + + $gcc = $old_gcc; + %capabilities = %old_cap; + + } else { + compileSource($file, \@ARGV); + } + } + exit; + +} elsif ($situation eq 'linking') { + linkObjects(\@ARGV); + + if ($gxx2) { + # Check whether there are .GCCABI2 objects. Link them if there are. + my @options; + my $doubleCompile; + + my $callback = sub { + my $type = shift; + + if ($type eq 'param' && ($gxx2->isLibrary($_[0]) || $gxx2->isObject($_[0])) && !$gxx2->isStaticLib($_[0]) && -f "$_[0].GCCABI2") { + push @options, "$_[0].GCCABI2"; + $doubleCompile = 1; + } else { + push @options, @_; + } + }; + + $gcc = $gxx2; + %capabilities = %capabilities_gxx2; + + $gcc->foreach(\@ARGV, $callback); + + if ($doubleCompile) { + debug "Double compiling.\n"; + beginDoubleCompiling(); + linkObjects(\@options, ".GCCABI2"); + endDoubleCompiling(); + } + } + exit; +} elsif ($situation eq 'precompiled header') { + # Extract the parameters and files + my (@files, @params); + $gcc->splitParams(\@ARGV, \@files, \@params); + + # Compile each source file to an object file. + # Force GCC to compile C/C++ source files with older glibc symbols. + debug "\@files: is @files\n"; + foreach my $file (@files) + { + compileSource($file, \@ARGV); + } +} elsif ($situation eq 'compile and link') { + # Extract the parameters and files + my (@params, @files, @linking2); + my @command; + my $status; + + # Seperate files and linker options. + # @params are all options except linker options, and is used for compilation of each individual source file. + # @files are the source files. + $gcc->splitParams(\@ARGV, \@files, \@params); + $gcc->stripLinkerParams(\@params, \@linking2); + + # Compile & link only one source file + if (@files == 1) { + my @options = modifyLinkerOptions(@params); + push @options, @linking2; + + if ($gxx2 && $gxx2->isCxxSource($files[0])) { + # This is a C++ file. Compile twice with different ABIs. + compileSource($files[0], \@ARGV); + manipulateDeps(@options); + + $gcc = $gxx2; + %capabilities = %capabilities_gxx2; + + beginDoubleCompiling(); + compileSource($files[0], \@ARGV, '.GCCABI2'); + manipulateDeps(@options); + endDoubleCompiling(); + + } else { + compileSource($files[0], [@linking, @options], undef); + manipulateDeps($files[0], @options); + } + + exit; + } + + # Compile individual files into objects + my $cxx; + debug "Multiple source files: @files\n"; + foreach my $file (@files) { + my $out = $file; + $out =~ s/^(.*)\..*?$/$1.o/; + + if ($gxx2 && $gxx2->isCxxSource($file)) { + # This is a C++ file. Compile twice with different ABIs. + my $old_gcc; + my %old_cap; + + $cxx = 1; + compileSource($file, [@ARGV, '-c']); + + $old_gcc = $gcc; + %old_cap = %capabilities; + $gcc = $gxx2; + %capabilities = %capabilities_gxx2; + + beginDoubleCompiling(); + compileSource($file, [@ARGV, '-c'], '.GCCABI2'); + endDoubleCompiling(); + + $gcc = $old_gcc; + %capabilities = %old_cap; + + } else { + compileSource($file, [@params, '-c'], undef); + } + + $file = $out; + } + + # Finally, link all objects together. + my @options = (@params, @linking2); + linkObjects([@files, @options]); + + if ($cxx) { + $gcc = $gxx2; + %capabilities = %capabilities_gxx2; + + # Also link the objects with ABI 2 together + foreach (@files) { + $_ .= ".GCCABI2"; + } + beginDoubleCompiling(); + linkObjects([@files, @options], '.GCCABI2'); + endDoubleCompiling(); + } + exit; + +} else { + my $ret = run($gcc->command, @ARGV); + if (defined $ARGV[0] && $ARGV[0] eq '--help') { + print "\napbuild environment variables:\n"; + print " APBUILD_PATH=path Specifies the include path for apsymbols.h\n" . + " (like: /usr/local/include/apbuild)\n" . + " APBUILD_DEBUG=1 Enable debugging messages\n" . + " APBUILD_BOGUS_DEPS=deps Specify a list of whitespace-seperated bogus\n" . + " library dependancies (like: X11 ICE png). These\n" . + " libraries will not be linked.\n" . + " APBUILD_STATIC=deps Specify a list of whitespace-seperated libraries\n" . + " to statically link to (like: popt z). You can also\n" . + " explicitly specify a filename to the static library.\n" . + " Example: popt=/usr/lib/libpopt.a\n" . + " APBUILD_STATIC_X=1 Force static linking of some X extension libraries\n" . + " Don't use this unless you know what you're doing.\n" . + " APBUILD_DISABLE_BOGUS_DETECTOR=1 Disable the automatic bogus dependancy\n" . + " detector. This is useful when linking to libraries\n" . + " don't have correct DT_NEEDED entries, like GTK 1.2.\n" . + " APBUILD_NOT_BOGUS=deps If you want to use the automatic bogus dependancy\n" . + " dectector anyway, then you can specify a list of\n" . + " dependancies here that are not bogus.\n" . + " APBUILD_STATIC_LIBGCC=1 Link all binaries with -static-libgcc. See the gcc\n" . + " info page for more info about this option.\n" . + " APBUILD_PROJECTNAME If non-empty, apbuild will add\n" . + " \$ORIGIN/../lib/\$APBUILD_PROJECTNAME to the library\n" . + " search path.\n" . + " APBUILD_INCLUDE Prepend the specified directory to the compiler's\n" . + " header search path. The compiler will search this\n" . + " directory first, before searching any other\n" . + " directory. This is useful in combination with the\n" . + " older GTK headers package (see the autopackage\n" . + " website). You can specify multiple directories,\n" . + " seperated by a ':', just like the \$PATH environment\n" . + " variable.\n" . + " APBUILD_NO_RPATH Do not add rpath entries during linking.\n" . + " APBUILD_CC Use the specified C compiler. Default value: gcc\n" . + " APBUILD_CXX1,APBUILD_CXX2 Use the specified C++ compiler. Default value: g++\n" . + " Set both variables to enable double compiling. The\n" . + " first should be set to the g++ 3.2 compiler and the\n" . + " second should be set to the g++ 3.4 (or newer)\n" . + " compiler.\n" . + " APBUILD_RESOLVE_LIBPATH A whitespace-separated list of regular expressions which\n" . + " specify the libraries whose path must be resolved into\n" . + " an absolute path.\n"; + } + exit $ret; +} + + +######## Functions ######## + + +sub modifyLinkerOptions { + my @argv = @_; + + # Remove manually specified bogus library dependancies + my @bogusDeps; + @bogusDeps = split / +/, $ENV{APBUILD_BOGUS_DEPS} if (!empty($ENV{APBUILD_BOGUS_DEPS})); + + # We call removeLibraries() twice because it may detect + # some dependancies after we've resolved the library names + @argv = removeLibraries(\@bogusDeps, @argv); + @argv = translateLibNames(@argv); + @argv = removeLibraries(\@bogusDeps, @argv); + + @argv = removeStaticGlibc(@argv); + if ($capabilities{as_needed}) { + @argv = rearrangeForAsNeeded(@argv); + @argv = forceStatic(@argv); + } + + return @argv; +} + + +sub removeLibraries { + my $blacklist = shift; + return @_ if (@{$blacklist} == 0); + + my @args; + my $callback = sub { + my $type = shift; + if ($type ne "param") { + push @args, @_; + return; + } + + my $lib; + $_ = $_[0]; + if (/^-l(.+)/) { + $lib = $1 + } elsif (/(.*)\/lib(.+)\.so/) { + $gcc->addSearchPaths($1); + $lib = $2; + } else { + push @args, @_; + return; + } + + # We now have a library parameter; remove this parameter + # if the library's in the blacklist + foreach my $dep (@{$blacklist}) { + return if ($lib eq $dep); + } + push @args, @_; + }; + + $gcc->foreach(\@_, $callback); + return @args; +} + + +# This function translates library linker options to something saner. +# - On my system, -lpng links to libpng.so. However, libpng.so is a symlink to libpng12.so. +# This function translates -lpng to -lpng12 so that the automatic bogus dependancy stripper +# can detect this as a bogus dependancy. +# - Translate /usr/lib/libpng.so to /usr/lib/libpng12.so because the soname is different. +# - Translates -pthread to -lpthread. +# - When in C++ mode, removes libstdc++.so from the argument list. This causes trouble when +# double compiling, unless the -nostdlib option is specified and we're not double compiling. +# libtool can put us in this configuration. + +# TODO: correctly handle static libraries. +# apg++ ... -L/usr/lib -Wl,-Bstatic -lphysfs -Wl,-Bdynamic +# -> /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.5/../../../../i686-pc-linux-gnu/bin/ld: cannot find -lphysfs-1.0 +sub translateLibNames { + my (@args, @searchPaths); + + # Get a list of search paths + $gcc->getSearchPaths(\@_, \@searchPaths); + + my $staticMode = 0; + my $callback = sub { + my $type = shift; + my $dontAdd; + + if ($type ne 'param') { + push @args, @_; + return; + } + + $_ = $_[0]; + if (/^-Wl,(.+)/) { + # Detect whether the next library will be linked statically or dynamically + foreach my $arg (split /,/, $1) { + if ($arg eq '-Bdynamic') { + $staticMode = 0; + } elsif ($arg eq '-Bstatic') { + $staticMode = 1; + } + } + + } elsif ($staticMode) { + # Don't try to resolve library name if it's linked statically + + } elsif (/^-l(.+)/ || /--library=(.+)/) { + my $libname = $1; + + # Resolve libname if explicitely asked to, through APBUILD_RESOLVE_LIBPATH. + my @libtosolve = split / +/, $ENV{APBUILD_RESOLVE_LIBPATH} if (!empty($ENV{APBUILD_RESOLVE_LIBPATH})); + foreach (@libtosolve) { + my $regexp = $_; + if ($libname =~ /($regexp)/) { + my $file = searchLib("lib$libname.a", \@searchPaths); + if ($file && -f $file) { + debug "resolved", $_[0], "as", $file; + # Replace -lXXX with the absolute path for libXXX.a + $_[0] = $file; + last; + } + } + } + + # Library is a symlink; check whether the sonames match + my $lib = searchLib("lib$libname.so", \@searchPaths); + if ($lib && -l $lib) { + my ($soname1) = $lib =~ /.*\/lib(.+)\.so/; + my $lib2 = soname($lib); + my ($soname2) = $lib2 =~ /lib(.+)\.so/; + + if ($soname1 ne $soname2 && defined searchLib("lib$soname2.so", \@searchPaths)) { + $_[0] = "-l$soname2"; + } + } + + } elsif ($_ eq '-pthread') { + $_[0] = "-lpthread"; + + } elsif ($ENV{APBUILD_CXX_MODE} && /\/?libstdc\+\+\.so(.[56])?/) { + # drop this in double compile mode as it can cause issues + # in single-compile mode leave it alone, otherwise, libtool can break + # ^^^ That used to be true + # Now drop it and add the compilers stdc++ + # Works around libtool problems where the wrong libstdc++.so is + # picked up from .la files of dependencies + my @command = ($gcc->command, "--print-file-name=libstdc++.so"); + chomp($_[0] = `@command`); + + } elsif (/(.*)\/?(lib.+\.so.*)/) { + $gcc->addSearchPaths ($1); + push @searchPaths, $1; + my $lib = searchLib($2, \@searchPaths); + if (defined $lib) { + my $soname = soname($lib); + $lib = searchLib($soname, \@searchPaths); + $_[0] = $lib if (defined $lib); + } + } + push @args, @_ if (!$dontAdd); + }; + $gcc->foreach(\@_, $callback); + + return @args; +} + + +# Replace -static with something else. We can't statically link to glibc! +# So we statically link to everything but glibc. +sub removeStaticGlibc { + my $hasStatic = 0; + foreach (@_) { + if ($_ eq '-static') { + $hasStatic = 1; + last; + } + } + return @_ if (!$hasStatic); + + my @argv; + foreach (@_) { + if ((/^-l(.+)/ || /^--library=(.+)/) && defined $1 && $1 ne 'c') { + push @argv, '-Wl,-Bstatic'; + push @argv, $_; + push @argv, '-Wl,-Bdynamic'; + } elsif ($_ ne "-static") { + push @argv, $_; + } + } + return @argv; +} + + +# 'gcc -Wl,--as-needed foo.o -lpng' breaks the binary. +# 'gcc foo.o -Wl,--as-needed -lpng' doesn't. +# Move object files to before the first library flag. +# +# Furthermore, -lbfd and -liberty must be the last arguments, or +# an app won't link properly in some cases. XRender needs to be +# after XCursor for some reason, so push it to the end too. +sub rearrangeForAsNeeded { + my @args; + my @nonParams; + my @last; + + my $callback = sub { + my $type = shift; + + if ($type ne "param") { + push @nonParams, @_; + + } elsif ($_[0] eq "-lbfd" || $_[0] eq "-liberty" || $_[0] eq "-lXrender") { + push @last, @_; + + } elsif ($gcc->isLibrary($_[0])) { + push @args, @_; + + } elsif ($gcc->isObject($_[0]) || $gcc->linkOrderIsImportant($_[0])) { + push @nonParams, @_; + + } else { + push @args, @_; + } + }; + + $gcc->foreach(\@_, $callback); + unshift @args, "-Wl,--as-needed"; + unshift @args, @nonParams; + push @args, @last; + return @args; +} + + +################ Automatic bogus dependancy stripper ################ + + +# Automatically detecting bogus dependancies & force static linking to certain X libraries +sub manipulateDeps { + return if ($capabilities{as_needed}); + my @searchPaths; + my $output = 'a.out'; + my $i = 0; + my @deps; + my @argv; + + if ($ENV{APBUILD_DISABLE_BOGUS_DETECTOR}) { + @argv = @_; + goto FINAL; + } + + # Get a list of search paths and the output filename + for ($i = 0; $i < @_; $i++) { + if ($_[$i] eq "-L") { + push (@searchPaths, $_[$i + 1]) if (defined $_[$i + 1]); + $i++; + } elsif ($_[$i] =~ /^-L(.+)/ || $_[$i] =~ /^--library-path=(.+)/) { + push (@searchPaths, $1); + } elsif ($_[$i] eq "-o") { + $output = $_[$i + 1] if (defined $_[$i + 1]); + $i++; + } + } + + # Find out what libraries the executable needs + my ($r, $w); + my $pid = open2 ($r, $w, 'objdump', '-p', $output); + close ($w); + foreach (<$r>) { + next unless (/^ NEEDED/); + s/^ NEEDED[ \t]+//; + s/\n//; + my $lib = searchLib ($_, \@searchPaths); + push (@deps, $lib) if (defined $lib); + } + close ($r); + waitpid ($pid, 0); + + # Some -l options have no effect. For example, when linking apollon, + # -lXinerama is passed, yet the resulting executable doesn't have a + # DT_NEEDED entry for libXinerama.so. Remove those options so that + # they won't interfere with forceStatic(). + foreach (@_) { + if ((/^-l(.+)/ || /^--library=(.+)/) + && !searchLib("lib$1.a", \@searchPaths) + && !(/^-lpng$/) # Special case the libpng mess, bah + ) { + # "Xinerama" + my $arg = $1; + # Only add to @argv if $arg is in @deps + foreach my $dep (@deps) { + # "/usr/X11R6/lib/libXinerama.so.1" -> "Xinerama" + my ($soname) = $dep =~ /.*\/lib(.+)\.so/; + if ($arg eq $soname) { + push (@argv, "-l$arg"); + last; + } + } + } else { + push (@argv, $_); + } + } + + # Find out which symbols the executable needs, and which symbols are provided + # by the libraries it's linked to. + my %appsyms = extractSymbols ('UBV', $output); + my @bogusDeps; + + foreach my $lib (@deps) { + # Never remove libc, libgcc_s and libstdc++ + next if ($lib =~ /^\/lib\/lib(c|gcc_s|stdc\+\+)\.so/); + + my %libsyms = extractSymbols ('TBVRDSWG', $lib); + my $bogus = 1; + + foreach my $sym (keys %libsyms) { + if (defined $appsyms{$sym}) { + debug ("Real dependancy $lib: $sym (lib: $libsyms{$sym} - app: $appsyms{$sym})\n"); + $bogus = 0; + last; + } + } + + if ($bogus) { + my ($soname) = $lib =~ /.*\/lib(.+)\.so/; + push (@bogusDeps, $soname); + } + } + + FINAL: { + # Don't strip dependancies that are explicitly marked as not bogus + my %notBogus; + if (!empty($ENV{APBUILD_NOT_BOGUS})) { + foreach (split / +/, $ENV{APBUILD_NOT_BOGUS}) { + $notBogus{$_} = 1; + } + } + + my @tmp; + foreach (@bogusDeps) { + push @tmp, $_ if (!$notBogus{$_}); + } + @bogusDeps = @tmp; + + my @options = removeLibraries(\@bogusDeps, @argv); + @options = forceStatic(@options); + + if ("@options" ne "@argv") { + my @command = ($gcc->command, @include, @linking, @options); + debug("Bogus dependancies: @bogusDeps\n") if (@bogusDeps); + debug("Relinking: @command\n"); + my $status = run(@command); + exit($status) if ($status != 0); + } + } +} + +sub extractSymbols { + my $types = shift; + my %symbols = (); + my ($r, $w); + my $pid = open2 ($r, $w, 'nm', '-D', @_); + + close ($w); + foreach (<$r>) { + if (/^.{9}[$types]/) { + s/\n//; + s/^.{9}//; + my ($type, $name) = split (/ /, $_, 2); + $symbols{$name} = $type; + } + } + close ($r); + waitpid ($pid, 0); + return %symbols; +} + + +# Force static linking against libraries in $APBUILD_STATIC and certain X libraries. +sub forceStatic { + my (%xlibs, %staticList, $X11linked, $linkedToStaticX); + my (@args, @searchPaths); + + # Create a list of libraries that we want to statically link + $gcc->getSearchPaths(\@_, \@searchPaths); + if (defined $ENV{'APBUILD_NO_STATIC_X'}) { + warn "WARNING: APBUILD_NO_STATIC_X is no longer used because it became the default behaviour.\n"; + } + if (defined $ENV{'APBUILD_STATIC_X'} && $ENV{'APBUILD_STATIC_X'} eq "1") { + foreach (qw(Xrender Xcursor Xfixes Xi Xinerama Xrandr Xv Xxf86dga Xxf86misc Xxf86vm)) { + my $file = searchLib("lib$_.a", \@searchPaths); + $staticList{$_} = $file if (defined $file); + $xlibs{$_} = 1; + } + } + + my @static_deps; + if (!empty($ENV{APBUILD_STATIC})) { + foreach (split / +/, $ENV{APBUILD_STATIC}) { + my ($lib, $file) = split /=/, $_, 2; + $file = searchLib("lib$lib.a", \@searchPaths) if (!defined $file); + $staticList{$lib} = $file if (defined $file); + + if (defined $file) { + # find the DT_NEEDED entries that this library-to-be-made-static + # has so that final linking works (the deps need to be added after the static lib so the bogus stripper doesn't remove them) + my ($r, $w); + my $abslib = searchLib("lib$lib.so", \@searchPaths); + if (!defined $abslib) { + warn "WARNING: Failed to find lib$lib.so in " . join(":", @searchPaths) . ".\n"; + next; + } + my $pid = open2 ($r, $w, 'objdump', '-p', $abslib); + close ($w); + foreach (<$r>) { + next unless (/^ NEEDED\s+lib(.+?)\.so/); + s/^ NEEDED\s+lib(.+?)\.so(.*)/$1/; + s/\n//; + push(@static_deps, "-l$_"); + } + close ($r); + waitpid ($pid, 0); + } + } + } + + push (@_, @static_deps); + + # Modify linker options for static linking + my $callback = sub { + my $type = shift; + my $libname; + if ($type eq "param" && $gcc->isLibrary($_[0], \$libname)) { + $X11linked = 1 if (!$X11linked && $libname eq 'X11'); + if ($staticList{$libname}) { + # This parameter is a library and is in the list of libraries + # to statically link; replace parameter by a filename to the + # static library + push @args, $staticList{$libname}; + $linkedToStaticX = 1 if ($xlibs{$libname}); + + if ($libname eq "Xcursor") { + # With some versions of X11 (on Slack 11, + # xorg 6.9.0, anyway), Xcursor links against Xfixes. + # If we switch Xcursor to being linked statically, + # force linking of Xfixes too so we don't get + # undefined symbol errors from Xcursor. + push @args, $staticList{"Xfixes"}; + } + + } else { + push @args, @_; + } + + } else { + push @args, @_; + } + }; + $gcc->foreach(\@_, $callback); + + # The app must be linked to libX11 if it has statically linked any the static X libraries + push @args, "-lX11" if ($linkedToStaticX && !$X11linked); + return @args; +} + +## +# compileSource(source, argss, extension, extra...) +# source: the source filename. +# args: the full GCC arguments (may include other source files) used for compilation. +# extension: if not undef, $extension will be appended to the output object file's filename. +# extra: extra parameters to pass to the compiler. +sub compileSource { + my ($source, $args, $ext) = @_; + my (@command, @tmp, @params, @sourceParams, @otherParams); + + $gcc->splitParams($args, undef, \@tmp); + push @tmp, $source; + + if (defined $ext) { + # Change the output file's extension. + $gcc->setOutputFile(\@tmp, $gcc->getOutputFile(\@tmp) . $ext); + } + $gcc->splitParams(\@tmp, undef, \@params); + + my $callback = sub { + my $type = shift; + if ($type eq 'param' && $gcc->sourceOrderIsImportant($_[0])) { + push @sourceParams, @_; + } else { + push @otherParams, @_; + } + }; + $gcc->foreach(\@params, $callback); + + if ($source =~ /\.($srcTypes)$/) { + @command = ($gcc->command, @include, @sourceParams, $source, @otherParams); + } else { + @command = ($gcc->command, @sourceParams, $source, @otherParams); + } + + debug "@command\n"; + my $status = run(@command); + exit($status) if ($status != 0); +} + +# Checks whether there should be an ABI2 version of a certain static library. +sub checkStaticLibrary { + my ($lib, $ext) = @_; + my ($pid, $r, $w, @objects, $doubleCompile); + my (undef, $libdir, $libname) = File::Spec->splitpath($lib); + my $newlib = "$lib$ext"; + + # Return the ABI2 version if already exists. + return $newlib if (-f $newlib); + + # Check the content of the archive. Check whether + # there are ABI2 versions of the object files inside. + $pid = open2($r, $w, 'ar', 't', $lib); + close($w); + while ((my $file = <$r>)) { + $file =~ s/\n//g; + if (-f "$libdir/$file$ext") { + push @objects, "$file$ext"; + $doubleCompile = 1; + } else { + push @objects, $file; + } + } + close($r); + waitpid ($pid, 0); + + if ($doubleCompile) { + my $oldDir = getcwd(); + $newlib = "$libname$ext"; + debug "Creating static library $newlib\n"; + + chdir($libdir); + my @command = ("ar", "cru", $newlib, @objects); + debug(@command); + my $ret = run(@command); + exit($ret) if ($ret != 0); + + @command = ("ranlib", $newlib); + debug(@command); + $ret = run(@command); + exit($ret) if ($ret != 0); + + chdir($oldDir); + return $newlib; + } else { + return undef; + } +} + +sub linkObjects { + my ($args, $ext) = @_; + my @options = modifyLinkerOptions(@{$args}); + + if (defined $ext) { + $gcc->setOutputFile(\@options, $gcc->getOutputFile(\@options) . $ext); + + # Check whether this object links to any static libraries. + # If it does, check whether there should be an ABI2 version of that + # static library, and attempt to create it. + my @options2; + + my $callback = sub { + my $type = shift; + if ($type eq 'param' && $gcc->isStaticLib($_[0])) { + my $newlib = checkStaticLibrary($_[0], $ext); + if (defined $newlib) { + push @options2, $newlib; + } else { + push @options2, @_; + } + } else { + push @options2, @_; + } + }; + $gcc->foreach(\@options, $callback); + @options = @options2; + } + + my @command = ($gcc->command, @linking, @options); + debug "@command\n"; + + my $status = run(@command); + exit ($status) if ($status != 0); + + my (@files, @options2); + $gcc->splitParams(\@options, \@files, \@options2); + manipulateDeps(@files, @options2); +} + +## +# beginDoubleCompiling() +# +# Prepare the environment for double compiling. +sub beginDoubleCompiling { + # Since g++ will be executed another time, we don't want it to + # print output to stdout/stderr, because it can potentially + # screw up some build systems such as libtool. + # stderr will go to the console (/dev/tty), stdout will be + # lost (/dev/null). + + our $stdout_fd = fileno(STDOUT); + our $stderr_fd = fileno(STDERR); + our $stdout_saved = POSIX::dup($stdout_fd); + our $stderr_saved = POSIX::dup($stderr_fd); + + my $fd1 = POSIX::open("/dev/null", O_CREAT | O_WRONLY, 0644); + my $fd2 = POSIX::open("/dev/tty", O_CREAT | O_WRONLY, 0644); + POSIX::dup2($fd1, $stdout_fd); + POSIX::dup2($fd2, $stderr_fd); + POSIX::close($fd1); + POSIX::close($fd2); +} + +## +# endDoubleCompiling() +# +# Unprepare the environment for double compiling. +sub endDoubleCompiling { + our ($stdout_fd, $stderr_fd, $stdout_saved, $stderr_saved); + + POSIX::dup2($stdout_saved, $stdout_fd); + POSIX::dup2($stderr_saved, $stderr_fd); + POSIX::close($stdout_saved); + POSIX::close($stderr_saved); +} diff --git a/tools/apbuild/apsymbols.h b/tools/apbuild/apsymbols.h new file mode 100644 index 00000000..32c7b18c --- /dev/null +++ b/tools/apbuild/apsymbols.h @@ -0,0 +1,275 @@ +/* apbuild embedded metadata */ +#define APBUILD_NOTE_METADATA(s) __asm__(".section .metadata, \"MS\", @note, 1\n\t.string \"" s "\"\n\t.previous\n\t") + +#ifdef APBUILD_VERSION +APBUILD_NOTE_METADATA("apbuild.version=" APBUILD_VERSION); +#endif + +/* apbuild generated symbol exclusion list */ +__asm__(".symver _sys_errlist,_sys_errlist@GLIBC_2.0"); +__asm__(".symver _sys_nerr,_sys_nerr@GLIBC_2.0"); +__asm__(".symver _sys_siglist,_sys_siglist@GLIBC_2.0"); +__asm__(".symver clnt_pcreateerror,clnt_pcreateerror@GLIBC_2.0"); +__asm__(".symver clnt_spcreateerror,clnt_spcreateerror@GLIBC_2.0"); +__asm__(".symver feupdateenv,feupdateenv@GLIBC_2.1"); +__asm__(".symver lio_listio,lio_listio@GLIBC_2.1"); +__asm__(".symver lio_listio64,lio_listio64@GLIBC_2.1"); +__asm__(".symver nftw,nftw@GLIBC_2.1"); +__asm__(".symver nftw64,nftw64@GLIBC_2.1"); +__asm__(".symver posix_fadvise64,posix_fadvise64@GLIBC_2.2"); +__asm__(".symver posix_fallocate64,posix_fallocate64@GLIBC_2.2"); +__asm__(".symver pthread_cond_broadcast,pthread_cond_broadcast@GLIBC_2.0"); +__asm__(".symver pthread_cond_destroy,pthread_cond_destroy@GLIBC_2.0"); +__asm__(".symver pthread_cond_init,pthread_cond_init@GLIBC_2.0"); +__asm__(".symver pthread_cond_signal,pthread_cond_signal@GLIBC_2.0"); +__asm__(".symver pthread_cond_timedwait,pthread_cond_timedwait@GLIBC_2.0"); +__asm__(".symver pthread_cond_wait,pthread_cond_wait@GLIBC_2.0"); +__asm__(".symver regexec,regexec@GLIBC_2.0"); +__asm__(".symver rpc_createerr,rpc_createerr@GLIBC_2.0"); +__asm__(".symver sys_errlist,sys_errlist@GLIBC_2.0"); +__asm__(".symver sys_nerr,sys_nerr@GLIBC_2.0"); +__asm__(".symver sys_sigabbrev,sys_sigabbrev@GLIBC_2.0"); +__asm__(".symver sys_siglist,sys_siglist@GLIBC_2.0"); +__asm__(".symver vm86,vm86@GLIBC_2.0"); +__asm__(".symver __rpc_thread_createerr,__rpc_thread_createerr@GLIBC_2.2.3"); +__asm__(".symver __guard,__guard@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __gethostname_chk,__gethostname_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver epoll_create,epoll_create@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __getdomainname_chk,__getdomainname_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __vswprintf_chk,__vswprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __stpcpy_chk,__stpcpy_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver timerfd_gettime,timerfd_gettime@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inotify_init1,inotify_init1@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wcstombs_chk,__wcstombs_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __printf_chk,__printf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __fgetws_chk,__fgetws_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __register_atfork,__register_atfork@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver gnu_dev_major,gnu_dev_major@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __vfwprintf_chk,__vfwprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wcpcpy_chk,__wcpcpy_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver open_wmemstream,open_wmemstream@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_opt_append,inet6_opt_append@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver timerfd_create,timerfd_create@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __swprintf_chk,__swprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver getipv4sourcefilter,getipv4sourcefilter@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __vwprintf_chk,__vwprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver readlinkat,readlinkat@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wctomb_chk,__wctomb_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __readlink_chk,__readlink_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver setipv4sourcefilter,setipv4sourcefilter@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __isoc99_sscanf,__isoc99_sscanf@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __getlogin_r_chk,__getlogin_r_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver sync_file_range,sync_file_range@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __open64_2,__open64_2@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_rth_init,inet6_rth_init@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_opt_next,inet6_opt_next@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __fxstatat64,__fxstatat64@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver unlinkat,unlinkat@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __fwprintf_chk,__fwprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __mempcpy_chk,__mempcpy_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver epoll_wait,epoll_wait@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver mkfifoat,mkfifoat@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __isoc99_scanf,__isoc99_scanf@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __read_chk,__read_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __fgetws_unlocked_chk,__fgetws_unlocked_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __vsprintf_chk,__vsprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wcsncpy_chk,__wcsncpy_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __stack_chk_fail,__stack_chk_fail@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inotify_rm_watch,inotify_rm_watch@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver xdr_quad_t,xdr_quad_t@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __sched_cpualloc,__sched_cpualloc@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __obstack_vprintf_chk,__obstack_vprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __isoc99_swscanf,__isoc99_swscanf@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __isoc99_vfwscanf,__isoc99_vfwscanf@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __sched_cpufree,__sched_cpufree@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_opt_finish,inet6_opt_finish@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __confstr_chk,__confstr_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wcsncat_chk,__wcsncat_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver setsourcefilter,setsourcefilter@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver xdr_u_quad_t,xdr_u_quad_t@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __fread_unlocked_chk,__fread_unlocked_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver eaccess,eaccess@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_option_alloc,inet6_option_alloc@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __openat64_2,__openat64_2@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver sched_setaffinity,sched_setaffinity@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_option_append,inet6_option_append@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver futimens,futimens@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver renameat,renameat@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wmemset_chk,__wmemset_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_opt_get_val,inet6_opt_get_val@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver unshare,unshare@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __isoc99_vsscanf,__isoc99_vsscanf@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver signalfd,signalfd@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_option_next,inet6_option_next@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_rth_add,inet6_rth_add@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver semtimedop,semtimedop@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver utimensat,utimensat@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_rth_segments,inet6_rth_segments@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __pread_chk,__pread_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __syslog_chk,__syslog_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver eventfd,eventfd@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __fgets_unlocked_chk,__fgets_unlocked_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __getcwd_chk,__getcwd_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver fchmodat,fchmodat@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver dup3,dup3@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __vprintf_chk,__vprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __fprintf_chk,__fprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wmemcpy_chk,__wmemcpy_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __isoc99_wscanf,__isoc99_wscanf@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wcscpy_chk,__wcscpy_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __isoc99_fscanf,__isoc99_fscanf@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __mbstowcs_chk,__mbstowcs_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __dprintf_chk,__dprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wmempcpy_chk,__wmempcpy_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver symlinkat,symlinkat@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __memmove_chk,__memmove_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __getwd_chk,__getwd_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __vsnprintf_chk,__vsnprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver mkostemp64,mkostemp64@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver eventfd_read,eventfd_read@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver remap_file_pages,remap_file_pages@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __isoc99_vswscanf,__isoc99_vswscanf@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver fdopendir,fdopendir@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __openat_2,__openat_2@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __fgets_chk,__fgets_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __strncpy_chk,__strncpy_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __sched_cpucount,__sched_cpucount@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __mbsrtowcs_chk,__mbsrtowcs_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wcscat_chk,__wcscat_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_option_space,inet6_option_space@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver sched_getaffinity,sched_getaffinity@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __open_2,__open_2@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver fchownat,fchownat@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver timerfd_settime,timerfd_settime@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver sched_getcpu,sched_getcpu@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __getgroups_chk,__getgroups_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_opt_init,inet6_opt_init@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __snprintf_chk,__snprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver mkdirat,mkdirat@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __memset_chk,__memset_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __strncat_chk,__strncat_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_rth_space,inet6_rth_space@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __recv_chk,__recv_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_rth_reverse,inet6_rth_reverse@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __stack_smash_handler,__stack_smash_handler@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __realpath_chk,__realpath_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver qsort_r,qsort_r@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __obstack_printf_chk,__obstack_printf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_rth_getaddr,inet6_rth_getaddr@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver splice,splice@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver eventfd_write,eventfd_write@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver vmsplice,vmsplice@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver getsourcefilter,getsourcefilter@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __isoc99_vwscanf,__isoc99_vwscanf@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver epoll_ctl,epoll_ctl@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver gnu_dev_minor,gnu_dev_minor@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __memcpy_chk,__memcpy_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __isoc99_vfscanf,__isoc99_vfscanf@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __stpncpy_chk,__stpncpy_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_opt_find,inet6_opt_find@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __mbsnrtowcs_chk,__mbsnrtowcs_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver strerror_l,strerror_l@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __fread_chk,__fread_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wcsnrtombs_chk,__wcsnrtombs_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wprintf_chk,__wprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver epoll_create1,epoll_create1@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __vfprintf_chk,__vfprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __vsyslog_chk,__vsyslog_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inotify_add_watch,inotify_add_watch@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wcrtomb_chk,__wcrtomb_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver epoll_pwait,epoll_pwait@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __strcpy_chk,__strcpy_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __vdprintf_chk,__vdprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __vasprintf_chk,__vasprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __xpg_strerror_r,__xpg_strerror_r@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wcpncpy_chk,__wcpncpy_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_option_init,inet6_option_init@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wmemmove_chk,__wmemmove_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __sprintf_chk,__sprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver futimesat,futimesat@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __pread64_chk,__pread64_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver strptime_l,strptime_l@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver lchmod,lchmod@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __chk_fail,__chk_fail@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __isoc99_vscanf,__isoc99_vscanf@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __wcsrtombs_chk,__wcsrtombs_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pipe2,pipe2@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __strcat_chk,__strcat_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver faccessat,faccessat@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __asprintf_chk,__asprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ppoll,ppoll@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __recvfrom_chk,__recvfrom_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_opt_set_val,inet6_opt_set_val@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __ptsname_r_chk,__ptsname_r_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __isoc99_fwscanf,__isoc99_fwscanf@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __gets_chk,__gets_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver gnu_dev_makedev,gnu_dev_makedev@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __xmknodat,__xmknodat@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver inet6_option_find,inet6_option_find@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __ttyname_r_chk,__ttyname_r_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __readlinkat_chk,__readlinkat_chk@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver dlmopen,dlmopen@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver dladdr1,dladdr1@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver dlinfo,dlinfo@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_mutexattr_getprotocol,pthread_mutexattr_getprotocol@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_mutex_setprioceiling,pthread_mutex_setprioceiling@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_mutexattr_setprioceiling,pthread_mutexattr_setprioceiling@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __pthread_unregister_cancel_restore,__pthread_unregister_cancel_restore@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_attr_setaffinity_np,pthread_attr_setaffinity_np@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __pthread_cleanup_routine,__pthread_cleanup_routine@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_condattr_getclock,pthread_condattr_getclock@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __pthread_register_cancel_defer,__pthread_register_cancel_defer@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __pthread_unwind_next,__pthread_unwind_next@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_timedjoin_np,pthread_timedjoin_np@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_setaffinity_np,pthread_setaffinity_np@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_mutex_getprioceiling,pthread_mutex_getprioceiling@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_mutexattr_getprioceiling,pthread_mutexattr_getprioceiling@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_attr_getaffinity_np,pthread_attr_getaffinity_np@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_barrierattr_getpshared,pthread_barrierattr_getpshared@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_condattr_setclock,pthread_condattr_setclock@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_tryjoin_np,pthread_tryjoin_np@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_setschedprio,pthread_setschedprio@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_getaffinity_np,pthread_getaffinity_np@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_mutexattr_setrobust_np,pthread_mutexattr_setrobust_np@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_mutexattr_getrobust_np,pthread_mutexattr_getrobust_np@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_mutexattr_setprotocol,pthread_mutexattr_setprotocol@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver pthread_mutex_consistent_np,pthread_mutex_consistent_np@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_put16,ns_put16@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_name_pton,ns_name_pton@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_name_skip,ns_name_skip@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_name_pack,ns_name_pack@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_name_ntol,ns_name_ntol@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_sprintrr,ns_sprintrr@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_format_ttl,ns_format_ttl@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_name_ntop,ns_name_ntop@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_name_compress,ns_name_compress@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_name_unpack,ns_name_unpack@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_put32,ns_put32@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_sprintrrf,ns_sprintrrf@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_datetosecs,ns_datetosecs@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_get16,ns_get16@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_msg_getflag,ns_msg_getflag@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_samedomain,ns_samedomain@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __p_rcode,__p_rcode@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_parse_ttl,ns_parse_ttl@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_get32,ns_get32@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_skiprr,ns_skiprr@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_parserr,ns_parserr@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_name_rollback,ns_name_rollback@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_samename,ns_samename@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_name_uncompress,ns_name_uncompress@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_subdomain,ns_subdomain@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_makecanon,ns_makecanon@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver ns_initparse,ns_initparse@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver mq_open,mq_open@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver __mq_open_2,__mq_open_2@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver mq_timedsend,mq_timedsend@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver mq_notify,mq_notify@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver mq_receive,mq_receive@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver mq_close,mq_close@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver mq_getattr,mq_getattr@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver mq_send,mq_send@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver mq_unlink,mq_unlink@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver mq_setattr,mq_setattr@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver mq_timedreceive,mq_timedreceive@GLIBC_DONT_USE_THIS_SYMBOL"); +__asm__(".symver td_thr_tlsbase,td_thr_tlsbase@GLIBC_DONT_USE_THIS_SYMBOL"); diff --git a/tools/apbuild/buildlist b/tools/apbuild/buildlist new file mode 100755 index 00000000..24e789fd --- /dev/null +++ b/tools/apbuild/buildlist @@ -0,0 +1,48 @@ +#!/bin/bash + +# get a list of all symbols - YOU MUST RUN THIS SCRIPT WITH THE LATEST VERSIONS OF GLIBC +# currently blacklists all newer than 2.3.0 + +if [ -e syms ]; then rm syms; fi +if [ -e allsym ]; then rm allsym; fi +for f in /lib/*; do + if [ ! -f $f ]; then continue; fi + readelf -s --wide $f >>syms + objdump -T $f | grep "GLIBC_" | sed 's/\(.*\)GLIBC_//; s/)//' | grep -v PRIVATE | column -t >>allsym +done + + +# get a list of all symbol versions only available in 2.3+ +grep @@GLIBC_ syms | awk ' { print $8 } ' | sed 's/@@/ /; /GLIBC_P/d; s/GLIBC_//' | awk ' { if ($2 > 2.3) print $1 " " $2 } ' | column -t >glibc2.4.syms + +# select the symbols that already existed, but were obsoleted by 2.2+ versions +cat glibc2.4.syms | awk '{print $1}' | while read; do grep $REPLY allsym; done | sed '/2\.4/d' >syms-to-header + +# select the latest symbols of that set +# build a header from them +cat syms-to-header | awk '{print $2 " " $1 }' | sort | uniq >output +cat glibc2.4.syms | sort | uniq >> output + +cat output | sort | uniq | awk '{print $2 " " $1}' | sort -k2,1 | awk '{ if ($1 <= 2.3) print $1 " " $2 }' | column -t | sort -k2 | uniq -f1 >output2 + +# output the symbols that are brand new to 2.3+, ie not the ones that had earlier versions +cat glibc2.4.syms | awk '{ print $1 }' | while read; do if ! grep "$REPLY" output2 >/dev/null; then echo "DONT_USE_THIS_SYMBOL $REPLY" >>output2; fi; done; + +cat output2 | column -t | awk '{ print "__asm__(\".symver " $2 "," $2 "@GLIBC_" $1 "\");" }' > output + +# now remove dl_iterate_phdr as it's weak anyway (we should probably do this for all weak syms) +cat output | sed 's/__asm__("\.symver dl_iterate_phdr.*//' >output2 + +cat <<EOF >apsymbols.h +/* apbuild embedded metadata */ +#define APBUILD_NOTE_METADATA(s) \ + __asm__(".section .metadata, \"MS\", @note, 1\n\t.string \"" s "\"\n\t.previous\n\t") + +#ifdef APBUILD_VERSION +APBUILD_NOTE_METADATA("apbuild.version=" APBUILD_VERSION); +#endif + +/* apbuild generated symbol exclusion list */ +EOF +cat output2 >> apsymbols.h +rm output2 diff --git a/tools/apbuild/ctype.h b/tools/apbuild/ctype.h new file mode 100644 index 00000000..2db84cc1 --- /dev/null +++ b/tools/apbuild/ctype.h @@ -0,0 +1,268 @@ +/* Copyright (C) 1991,92,93,95,96,97,98,99,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* + * ISO C99 Standard 7.4: Character handling <ctype.h> + */ + +#ifndef _CTYPE_H +#define _CTYPE_H 1 + +#include <features.h> +#include <bits/types.h> + +__BEGIN_DECLS + +#ifndef _ISbit +/* These are all the characteristics of characters. + If there get to be more than 16 distinct characteristics, + many things must be changed that use `unsigned short int's. + + The characteristics are stored always in network byte order (big + endian). We define the bit value interpretations here dependent on the + machine's byte order. */ + +# include <endian.h> +# if __BYTE_ORDER == __BIG_ENDIAN +# define _ISbit(bit) (1 << (bit)) +# else /* __BYTE_ORDER == __LITTLE_ENDIAN */ +# define _ISbit(bit) ((bit) < 8 ? ((1 << (bit)) << 8) : ((1 << (bit)) >> 8)) +# endif + +enum +{ + _ISupper = _ISbit (0), /* UPPERCASE. */ + _ISlower = _ISbit (1), /* lowercase. */ + _ISalpha = _ISbit (2), /* Alphabetic. */ + _ISdigit = _ISbit (3), /* Numeric. */ + _ISxdigit = _ISbit (4), /* Hexadecimal numeric. */ + _ISspace = _ISbit (5), /* Whitespace. */ + _ISprint = _ISbit (6), /* Printing. */ + _ISgraph = _ISbit (7), /* Graphical. */ + _ISblank = _ISbit (8), /* Blank (usually SPC and TAB). */ + _IScntrl = _ISbit (9), /* Control character. */ + _ISpunct = _ISbit (10), /* Punctuation. */ + _ISalnum = _ISbit (11) /* Alphanumeric. */ +}; +#endif /* ! _ISbit */ + +/* These are defined in ctype-info.c. + The declarations here must match those in localeinfo.h. + + These point into arrays of 384, so they can be indexed by any `unsigned + char' value [0,255]; by EOF (-1); or by any `signed char' value + [-128,-1). ISO C requires that the ctype functions work for `unsigned + char' values and for EOF; we also support negative `signed char' values + for broken old programs. The case conversion arrays are of `int's + rather than `unsigned char's because tolower (EOF) must be EOF, which + doesn't fit into an `unsigned char'. But today more important is that + the arrays are also used for multi-byte character sets. */ +extern __const unsigned short int *__ctype_b; /* Characteristics. */ +extern __const __int32_t *__ctype_tolower; /* Case conversions. */ +extern __const __int32_t *__ctype_toupper; /* Case conversions. */ + +__asm__(".symver __ctype_b,__ctype_b@GLIBC_2.0"); +__asm__(".symver __ctype_tolower,__ctype_tolower@GLIBC_2.0"); +__asm__(".symver __ctype_toupper,__ctype_toupper@GLIBC_2.0"); + +#define __isctype(c, type) \ + (__ctype_b[(int) (c)] & (unsigned short int) type) + +#define __isascii(c) (((c) & ~0x7f) == 0) /* If C is a 7 bit value. */ +#define __toascii(c) ((c) & 0x7f) /* Mask off high bits. */ + +#define __exctype(name) extern int name (int) __THROW + +/* The following names are all functions: + int isCHARACTERISTIC(int c); + which return nonzero iff C has CHARACTERISTIC. + For the meaning of the characteristic names, see the `enum' above. */ +__exctype (isalnum); +__exctype (isalpha); +__exctype (iscntrl); +__exctype (isdigit); +__exctype (islower); +__exctype (isgraph); +__exctype (isprint); +__exctype (ispunct); +__exctype (isspace); +__exctype (isupper); +__exctype (isxdigit); + +#ifdef __USE_ISOC99 +__exctype (isblank); +#endif + + +/* Return the lowercase version of C. */ +extern int tolower (int __c) __THROW; + +/* Return the uppercase version of C. */ +extern int toupper (int __c) __THROW; + + +#if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN + +/* Return nonzero iff C is in the ASCII set + (i.e., is no more than 7 bits wide). */ +extern int isascii (int __c) __THROW; + +/* Return the part of C that is in the ASCII set + (i.e., the low-order 7 bits of C). */ +extern int toascii (int __c) __THROW; + +/* These are the same as `toupper' and `tolower' except that they do not + check the argument for being in the range of a `char'. */ +__exctype (_toupper); +__exctype (_tolower); +#endif /* Use SVID or use misc. */ + +/* This code is needed for the optimized mapping functions. */ +#define __tobody(c, f, a, args) \ + (__extension__ \ + ({ int __res; \ + if (sizeof (c) > 1) \ + { \ + if (__builtin_constant_p (c)) \ + { \ + int __c = (c); \ + __res = __c < -128 || __c > 255 ? __c : a[__c]; \ + } \ + else \ + __res = f args; \ + } \ + else \ + __res = a[(int) (c)]; \ + __res; })) + +#ifndef __NO_CTYPE +# define isalnum(c) __isctype((c), _ISalnum) +# define isalpha(c) __isctype((c), _ISalpha) +# define iscntrl(c) __isctype((c), _IScntrl) +# define isdigit(c) __isctype((c), _ISdigit) +# define islower(c) __isctype((c), _ISlower) +# define isgraph(c) __isctype((c), _ISgraph) +# define isprint(c) __isctype((c), _ISprint) +# define ispunct(c) __isctype((c), _ISpunct) +# define isspace(c) __isctype((c), _ISspace) +# define isupper(c) __isctype((c), _ISupper) +# define isxdigit(c) __isctype((c), _ISxdigit) + +# ifdef __USE_ISOC99 +# define isblank(c) __isctype((c), _ISblank) +# endif + +# if __GNUC__ >= 2 && defined __OPTIMIZE__ && !defined __cplusplus +# define tolower(c) __tobody (c, tolower, __ctype_tolower, (c)) +# define toupper(c) __tobody (c, toupper, __ctype_toupper, (c)) +# endif /* Optimizing gcc */ + +# if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN +# define isascii(c) __isascii (c) +# define toascii(c) __toascii (c) + +# define _tolower(c) ((int) __ctype_tolower[(int) (c)]) +# define _toupper(c) ((int) __ctype_toupper[(int) (c)]) +# endif + +#endif /* Not __NO_CTYPE. */ + + +#ifdef __USE_GNU +/* The concept of one static locale per category is not very well + thought out. Many applications will need to process its data using + information from several different locales. Another application is + the implementation of the internationalization handling in the + upcoming ISO C++ standard library. To support this another set of + the functions using locale data exist which have an additional + argument. + + Attention: all these functions are *not* standardized in any form. + This is a proof-of-concept implementation. */ + +/* Structure for reentrant locale using functions. This is an + (almost) opaque type for the user level programs. */ +# include <xlocale.h> + +/* These definitions are similar to the ones above but all functions + take as an argument a handle for the locale which shall be used. */ +# define __isctype_l(c, type, locale) \ + ((locale)->__ctype_b[(int) (c)] & (unsigned short int) type) + +# define __exctype_l(name) extern int name (int, __locale_t) __THROW + +/* The following names are all functions: + int isCHARACTERISTIC(int c, locale_t *locale); + which return nonzero iff C has CHARACTERISTIC. + For the meaning of the characteristic names, see the `enum' above. */ +__exctype_l (__isalnum_l); +__exctype_l (__isalpha_l); +__exctype_l (__iscntrl_l); +__exctype_l (__isdigit_l); +__exctype_l (__islower_l); +__exctype_l (__isgraph_l); +__exctype_l (__isprint_l); +__exctype_l (__ispunct_l); +__exctype_l (__isspace_l); +__exctype_l (__isupper_l); +__exctype_l (__isxdigit_l); + +__exctype_l (__isblank_l); + + +/* Return the lowercase version of C in locale L. */ +extern int __tolower_l (int __c, __locale_t __l) __THROW; + +/* Return the uppercase version of C. */ +extern int __toupper_l (int __c, __locale_t __l) __THROW; + +# if __GNUC__ >= 2 && defined __OPTIMIZE__ && !defined __cplusplus +# define __tolower_l(c, locale) \ + __tobody (c, __tolower_l, (locale)->__ctype_tolower, (c, locale)) +# define __toupper_l(c, locale) \ + __tobody (c, __toupper_l, (locale)->__ctype_toupper, (c, locale)) +# endif /* Optimizing gcc */ + + +# ifndef __NO_CTYPE +# define __isalnum_l(c,l) __isctype_l((c), _ISalnum, (l)) +# define __isalpha_l(c,l) __isctype_l((c), _ISalpha, (l)) +# define __iscntrl_l(c,l) __isctype_l((c), _IScntrl, (l)) +# define __isdigit_l(c,l) __isctype_l((c), _ISdigit, (l)) +# define __islower_l(c,l) __isctype_l((c), _ISlower, (l)) +# define __isgraph_l(c,l) __isctype_l((c), _ISgraph, (l)) +# define __isprint_l(c,l) __isctype_l((c), _ISprint, (l)) +# define __ispunct_l(c,l) __isctype_l((c), _ISpunct, (l)) +# define __isspace_l(c,l) __isctype_l((c), _ISspace, (l)) +# define __isupper_l(c,l) __isctype_l((c), _ISupper, (l)) +# define __isxdigit_l(c,l) __isctype_l((c), _ISxdigit, (l)) + +# define __isblank_l(c,l) __isctype_l((c), _ISblank, (l)) + +# if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN +# define __isascii_l(c,l) __isascii(c) +# define __toascii_l(c,l) __toascii(c) +# endif + +# endif /* Not __NO_CTYPE. */ + +#endif /* Use GNU. */ + +__END_DECLS + +#endif /* ctype.h */ diff --git a/tools/apbuild/make-icons b/tools/apbuild/make-icons new file mode 100755 index 00000000..32c0c600 --- /dev/null +++ b/tools/apbuild/make-icons @@ -0,0 +1,58 @@ +#!/bin/sh + +# +# This script generates a directory and an automake fragment from an SVG +# file. It's useful when you have an SVG and want to pre-render icons of +# various sizes from it, then install them into the users icon theme. +# +# For autopackage users, put the following line in your specfile: +# +# installIcon share/icons/hicolor +# +# It uses rsvg to render the icons + +if [[ "$1" == "" ]] || [[ "$2" == "" ]] || [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then + echo "Usage: make-icons myprogram.svg type" + echo + echo "Generates a subdirectory called icons with an icon theme tree" + echo "in it. Also outputs some automake code you can copy/paste". + echo "" + echo "type is the type of icon and should be one of the following:" + echo "apps, mimetypes, actions, devices, filesystems" + echo "See FDO spec for details--you most likely want apps or mimetypes" + exit 0 +fi + +if ! which rsvg >/dev/null; then + # a part of librsvg + echo "make-icons: this script needs the rsvg program installed" + exit 1 +fi + +if [ ! -e $1 ]; then + echo "make-icons: the given file does not exist" + exit 1 +fi + +if [[ "$2" != "apps" && "$2" != "mimetypes" && "$2" != "actions" && "$2" != "devices" && "$2" != "filesystems" ]]; then + echo "make-icons: $2 is not a valid icon type. type should be one of these:" + echo "apps, mimetypes, actions, devices, filesystems" + echo "See FDO spec for details--you most likely want apps or mimetypes" + exit 1 +fi +mkdir -p icons/scalable/$2 +cp $1 icons/scalable/$2 + +newname="`basename $1`" +echo "iconSVGdir = \$(datadir)/icons/hicolor/scalable/$2" +echo "iconSVG_DATA = icons/scalable/$2/$newname" + +newname="${newname/.svg/}.png" + + +for size in 128 64 48 24 16; do + mkdir -p icons/${size}x${size}/$2 + rsvg --width=$size --height=$size $1 icons/${size}x${size}/$2/$newname + echo "icon${size}dir = \$(datadir)/icons/hicolor/${size}x${size}/$2" + echo "icon${size}_DATA = icons/${size}x${size}/$2/$newname" +done diff --git a/tools/apbuild/relaytool b/tools/apbuild/relaytool new file mode 100755 index 00000000..40b6de03 --- /dev/null +++ b/tools/apbuild/relaytool @@ -0,0 +1,584 @@ +#!/bin/bash + +# relaytool 1.2 +# Copyright 2004-2005 Mike Hearn <mike@plan99.net> +# Copyright 2005 Vincent Béron <vberon@mecano.gme.usherb.ca> +# Copyright 2006 Psyche <psyche@ruidoabsurdo.com> +# Copyright 2007 Taj Morton <tajmorton@gmail.com> +# +############################################################################# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +############################################################################# +# +# TODO: +# - Figure out how to grab the GOT addr on PowerPC +# - Port to more archs +# - Figure out a way to check if we're on an ELF platform or not, +# maybe check for _GLOBAL_OFFSET_TABLE_ ? + +using_partial_map=false +using_minimal_list=false +using_multilink=false +outdir="." + +if [[ "$1" == "--version" ]]; then + echo "Relaytool 1.11" + echo "Copyright 2004 Mike Hearn" + echo "Copyright 2005 Vincent Béron" + echo + echo "See $0 for license details." + exit 1 +fi + +if [[ "$@" == "" ]] || [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then + echo "Relaytool will generate a file that can be used instead of linking" + echo "directly against a library, which will dlopen the DSO at init time" + echo + echo "Usage: relaytool [OPTION]... [LINKER COMMAND]..." + echo + echo "Options:" + echo " --relay LIB If a matching -lLIB is found, generate a file" + echo " that can be used instead of linking directly to" + echo " LIB. The name of the file is echoed on stdout." + echo " Multiple --relay can be used together, a file will" + echo " be generated for each matching ones." + echo " --replace-all-libs Generate a file for every -lLIB parameter." + echo " --minimal-list OBJ_LIST Will look in OBJ_LIST for undefined symbols, and" + echo " generate a file creating only the needed symbols" + echo " for each LIB." + echo " --partial-map MAP_FILE Generate a file creating only the symbols contained" + echo " in MAP_FILE. Will apply to all further -lLIB" + echo " parameters, so in general is not suitable to" + echo " multiple libs in the same invocation of relaytool." + echo " --no-replace Echo -lLIB on stdout even if a --relay LIB is" + echo " found, so it'll be linked in normally." + echo " --multilink [SONAMES...] If a library has different SONAMES on different" + echo " Linux distributions you can specify the various" + echo " SONAMES that it's known by here. Relaytool will" + echo " attempt to load them (in the order provided) until" + echo " one if found. This cannot be used with multiple" + echo " --relay options. The first SONAME in the list will" + echo " be used as the name in the _is_present variable and" + echo " _symbol_is_present function." + echo " --out-dir DIRECTORY Write stub file to DIRECTORY instead of CWD." + echo "Linker commands:" + echo " -LPATH Add PATH to the list of paths to search for LIBs." + echo " -lLIB If a matching --relay LIB is found (or if" + echo " --replace-all-libs is specified), generate a file" + echo " that can be used instead of linking directly to" + echo " LIB. If there's no --relay LIB, echo -lLIB to" + echo " stdout." + echo " All other linker commands are passed as is to stdout." + echo "Other commands:" + echo " --help|-h Print this help." + echo " --version Print version information." + exit 1 +fi + +function error() { + echo $@ >/dev/stderr + exit 1 +} + +function readfinallink() { + link_name="$1" + while [ -L "$link_name" ]; do + new_name=$( readlink "$link_name" ) + if [ "${new_name:0:1}" == "/" ]; then + link_name="$new_name" + else + link_name="`dirname "$link_name"`/$new_name" + fi + done + if [ -f "$link_name" ]; then + echo -n "$link_name" + exit 0 + else + exit 1 + fi +} + +function relay() { + lib="$1" + if $using_multilink; then + libname=$( echo $( basename ${multilinklist[0]} ) | sed 's/\.so.*//' | tr '-' '_' | tr '.' '_' ) + else + libname=$( echo $( basename "$lib" ) | sed 's/\.so.*//' | tr '-' '_' | tr '.' '_' ) + fi + soname=$( objdump -x "$lib" |grep SONAME | awk '{print $2}' ) + outfile="$outdir/`basename "$soname"`.stub.c" + + echo -n "$outfile" + + if $using_partial_map; then + functions=$( grep "^F " "$partial_map" | cut -d' ' -f2 ) + variables=$( grep "^V " "$partial_map" | cut -d' ' -f2 ) + else + functions=$( nm --extern-only -D "$lib" | awk '{ if (($2 == "T") || ($2 == "W")) print $3; }' | LC_ALL=C grep -v '\(\<_init\>\|\<_fini\>\)' | LC_ALL=C sort -u ) + variables=$( nm --extern-only -D "$lib" | awk '{ if (($2 == "D") || ($2 == "G") || ($2 == "B") || ($2 == "V")) print $3; }' | LC_ALL=C sort -u ) + fi + if $using_minimal_list; then + functions="$functions +$( nm `echo "$object_list"` | awk '{ if ($1 == "U") print $2; }' | LC_ALL=C sort -u )" + functions=$( echo "$functions" | LC_ALL=C sort | LC_ALL=C uniq -d ) + variables="$variables +$( nm `echo "$object_list"` | awk '{ if ($1 == "U") print $2; }' | LC_ALL=C sort -u )" + variables=$( echo "$variables" | LC_ALL=C sort | LC_ALL=C uniq -d ) + fi + + if [ "$functions" == "" ] && [ "$variables" == "" ]; then + # Nothing will be used, so do nothing for that lib + exit 1 + fi + + cat <<EOF >"$outfile" +/* automatically generated: `date` by `id -un`@`uname -n`, do not edit + * + * Built by relaytool, a program for building delay-load jumptables + * relaytool is (C) 2004 Mike Hearn <mike@navi.cx> + * See http://autopackage.org/ for details. + */ +#include <dlfcn.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <sys/mman.h> + +#ifdef __cplusplus + extern "C" { +#endif + +static void **ptrs; +static char *functions[] = { +EOF + + for s in $functions; do + echo " \"$s\"," >>"$outfile" + done + echo " 0" >>"$outfile" + + cat <<EOF >>"$outfile" +}; + +static char *variables[] = { +EOF + + for s in $variables; do + echo " \"$s\"," >>"$outfile" + done + echo " 0" >>"$outfile" + + cat <<EOF >>"$outfile" +}; + +/* 1 if present, 0 if not */ +int ${libname}_is_present = 0; + +static void *handle = 0; + +/* 1 if present, 0 if not, 0 with warning to stderr if lib not present or symbol not found */ +int ${libname}_symbol_is_present(char *s) +{ + int i; + + if( !${libname}_is_present ) { + fprintf(stderr, "%s: relaytool: `basename "$lib"` not present so cannot check for symbol %s.\n", getenv("_"), s); + fprintf(stderr, "%s: relaytool: This probably indicates a bug in the application, please report.\n", getenv("_")); + return 0; + } + + i = 0; + while (functions[i++]) if (!strcmp( functions[i - 1], s )) return ptrs[i - 1] > 0 ? 1 : 0; + i = 0; + while (variables[i++]) if (!strcmp( variables[i - 1], s )) return dlsym( handle, s ) > 0 ? 1 : 0; + + fprintf( stderr, "%s: relaytool: %s is an unknown symbol in `basename "$lib"`.\n", getenv("_"), s ); + fprintf( stderr, "%s: relaytool: If you are the developer of this program, please correct the symbol name or rerun relaytool.\n", getenv("_") ); + return 0; +} + +__attribute__((noreturn)) void _relaytool_stubcall_${libname}(int offset) +{ + fprintf( stderr, "%s: relaytool: stub call to `basename "${lib}"`:%s, aborting.\n", getenv("_"), + functions[offset / sizeof(void*)] ); + exit( 1 ); +} + +#if defined( __i386__ ) + #define FIXUP_GOT_RELOC(sym, addr) \\ + asm("\tmovl %0, %%eax\n" \\ + "\tmovl %%eax, " sym "@GOT(%%ebx)\n" : : "r" (addr)); +#elif defined( __powerpc__ ) + + /* The PowerPC ELF ABI is a twisted nightmare. Until I figure it out, + for now we don't support GOT fixup on this architecture */ + + #error Variables are not currently supported on PowerPC + +#elif defined( __x86_64__ ) + #define FIXUP_GOT_RELOC(sym, addr) \\ + asm("\tmovq %0, %%rax\n" \\ + "\tmovq %%rax, " sym "@GOT(%%rbx)\n" : : "r" (addr)); +#else + #error Please define FIXUP_GOT_RELOC for your architecture +#endif + +void __attribute__((constructor)) _relaytool_init_${libname}() +{ + int i = 0; + + ptrs = malloc( sizeof(functions) ); + memset( ptrs, 0, sizeof(functions) ); +EOF + if $using_multilink; then + echo -n "char *multilink_libs[${#multilinklist[@]}] = {" | cat >> "$outfile" + for l in ${multilinklist[@]}; do + echo -n "\"$l\"" | cat >> "$outfile"; + if [[ "$l" != "${multilinklist[${#multilinklist[@]}-1]}" ]]; then + echo -n ", " | cat >> "$outfile"; + else + echo "};" | cat >> "$outfile" + fi + done + echo 'int multilink_count=0;' | cat >> "$outfile" + + echo 'while (!handle) { + handle = dlopen(multilink_libs[multilink_count++], RTLD_LAZY );' | cat >> "$outfile" + echo "if (multilink_count==${#multilinklist[@]}) break;}"| cat >> "$outfile" + else + echo "handle = dlopen( \"$soname\", RTLD_LAZY );" | cat >> "$outfile" + fi +cat <<EOF >>"$outfile" + if (!handle) return; + + ${libname}_is_present = 1; + + /* build function jumptable */ + while (functions[i++]) ptrs[i - 1] = dlsym( handle, functions[i - 1] ); + +EOF + + if [ "$variables" != "" ]; then echo " /* now fixup the global offset table for variable imports */" >>"$outfile"; fi + for s in $variables; do + echo " FIXUP_GOT_RELOC( \"$s\", dlsym(handle, \"$s\") );" >>"$outfile" + done + + cat <<EOF >>"$outfile" +} + +#if defined( __i386__ ) + +#define JUMP_SLOT(name, index) \\ + asm(".section .text." name ", \"ax\", @progbits\n" \\ + ".globl " name "\n" \\ + ".hidden " name "\n" \\ + " .type " name ", @function\n" \\ + name ":\n" \\ + " movl ptrs, %eax\n" \\ + " movl " #index "(%eax), %eax\n" \\ + " test %eax, %eax\n" \\ + " jnz JS" #index "\n" \\ + " push \$" #index "\n" \\ + " call _relaytool_stubcall_${libname}\n" \\ + "JS" #index ": jmp *%eax\n"); + + +#elif defined( __x86_64__ ) + +#define JUMP_SLOT(name, index) \\ + asm(".section .text." name ", \"ax\", @progbits\n" \\ + ".globl " name "\n" \\ + ".hidden " name "\n" \\ + " .type " name ", @function\n" \\ + name ":\n" \\ + " movq ptrs, %r11\n" \\ + " movq " #index "(%r11), %r11\n" \\ + " test %r11, %r11\n" \\ + " jnz JS" #index "\n" \\ + " push $" #index "\n" \\ + " call _relaytool_stubcall_${libname}\n" \\ + "JS" #index ": jmp *%r11\n"); +#elif defined( __powerpc__ ) + +#define JUMP_SLOT(name, index) \ \ + asm(".section .text." name ", \"ax\", @progbits\n" \\ + ".globl " name "\n" \\ + ".hidden " name "\n" \\ + " .type " name ", @function\n" \\ + name ":\n" \\ + " lis r11, ptrs@ha\n" \\ + " lwz r11, " #index "(r11)\n" \\ + " cmpi cr0,r11,0\n" \\ + " beq- 1f\n" \\ + " mtctr r11\n" \\ + " bctr\n" \\ + "1: li r3, " #index "\n" \\ + " b _relaytool_stubcall_${libname}\n" \\ + ); + +#else + #error Please define JUMP_SLOT for your architecture +#endif + +/* define placeholders for the variable imports: their type doesn't matter, + however we must restrict ELF symbol scope to prevent the definition in the imported + shared library being bound to this dummy symbol (not all libs are compiled -Bsymbolic) + */ +EOF + + for s in $variables; do + echo "int $s __attribute__(( visibility(\"hidden\") )) = -1;" >>"$outfile" + done + + cat <<EOF >>"$outfile" + +/* define each jump slot in its own section. this increases generated code + size, but it means unused slots can be deleted by the linker when + --gc-sections is used. + */ +EOF + +# now generate the stubs + c=0 + for s in $functions; do + echo "JUMP_SLOT(\"$s\", $[c * $arch_ptr_size]);" >>"$outfile" + (( c++ )) + done + + echo >>"$outfile" + + cat <<EOF >>"$outfile" + +#ifdef __cplusplus + } +#endif +EOF + +} + +function fakerelay() { + lib="$1" + libname=$( echo $( basename "$lib" ) | sed 's/\.so.*//' | tr '-' '_' | tr '.' '_' ) + soname=$( objdump -x "$lib" |grep SONAME | awk '{print $2}' ) + outfile="$outdir/`basename "$soname"`.stub.c" + + echo -n "$outfile" + + cat <<EOF >"$outfile" +/* automatically generated: `date` by `id -un`@`uname -n`, do not edit + * + * Built by relaytool, a program for building delay-load jumptables + * relaytool is (C) 2004 Mike Hearn <mike@navi.cx> + * See http://autopackage.org/ for details. + */ + +#ifdef __cplusplus + extern "C" { +#endif + +/* 1 if present, 0 if not */ +int ${libname}_is_present = 1; + +/* 1 if present, 0 if not, 0 with warning to stderr if lib not present or symbol not found */ +int ${libname}_symbol_is_present(char * s) +{ + return 1; +} + +#ifdef __cplusplus + } +#endif +EOF + +} + +no_replace=false +replace_all=false +arch_ok=false +arch_ptr_size=0 +case `uname -m` in + i386 | i486 | i586 | i686 ) + arch_ok=true + arch_ptr_size=4 + ;; + x86_64) + arch_ok=true + arch_ptr_size=8 + ;; +esac + +searchpath=( "/usr/lib" "/usr/local/lib" "/lib" `pwd` ) +multilinklist=( ) +relaylist=( ) + +# process arguments +i=1 +while (( i <= $# )); do + a="${!i}" + + if [ "${a:0:2}" == "-L" ]; then + searchpath[${#searchpath}]="${a:2}" + echo -n "$a " # copy to stdout + + elif [ "$a" == "--replace-all-libs" ]; then + replace_all=true + + elif [ "$a" == "--partial-map" ]; then + using_partial_map=true + (( i++ )) + partial_map="${!i}" + + elif [ "$a" == "--minimal-list" ]; then + using_minimal_list=true + (( i++ )) + object_list="${!i}" + + elif [ "$a" == "--no-replace" ]; then + no_replace=true + + elif [ "$a" == "--multilink" ]; then + using_multilink=true + (( i++ )) + while [[ $i -lt $# && ${!i:0:2} != "--" ]]; do + multilinklist[${#multilinklist[@]}]="${!i}" + (( i++ )) + done + continue # $i has already been incremented, just continue with the loop + + elif [ "$a" == "--relay" ]; then + (( i++ )) + relaylist[${#relaylist[@]}]="${!i}" + + elif [ "$a" == "--out-dir" ]; then + (( i++ )) + outdir="${!i}" + + elif [ "$a" == "-ldl" ]; then + # libdl won't ever be supported by relaytool, so just pass it to stdout + echo -n "$a " + + elif [ "${a:0:2}" == "-l" ]; then + lib="${a:2}" + + # is this lib meant to be relayed? + if $replace_all; then + found=true + else + found=false + for b in ${relaylist[@]}; do + if [ "$b" == "$lib" ]; then + found=true + fi + done + fi + + if $found && $arch_ok; then + + # yes, so let's find its absolute filename by checking in each search path directory + spfound=false + for d in ${searchpath[@]}; do + if [ -e "$d/lib$lib.so" ]; then + + absname=$( readfinallink "$d/lib$lib.so" ) + if [ $? != 0 ] || [ ! -f "$absname" ]; then + error broken symlink "$absname" + fi + + stubfile=$( relay "$absname" ) + + # now we have to compile the stub + if [ $? == 0 ]; then + stubobj=$( echo "$stubfile" | sed 's/\.c$/\.o/' ) + # remove -include flags from CFLAGS, if any + CFLAGS=$( echo $CFLAGS | sed 's/-include .*\.h//g' ) + if [ -e /dev/tty ]; then + ${CC:-gcc} ${CFLAGS} -fPIC -c -o "$stubobj" "$stubfile" 2>/dev/tty + else + ${CC:-gcc} ${CFLAGS} -fPIC -c -o "$stubobj" "$stubfile" + fi + echo -n "$stubobj " + fi + + if $no_replace; then + echo -n "-l$lib " + fi + + spfound=true + break; + fi + done + + if ! $spfound; then + error could not find "$lib" in search path + fi + elif $found && ! $arch_ok; then + # yes, so let's find its absolute filename by checking in each search path directory + spfound=false + for d in ${searchpath[@]}; do + if [ -e "$d/lib$lib.so" ]; then + + absname=$( readfinallink "$d/lib$lib.so" ) + if [ $? != 0 ] || [ ! -f "$absname" ]; then + error broken symlink "$absname" + fi + + # Create a stub C source that just contains dummy + # libwhatever_... support functions + stubfile=$( fakerelay "$absname" ) + + # now we have to compile the stub + if [ $? == 0 ]; then + stubobj=$( echo "$stubfile" | sed 's/\.c$/\.o/' ) + # remove -include flags from CFLAGS, if any + CFLAGS=$( echo $CFLAGS | sed 's/-include .*\.h//g' ) + if [ -e /dev/tty ]; then + ${CC:-gcc} ${CFLAGS} -fPIC -c -o "$stubobj" "$stubfile" 2>/dev/tty + else + ${CC:-gcc} ${CFLAGS} -fPIC -c -o "$stubobj" "$stubfile" + fi + echo -n "$stubobj " + fi + + if $no_replace; then + echo -n "-l$lib " + fi + + spfound=true + break; + fi + done + + if ! $spfound; then + error could not find "$lib" in search path + fi + else + echo -n "$a " + fi + + else + # just copy whatever we don't recognise + echo -n "$a " + fi + + (( i++ )) +done +echo diff --git a/tools/apbuild/relaytool.m4 b/tools/apbuild/relaytool.m4 new file mode 100644 index 00000000..f8f20f98 --- /dev/null +++ b/tools/apbuild/relaytool.m4 @@ -0,0 +1,28 @@ +dnl Usage: RELAYTOOL(LIBRARY_NAME, LIBS, CFLAGS, ACTION-IF-WEAK-LINK-IS-POSSIBLE) + +dnl Example: +dnl RELAYTOOL("gtkspell", GTKSPELL_LIBS, GTKSPELL_CFLAGS, gtkspell_weak=yes) +dnl Will modify GTKSPELL_LIBS to include a call to relaytool if available +dnl or if not, will modify GTKSPELL_CFLAGS to include -D switches to define +dnl libgtkspell_is_present=1 and libgtkspell_symbol_is_present=1 + +AC_DEFUN([RELAYTOOL], [ + if test -z "$RELAYTOOL_PROG"; then + AC_PATH_PROG(RELAYTOOL_PROG, relaytool, no) + fi + + AC_MSG_CHECKING(whether we can weak link $1) + + _RELAYTOOL_PROCESSED_NAME=`echo "$1" | sed 's/-/_/g;s/\./_/g;'` + _RELAYTOOL_UPPER_NAME=`echo $_RELAYTOOL_PROCESSED_NAME | tr '[[:lower:]]' '[[:upper:]]'` + + if test "$RELAYTOOL_PROG" = "no"; then + AC_MSG_RESULT(no) + $3="-DRELAYTOOL_${_RELAYTOOL_UPPER_NAME}='static const int lib${_RELAYTOOL_PROCESSED_NAME}_is_present = 1; static int __attribute__((unused)) lib${_RELAYTOOL_PROCESSED_NAME}_symbol_is_present(char *m) { return 1; }' $$3" + else + AC_MSG_RESULT(yes) + $2="-Wl,--gc-sections \`relaytool --relay $1 $$2\`" + $3="-DRELAYTOOL_${_RELAYTOOL_UPPER_NAME}='extern int lib${_RELAYTOOL_PROCESSED_NAME}_is_present; extern int lib${_RELAYTOOL_PROCESSED_NAME}_symbol_is_present(char *s);' $$3" + $4 + fi +]) diff --git a/tools/apbuild/scandeps b/tools/apbuild/scandeps new file mode 100755 index 00000000..7d057129 --- /dev/null +++ b/tools/apbuild/scandeps @@ -0,0 +1,137 @@ +#!/usr/bin/env perl +use strict; +use IPC::Open2; + +if ($ARGV[0] eq '--version') { + print "scandeps version 1.0\n"; + print "Copright (c) 2005 Hongli Lai\n"; + print "Licensed under the GNU General Public License v2.\n"; + exit; +} elsif ($ARGV[0] eq '--help') { + print "Usage: scandeps [FILES...]\n"; + print "This script scans ELF binaries' library dependancies and prints a nice report\n" . + "of the dependancies.\n"; + exit; +} + + +# First, generate a list of binaries. Either scan user-specified files, +# or scan all files in the current directory (including subfolders). +my @files; + +if (@ARGV > 0) { + # Scan user-specified files + @files = @ARGV; +} else { + # Scan directory recursively + @files = scandir("."); +} + +# Now get the dependancies for all binaries +# %fileDeps: hash which contains a list of dependancies. The filename is the key. +# %depFiles: hash which contains a list of files. The dependancy is the key. +my (%fileDeps, %depFiles); +getdeps(\%fileDeps, \%depFiles, \@files); + +print "Common dependancies:\n"; +foreach my $dep (keys %depFiles) { + if (@{$depFiles{$dep}} == @files) { + print " $dep\n"; + } +} +print "\n"; + +print "All dependancies:\n"; +my @keys = keys %depFiles; +@keys = sort { @{$depFiles{$b}} - @{$depFiles{$a}} } @keys; +foreach my $dep (@keys) { + my $num = scalar(@{$depFiles{$dep}}); + my $word = ($num > 1) ? "files" : "file"; + printf " %-40s (used by %3d $word)\n", $dep, $num; +} + +print "\n"; +print "Dependancies and associated binaries:\n"; +foreach my $dep (@keys) { + print " $dep:\n"; + if (@{$depFiles{$dep}} == @files) { + print " All files depend on this library.\n"; + } else { + foreach my $file (@{$depFiles{$dep}}) { + print " $file\n"; + } + } + print "\n"; +} + + +################################## + +sub fatal { + print STDERR $_[0]; + exit 1; +} + +sub isELF { + my ($f, $data); + + if (!open($f, $_[0])) { + print STDERR "Warning: cannot open file '$_[0]' for reading.\n"; + return 0; + } + + binmode $f; + sysread $f, $data, 4; + close $f; + return $data eq "\177ELF"; +} + +sub scandir { + my $d; + + if (!opendir($d, $_[0])) { + print STDERR "Warning: cannot open directory '$_[0]' for reading.\n"; + return; + } + + my @files; + foreach my $file (readdir($d)) { + next if ($file eq "." || $file eq ".."); + + $file = "$_[0]/$file"; + if (-d $file) { + # Recurse into subdirectory + push @files, scandir("$file"); + + } elsif (-f $file && -x $file && isELF($file)) { + push @files, $file; + } + } + closedir($d); + return @files; +} + +sub getdeps { + my ($fileDeps, $depFiles, $files) = @_; + my ($r, $w); + if (!open2($r, $w, 'objdump', '-p', @{$files})) { + fatal("Cannot communicate with objdump.\n"); + } + close $w; + + my $currentFile; + foreach my $line (<$r>) { + if ($line =~ /^(.+):[ \t]+file format /) { + $currentFile = $1; + $currentFile =~ s/^.\///; + + } elsif ($line =~ /NEEDED[ \t]+(.+)$/) { + $fileDeps->{$currentFile} = [] if (!exists $fileDeps->{$currentFile}); + push @{$fileDeps->{$currentFile}}, $1; + + $depFiles->{$1} = [] if (!exists $depFiles->{$1}); + push @{$depFiles->{$1}}, $currentFile; + } + } + close $r; +} diff --git a/tools/apbuild/test-app/randomapp1.c b/tools/apbuild/test-app/randomapp1.c new file mode 100644 index 00000000..70252276 --- /dev/null +++ b/tools/apbuild/test-app/randomapp1.c @@ -0,0 +1,16 @@ +#include <stdio.h> +#include <limits.h> +#include <stdlib.h> +#include <ctype.h> +#include <fnmatch.h> + +int main() { + char *respath = malloc(PATH_MAX); + unsigned char c = (unsigned char)"c"; + + printf("foo\n"); + printf("%d\n", isalpha(c)); + realpath("/some/path", respath); + fnmatch ("foo", "bar", 0); + return 0; +} diff --git a/tools/pluginfo/Makefile b/tools/pluginfo/Makefile new file mode 100644 index 00000000..108e47e7 --- /dev/null +++ b/tools/pluginfo/Makefile @@ -0,0 +1,9 @@ +#CC=../apbuild/apgcc +CC=gcc +CFLAGS=-Wall +LDFLAGS=-lpthread -ldl -lm + +pluginfo: pluginfo.o + +clean: + rm *.o pluginfo diff --git a/tools/pluginfo/pluginfo.c b/tools/pluginfo/pluginfo.c new file mode 100644 index 00000000..db3f096d --- /dev/null +++ b/tools/pluginfo/pluginfo.c @@ -0,0 +1,77 @@ +/* + DeaDBeeF - ultimate music player for GNU/Linux systems with X11 + Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net> + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dlfcn.h> +#include "../../deadbeef.h" + +int +main (int argc, char *argv[]) { + char d_name[256]; + void *handle; + size_t l; + + if (argc <= 1) { + fprintf (stderr, "usage: pluginfo plugin.so\n"); + exit (-1); + } + char *slash = strrchr (argv[1], '/'); + if (!slash) { + slash = argv[1]; + } + else { + slash++; + } + l = strlen (slash); + if (l < 3 || strcasecmp (&slash[l-3], ".so")) { + fprintf (stderr, "pluginfo: invalid fname %s\n", argv[1]); + exit (-1); + } + + strcpy (d_name, slash); + + handle = dlopen (argv[1], RTLD_NOW); + if (!handle) { + fprintf (stderr, "dlopen error: %s\n", dlerror ()); + exit (-1); + } + d_name[l-3] = 0; + strcat (d_name, "_load"); + DB_plugin_t *(*plug_load)(DB_functions_t *api) = dlsym (handle, d_name); + if (!plug_load) { + fprintf (stderr, "pluginfo: dlsym error: %s\n", dlerror ()); + dlclose (handle); + exit (-1); + } + + DB_plugin_t *plug = plug_load ((DB_functions_t *)0xdeadbeef); + printf ("type=\"%d\"\n", plug->type); + printf ("api_version=\"%d.%d\"\n", plug->api_vmajor, plug->api_vminor); + printf ("version=\"%d.%d\"\n", plug->version_major, plug->version_minor); + printf ("id=\"%s\"\n", plug->id); + printf ("name=\"%s\"\n", plug->name); + printf ("descr=\"%s\"\n", plug->descr); + printf ("author=\"%s\"\n", plug->author); + printf ("email=\"%s\"\n", plug->email); + printf ("website=\"%s\"\n", plug->website); + + dlclose (handle); + return 0; +} |