diff options
66 files changed, 362 insertions, 14924 deletions
diff --git a/README-AGL.md b/README-AGL.md index bb6e8aa63..146d6ff16 100644 --- a/README-AGL.md +++ b/README-AGL.md @@ -173,7 +173,7 @@ To build an image from 'meta-agl' > $ bitbake agl-demo-platform - If you want to run QEMU directly as VM in Virtual Box or your other favorite VM software then add this line to your "conf/local.conf" file. - > IMAGE_FSTYPES += "vmdk" + > IMAGE_FSTYPES += "wic.vmdk" 5. Run in the emulator > $ runqemu agl-image-ivi qemux86-64 @@ -194,7 +194,7 @@ To build an image from 'meta-agl' > $ runqemu agl-image-ivi qemux86-64 bootparams="uvesafb.mode_option=1280x720-32" serial **Or use the virtual disk in Virtual Box from this location:** - > tmp/deploy/images/qemux86-64/agl-demo-platform-qemux86-64.vmdk + > tmp/deploy/images/qemux86-64/agl-demo-platform-qemux86-64.wic.vmdk 6. Some weston samples are available from weston terminal (click top left icon). Check the folder `/opt/AGL/ALS2016`. @@ -52,7 +52,6 @@ See README-AGL.md Specifically out of meta-openembedded these sub-layers are used: * meta-openembedded/meta-oe * meta-openembedded/meta-multimedia - * meta-openembedded/meta-efl * meta-openembedded/meta-networking * meta-openembedded/meta-python diff --git a/meta-agl-bsp/classes/image-vm.bbclass b/meta-agl-bsp/classes/image-vm.bbclass deleted file mode 100644 index ec8f0cb8f..000000000 --- a/meta-agl-bsp/classes/image-vm.bbclass +++ /dev/null @@ -1,181 +0,0 @@ -# image-vm.bbclass -# (loosly based off image-live.bbclass Copyright (C) 2004, Advanced Micro Devices, Inc.) -# -# Create an image which can be placed directly onto a harddisk using dd and then -# booted. -# -# This uses syslinux. extlinux would have been nice but required the ext2/3 -# partition to be mounted. grub requires to run itself as part of the install -# process. -# -# The end result is a 512 boot sector populated with an MBR and partition table -# followed by an msdos fat16 partition containing syslinux and a linux kernel -# completed by the ext2/3 rootfs. -# -# We have to push the msdos parition table size > 16MB so fat 16 is used as parted -# won't touch fat12 partitions. - -inherit live-vm-common - -do_bootdirectdisk[depends] += "dosfstools-native:do_populate_sysroot \ - virtual/kernel:do_deploy \ - syslinux:do_populate_sysroot \ - syslinux-native:do_populate_sysroot \ - parted-native:do_populate_sysroot \ - mtools-native:do_populate_sysroot \ - ${PN}:do_image_${VM_ROOTFS_TYPE} \ - " - -IMAGE_TYPEDEP_vmdk = "${VM_ROOTFS_TYPE}" -IMAGE_TYPEDEP_vmdk.xz = "${VM_ROOTFS_TYPE}" -IMAGE_TYPEDEP_vdi = "${VM_ROOTFS_TYPE}" -IMAGE_TYPEDEP_qcow2 = "${VM_ROOTFS_TYPE}" -IMAGE_TYPEDEP_hdddirect = "${VM_ROOTFS_TYPE}" -IMAGE_TYPES_MASKED += "vmdk vmdk.xz vdi qcow2 hdddirect" - -VM_ROOTFS_TYPE ?= "ext4" -ROOTFS ?= "${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.${VM_ROOTFS_TYPE}" - -# Used by bootloader -LABELS_VM ?= "boot" -ROOT_VM ?= "root=/dev/sda2" -# Using an initramfs is optional. Enable it by setting INITRD_IMAGE_VM. -INITRD_IMAGE_VM ?= "" -INITRD_VM ?= "${@'${IMGDEPLOYDIR}/${INITRD_IMAGE_VM}-${MACHINE}.cpio.gz' if '${INITRD_IMAGE_VM}' else ''}" -do_bootdirectdisk[depends] += "${@'${INITRD_IMAGE_VM}:do_image_complete' if '${INITRD_IMAGE_VM}' else ''}" - -BOOTDD_VOLUME_ID ?= "boot" -BOOTDD_EXTRA_SPACE ?= "16384" - -DISK_SIGNATURE ?= "${DISK_SIGNATURE_GENERATED}" -DISK_SIGNATURE[vardepsexclude] = "DISK_SIGNATURE_GENERATED" - -build_boot_dd() { - HDDDIR="${S}/hdd/boot" - HDDIMG="${S}/hdd.image" - IMAGE=${IMGDEPLOYDIR}/${IMAGE_NAME}.hdddirect - - populate_kernel $HDDDIR - - if [ "${PCBIOS}" = "1" ]; then - syslinux_hddimg_populate $HDDDIR - fi - if [ "${EFI}" = "1" ]; then - efi_hddimg_populate $HDDDIR - fi - - BLOCKS=`du -bks $HDDDIR | cut -f 1` - BLOCKS=`expr $BLOCKS + ${BOOTDD_EXTRA_SPACE}` - - # Remove it since mkdosfs would fail when it exists - rm -f $HDDIMG - mkdosfs -n ${BOOTDD_VOLUME_ID} -S 512 -C $HDDIMG $BLOCKS - mcopy -i $HDDIMG -s $HDDDIR/* ::/ - - if [ "${PCBIOS}" = "1" ]; then - syslinux_hdddirect_install $HDDIMG - fi - chmod 644 $HDDIMG - - ROOTFSBLOCKS=`du -Lbks ${ROOTFS} | cut -f 1` - TOTALSIZE=`expr $BLOCKS + $ROOTFSBLOCKS` - END1=`expr $BLOCKS \* 1024` - END2=`expr $END1 + 512` - END3=`expr \( $ROOTFSBLOCKS \* 1024 \) + $END1` - - echo $ROOTFSBLOCKS $TOTALSIZE $END1 $END2 $END3 - rm -rf $IMAGE - dd if=/dev/zero of=$IMAGE bs=1024 seek=$TOTALSIZE count=1 - - parted $IMAGE mklabel msdos - parted $IMAGE mkpart primary fat16 0 ${END1}B - parted $IMAGE unit B mkpart primary ext2 ${END2}B ${END3}B - parted $IMAGE set 1 boot on - - parted $IMAGE print - - awk "BEGIN { printf \"$(echo ${DISK_SIGNATURE} | sed 's/\(..\)\(..\)\(..\)\(..\)/\\x\4\\x\3\\x\2\\x\1/')\" }" | \ - dd of=$IMAGE bs=1 seek=440 conv=notrunc - - OFFSET=`expr $END2 / 512` - if [ "${PCBIOS}" = "1" ]; then - dd if=${STAGING_DATADIR}/syslinux/mbr.bin of=$IMAGE conv=notrunc - fi - - dd if=$HDDIMG of=$IMAGE conv=notrunc seek=1 bs=512 - dd if=${ROOTFS} of=$IMAGE conv=notrunc seek=$OFFSET bs=512 - - cd ${IMGDEPLOYDIR} - - ln -sf ${IMAGE_NAME}.hdddirect ${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.hdddirect -} - -python do_bootdirectdisk() { - validate_disk_signature(d) - set_live_vm_vars(d, 'VM') - if d.getVar("PCBIOS") == "1": - bb.build.exec_func('build_syslinux_cfg', d) - if d.getVar("EFI") == "1": - bb.build.exec_func('build_efi_cfg', d) - bb.build.exec_func('build_boot_dd', d) -} - -def generate_disk_signature(): - import uuid - - signature = str(uuid.uuid4())[:8] - - if signature != '00000000': - return signature - else: - return 'ffffffff' - -def validate_disk_signature(d): - import re - - disk_signature = d.getVar("DISK_SIGNATURE") - - if not re.match(r'^[0-9a-fA-F]{8}$', disk_signature): - bb.fatal("DISK_SIGNATURE '%s' must be an 8 digit hex string" % disk_signature) - -DISK_SIGNATURE_GENERATED := "${@generate_disk_signature()}" - -run_qemu_img (){ - type="$1" - qemu-img convert -O $type ${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.hdddirect ${IMGDEPLOYDIR}/${IMAGE_NAME}.$type - - ln -sf ${IMAGE_NAME}.$type ${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.$type -} -create_vmdk_image () { - run_qemu_img vmdk -} - -create_vmdkxz_image () { - run_qemu_img vmdk - xz -f ${XZ_COMPRESSION_LEVEL} ${XZ_THREADS} --check=${XZ_INTEGRITY_CHECK} ${IMGDEPLOYDIR}/${IMAGE_NAME}.vmdk - ln -sf ${IMAGE_NAME}.vmdk.xz ${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.vmdk.xz - rm -f ${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.vmdk -} - -create_vdi_image () { - run_qemu_img vdi -} - -create_qcow2_image () { - run_qemu_img qcow2 -} - -python do_vmimg() { - if bb.utils.contains('IMAGE_FSTYPES', 'vmdk.xz', True, False, d): - bb.build.exec_func('create_vmdkxz_image', d) - if bb.utils.contains('IMAGE_FSTYPES', 'vmdk', True, False, d): - bb.build.exec_func('create_vmdk_image', d) - if 'vdi' in d.getVar('IMAGE_FSTYPES', True): - bb.build.exec_func('create_vdi_image', d) - if 'qcow2' in d.getVar('IMAGE_FSTYPES', True): - bb.build.exec_func('create_qcow2_image', d) -} - -addtask bootdirectdisk before do_vmimg -addtask vmimg after do_bootdirectdisk before do_image_complete -do_vmimg[depends] += "qemu-native:do_populate_sysroot" diff --git a/meta-agl-bsp/classes/image.bbclass b/meta-agl-bsp/classes/image.bbclass deleted file mode 100644 index ccaffce60..000000000 --- a/meta-agl-bsp/classes/image.bbclass +++ /dev/null @@ -1,624 +0,0 @@ -inherit rootfs_${IMAGE_PKGTYPE} - -# Only Linux SDKs support populate_sdk_ext, fall back to populate_sdk_base -# in the non-Linux SDK_OS case, such as mingw32 -SDKEXTCLASS ?= "${@['populate_sdk_base', 'populate_sdk_ext']['linux' in d.getVar("SDK_OS")]}" -inherit ${SDKEXTCLASS} - -TOOLCHAIN_TARGET_TASK += "${PACKAGE_INSTALL}" -TOOLCHAIN_TARGET_TASK_ATTEMPTONLY += "${PACKAGE_INSTALL_ATTEMPTONLY}" -POPULATE_SDK_POST_TARGET_COMMAND += "rootfs_sysroot_relativelinks; " - -LICENSE = "MIT" -PACKAGES = "" -DEPENDS += "${MLPREFIX}qemuwrapper-cross depmodwrapper-cross" -RDEPENDS += "${PACKAGE_INSTALL} ${LINGUAS_INSTALL}" -RRECOMMENDS += "${PACKAGE_INSTALL_ATTEMPTONLY}" - -INHIBIT_DEFAULT_DEPS = "1" - -TESTIMAGECLASS = "${@base_conditional('TEST_IMAGE', '1', 'testimage-auto', '', d)}" -inherit ${TESTIMAGECLASS} - -# IMAGE_FEATURES may contain any available package group -IMAGE_FEATURES ?= "" -IMAGE_FEATURES[type] = "list" -IMAGE_FEATURES[validitems] += "debug-tweaks read-only-rootfs empty-root-password allow-empty-password post-install-logging" - -# Generate companion debugfs? -IMAGE_GEN_DEBUGFS ?= "0" - -# rootfs bootstrap install -ROOTFS_BOOTSTRAP_INSTALL = "run-postinsts" - -# These packages will be removed from a read-only rootfs after all other -# packages have been installed -ROOTFS_RO_UNNEEDED = "update-rc.d base-passwd shadow ${VIRTUAL-RUNTIME_update-alternatives} ${ROOTFS_BOOTSTRAP_INSTALL}" - -# packages to install from features -FEATURE_INSTALL = "${@' '.join(oe.packagegroup.required_packages(oe.data.typed_value('IMAGE_FEATURES', d), d))}" -FEATURE_INSTALL[vardepvalue] = "${FEATURE_INSTALL}" -FEATURE_INSTALL_OPTIONAL = "${@' '.join(oe.packagegroup.optional_packages(oe.data.typed_value('IMAGE_FEATURES', d), d))}" -FEATURE_INSTALL_OPTIONAL[vardepvalue] = "${FEATURE_INSTALL_OPTIONAL}" - -# Define some very basic feature package groups -FEATURE_PACKAGES_package-management = "${ROOTFS_PKGMANAGE}" -SPLASH ?= "psplash" -FEATURE_PACKAGES_splash = "${SPLASH}" - -IMAGE_INSTALL_COMPLEMENTARY = '${@complementary_globs("IMAGE_FEATURES", d)}' - -def check_image_features(d): - valid_features = (d.getVarFlag('IMAGE_FEATURES', 'validitems') or "").split() - valid_features += d.getVarFlags('COMPLEMENTARY_GLOB').keys() - for var in d: - if var.startswith("PACKAGE_GROUP_"): - bb.warn("PACKAGE_GROUP is deprecated, please use FEATURE_PACKAGES instead") - valid_features.append(var[14:]) - elif var.startswith("FEATURE_PACKAGES_"): - valid_features.append(var[17:]) - valid_features.sort() - - features = set(oe.data.typed_value('IMAGE_FEATURES', d)) - for feature in features: - if feature not in valid_features: - if bb.utils.contains('EXTRA_IMAGE_FEATURES', feature, True, False, d): - raise bb.parse.SkipRecipe("'%s' in IMAGE_FEATURES (added via EXTRA_IMAGE_FEATURES) is not a valid image feature. Valid features: %s" % (feature, ' '.join(valid_features))) - else: - raise bb.parse.SkipRecipe("'%s' in IMAGE_FEATURES is not a valid image feature. Valid features: %s" % (feature, ' '.join(valid_features))) - -IMAGE_INSTALL ?= "" -IMAGE_INSTALL[type] = "list" -export PACKAGE_INSTALL ?= "${IMAGE_INSTALL} ${ROOTFS_BOOTSTRAP_INSTALL} ${FEATURE_INSTALL}" -PACKAGE_INSTALL_ATTEMPTONLY ?= "${FEATURE_INSTALL_OPTIONAL}" - -IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-image-complete" - -# Images are generally built explicitly, do not need to be part of world. -EXCLUDE_FROM_WORLD = "1" - -USE_DEVFS ?= "1" -USE_DEPMOD ?= "1" - -PID = "${@os.getpid()}" - -PACKAGE_ARCH = "${MACHINE_ARCH}" - -LDCONFIGDEPEND ?= "ldconfig-native:do_populate_sysroot" -LDCONFIGDEPEND_libc-uclibc = "" -LDCONFIGDEPEND_libc-musl = "" - -# This is needed to have depmod data in PKGDATA_DIR, -# but if you're building small initramfs image -# e.g. to include it in your kernel, you probably -# don't want this dependency, which is causing dependency loop -KERNELDEPMODDEPEND ?= "virtual/kernel:do_packagedata" - -do_rootfs[depends] += " \ - makedevs-native:do_populate_sysroot virtual/fakeroot-native:do_populate_sysroot ${LDCONFIGDEPEND} \ - virtual/update-alternatives-native:do_populate_sysroot update-rc.d-native:do_populate_sysroot \ - ${KERNELDEPMODDEPEND} \ -" -do_rootfs[recrdeptask] += "do_packagedata" - -def rootfs_command_variables(d): - return ['ROOTFS_POSTPROCESS_COMMAND','ROOTFS_PREPROCESS_COMMAND','ROOTFS_POSTINSTALL_COMMAND','ROOTFS_POSTUNINSTALL_COMMAND','OPKG_PREPROCESS_COMMANDS','OPKG_POSTPROCESS_COMMANDS','IMAGE_POSTPROCESS_COMMAND', - 'IMAGE_PREPROCESS_COMMAND','RPM_PREPROCESS_COMMANDS','RPM_POSTPROCESS_COMMANDS','DEB_PREPROCESS_COMMANDS','DEB_POSTPROCESS_COMMANDS'] - -python () { - variables = rootfs_command_variables(d) + sdk_command_variables(d) - for var in variables: - if d.getVar(var, False): - d.setVarFlag(var, 'func', '1') -} - -def rootfs_variables(d): - from oe.rootfs import variable_depends - variables = ['IMAGE_DEVICE_TABLE','IMAGE_DEVICE_TABLES','BUILD_IMAGES_FROM_FEEDS','IMAGE_TYPES_MASKED','IMAGE_ROOTFS_ALIGNMENT','IMAGE_OVERHEAD_FACTOR','IMAGE_ROOTFS_SIZE','IMAGE_ROOTFS_EXTRA_SPACE', - 'IMAGE_ROOTFS_MAXSIZE','IMAGE_NAME','IMAGE_LINK_NAME','IMAGE_MANIFEST','DEPLOY_DIR_IMAGE','IMAGE_FSTYPES','IMAGE_INSTALL_COMPLEMENTARY','IMAGE_LINGUAS', - 'MULTILIBRE_ALLOW_REP','MULTILIB_TEMP_ROOTFS','MULTILIB_VARIANTS','MULTILIBS','ALL_MULTILIB_PACKAGE_ARCHS','MULTILIB_GLOBAL_VARIANTS','BAD_RECOMMENDATIONS','NO_RECOMMENDATIONS', - 'PACKAGE_ARCHS','PACKAGE_CLASSES','TARGET_VENDOR','TARGET_ARCH','TARGET_OS','OVERRIDES','BBEXTENDVARIANT','FEED_DEPLOYDIR_BASE_URI','INTERCEPT_DIR','USE_DEVFS', - 'CONVERSIONTYPES', 'IMAGE_GEN_DEBUGFS', 'ROOTFS_RO_UNNEEDED', 'IMGDEPLOYDIR', 'PACKAGE_EXCLUDE_COMPLEMENTARY'] - variables.extend(rootfs_command_variables(d)) - variables.extend(variable_depends(d)) - return " ".join(variables) - -do_rootfs[vardeps] += "${@rootfs_variables(d)}" - -do_build[depends] += "virtual/kernel:do_deploy" - -def build_live(d): - if bb.utils.contains("IMAGE_FSTYPES", "live", "live", "0", d) == "0": # live is not set but hob might set iso or hddimg - d.setVar('NOISO', bb.utils.contains('IMAGE_FSTYPES', "iso", "0", "1", d)) - d.setVar('NOHDD', bb.utils.contains('IMAGE_FSTYPES', "hddimg", "0", "1", d)) - if d.getVar('NOISO') == "0" or d.getVar('NOHDD') == "0": - return "image-live" - return "" - return "image-live" - -IMAGE_TYPE_live = "${@build_live(d)}" -inherit ${IMAGE_TYPE_live} - -IMAGE_TYPE_vm = '${@bb.utils.contains_any("IMAGE_FSTYPES", ["vmdk", "vmdk.xz", "vdi", "qcow2", "hdddirect"], "image-vm", "", d)}' - -inherit ${IMAGE_TYPE_vm} - -IMAGE_TYPE_container = '${@bb.utils.contains("IMAGE_FSTYPES", "container", "image-container", "", d)}' -inherit ${IMAGE_TYPE_container} - -def build_uboot(d): - if 'u-boot' in (d.getVar('IMAGE_FSTYPES') or ''): - return "image_types_uboot" - else: - return "" - -IMAGE_TYPE_uboot = "${@build_uboot(d)}" -inherit ${IMAGE_TYPE_uboot} - -IMAGE_TYPE_wic = "image_types_wic" -inherit ${IMAGE_TYPE_wic} - -python () { - def extraimage_getdepends(task): - deps = "" - for dep in (d.getVar('EXTRA_IMAGEDEPENDS') or "").split(): - deps += " %s:%s" % (dep, task) - return deps - - d.appendVarFlag('do_image', 'depends', extraimage_getdepends('do_populate_lic')) - d.appendVarFlag('do_image_complete', 'depends', extraimage_getdepends('do_populate_sysroot')) - - deps = " " + imagetypes_getdepends(d) - d.appendVarFlag('do_rootfs', 'depends', deps) - - #process IMAGE_FEATURES, we must do this before runtime_mapping_rename - #Check for replaces image features - features = set(oe.data.typed_value('IMAGE_FEATURES', d)) - remain_features = features.copy() - for feature in features: - replaces = set((d.getVar("IMAGE_FEATURES_REPLACES_%s" % feature) or "").split()) - remain_features -= replaces - - #Check for conflict image features - for feature in remain_features: - conflicts = set((d.getVar("IMAGE_FEATURES_CONFLICTS_%s" % feature) or "").split()) - temp = conflicts & remain_features - if temp: - bb.fatal("%s contains conflicting IMAGE_FEATURES %s %s" % (d.getVar('PN'), feature, ' '.join(list(temp)))) - - d.setVar('IMAGE_FEATURES', ' '.join(sorted(list(remain_features)))) - - check_image_features(d) - initramfs_image = d.getVar('INITRAMFS_IMAGE') or "" - if initramfs_image != "": - d.appendVarFlag('do_build', 'depends', " %s:do_bundle_initramfs" % d.getVar('PN')) - d.appendVarFlag('do_bundle_initramfs', 'depends', " %s:do_image_complete" % initramfs_image) -} - -IMAGE_CLASSES += "image_types" -inherit ${IMAGE_CLASSES} - -IMAGE_POSTPROCESS_COMMAND ?= "" - -# some default locales -IMAGE_LINGUAS ?= "de-de fr-fr en-gb" - -LINGUAS_INSTALL ?= "${@" ".join(map(lambda s: "locale-base-%s" % s, d.getVar('IMAGE_LINGUAS').split()))}" - -# Prefer image, but use the fallback files for lookups if the image ones -# aren't yet available. -PSEUDO_PASSWD = "${IMAGE_ROOTFS}:${STAGING_DIR_NATIVE}" - -inherit rootfs-postcommands - -PACKAGE_EXCLUDE ??= "" -PACKAGE_EXCLUDE[type] = "list" - -fakeroot python do_rootfs () { - from oe.rootfs import create_rootfs - from oe.manifest import create_manifest - import logging - - logger = d.getVar('BB_TASK_LOGGER', False) - if logger: - logcatcher = bb.utils.LogCatcher() - logger.addHandler(logcatcher) - else: - logcatcher = None - - # NOTE: if you add, remove or significantly refactor the stages of this - # process then you should recalculate the weightings here. This is quite - # easy to do - just change the MultiStageProgressReporter line temporarily - # to pass debug=True as the last parameter and you'll get a printout of - # the weightings as well as a map to the lines where next_stage() was - # called. Of course this isn't critical, but it helps to keep the progress - # reporting accurate. - stage_weights = [1, 203, 354, 186, 65, 4228, 1, 353, 49, 330, 382, 23, 1] - progress_reporter = bb.progress.MultiStageProgressReporter(d, stage_weights) - progress_reporter.next_stage() - - # Handle package exclusions - excl_pkgs = d.getVar("PACKAGE_EXCLUDE").split() - inst_pkgs = d.getVar("PACKAGE_INSTALL").split() - inst_attempt_pkgs = d.getVar("PACKAGE_INSTALL_ATTEMPTONLY").split() - - d.setVar('PACKAGE_INSTALL_ORIG', ' '.join(inst_pkgs)) - d.setVar('PACKAGE_INSTALL_ATTEMPTONLY', ' '.join(inst_attempt_pkgs)) - - for pkg in excl_pkgs: - if pkg in inst_pkgs: - bb.warn("Package %s, set to be excluded, is in %s PACKAGE_INSTALL (%s). It will be removed from the list." % (pkg, d.getVar('PN'), inst_pkgs)) - inst_pkgs.remove(pkg) - - if pkg in inst_attempt_pkgs: - bb.warn("Package %s, set to be excluded, is in %s PACKAGE_INSTALL_ATTEMPTONLY (%s). It will be removed from the list." % (pkg, d.getVar('PN'), inst_pkgs)) - inst_attempt_pkgs.remove(pkg) - - d.setVar("PACKAGE_INSTALL", ' '.join(inst_pkgs)) - d.setVar("PACKAGE_INSTALL_ATTEMPTONLY", ' '.join(inst_attempt_pkgs)) - - # Ensure we handle package name remapping - # We have to delay the runtime_mapping_rename until just before rootfs runs - # otherwise, the multilib renaming could step in and squash any fixups that - # may have occurred. - pn = d.getVar('PN') - runtime_mapping_rename("PACKAGE_INSTALL", pn, d) - runtime_mapping_rename("PACKAGE_INSTALL_ATTEMPTONLY", pn, d) - runtime_mapping_rename("BAD_RECOMMENDATIONS", pn, d) - - # Generate the initial manifest - create_manifest(d) - - progress_reporter.next_stage() - - # generate rootfs - create_rootfs(d, progress_reporter=progress_reporter, logcatcher=logcatcher) - - progress_reporter.finish() -} -do_rootfs[dirs] = "${TOPDIR}" -do_rootfs[cleandirs] += "${S} ${IMGDEPLOYDIR}" -do_rootfs[umask] = "022" -addtask rootfs before do_build after do_prepare_recipe_sysroot - -fakeroot python do_image () { - from oe.utils import execute_pre_post_process - - pre_process_cmds = d.getVar("IMAGE_PREPROCESS_COMMAND") - - execute_pre_post_process(d, pre_process_cmds) -} -do_image[dirs] = "${TOPDIR}" -do_image[umask] = "022" -addtask do_image after do_rootfs before do_build - -fakeroot python do_image_complete () { - from oe.utils import execute_pre_post_process - - post_process_cmds = d.getVar("IMAGE_POSTPROCESS_COMMAND") - - execute_pre_post_process(d, post_process_cmds) -} -do_image_complete[dirs] = "${TOPDIR}" -do_image_complete[umask] = "022" -SSTATETASKS += "do_image_complete" -SSTATE_SKIP_CREATION_task-image-complete = '1' -do_image_complete[sstate-inputdirs] = "${IMGDEPLOYDIR}" -do_image_complete[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}" -do_image_complete[stamp-extra-info] = "${MACHINE}" -addtask do_image_complete after do_image before do_build - -# Add image-level QA/sanity checks to IMAGE_QA_COMMANDS -# -# IMAGE_QA_COMMANDS += " \ -# image_check_everything_ok \ -# " -# This task runs all functions in IMAGE_QA_COMMANDS after the image -# construction has completed in order to validate the resulting image. -fakeroot python do_image_qa () { - from oe.utils import ImageQAFailed - - qa_cmds = (d.getVar('IMAGE_QA_COMMANDS') or '').split() - qamsg = "" - - for cmd in qa_cmds: - try: - bb.build.exec_func(cmd, d) - except oe.utils.ImageQAFailed as e: - qamsg = qamsg + '\tImage QA function %s failed: %s\n' % (e.name, e.description) - except bb.build.FuncFailed as e: - qamsg = qamsg + '\tImage QA function %s failed' % e.name - if e.logfile: - qamsg = qamsg + ' (log file is located at %s)' % e.logfile - qamsg = qamsg + '\n' - - if qamsg: - imgname = d.getVar('IMAGE_NAME') - bb.fatal("QA errors found whilst validating image: %s\n%s" % (imgname, qamsg)) -} -addtask do_image_qa after do_image_complete before do_build - -def setup_debugfs_variables(d): - d.appendVar('IMAGE_ROOTFS', '-dbg') - d.appendVar('IMAGE_LINK_NAME', '-dbg') - d.appendVar('IMAGE_NAME','-dbg') - d.setVar('IMAGE_BUILDING_DEBUGFS', 'true') - debugfs_image_fstypes = d.getVar('IMAGE_FSTYPES_DEBUGFS') - if debugfs_image_fstypes: - d.setVar('IMAGE_FSTYPES', debugfs_image_fstypes) - -python setup_debugfs () { - setup_debugfs_variables(d) -} - -python () { - vardeps = set() - # We allow CONVERSIONTYPES to have duplicates. That avoids breaking - # derived distros when OE-core or some other layer independently adds - # the same type. There is still only one command for each type, but - # presumably the commands will do the same when the type is the same, - # even when added in different places. - # - # Without de-duplication, gen_conversion_cmds() below - # would create the same compression command multiple times. - ctypes = set(d.getVar('CONVERSIONTYPES').split()) - old_overrides = d.getVar('OVERRIDES', False) - - def _image_base_type(type): - basetype = type - for ctype in ctypes: - if type.endswith("." + ctype): - basetype = type[:-len("." + ctype)] - break - - if basetype != type: - # New base type itself might be generated by a conversion command. - basetype = _image_base_type(basetype) - - return basetype - - basetypes = {} - alltypes = d.getVar('IMAGE_FSTYPES').split() - typedeps = {} - - if d.getVar('IMAGE_GEN_DEBUGFS') == "1": - debugfs_fstypes = d.getVar('IMAGE_FSTYPES_DEBUGFS').split() - for t in debugfs_fstypes: - alltypes.append("debugfs_" + t) - - def _add_type(t): - baset = _image_base_type(t) - input_t = t - if baset not in basetypes: - basetypes[baset]= [] - if t not in basetypes[baset]: - basetypes[baset].append(t) - debug = "" - if t.startswith("debugfs_"): - t = t[8:] - debug = "debugfs_" - deps = (d.getVar('IMAGE_TYPEDEP_' + t) or "").split() - vardeps.add('IMAGE_TYPEDEP_' + t) - if baset not in typedeps: - typedeps[baset] = set() - deps = [debug + dep for dep in deps] - for dep in deps: - if dep not in alltypes: - alltypes.append(dep) - _add_type(dep) - basedep = _image_base_type(dep) - typedeps[baset].add(basedep) - - if baset != input_t: - _add_type(baset) - - for t in alltypes[:]: - _add_type(t) - - d.appendVarFlag('do_image', 'vardeps', ' '.join(vardeps)) - - maskedtypes = (d.getVar('IMAGE_TYPES_MASKED') or "").split() - maskedtypes = [dbg + t for t in maskedtypes for dbg in ("", "debugfs_")] - - for t in basetypes: - vardeps = set() - cmds = [] - subimages = [] - realt = t - - if t in maskedtypes: - continue - - localdata = bb.data.createCopy(d) - debug = "" - if t.startswith("debugfs_"): - setup_debugfs_variables(localdata) - debug = "setup_debugfs " - realt = t[8:] - localdata.setVar('OVERRIDES', '%s:%s' % (realt, old_overrides)) - localdata.setVar('type', realt) - # Delete DATETIME so we don't expand any references to it now - # This means the task's hash can be stable rather than having hardcoded - # date/time values. It will get expanded at execution time. - # Similarly TMPDIR since otherwise we see QA stamp comparision problems - localdata.delVar('DATETIME') - localdata.delVar('TMPDIR') - - image_cmd = localdata.getVar("IMAGE_CMD") - vardeps.add('IMAGE_CMD_' + realt) - if image_cmd: - cmds.append("\t" + image_cmd) - else: - bb.fatal("No IMAGE_CMD defined for IMAGE_FSTYPES entry '%s' - possibly invalid type name or missing support class" % t) - cmds.append(localdata.expand("\tcd ${IMGDEPLOYDIR}")) - - # Since a copy of IMAGE_CMD_xxx will be inlined within do_image_xxx, - # prevent a redundant copy of IMAGE_CMD_xxx being emitted as a function. - d.delVarFlag('IMAGE_CMD_' + realt, 'func') - - rm_tmp_images = set() - def gen_conversion_cmds(bt): - for ctype in sorted(ctypes): - if bt.endswith("." + ctype): - type = bt[0:-len(ctype) - 1] - if type.startswith("debugfs_"): - type = type[8:] - # Create input image first. - gen_conversion_cmds(type) - localdata.setVar('type', type) - cmd = "\t" + (localdata.getVar("CONVERSION_CMD_" + ctype) or localdata.getVar("COMPRESS_CMD_" + ctype)) - if cmd not in cmds: - cmds.append(cmd) - vardeps.add('CONVERSION_CMD_' + ctype) - vardeps.add('COMPRESS_CMD_' + ctype) - subimage = type + "." + ctype - if subimage not in subimages: - subimages.append(subimage) - if type not in alltypes: - rm_tmp_images.add(localdata.expand("${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}")) - - for bt in basetypes[t]: - gen_conversion_cmds(bt) - - localdata.setVar('type', realt) - if t not in alltypes: - rm_tmp_images.add(localdata.expand("${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}")) - else: - subimages.append(realt) - - # Clean up after applying all conversion commands. Some of them might - # use the same input, therefore we cannot delete sooner without applying - # some complex dependency analysis. - for image in sorted(rm_tmp_images): - cmds.append("\trm " + image) - - after = 'do_image' - for dep in typedeps[t]: - after += ' do_image_%s' % dep.replace("-", "_").replace(".", "_") - - t = t.replace("-", "_").replace(".", "_") - - d.setVar('do_image_%s' % t, '\n'.join(cmds)) - d.setVarFlag('do_image_%s' % t, 'func', '1') - d.setVarFlag('do_image_%s' % t, 'fakeroot', '1') - d.setVarFlag('do_image_%s' % t, 'prefuncs', debug + 'set_image_size') - d.setVarFlag('do_image_%s' % t, 'postfuncs', 'create_symlinks') - d.setVarFlag('do_image_%s' % t, 'subimages', ' '.join(subimages)) - d.appendVarFlag('do_image_%s' % t, 'vardeps', ' '.join(vardeps)) - d.appendVarFlag('do_image_%s' % t, 'vardepsexclude', 'DATETIME') - - bb.debug(2, "Adding type %s before %s, after %s" % (t, 'do_image_complete', after)) - bb.build.addtask('do_image_%s' % t, 'do_image_complete', after, d) -} - -# -# Compute the rootfs size -# -def get_rootfs_size(d): - import subprocess - - rootfs_alignment = int(d.getVar('IMAGE_ROOTFS_ALIGNMENT')) - overhead_factor = float(d.getVar('IMAGE_OVERHEAD_FACTOR')) - rootfs_req_size = int(d.getVar('IMAGE_ROOTFS_SIZE')) - rootfs_extra_space = eval(d.getVar('IMAGE_ROOTFS_EXTRA_SPACE')) - rootfs_maxsize = d.getVar('IMAGE_ROOTFS_MAXSIZE') - image_fstypes = d.getVar('IMAGE_FSTYPES') or '' - initramfs_fstypes = d.getVar('INITRAMFS_FSTYPES') or '' - initramfs_maxsize = d.getVar('INITRAMFS_MAXSIZE') - - output = subprocess.check_output(['du', '-ks', - d.getVar('IMAGE_ROOTFS')]) - size_kb = int(output.split()[0]) - base_size = size_kb * overhead_factor - base_size = max(base_size, rootfs_req_size) + rootfs_extra_space - - if base_size != int(base_size): - base_size = int(base_size + 1) - else: - base_size = int(base_size) - - base_size += rootfs_alignment - 1 - base_size -= base_size % rootfs_alignment - - # Do not check image size of the debugfs image. This is not supposed - # to be deployed, etc. so it doesn't make sense to limit the size - # of the debug. - if (d.getVar('IMAGE_BUILDING_DEBUGFS') or "") == "true": - return base_size - - # Check the rootfs size against IMAGE_ROOTFS_MAXSIZE (if set) - if rootfs_maxsize: - rootfs_maxsize_int = int(rootfs_maxsize) - if base_size > rootfs_maxsize_int: - bb.fatal("The rootfs size %d(K) overrides IMAGE_ROOTFS_MAXSIZE: %d(K)" % \ - (base_size, rootfs_maxsize_int)) - - # Check the initramfs size against INITRAMFS_MAXSIZE (if set) - if image_fstypes == initramfs_fstypes != '' and initramfs_maxsize: - initramfs_maxsize_int = int(initramfs_maxsize) - if base_size > initramfs_maxsize_int: - bb.error("The initramfs size %d(K) overrides INITRAMFS_MAXSIZE: %d(K)" % \ - (base_size, initramfs_maxsize_int)) - bb.error("You can set INITRAMFS_MAXSIZE a larger value. Usually, it should") - bb.fatal("be less than 1/2 of ram size, or you may fail to boot it.\n") - return base_size - -python set_image_size () { - rootfs_size = get_rootfs_size(d) - d.setVar('ROOTFS_SIZE', str(rootfs_size)) - d.setVarFlag('ROOTFS_SIZE', 'export', '1') -} - -# -# Create symlinks to the newly created image -# -python create_symlinks() { - - deploy_dir = d.getVar('IMGDEPLOYDIR') - img_name = d.getVar('IMAGE_NAME') - link_name = d.getVar('IMAGE_LINK_NAME') - manifest_name = d.getVar('IMAGE_MANIFEST') - taskname = d.getVar("BB_CURRENTTASK") - subimages = (d.getVarFlag("do_" + taskname, 'subimages', False) or "").split() - imgsuffix = d.getVarFlag("do_" + taskname, 'imgsuffix') or d.expand("${IMAGE_NAME_SUFFIX}.") - - if not link_name: - return - for type in subimages: - dst = os.path.join(deploy_dir, link_name + "." + type) - src = img_name + imgsuffix + type - if os.path.exists(os.path.join(deploy_dir, src)): - bb.note("Creating symlink: %s -> %s" % (dst, src)) - if os.path.islink(dst): - os.remove(dst) - os.symlink(src, dst) - else: - bb.note("Skipping symlink, source does not exist: %s -> %s" % (dst, src)) -} - -MULTILIBRE_ALLOW_REP =. "${base_bindir}|${base_sbindir}|${bindir}|${sbindir}|${libexecdir}|${sysconfdir}|${nonarch_base_libdir}/udev|/lib/modules/[^/]*/modules.*|" -MULTILIB_CHECK_FILE = "${WORKDIR}/multilib_check.py" -MULTILIB_TEMP_ROOTFS = "${WORKDIR}/multilib" - -do_fetch[noexec] = "1" -do_unpack[noexec] = "1" -do_patch[noexec] = "1" -do_configure[noexec] = "1" -do_compile[noexec] = "1" -do_install[noexec] = "1" -deltask do_populate_sysroot -do_package[noexec] = "1" -deltask do_package_qa -do_packagedata[noexec] = "1" -do_package_write_ipk[noexec] = "1" -do_package_write_deb[noexec] = "1" -do_package_write_rpm[noexec] = "1" - -# Allow the kernel to be repacked with the initramfs and boot image file as a single file -do_bundle_initramfs[depends] += "virtual/kernel:do_bundle_initramfs" -do_bundle_initramfs[nostamp] = "1" -do_bundle_initramfs[noexec] = "1" -do_bundle_initramfs () { - : -} -addtask bundle_initramfs after do_image_complete diff --git a/meta-agl-bsp/classes/sdcard_image-rpi.bbclass b/meta-agl-bsp/classes/sdcard_image-rpi.bbclass deleted file mode 100644 index c22a6f880..000000000 --- a/meta-agl-bsp/classes/sdcard_image-rpi.bbclass +++ /dev/null @@ -1,184 +0,0 @@ -inherit image_types -inherit linux-raspberrypi-base - -# -# Create an image that can by written onto a SD card using dd. -# -# The disk layout used is: -# -# 0 -> IMAGE_ROOTFS_ALIGNMENT - reserved for other data -# IMAGE_ROOTFS_ALIGNMENT -> BOOT_SPACE - bootloader and kernel -# BOOT_SPACE -> SDIMG_SIZE - rootfs -# - -# Default Free space = 1.3x -# Use IMAGE_OVERHEAD_FACTOR to add more space -# <---------> -# 4MiB 40MiB SDIMG_ROOTFS -# <-----------------------> <----------> <----------------------> -# ------------------------ ------------ ------------------------ -# | IMAGE_ROOTFS_ALIGNMENT | BOOT_SPACE | ROOTFS_SIZE | -# ------------------------ ------------ ------------------------ -# ^ ^ ^ ^ -# | | | | -# 0 4MiB 4MiB + 40MiB 4MiB + 40Mib + SDIMG_ROOTFS - -# This image depends on the rootfs image -IMAGE_TYPEDEP_rpi-sdimg = "${SDIMG_ROOTFS_TYPE}" - -# Set kernel and boot loader -IMAGE_BOOTLOADER ?= "bcm2835-bootfiles" - -# Set initramfs extension -KERNEL_INITRAMFS ?= "" - -# Kernel image name -SDIMG_KERNELIMAGE_raspberrypi ?= "kernel.img" -SDIMG_KERNELIMAGE_raspberrypi2 ?= "kernel7.img" -SDIMG_KERNELIMAGE_raspberrypi3-64 ?= "kernel8.img" - -# Boot partition volume id -BOOTDD_VOLUME_ID ?= "${MACHINE}" - -# Boot partition size [in KiB] (will be rounded up to IMAGE_ROOTFS_ALIGNMENT) -BOOT_SPACE ?= "40960" - -# Set alignment to 4MB [in KiB] -IMAGE_ROOTFS_ALIGNMENT = "4096" - -# Use an uncompressed ext3 by default as rootfs -SDIMG_ROOTFS_TYPE ?= "ext3" -SDIMG_ROOTFS = "${IMGDEPLOYDIR}/${IMAGE_NAME}.rootfs.${SDIMG_ROOTFS_TYPE}" - -IMAGE_DEPENDS_rpi-sdimg = " \ - parted-native \ - mtools-native \ - dosfstools-native \ - virtual/kernel:do_deploy \ - ${IMAGE_BOOTLOADER} \ - ${@bb.utils.contains('KERNEL_IMAGETYPE', 'uImage', 'u-boot', '',d)} \ - " - -# SD card image name -SDIMG = "${IMGDEPLOYDIR}/${IMAGE_NAME}.rootfs.rpi-sdimg" - -# Compression method to apply to SDIMG after it has been created. Supported -# compression formats are "gzip", "bzip2" or "xz". The original .rpi-sdimg file -# is kept and a new compressed file is created if one of these compression -# formats is chosen. If SDIMG_COMPRESSION is set to any other value it is -# silently ignored. -#SDIMG_COMPRESSION ?= "" - -# Additional files and/or directories to be copied into the vfat partition from the IMAGE_ROOTFS. -FATPAYLOAD ?= "" - -IMAGE_CMD_rpi-sdimg () { - - # Align partitions - BOOT_SPACE_ALIGNED=$(expr ${BOOT_SPACE} + ${IMAGE_ROOTFS_ALIGNMENT} - 1) - BOOT_SPACE_ALIGNED=$(expr ${BOOT_SPACE_ALIGNED} - ${BOOT_SPACE_ALIGNED} % ${IMAGE_ROOTFS_ALIGNMENT}) - SDIMG_SIZE=$(expr ${IMAGE_ROOTFS_ALIGNMENT} + ${BOOT_SPACE_ALIGNED} + $ROOTFS_SIZE) - - echo "Creating filesystem with Boot partition ${BOOT_SPACE_ALIGNED} KiB and RootFS $ROOTFS_SIZE KiB" - - # Check if we are building with device tree support - DTS="${@get_dts(d)}" - - # Initialize sdcard image file - dd if=/dev/zero of=${SDIMG} bs=1024 count=0 seek=${SDIMG_SIZE} - - # Create partition table - parted -s ${SDIMG} mklabel msdos - # Create boot partition and mark it as bootable - parted -s ${SDIMG} unit KiB mkpart primary fat32 ${IMAGE_ROOTFS_ALIGNMENT} $(expr ${BOOT_SPACE_ALIGNED} \+ ${IMAGE_ROOTFS_ALIGNMENT}) - parted -s ${SDIMG} set 1 boot on - # Create rootfs partition to the end of disk - parted -s ${SDIMG} -- unit KiB mkpart primary ext2 $(expr ${BOOT_SPACE_ALIGNED} \+ ${IMAGE_ROOTFS_ALIGNMENT}) -1s - parted ${SDIMG} print - - # Create a vfat image with boot files - BOOT_BLOCKS=$(LC_ALL=C parted -s ${SDIMG} unit b print | awk '/ 1 / { print substr($4, 1, length($4 -1)) / 512 /2 }') - rm -f ${WORKDIR}/boot.img - mkfs.vfat -n "${BOOTDD_VOLUME_ID}" -S 512 -C ${WORKDIR}/boot.img $BOOT_BLOCKS - mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/bcm2835-bootfiles/* ::/ - if test -n "${DTS}"; then - # Device Tree Overlays are assumed to be suffixed by '-overlay.dtb' (4.1.x) or by '.dtbo' (4.4.9+) string and will be put in a dedicated folder - DT_OVERLAYS="${@split_overlays(d, 0)}" - DT_ROOT="${@split_overlays(d, 1)}" - - # Copy board device trees to root folder - for DTB in ${DT_ROOT}; do - DTB_BASE_NAME=`basename ${DTB} .dtb` - - mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${DTB_BASE_NAME}.dtb ::${DTB_BASE_NAME}.dtb - done - - # Copy device tree overlays to dedicated folder - mmd -i ${WORKDIR}/boot.img overlays - for DTB in ${DT_OVERLAYS}; do - DTB_EXT=${DTB##*.} - DTB_BASE_NAME=`basename ${DTB} ."${DTB_EXT}"` - - mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${DTB_BASE_NAME}.${DTB_EXT} ::overlays/${DTB_BASE_NAME}.${DTB_EXT} - done - fi - case "${KERNEL_IMAGETYPE}" in - "uImage") - mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/u-boot.bin ::${SDIMG_KERNELIMAGE} - mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}${KERNEL_INITRAMFS}-${MACHINE}.bin ::uImage - mcopy -o -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/boot.scr ::boot.scr - ;; - *) - mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}${KERNEL_INITRAMFS}-${MACHINE}.bin ::${SDIMG_KERNELIMAGE} - ;; - esac - - if [ -n ${FATPAYLOAD} ] ; then - echo "Copying payload into VFAT" - for entry in ${FATPAYLOAD} ; do - # add the || true to stop aborting on vfat issues like not supporting .~lock files - mcopy -i ${WORKDIR}/boot.img -s -v ${IMAGE_ROOTFS}$entry :: || true - done - fi - - # Add stamp file - echo "${IMAGE_NAME}" > ${WORKDIR}/image-version-info - mcopy -i ${WORKDIR}/boot.img -v ${WORKDIR}/image-version-info :: - - # Burn Partitions - dd if=${WORKDIR}/boot.img of=${SDIMG} conv=notrunc seek=1 bs=$(expr ${IMAGE_ROOTFS_ALIGNMENT} \* 1024) && sync && sync - # If SDIMG_ROOTFS_TYPE is a .xz file use xzcat - if echo "${SDIMG_ROOTFS_TYPE}" | egrep -q "*\.xz" - then - xzcat ${SDIMG_ROOTFS} | dd of=${SDIMG} conv=notrunc seek=1 bs=$(expr 1024 \* ${BOOT_SPACE_ALIGNED} + ${IMAGE_ROOTFS_ALIGNMENT} \* 1024) && sync && sync - else - dd if=${SDIMG_ROOTFS} of=${SDIMG} conv=notrunc seek=1 bs=$(expr 1024 \* ${BOOT_SPACE_ALIGNED} + ${IMAGE_ROOTFS_ALIGNMENT} \* 1024) && sync && sync - fi - - # Optionally apply compression - case "${SDIMG_COMPRESSION}" in - "gzip") - gzip -k9 "${SDIMG}" - ;; - "bzip2") - bzip2 -k9 "${SDIMG}" - ;; - "xz") - xz -k "${SDIMG}" - ;; - esac -} - -ROOTFS_POSTPROCESS_COMMAND += " rpi_generate_sysctl_config ; " - -rpi_generate_sysctl_config() { - # systemd sysctl config - test -d ${IMAGE_ROOTFS}${sysconfdir}/sysctl.d && \ - echo "vm.min_free_kbytes = 8192" > ${IMAGE_ROOTFS}${sysconfdir}/sysctl.d/rpi-vm.conf - - # sysv sysctl config - IMAGE_SYSCTL_CONF="${IMAGE_ROOTFS}${sysconfdir}/sysctl.conf" - test -e ${IMAGE_ROOTFS}${sysconfdir}/sysctl.conf && \ - sed -e "/vm.min_free_kbytes/d" -i ${IMAGE_SYSCTL_CONF} - echo "" >> ${IMAGE_SYSCTL_CONF} && echo "vm.min_free_kbytes = 8192" >> ${IMAGE_SYSCTL_CONF} -} diff --git a/meta-agl-bsp/conf/include/agl_qemux86-64.inc b/meta-agl-bsp/conf/include/agl_qemux86-64.inc index 3ad9c513f..165deae41 100644 --- a/meta-agl-bsp/conf/include/agl_qemux86-64.inc +++ b/meta-agl-bsp/conf/include/agl_qemux86-64.inc @@ -21,7 +21,8 @@ APPEND += "quiet" DISTRO_FEATURES_append = " sota" # Image support -AGL_EXTRA_IMAGE_FSTYPES = "vmdk.xz" +AGL_EXTRA_IMAGE_FSTYPES = "wic.vmdk" +IMAGE_BOOT_FILES_sota = "u-boot-qemux86-64.rom" # Root device ROOT_VM = "root=PARTUUID=${DISK_SIGNATURE}-02" diff --git a/meta-agl-bsp/meta-intel/recipes-kernel/linux-firmware/linux-firmware_git.bbappend b/meta-agl-bsp/meta-intel/recipes-kernel/linux-firmware/linux-firmware_git.bbappend index a34159cad..824f39359 100644 --- a/meta-agl-bsp/meta-intel/recipes-kernel/linux-firmware/linux-firmware_git.bbappend +++ b/meta-agl-bsp/meta-intel/recipes-kernel/linux-firmware/linux-firmware_git.bbappend @@ -1,8 +1,3 @@ -LICENSE_${PN}-ibt-license = "Firmware-ibt_firmware" -LICENSE_${PN}-ibt-11-5 = "Firmware-ibt_firmware" -FILES_${PN}-ibt-license = "/lib/firmware/LICENCE.ibt_firmware" FILES_${PN}-ibt = "/lib/firmware/intel" RDEPENDS_${PN}-ibt += "${PN}-ibt-license" - -PACKAGES =+ " ${PN}-ibt-license ${PN}-ibt " diff --git a/meta-agl-bsp/meta-qcom/recipes-bsp/96boards-tools/96boards-tools_0.7.bb b/meta-agl-bsp/meta-qcom/recipes-bsp/96boards-tools/96boards-tools_0.11.bb index 36a983198..5c3583526 100644 --- a/meta-agl-bsp/meta-qcom/recipes-bsp/96boards-tools/96boards-tools_0.7.bb +++ b/meta-agl-bsp/meta-qcom/recipes-bsp/96boards-tools/96boards-tools_0.11.bb @@ -5,16 +5,18 @@ SECTION = "devel" LICENSE = "GPLv2+" LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" -SRCREV = "193f355823d9dc38f370759153ac950a2833b0e2" +SRCREV = "395b5994a5fa52f9db10f480fce74e9acdbe3318" SRC_URI = "git://github.com/96boards/96boards-tools;branch=master;protocol=https" S = "${WORKDIR}/git" -inherit systemd allarch +inherit systemd allarch update-rc.d do_install () { install -d ${D}${sysconfdir}/udev/rules.d install -m 0755 ${S}/*.rules ${D}${sysconfdir}/udev/rules.d/ + install -d ${D}${sysconfdir}/init.d + install -m 0755 ${S}/resize-disk ${D}${sysconfdir}/init.d/ install -d ${D}${systemd_unitdir}/system install -m 0644 ${S}/resize-helper.service ${D}${systemd_unitdir}/system @@ -23,5 +25,8 @@ do_install () { install -m 0755 ${S}/resize-helper ${D}${sbindir} } +INITSCRIPT_NAME = "resize-disk" +INITSCRIPT_PARAMS = "start 99 5 2 . stop 20 0 1 6 ." + SYSTEMD_SERVICE_${PN} = "resize-helper.service" RDEPENDS_${PN} += "e2fsprogs-resize2fs gptfdisk parted util-linux udev" diff --git a/meta-agl-bsp/meta-qcom/recipes-kernel/linux/linux-linaro-qcomlt_4.9.bbappend b/meta-agl-bsp/meta-qcom/recipes-kernel/linux/linux-linaro-qcomlt_4.14.bbappend index 17c8f3f0d..0b2b99d4d 100644 --- a/meta-agl-bsp/meta-qcom/recipes-kernel/linux/linux-linaro-qcomlt_4.9.bbappend +++ b/meta-agl-bsp/meta-qcom/recipes-kernel/linux/linux-linaro-qcomlt_4.14.bbappend @@ -1,4 +1,3 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/files:" require recipes-kernel/linux/linux-agl.inc -require recipes-kernel/linux/linux-agl-4.9.inc diff --git a/meta-agl-bsp/meta-qcom/recipes-kernel/most/most.bbappend b/meta-agl-bsp/meta-qcom/recipes-kernel/most/most.bbappend new file mode 100644 index 000000000..6b4444a4e --- /dev/null +++ b/meta-agl-bsp/meta-qcom/recipes-kernel/most/most.bbappend @@ -0,0 +1,5 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/files:" + +SRC_URI_remove = " \ + file://0001-src-most-net-add-skb_put_data-function.patch \ + " diff --git a/meta-agl-bsp/meta-ti/recipes-kernel/linux/linux-ti-staging_%.bbappend b/meta-agl-bsp/meta-ti/recipes-kernel/linux/linux-ti-staging_%.bbappend index 283e8b778..02161415f 100644 --- a/meta-agl-bsp/meta-ti/recipes-kernel/linux/linux-ti-staging_%.bbappend +++ b/meta-agl-bsp/meta-ti/recipes-kernel/linux/linux-ti-staging_%.bbappend @@ -1,4 +1,2 @@ -require recipes-kernel/linux/linux-dtb.inc - require recipes-kernel/linux/linux-agl.inc require recipes-kernel/linux/linux-agl-4.9.inc diff --git a/meta-agl-bsp/recipes-bsp/u-boot/u-boot-ota/0002-fixup-build-with-gcc7.patch b/meta-agl-bsp/recipes-bsp/u-boot/u-boot-ota/0002-fixup-build-with-gcc7.patch new file mode 100644 index 000000000..fc7933ea0 --- /dev/null +++ b/meta-agl-bsp/recipes-bsp/u-boot/u-boot-ota/0002-fixup-build-with-gcc7.patch @@ -0,0 +1,101 @@ +From eea58226f0b604d3047c495985197113838d3a7a Mon Sep 17 00:00:00 2001 +From: Trevor Woerner <twoerner@gmail.com> +Date: Tue, 20 Jun 2017 13:25:20 -0400 +Subject: [PATCH] fix build for gcc7 + +| In file included from .../include/linux/compiler.h:54:0, +| from .../include/uapi/linux/stddef.h:1, +| from .../include/linux/stddef.h:4, +| from .../include/uapi/linux/posix_types.h:4, +| from .../include/uapi/linux/types.h:13, +| from .../include/linux/types.h:5, +| from .../include/linux/mod_devicetable.h:11, +| from .../scripts/mod/devicetable-offsets.c:2: +| .../include/linux/compiler-gcc.h:121:1: fatal error: linux/compiler-gcc7.h: No such file or directory +| #include gcc_header(__GNUC__) + +Upstream-Status: Pending + +Signed-off-by: Trevor Woerner <twoerner@gmail.com> +Signed-off-by: Fabio Berton <fabio.berton@gmail.com> +Signed-off-by: Leon Anavi <leon.anavi@konsulko.com> +--- + include/linux/compiler-gcc7.h | 66 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 66 insertions(+) + create mode 100644 include/linux/compiler-gcc7.h + +diff --git a/include/linux/compiler-gcc7.h b/include/linux/compiler-gcc7.h +new file mode 100644 +index 0000000..cdd1cc2 +--- /dev/null ++++ b/include/linux/compiler-gcc7.h +@@ -0,0 +1,66 @@ ++#ifndef __LINUX_COMPILER_H ++#error "Please don't include <linux/compiler-gcc5.h> directly, include <linux/compiler.h> instead." ++#endif ++ ++#define __used __attribute__((__used__)) ++#define __must_check __attribute__((warn_unused_result)) ++#define __compiler_offsetof(a, b) __builtin_offsetof(a, b) ++ ++/* Mark functions as cold. gcc will assume any path leading to a call ++ to them will be unlikely. This means a lot of manual unlikely()s ++ are unnecessary now for any paths leading to the usual suspects ++ like BUG(), printk(), panic() etc. [but let's keep them for now for ++ older compilers] ++ ++ Early snapshots of gcc 4.3 don't support this and we can't detect this ++ in the preprocessor, but we can live with this because they're unreleased. ++ Maketime probing would be overkill here. ++ ++ gcc also has a __attribute__((__hot__)) to move hot functions into ++ a special section, but I don't see any sense in this right now in ++ the kernel context */ ++#define __cold __attribute__((__cold__)) ++ ++#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) ++ ++#ifndef __CHECKER__ ++# define __compiletime_warning(message) __attribute__((warning(message))) ++# define __compiletime_error(message) __attribute__((error(message))) ++#endif /* __CHECKER__ */ ++ ++/* ++ * Mark a position in code as unreachable. This can be used to ++ * suppress control flow warnings after asm blocks that transfer ++ * control elsewhere. ++ * ++ * Early snapshots of gcc 4.5 don't support this and we can't detect ++ * this in the preprocessor, but we can live with this because they're ++ * unreleased. Really, we need to have autoconf for the kernel. ++ */ ++#define unreachable() __builtin_unreachable() ++ ++/* Mark a function definition as prohibited from being cloned. */ ++#define __noclone __attribute__((__noclone__)) ++ ++/* ++ * Tell the optimizer that something else uses this function or variable. ++ */ ++#define __visible __attribute__((externally_visible)) ++ ++/* ++ * GCC 'asm goto' miscompiles certain code sequences: ++ * ++ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 ++ * ++ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek. ++ * Fixed in GCC 4.8.2 and later versions. ++ * ++ * (asm goto is automatically volatile - the naming reflects this.) ++ */ ++#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) ++ ++#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP ++#define __HAVE_BUILTIN_BSWAP32__ ++#define __HAVE_BUILTIN_BSWAP64__ ++#define __HAVE_BUILTIN_BSWAP16__ ++#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */ +-- +2.7.4 + diff --git a/meta-agl-bsp/recipes-bsp/u-boot/u-boot-ota_2015.07.bb b/meta-agl-bsp/recipes-bsp/u-boot/u-boot-ota_2015.07.bb index 37abc5a50..7ef3cacd4 100644 --- a/meta-agl-bsp/recipes-bsp/u-boot/u-boot-ota_2015.07.bb +++ b/meta-agl-bsp/recipes-bsp/u-boot/u-boot-ota_2015.07.bb @@ -14,6 +14,7 @@ SRC_URI = "\ file://0001-Set-up-environment-for-OSTree-integration.patch \ file://0002-Replace-wraps-with-built-in-code-to-remove-dependenc.patch \ file://0001-fixup-build-with-gcc6.patch \ + file://0002-fixup-build-with-gcc7.patch \ " S = "${WORKDIR}/git" diff --git a/meta-agl-bsp/recipes-graphics/harfbuzz/harfbuzz_1.4.1.bbappend b/meta-agl-bsp/recipes-graphics/harfbuzz/harfbuzz_1.4.8.bbappend index db50df5d9..db50df5d9 100644 --- a/meta-agl-bsp/recipes-graphics/harfbuzz/harfbuzz_1.4.1.bbappend +++ b/meta-agl-bsp/recipes-graphics/harfbuzz/harfbuzz_1.4.8.bbappend diff --git a/meta-agl-bsp/recipes-graphics/mesa/mesa/0001-Use-llvm_prefix-variable-directly.patch b/meta-agl-bsp/recipes-graphics/mesa/mesa/0001-Use-llvm_prefix-variable-directly.patch deleted file mode 100644 index 4f1905492..000000000 --- a/meta-agl-bsp/recipes-graphics/mesa/mesa/0001-Use-llvm_prefix-variable-directly.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0b316ee830765eb1d68cdece5fd4c991e9fba96c Mon Sep 17 00:00:00 2001 -From: Changhyeok Bae <changhyeok.bae@gmail.com> -Date: Sat, 8 Jul 2017 15:22:09 +0900 -Subject: [PATCH] Use $llvm_prefix variable directly - ---- - configure.ac | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index ac110e8..d094ca6 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -896,7 +896,7 @@ fi - - if test -z "$LLVM_CONFIG"; then - if test -n "$llvm_prefix"; then -- AC_PATH_TOOL([LLVM_CONFIG], [llvm-config], [no], ["$llvm_prefix/bin"]) -+ AC_PATH_TOOL([LLVM_CONFIG], [llvm-config], [no], ["$llvm_prefix"]) - else - AC_PATH_TOOL([LLVM_CONFIG], [llvm-config], [no]) - fi --- -1.9.1 - diff --git a/meta-agl-bsp/recipes-graphics/mesa/mesa_%.bbappend b/meta-agl-bsp/recipes-graphics/mesa/mesa_%.bbappend index 13273792b..49e527707 100644 --- a/meta-agl-bsp/recipes-graphics/mesa/mesa_%.bbappend +++ b/meta-agl-bsp/recipes-graphics/mesa/mesa_%.bbappend @@ -1,7 +1,3 @@ -FILESEXTRAPATHS_prepend_qemux86-64 := "${THISDIR}/${BPN}:" -SRC_URI_append_qemux86-64 = " file://0001-Use-llvm_prefix-variable-directly.patch" -EXTRA_OECONF_qemux86-64 = "--enable-shared-glapi --with-llvm-prefix=${STAGING_BINDIR_CROSS}" - # The gallium-llvm is recommended as software 3D graphics renderer GALLIUM_LLVM = "gallium-llvm" PACKAGECONFIG_append_qemux86 = " gallium ${GALLIUM_LLVM}" diff --git a/meta-agl-bsp/recipes-kernel/linux/linux-yocto/0001-fanotify-fix-notification-of-groups-with-inode-mount.patch b/meta-agl-bsp/recipes-kernel/linux/linux-yocto/0001-fanotify-fix-notification-of-groups-with-inode-mount.patch deleted file mode 100644 index c50c152a1..000000000 --- a/meta-agl-bsp/recipes-kernel/linux/linux-yocto/0001-fanotify-fix-notification-of-groups-with-inode-mount.patch +++ /dev/null @@ -1,206 +0,0 @@ -From 8edc6e1688fc8f02c8c1f53a2ec4928cb1055f4d Mon Sep 17 00:00:00 2001 -From: Jan Kara <jack@suse.cz> -Date: Thu, 13 Nov 2014 15:19:33 -0800 -Subject: [PATCH] fanotify: fix notification of groups with inode & mount marks - -fsnotify() needs to merge inode and mount marks lists when notifying -groups about events so that ignore masks from inode marks are reflected -in mount mark notifications and groups are notified in proper order -(according to priorities). - -Currently the sorting of the lists done by fsnotify_add_inode_mark() / -fsnotify_add_vfsmount_mark() and fsnotify() differed which resulted -ignore masks not being used in some cases. - -Fix the problem by always using the same comparison function when -sorting / merging the mark lists. - -Thanks to Heinrich Schuchardt for improvements of my patch. - -Link: https://bugzilla.kernel.org/show_bug.cgi?id=87721 -Signed-off-by: Jan Kara <jack@suse.cz> -Reported-by: Heinrich Schuchardt <xypron.glpk@gmx.de> -Tested-by: Heinrich Schuchardt <xypron.glpk@gmx.de> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> ---- - fs/notify/fsnotify.c | 36 +++++++++++++++++++++--------------- - fs/notify/fsnotify.h | 4 ++++ - fs/notify/inode_mark.c | 8 +++----- - fs/notify/mark.c | 36 ++++++++++++++++++++++++++++++++++++ - fs/notify/vfsmount_mark.c | 8 +++----- - 5 files changed, 67 insertions(+), 25 deletions(-) - -diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c -index 9d3e9c5..89326ac 100644 ---- a/fs/notify/fsnotify.c -+++ b/fs/notify/fsnotify.c -@@ -229,8 +229,16 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, - &fsnotify_mark_srcu); - } - -+ /* -+ * We need to merge inode & vfsmount mark lists so that inode mark -+ * ignore masks are properly reflected for mount mark notifications. -+ * That's why this traversal is so complicated... -+ */ - while (inode_node || vfsmount_node) { -- inode_group = vfsmount_group = NULL; -+ inode_group = NULL; -+ inode_mark = NULL; -+ vfsmount_group = NULL; -+ vfsmount_mark = NULL; - - if (inode_node) { - inode_mark = hlist_entry(srcu_dereference(inode_node, &fsnotify_mark_srcu), -@@ -244,21 +252,19 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, - vfsmount_group = vfsmount_mark->group; - } - -- if (inode_group > vfsmount_group) { -- /* handle inode */ -- ret = send_to_group(to_tell, inode_mark, NULL, mask, -- data, data_is, cookie, file_name); -- /* we didn't use the vfsmount_mark */ -- vfsmount_group = NULL; -- } else if (vfsmount_group > inode_group) { -- ret = send_to_group(to_tell, NULL, vfsmount_mark, mask, -- data, data_is, cookie, file_name); -- inode_group = NULL; -- } else { -- ret = send_to_group(to_tell, inode_mark, vfsmount_mark, -- mask, data, data_is, cookie, -- file_name); -+ if (inode_group && vfsmount_group) { -+ int cmp = fsnotify_compare_groups(inode_group, -+ vfsmount_group); -+ if (cmp > 0) { -+ inode_group = NULL; -+ inode_mark = NULL; -+ } else if (cmp < 0) { -+ vfsmount_group = NULL; -+ vfsmount_mark = NULL; -+ } - } -+ ret = send_to_group(to_tell, inode_mark, vfsmount_mark, mask, -+ data, data_is, cookie, file_name); - - if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS)) - goto out; -diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h -index 9c0898c..3b68b0a 100644 ---- a/fs/notify/fsnotify.h -+++ b/fs/notify/fsnotify.h -@@ -12,6 +12,10 @@ extern void fsnotify_flush_notify(struct fsnotify_group *group); - /* protects reads of inode and vfsmount marks list */ - extern struct srcu_struct fsnotify_mark_srcu; - -+/* compare two groups for sorting of marks lists */ -+extern int fsnotify_compare_groups(struct fsnotify_group *a, -+ struct fsnotify_group *b); -+ - extern void fsnotify_set_inode_mark_mask_locked(struct fsnotify_mark *fsn_mark, - __u32 mask); - /* add a mark to an inode */ -diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c -index e849714..dfbf544 100644 ---- a/fs/notify/inode_mark.c -+++ b/fs/notify/inode_mark.c -@@ -194,6 +194,7 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark, - { - struct fsnotify_mark *lmark, *last = NULL; - int ret = 0; -+ int cmp; - - mark->flags |= FSNOTIFY_MARK_FLAG_INODE; - -@@ -219,11 +220,8 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark, - goto out; - } - -- if (mark->group->priority < lmark->group->priority) -- continue; -- -- if ((mark->group->priority == lmark->group->priority) && -- (mark->group < lmark->group)) -+ cmp = fsnotify_compare_groups(lmark->group, mark->group); -+ if (cmp < 0) - continue; - - hlist_add_before_rcu(&mark->i.i_list, &lmark->i.i_list); -diff --git a/fs/notify/mark.c b/fs/notify/mark.c -index d90deaa..34c38fa 100644 ---- a/fs/notify/mark.c -+++ b/fs/notify/mark.c -@@ -210,6 +210,42 @@ void fsnotify_set_mark_ignored_mask_locked(struct fsnotify_mark *mark, __u32 mas - } - - /* -+ * Sorting function for lists of fsnotify marks. -+ * -+ * Fanotify supports different notification classes (reflected as priority of -+ * notification group). Events shall be passed to notification groups in -+ * decreasing priority order. To achieve this marks in notification lists for -+ * inodes and vfsmounts are sorted so that priorities of corresponding groups -+ * are descending. -+ * -+ * Furthermore correct handling of the ignore mask requires processing inode -+ * and vfsmount marks of each group together. Using the group address as -+ * further sort criterion provides a unique sorting order and thus we can -+ * merge inode and vfsmount lists of marks in linear time and find groups -+ * present in both lists. -+ * -+ * A return value of 1 signifies that b has priority over a. -+ * A return value of 0 signifies that the two marks have to be handled together. -+ * A return value of -1 signifies that a has priority over b. -+ */ -+int fsnotify_compare_groups(struct fsnotify_group *a, struct fsnotify_group *b) -+{ -+ if (a == b) -+ return 0; -+ if (!a) -+ return 1; -+ if (!b) -+ return -1; -+ if (a->priority < b->priority) -+ return 1; -+ if (a->priority > b->priority) -+ return -1; -+ if (a < b) -+ return 1; -+ return -1; -+} -+ -+/* - * Attach an initialized mark to a given group and fs object. - * These marks may be used for the fsnotify backend to determine which - * event types should be delivered to which group. -diff --git a/fs/notify/vfsmount_mark.c b/fs/notify/vfsmount_mark.c -index ac851e8..faefa72 100644 ---- a/fs/notify/vfsmount_mark.c -+++ b/fs/notify/vfsmount_mark.c -@@ -153,6 +153,7 @@ int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark, - struct mount *m = real_mount(mnt); - struct fsnotify_mark *lmark, *last = NULL; - int ret = 0; -+ int cmp; - - mark->flags |= FSNOTIFY_MARK_FLAG_VFSMOUNT; - -@@ -178,11 +179,8 @@ int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark, - goto out; - } - -- if (mark->group->priority < lmark->group->priority) -- continue; -- -- if ((mark->group->priority == lmark->group->priority) && -- (mark->group < lmark->group)) -+ cmp = fsnotify_compare_groups(lmark->group, mark->group); -+ if (cmp < 0) - continue; - - hlist_add_before_rcu(&mark->m.m_list, &lmark->m.m_list); --- -1.8.3.1 - diff --git a/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0001-mm-larger-stack-guard-gap-between-vmas.patch b/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0001-mm-larger-stack-guard-gap-between-vmas.patch deleted file mode 100644 index e9fafad74..000000000 --- a/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0001-mm-larger-stack-guard-gap-between-vmas.patch +++ /dev/null @@ -1,900 +0,0 @@ -From 3982d0807e02909957990f194c5ed2ffb6ab6c35 Mon Sep 17 00:00:00 2001 -From: Hugh Dickins <hughd@google.com> -Date: Mon, 19 Jun 2017 04:03:24 -0700 -Subject: [PATCH 1/3] mm: larger stack guard gap, between vmas - -commit 1be7107fbe18eed3e319a6c3e83c78254b693acb upstream. - -Stack guard page is a useful feature to reduce a risk of stack smashing -into a different mapping. We have been using a single page gap which -is sufficient to prevent having stack adjacent to a different mapping. -But this seems to be insufficient in the light of the stack usage in -userspace. E.g. glibc uses as large as 64kB alloca() in many commonly -used functions. Others use constructs liks gid_t buffer[NGROUPS_MAX] -which is 256kB or stack strings with MAX_ARG_STRLEN. - -This will become especially dangerous for suid binaries and the default -no limit for the stack size limit because those applications can be -tricked to consume a large portion of the stack and a single glibc call -could jump over the guard page. These attacks are not theoretical, -unfortunatelly. - -Make those attacks less probable by increasing the stack guard gap -to 1MB (on systems with 4k pages; but make it depend on the page size -because systems with larger base pages might cap stack allocations in -the PAGE_SIZE units) which should cover larger alloca() and VLA stack -allocations. It is obviously not a full fix because the problem is -somehow inherent, but it should reduce attack space a lot. - -One could argue that the gap size should be configurable from userspace, -but that can be done later when somebody finds that the new 1MB is wrong -for some special case applications. For now, add a kernel command line -option (stack_guard_gap) to specify the stack gap size (in page units). - -Implementation wise, first delete all the old code for stack guard page: -because although we could get away with accounting one extra page in a -stack vma, accounting a larger gap can break userspace - case in point, -a program run with "ulimit -S -v 20000" failed when the 1MB gap was -counted for RLIMIT_AS; similar problems could come with RLIMIT_MLOCK -and strict non-overcommit mode. - -Instead of keeping gap inside the stack vma, maintain the stack guard -gap as a gap between vmas: using vm_start_gap() in place of vm_start -(or vm_end_gap() in place of vm_end if VM_GROWSUP) in just those few -places which need to respect the gap - mainly arch_get_unmapped_area(), -and and the vma tree's subtree_gap support for that. - -Original-patch-by: Oleg Nesterov <oleg@redhat.com> -Original-patch-by: Michal Hocko <mhocko@suse.com> -Signed-off-by: Hugh Dickins <hughd@google.com> -Acked-by: Michal Hocko <mhocko@suse.com> -Tested-by: Helge Deller <deller@gmx.de> # parisc -Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> -[wt: backport to 4.11: adjust context] -[wt: backport to 4.9: adjust context ; kernel doc was not in admin-guide] -[wt: backport to 4.4: adjust context ; drop ppc hugetlb_radix changes] -Signed-off-by: Willy Tarreau <w@1wt.eu> -[gkh: minor build fixes for 4.4] -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - Documentation/kernel-parameters.txt | 7 ++ - arch/arc/mm/mmap.c | 2 +- - arch/arm/mm/mmap.c | 4 +- - arch/frv/mm/elf-fdpic.c | 2 +- - arch/mips/mm/mmap.c | 2 +- - arch/parisc/kernel/sys_parisc.c | 15 ++-- - arch/powerpc/mm/slice.c | 2 +- - arch/s390/mm/mmap.c | 4 +- - arch/sh/mm/mmap.c | 4 +- - arch/sparc/kernel/sys_sparc_64.c | 4 +- - arch/sparc/mm/hugetlbpage.c | 2 +- - arch/tile/mm/hugetlbpage.c | 2 +- - arch/x86/kernel/sys_x86_64.c | 4 +- - arch/x86/mm/hugetlbpage.c | 2 +- - arch/xtensa/kernel/syscall.c | 2 +- - fs/hugetlbfs/inode.c | 2 +- - fs/proc/task_mmu.c | 4 - - include/linux/mm.h | 53 ++++++------- - mm/gup.c | 5 -- - mm/memory.c | 38 --------- - mm/mmap.c | 149 +++++++++++++++++++++--------------- - 21 files changed, 149 insertions(+), 160 deletions(-) - -diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt -index c360f80..9738c8b 100644 ---- a/Documentation/kernel-parameters.txt -+++ b/Documentation/kernel-parameters.txt -@@ -3576,6 +3576,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. - spia_pedr= - spia_peddr= - -+ stack_guard_gap= [MM] -+ override the default stack gap protection. The value -+ is in page units and it defines how many pages prior -+ to (for stacks growing down) resp. after (for stacks -+ growing up) the main stack are reserved for no other -+ mapping. Default value is 256 pages. -+ - stacktrace [FTRACE] - Enabled the stack tracer on boot up. - -diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c -index 2e06d56..cf4ae69 100644 ---- a/arch/arc/mm/mmap.c -+++ b/arch/arc/mm/mmap.c -@@ -64,7 +64,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, - - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - -diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c -index 407dc78..c469c06 100644 ---- a/arch/arm/mm/mmap.c -+++ b/arch/arm/mm/mmap.c -@@ -89,7 +89,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, - - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - -@@ -140,7 +140,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, - addr = PAGE_ALIGN(addr); - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - -diff --git a/arch/frv/mm/elf-fdpic.c b/arch/frv/mm/elf-fdpic.c -index 836f147..efa59f1 100644 ---- a/arch/frv/mm/elf-fdpic.c -+++ b/arch/frv/mm/elf-fdpic.c -@@ -74,7 +74,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi - addr = PAGE_ALIGN(addr); - vma = find_vma(current->mm, addr); - if (TASK_SIZE - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - goto success; - } - -diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c -index 5c81fdd..025cb31 100644 ---- a/arch/mips/mm/mmap.c -+++ b/arch/mips/mm/mmap.c -@@ -92,7 +92,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp, - - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - -diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c -index 5aba01a..4dda73c 100644 ---- a/arch/parisc/kernel/sys_parisc.c -+++ b/arch/parisc/kernel/sys_parisc.c -@@ -88,7 +88,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags) - { - struct mm_struct *mm = current->mm; -- struct vm_area_struct *vma; -+ struct vm_area_struct *vma, *prev; - unsigned long task_size = TASK_SIZE; - int do_color_align, last_mmap; - struct vm_unmapped_area_info info; -@@ -115,9 +115,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, - else - addr = PAGE_ALIGN(addr); - -- vma = find_vma(mm, addr); -+ vma = find_vma_prev(mm, addr, &prev); - if (task_size - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma)) && -+ (!prev || addr >= vm_end_gap(prev))) - goto found_addr; - } - -@@ -141,7 +142,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, - const unsigned long len, const unsigned long pgoff, - const unsigned long flags) - { -- struct vm_area_struct *vma; -+ struct vm_area_struct *vma, *prev; - struct mm_struct *mm = current->mm; - unsigned long addr = addr0; - int do_color_align, last_mmap; -@@ -175,9 +176,11 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, - addr = COLOR_ALIGN(addr, last_mmap, pgoff); - else - addr = PAGE_ALIGN(addr); -- vma = find_vma(mm, addr); -+ -+ vma = find_vma_prev(mm, addr, &prev); - if (TASK_SIZE - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma)) && -+ (!prev || addr >= vm_end_gap(prev))) - goto found_addr; - } - -diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c -index 0f432a7..6ad12b2 100644 ---- a/arch/powerpc/mm/slice.c -+++ b/arch/powerpc/mm/slice.c -@@ -105,7 +105,7 @@ static int slice_area_is_free(struct mm_struct *mm, unsigned long addr, - if ((mm->task_size - len) < addr) - return 0; - vma = find_vma(mm, addr); -- return (!vma || (addr + len) <= vma->vm_start); -+ return (!vma || (addr + len) <= vm_start_gap(vma)); - } - - static int slice_low_has_vma(struct mm_struct *mm, unsigned long slice) -diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c -index f2b6b1d..126c4a9 100644 ---- a/arch/s390/mm/mmap.c -+++ b/arch/s390/mm/mmap.c -@@ -97,7 +97,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, - addr = PAGE_ALIGN(addr); - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - -@@ -135,7 +135,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, - addr = PAGE_ALIGN(addr); - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - -diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c -index 6777177..7df7d59 100644 ---- a/arch/sh/mm/mmap.c -+++ b/arch/sh/mm/mmap.c -@@ -63,7 +63,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, - - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - -@@ -113,7 +113,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, - - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - -diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c -index c690c8e..7f0f7c01 100644 ---- a/arch/sparc/kernel/sys_sparc_64.c -+++ b/arch/sparc/kernel/sys_sparc_64.c -@@ -118,7 +118,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi - - vma = find_vma(mm, addr); - if (task_size - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - -@@ -181,7 +181,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, - - vma = find_vma(mm, addr); - if (task_size - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - -diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c -index da11424..ffa842b 100644 ---- a/arch/sparc/mm/hugetlbpage.c -+++ b/arch/sparc/mm/hugetlbpage.c -@@ -115,7 +115,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, - addr = ALIGN(addr, HPAGE_SIZE); - vma = find_vma(mm, addr); - if (task_size - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - if (mm->get_unmapped_area == arch_get_unmapped_area) -diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c -index c034dc3..c97ee6c 100644 ---- a/arch/tile/mm/hugetlbpage.c -+++ b/arch/tile/mm/hugetlbpage.c -@@ -232,7 +232,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, - addr = ALIGN(addr, huge_page_size(h)); - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - if (current->mm->get_unmapped_area == arch_get_unmapped_area) -diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c -index 10e0272..136ad7c 100644 ---- a/arch/x86/kernel/sys_x86_64.c -+++ b/arch/x86/kernel/sys_x86_64.c -@@ -143,7 +143,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, - addr = PAGE_ALIGN(addr); - vma = find_vma(mm, addr); - if (end - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - -@@ -186,7 +186,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, - addr = PAGE_ALIGN(addr); - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - -diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c -index 42982b2..39bdaf3 100644 ---- a/arch/x86/mm/hugetlbpage.c -+++ b/arch/x86/mm/hugetlbpage.c -@@ -144,7 +144,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, - addr = ALIGN(addr, huge_page_size(h)); - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - if (mm->get_unmapped_area == arch_get_unmapped_area) -diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c -index 83cf496..3aaaae1 100644 ---- a/arch/xtensa/kernel/syscall.c -+++ b/arch/xtensa/kernel/syscall.c -@@ -87,7 +87,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, - /* At this point: (!vmm || addr < vmm->vm_end). */ - if (TASK_SIZE - len < addr) - return -ENOMEM; -- if (!vmm || addr + len <= vmm->vm_start) -+ if (!vmm || addr + len <= vm_start_gap(vmm)) - return addr; - addr = vmm->vm_end; - if (flags & MAP_SHARED) -diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c -index 595ebdb..a17da8b5 100644 ---- a/fs/hugetlbfs/inode.c -+++ b/fs/hugetlbfs/inode.c -@@ -191,7 +191,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, - addr = ALIGN(addr, huge_page_size(h)); - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - -diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c -index d598b9c..cb7020c 100644 ---- a/fs/proc/task_mmu.c -+++ b/fs/proc/task_mmu.c -@@ -295,11 +295,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) - - /* We don't show the stack guard page in /proc/maps */ - start = vma->vm_start; -- if (stack_guard_page_start(vma, start)) -- start += PAGE_SIZE; - end = vma->vm_end; -- if (stack_guard_page_end(vma, end)) -- end -= PAGE_SIZE; - - seq_setwidth(m, 25 + sizeof(void *) * 6 - 1); - seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ", -diff --git a/include/linux/mm.h b/include/linux/mm.h -index f0ffa01..55f950a 100644 ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -1278,39 +1278,11 @@ int clear_page_dirty_for_io(struct page *page); - - int get_cmdline(struct task_struct *task, char *buffer, int buflen); - --/* Is the vma a continuation of the stack vma above it? */ --static inline int vma_growsdown(struct vm_area_struct *vma, unsigned long addr) --{ -- return vma && (vma->vm_end == addr) && (vma->vm_flags & VM_GROWSDOWN); --} -- - static inline bool vma_is_anonymous(struct vm_area_struct *vma) - { - return !vma->vm_ops; - } - --static inline int stack_guard_page_start(struct vm_area_struct *vma, -- unsigned long addr) --{ -- return (vma->vm_flags & VM_GROWSDOWN) && -- (vma->vm_start == addr) && -- !vma_growsdown(vma->vm_prev, addr); --} -- --/* Is the vma a continuation of the stack vma below it? */ --static inline int vma_growsup(struct vm_area_struct *vma, unsigned long addr) --{ -- return vma && (vma->vm_start == addr) && (vma->vm_flags & VM_GROWSUP); --} -- --static inline int stack_guard_page_end(struct vm_area_struct *vma, -- unsigned long addr) --{ -- return (vma->vm_flags & VM_GROWSUP) && -- (vma->vm_end == addr) && -- !vma_growsup(vma->vm_next, addr); --} -- - int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t); - - extern unsigned long move_page_tables(struct vm_area_struct *vma, -@@ -2012,6 +1984,7 @@ void page_cache_async_readahead(struct address_space *mapping, - pgoff_t offset, - unsigned long size); - -+extern unsigned long stack_guard_gap; - /* Generic expand stack which grows the stack according to GROWS{UP,DOWN} */ - extern int expand_stack(struct vm_area_struct *vma, unsigned long address); - -@@ -2040,6 +2013,30 @@ static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * m - return vma; - } - -+static inline unsigned long vm_start_gap(struct vm_area_struct *vma) -+{ -+ unsigned long vm_start = vma->vm_start; -+ -+ if (vma->vm_flags & VM_GROWSDOWN) { -+ vm_start -= stack_guard_gap; -+ if (vm_start > vma->vm_start) -+ vm_start = 0; -+ } -+ return vm_start; -+} -+ -+static inline unsigned long vm_end_gap(struct vm_area_struct *vma) -+{ -+ unsigned long vm_end = vma->vm_end; -+ -+ if (vma->vm_flags & VM_GROWSUP) { -+ vm_end += stack_guard_gap; -+ if (vm_end < vma->vm_end) -+ vm_end = -PAGE_SIZE; -+ } -+ return vm_end; -+} -+ - static inline unsigned long vma_pages(struct vm_area_struct *vma) - { - return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; -diff --git a/mm/gup.c b/mm/gup.c -index 4b0b7e7..b599526 100644 ---- a/mm/gup.c -+++ b/mm/gup.c -@@ -312,11 +312,6 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma, - /* mlock all present pages, but do not fault in new pages */ - if ((*flags & (FOLL_POPULATE | FOLL_MLOCK)) == FOLL_MLOCK) - return -ENOENT; -- /* For mm_populate(), just skip the stack guard page. */ -- if ((*flags & FOLL_POPULATE) && -- (stack_guard_page_start(vma, address) || -- stack_guard_page_end(vma, address + PAGE_SIZE))) -- return -ENOENT; - if (*flags & FOLL_WRITE) - fault_flags |= FAULT_FLAG_WRITE; - if (nonblocking) -diff --git a/mm/memory.c b/mm/memory.c -index 76dcee3..e6fa134 100644 ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -2662,40 +2662,6 @@ out_release: - } - - /* -- * This is like a special single-page "expand_{down|up}wards()", -- * except we must first make sure that 'address{-|+}PAGE_SIZE' -- * doesn't hit another vma. -- */ --static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address) --{ -- address &= PAGE_MASK; -- if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) { -- struct vm_area_struct *prev = vma->vm_prev; -- -- /* -- * Is there a mapping abutting this one below? -- * -- * That's only ok if it's the same stack mapping -- * that has gotten split.. -- */ -- if (prev && prev->vm_end == address) -- return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM; -- -- return expand_downwards(vma, address - PAGE_SIZE); -- } -- if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) { -- struct vm_area_struct *next = vma->vm_next; -- -- /* As VM_GROWSDOWN but s/below/above/ */ -- if (next && next->vm_start == address + PAGE_SIZE) -- return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM; -- -- return expand_upwards(vma, address + PAGE_SIZE); -- } -- return 0; --} -- --/* - * We enter with non-exclusive mmap_sem (to exclude vma changes, - * but allow concurrent faults), and pte mapped but not yet locked. - * We return with mmap_sem still held, but pte unmapped and unlocked. -@@ -2715,10 +2681,6 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, - if (vma->vm_flags & VM_SHARED) - return VM_FAULT_SIGBUS; - -- /* Check if we need to add a guard page to the stack */ -- if (check_stack_guard_page(vma, address) < 0) -- return VM_FAULT_SIGSEGV; -- - /* Use the zero-page for reads */ - if (!(flags & FAULT_FLAG_WRITE) && !mm_forbids_zeropage(mm)) { - entry = pte_mkspecial(pfn_pte(my_zero_pfn(address), -diff --git a/mm/mmap.c b/mm/mmap.c -index 455772a..5e043dd 100644 ---- a/mm/mmap.c -+++ b/mm/mmap.c -@@ -288,6 +288,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk) - unsigned long retval; - unsigned long newbrk, oldbrk; - struct mm_struct *mm = current->mm; -+ struct vm_area_struct *next; - unsigned long min_brk; - bool populate; - -@@ -332,7 +333,8 @@ SYSCALL_DEFINE1(brk, unsigned long, brk) - } - - /* Check against existing mmap mappings. */ -- if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) -+ next = find_vma(mm, oldbrk); -+ if (next && newbrk + PAGE_SIZE > vm_start_gap(next)) - goto out; - - /* Ok, looks good - let it rip. */ -@@ -355,10 +357,22 @@ out: - - static long vma_compute_subtree_gap(struct vm_area_struct *vma) - { -- unsigned long max, subtree_gap; -- max = vma->vm_start; -- if (vma->vm_prev) -- max -= vma->vm_prev->vm_end; -+ unsigned long max, prev_end, subtree_gap; -+ -+ /* -+ * Note: in the rare case of a VM_GROWSDOWN above a VM_GROWSUP, we -+ * allow two stack_guard_gaps between them here, and when choosing -+ * an unmapped area; whereas when expanding we only require one. -+ * That's a little inconsistent, but keeps the code here simpler. -+ */ -+ max = vm_start_gap(vma); -+ if (vma->vm_prev) { -+ prev_end = vm_end_gap(vma->vm_prev); -+ if (max > prev_end) -+ max -= prev_end; -+ else -+ max = 0; -+ } - if (vma->vm_rb.rb_left) { - subtree_gap = rb_entry(vma->vm_rb.rb_left, - struct vm_area_struct, vm_rb)->rb_subtree_gap; -@@ -451,7 +465,7 @@ static void validate_mm(struct mm_struct *mm) - anon_vma_unlock_read(anon_vma); - } - -- highest_address = vma->vm_end; -+ highest_address = vm_end_gap(vma); - vma = vma->vm_next; - i++; - } -@@ -620,7 +634,7 @@ void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma, - if (vma->vm_next) - vma_gap_update(vma->vm_next); - else -- mm->highest_vm_end = vma->vm_end; -+ mm->highest_vm_end = vm_end_gap(vma); - - /* - * vma->vm_prev wasn't known when we followed the rbtree to find the -@@ -866,7 +880,7 @@ again: remove_next = 1 + (end > next->vm_end); - vma_gap_update(vma); - if (end_changed) { - if (!next) -- mm->highest_vm_end = end; -+ mm->highest_vm_end = vm_end_gap(vma); - else if (!adjust_next) - vma_gap_update(next); - } -@@ -909,7 +923,7 @@ again: remove_next = 1 + (end > next->vm_end); - else if (next) - vma_gap_update(next); - else -- mm->highest_vm_end = end; -+ VM_WARN_ON(mm->highest_vm_end != vm_end_gap(vma)); - } - if (insert && file) - uprobe_mmap(insert); -@@ -1741,7 +1755,7 @@ unsigned long unmapped_area(struct vm_unmapped_area_info *info) - - while (true) { - /* Visit left subtree if it looks promising */ -- gap_end = vma->vm_start; -+ gap_end = vm_start_gap(vma); - if (gap_end >= low_limit && vma->vm_rb.rb_left) { - struct vm_area_struct *left = - rb_entry(vma->vm_rb.rb_left, -@@ -1752,7 +1766,7 @@ unsigned long unmapped_area(struct vm_unmapped_area_info *info) - } - } - -- gap_start = vma->vm_prev ? vma->vm_prev->vm_end : 0; -+ gap_start = vma->vm_prev ? vm_end_gap(vma->vm_prev) : 0; - check_current: - /* Check if current node has a suitable gap */ - if (gap_start > high_limit) -@@ -1779,8 +1793,8 @@ check_current: - vma = rb_entry(rb_parent(prev), - struct vm_area_struct, vm_rb); - if (prev == vma->vm_rb.rb_left) { -- gap_start = vma->vm_prev->vm_end; -- gap_end = vma->vm_start; -+ gap_start = vm_end_gap(vma->vm_prev); -+ gap_end = vm_start_gap(vma); - goto check_current; - } - } -@@ -1844,7 +1858,7 @@ unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info) - - while (true) { - /* Visit right subtree if it looks promising */ -- gap_start = vma->vm_prev ? vma->vm_prev->vm_end : 0; -+ gap_start = vma->vm_prev ? vm_end_gap(vma->vm_prev) : 0; - if (gap_start <= high_limit && vma->vm_rb.rb_right) { - struct vm_area_struct *right = - rb_entry(vma->vm_rb.rb_right, -@@ -1857,7 +1871,7 @@ unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info) - - check_current: - /* Check if current node has a suitable gap */ -- gap_end = vma->vm_start; -+ gap_end = vm_start_gap(vma); - if (gap_end < low_limit) - return -ENOMEM; - if (gap_start <= high_limit && gap_end - gap_start >= length) -@@ -1883,7 +1897,7 @@ check_current: - struct vm_area_struct, vm_rb); - if (prev == vma->vm_rb.rb_right) { - gap_start = vma->vm_prev ? -- vma->vm_prev->vm_end : 0; -+ vm_end_gap(vma->vm_prev) : 0; - goto check_current; - } - } -@@ -1921,7 +1935,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags) - { - struct mm_struct *mm = current->mm; -- struct vm_area_struct *vma; -+ struct vm_area_struct *vma, *prev; - struct vm_unmapped_area_info info; - - if (len > TASK_SIZE - mmap_min_addr) -@@ -1932,9 +1946,10 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, - - if (addr) { - addr = PAGE_ALIGN(addr); -- vma = find_vma(mm, addr); -+ vma = find_vma_prev(mm, addr, &prev); - if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma)) && -+ (!prev || addr >= vm_end_gap(prev))) - return addr; - } - -@@ -1957,7 +1972,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, - const unsigned long len, const unsigned long pgoff, - const unsigned long flags) - { -- struct vm_area_struct *vma; -+ struct vm_area_struct *vma, *prev; - struct mm_struct *mm = current->mm; - unsigned long addr = addr0; - struct vm_unmapped_area_info info; -@@ -1972,9 +1987,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, - /* requesting a specific address */ - if (addr) { - addr = PAGE_ALIGN(addr); -- vma = find_vma(mm, addr); -+ vma = find_vma_prev(mm, addr, &prev); - if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && -- (!vma || addr + len <= vma->vm_start)) -+ (!vma || addr + len <= vm_start_gap(vma)) && -+ (!prev || addr >= vm_end_gap(prev))) - return addr; - } - -@@ -2099,21 +2115,19 @@ find_vma_prev(struct mm_struct *mm, unsigned long addr, - * update accounting. This is shared with both the - * grow-up and grow-down cases. - */ --static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, unsigned long grow) -+static int acct_stack_growth(struct vm_area_struct *vma, -+ unsigned long size, unsigned long grow) - { - struct mm_struct *mm = vma->vm_mm; - struct rlimit *rlim = current->signal->rlim; -- unsigned long new_start, actual_size; -+ unsigned long new_start; - - /* address space limit tests */ - if (!may_expand_vm(mm, grow)) - return -ENOMEM; - - /* Stack limit test */ -- actual_size = size; -- if (size && (vma->vm_flags & (VM_GROWSUP | VM_GROWSDOWN))) -- actual_size -= PAGE_SIZE; -- if (actual_size > READ_ONCE(rlim[RLIMIT_STACK].rlim_cur)) -+ if (size > READ_ONCE(rlim[RLIMIT_STACK].rlim_cur)) - return -ENOMEM; - - /* mlock limit tests */ -@@ -2151,17 +2165,30 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns - int expand_upwards(struct vm_area_struct *vma, unsigned long address) - { - struct mm_struct *mm = vma->vm_mm; -+ struct vm_area_struct *next; -+ unsigned long gap_addr; - int error = 0; - - if (!(vma->vm_flags & VM_GROWSUP)) - return -EFAULT; - - /* Guard against wrapping around to address 0. */ -- if (address < PAGE_ALIGN(address+4)) -- address = PAGE_ALIGN(address+4); -- else -+ address &= PAGE_MASK; -+ address += PAGE_SIZE; -+ if (!address) - return -ENOMEM; - -+ /* Enforce stack_guard_gap */ -+ gap_addr = address + stack_guard_gap; -+ if (gap_addr < address) -+ return -ENOMEM; -+ next = vma->vm_next; -+ if (next && next->vm_start < gap_addr) { -+ if (!(next->vm_flags & VM_GROWSUP)) -+ return -ENOMEM; -+ /* Check that both stack segments have the same anon_vma? */ -+ } -+ - /* We must make sure the anon_vma is allocated. */ - if (unlikely(anon_vma_prepare(vma))) - return -ENOMEM; -@@ -2206,7 +2233,7 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address) - if (vma->vm_next) - vma_gap_update(vma->vm_next); - else -- mm->highest_vm_end = address; -+ mm->highest_vm_end = vm_end_gap(vma); - spin_unlock(&mm->page_table_lock); - - perf_event_mmap(vma); -@@ -2227,6 +2254,8 @@ int expand_downwards(struct vm_area_struct *vma, - unsigned long address) - { - struct mm_struct *mm = vma->vm_mm; -+ struct vm_area_struct *prev; -+ unsigned long gap_addr; - int error; - - address &= PAGE_MASK; -@@ -2234,6 +2263,17 @@ int expand_downwards(struct vm_area_struct *vma, - if (error) - return error; - -+ /* Enforce stack_guard_gap */ -+ gap_addr = address - stack_guard_gap; -+ if (gap_addr > address) -+ return -ENOMEM; -+ prev = vma->vm_prev; -+ if (prev && prev->vm_end > gap_addr) { -+ if (!(prev->vm_flags & VM_GROWSDOWN)) -+ return -ENOMEM; -+ /* Check that both stack segments have the same anon_vma? */ -+ } -+ - /* We must make sure the anon_vma is allocated. */ - if (unlikely(anon_vma_prepare(vma))) - return -ENOMEM; -@@ -2289,28 +2329,25 @@ int expand_downwards(struct vm_area_struct *vma, - return error; - } - --/* -- * Note how expand_stack() refuses to expand the stack all the way to -- * abut the next virtual mapping, *unless* that mapping itself is also -- * a stack mapping. We want to leave room for a guard page, after all -- * (the guard page itself is not added here, that is done by the -- * actual page faulting logic) -- * -- * This matches the behavior of the guard page logic (see mm/memory.c: -- * check_stack_guard_page()), which only allows the guard page to be -- * removed under these circumstances. -- */ -+/* enforced gap between the expanding stack and other mappings. */ -+unsigned long stack_guard_gap = 256UL<<PAGE_SHIFT; -+ -+static int __init cmdline_parse_stack_guard_gap(char *p) -+{ -+ unsigned long val; -+ char *endptr; -+ -+ val = simple_strtoul(p, &endptr, 10); -+ if (!*endptr) -+ stack_guard_gap = val << PAGE_SHIFT; -+ -+ return 0; -+} -+__setup("stack_guard_gap=", cmdline_parse_stack_guard_gap); -+ - #ifdef CONFIG_STACK_GROWSUP - int expand_stack(struct vm_area_struct *vma, unsigned long address) - { -- struct vm_area_struct *next; -- -- address &= PAGE_MASK; -- next = vma->vm_next; -- if (next && next->vm_start == address + PAGE_SIZE) { -- if (!(next->vm_flags & VM_GROWSUP)) -- return -ENOMEM; -- } - return expand_upwards(vma, address); - } - -@@ -2332,14 +2369,6 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr) - #else - int expand_stack(struct vm_area_struct *vma, unsigned long address) - { -- struct vm_area_struct *prev; -- -- address &= PAGE_MASK; -- prev = vma->vm_prev; -- if (prev && prev->vm_end == address) { -- if (!(prev->vm_flags & VM_GROWSDOWN)) -- return -ENOMEM; -- } - return expand_downwards(vma, address); - } - -@@ -2437,7 +2466,7 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, - vma->vm_prev = prev; - vma_gap_update(vma); - } else -- mm->highest_vm_end = prev ? prev->vm_end : 0; -+ mm->highest_vm_end = prev ? vm_end_gap(prev) : 0; - tail_vma->vm_next = NULL; - - /* Kill the cache */ --- -2.1.4 - diff --git a/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0002-Allow-stack-to-grow-up-to-address-space-limit.patch b/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0002-Allow-stack-to-grow-up-to-address-space-limit.patch deleted file mode 100644 index d0c94cef2..000000000 --- a/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0002-Allow-stack-to-grow-up-to-address-space-limit.patch +++ /dev/null @@ -1,51 +0,0 @@ -From cd20f002742028366c33b38b3ca613eaee4582c9 Mon Sep 17 00:00:00 2001 -From: Helge Deller <deller@gmx.de> -Date: Mon, 19 Jun 2017 17:34:05 +0200 -Subject: [PATCH 2/3] Allow stack to grow up to address space limit - -commit bd726c90b6b8ce87602208701b208a208e6d5600 upstream. - -Fix expand_upwards() on architectures with an upward-growing stack (parisc, -metag and partly IA-64) to allow the stack to reliably grow exactly up to -the address space limit given by TASK_SIZE. - -Signed-off-by: Helge Deller <deller@gmx.de> -Acked-by: Hugh Dickins <hughd@google.com> -Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - mm/mmap.c | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - -diff --git a/mm/mmap.c b/mm/mmap.c -index 5e043dd..fcf4c88 100644 ---- a/mm/mmap.c -+++ b/mm/mmap.c -@@ -2172,16 +2172,19 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address) - if (!(vma->vm_flags & VM_GROWSUP)) - return -EFAULT; - -- /* Guard against wrapping around to address 0. */ -+ /* Guard against exceeding limits of the address space. */ - address &= PAGE_MASK; -- address += PAGE_SIZE; -- if (!address) -+ if (address >= TASK_SIZE) - return -ENOMEM; -+ address += PAGE_SIZE; - - /* Enforce stack_guard_gap */ - gap_addr = address + stack_guard_gap; -- if (gap_addr < address) -- return -ENOMEM; -+ -+ /* Guard against overflow */ -+ if (gap_addr < address || gap_addr > TASK_SIZE) -+ gap_addr = TASK_SIZE; -+ - next = vma->vm_next; - if (next && next->vm_start < gap_addr) { - if (!(next->vm_flags & VM_GROWSUP)) --- -2.1.4 - diff --git a/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0003-mm-fix-new-crash-in-unmapped_area_topdown.patch b/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0003-mm-fix-new-crash-in-unmapped_area_topdown.patch deleted file mode 100644 index 3f0acfa29..000000000 --- a/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0003-mm-fix-new-crash-in-unmapped_area_topdown.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 1c182004bcb1cd619b58ba6631b9d88052d18e02 Mon Sep 17 00:00:00 2001 -From: Hugh Dickins <hughd@google.com> -Date: Tue, 20 Jun 2017 02:10:44 -0700 -Subject: [PATCH 3/3] mm: fix new crash in unmapped_area_topdown() - -commit f4cb767d76cf7ee72f97dd76f6cfa6c76a5edc89 upstream. - -Trinity gets kernel BUG at mm/mmap.c:1963! in about 3 minutes of -mmap testing. That's the VM_BUG_ON(gap_end < gap_start) at the -end of unmapped_area_topdown(). Linus points out how MAP_FIXED -(which does not have to respect our stack guard gap intentions) -could result in gap_end below gap_start there. Fix that, and -the similar case in its alternative, unmapped_area(). - -Fixes: 1be7107fbe18 ("mm: larger stack guard gap, between vmas") -Reported-by: Dave Jones <davej@codemonkey.org.uk> -Debugged-by: Linus Torvalds <torvalds@linux-foundation.org> -Signed-off-by: Hugh Dickins <hughd@google.com> -Acked-by: Michal Hocko <mhocko@suse.com> -Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - mm/mmap.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/mm/mmap.c b/mm/mmap.c -index fcf4c88..0990f8b 100644 ---- a/mm/mmap.c -+++ b/mm/mmap.c -@@ -1771,7 +1771,8 @@ check_current: - /* Check if current node has a suitable gap */ - if (gap_start > high_limit) - return -ENOMEM; -- if (gap_end >= low_limit && gap_end - gap_start >= length) -+ if (gap_end >= low_limit && -+ gap_end > gap_start && gap_end - gap_start >= length) - goto found; - - /* Visit right subtree if it looks promising */ -@@ -1874,7 +1875,8 @@ check_current: - gap_end = vm_start_gap(vma); - if (gap_end < low_limit) - return -ENOMEM; -- if (gap_start <= high_limit && gap_end - gap_start >= length) -+ if (gap_start <= high_limit && -+ gap_end > gap_start && gap_end - gap_start >= length) - goto found; - - /* Visit left subtree if it looks promising */ --- -2.1.4 - diff --git a/meta-agl-bsp/recipes-kernel/linux/linux-yocto_4.4.bbappend b/meta-agl-bsp/recipes-kernel/linux/linux-yocto_4.4.bbappend deleted file mode 100644 index 45c170661..000000000 --- a/meta-agl-bsp/recipes-kernel/linux/linux-yocto_4.4.bbappend +++ /dev/null @@ -1,14 +0,0 @@ -FILESEXTRAPATHS_prepend := "${THISDIR}/linux-yocto:" - -# Backported fix for CVE-2017-1000364 -SRC_URI_append_core2-32-intel-common = "\ - file://4.4-0001-mm-larger-stack-guard-gap-between-vmas.patch \ - file://4.4-0002-Allow-stack-to-grow-up-to-address-space-limit.patch \ - file://4.4-0003-mm-fix-new-crash-in-unmapped_area_topdown.patch \ -" - -SRC_URI_append_corei7-64-intel-common = "\ - file://4.4-0001-mm-larger-stack-guard-gap-between-vmas.patch \ - file://4.4-0002-Allow-stack-to-grow-up-to-address-space-limit.patch \ - file://4.4-0003-mm-fix-new-crash-in-unmapped_area_topdown.patch \ -" diff --git a/meta-agl-distro/conf/distro/poky-agl.conf b/meta-agl-distro/conf/distro/poky-agl.conf index d7a12e301..d4ff01b7f 100644 --- a/meta-agl-distro/conf/distro/poky-agl.conf +++ b/meta-agl-distro/conf/distro/poky-agl.conf @@ -69,13 +69,13 @@ DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" PREFERRED_VERSION_wayland-ivi-extension ?= "1.1%" # Prefer GStreamer 1.10.x by default -PREFERRED_VERSION_gstreamer1.0 ?= "1.10.%" -PREFERRED_VERSION_gstreamer1.0-plugins-bad ?= "1.10.%" -PREFERRED_VERSION_gstreamer1.0-plugins-base ?= "1.10.%" -PREFERRED_VERSION_gstreamer1.0-plugins-good ?= "1.10.%" -PREFERRED_VERSION_gstreamer1.0-plugins-ugly ?= "1.10.%" -PREFERRED_VERSION_gstreamer1.0-libav ?= "1.10.%" -PREFERRED_VERSION_gstreamer1.0-omx ?= "1.2.%" +PREFERRED_VERSION_gstreamer1.0 ?= "1.12.%" +PREFERRED_VERSION_gstreamer1.0-plugins-bad ?= "1.12.%" +PREFERRED_VERSION_gstreamer1.0-plugins-base ?= "1.12.%" +PREFERRED_VERSION_gstreamer1.0-plugins-good ?= "1.12.%" +PREFERRED_VERSION_gstreamer1.0-plugins-ugly ?= "1.12.%" +PREFERRED_VERSION_gstreamer1.0-libav ?= "1.12.%" +PREFERRED_VERSION_gstreamer1.0-omx ?= "1.12.%" # Prefer libjpeg-turbo PREFERRED_PROVIDER_jpeg = "libjpeg-turbo" diff --git a/meta-agl/conf/include/agl-devel.inc b/meta-agl/conf/include/agl-devel.inc index c24143593..fd11ade75 100644 --- a/meta-agl/conf/include/agl-devel.inc +++ b/meta-agl/conf/include/agl-devel.inc @@ -4,7 +4,7 @@ IMAGE_INSTALL_append = " \ packagegroup-agl-devel \ " -IMAGE_INSTALL_append = "${@bb.utils.contains_any('IMAGE_FSTYPES', [ 'vmdk', 'vmdk.xz' ], ' open-vm-tools vboxguestdrivers', '', d)}" +IMAGE_INSTALL_append = "${@bb.utils.contains('IMAGE_FSTYPES', 'wic.vmdk', ' open-vm-tools vboxguestdrivers', '', d)}" # disable install of debug files in SDK # initial value: SDKIMAGE_FEATURES="dev-pkgs dbg-pkgs staticdev-pkgs" diff --git a/meta-agl/files/group b/meta-agl/files/group index d910f0f83..f8a3843bd 100644 --- a/meta-agl/files/group +++ b/meta-agl/files/group @@ -86,3 +86,5 @@ postdrop::954: display::200: agl-driver::1001: agl-passenger::1002: +systemd-network::1005: +systemd-resolve::1006: diff --git a/meta-agl/files/passwd b/meta-agl/files/passwd index df4c23e74..754cb819a 100644 --- a/meta-agl/files/passwd +++ b/meta-agl/files/passwd @@ -56,3 +56,5 @@ opensaf::957:957::: lldpd::956:956::: cyrus::955:8::: display::200:200::: +systemd-network::1005:1005::: +systemd-resolve::1006:1006::: diff --git a/meta-agl/recipes-connectivity/bluez5/bluez5/cve-2017-1000250.patch b/meta-agl/recipes-connectivity/bluez5/bluez5/cve-2017-1000250.patch deleted file mode 100644 index 9fac961bc..000000000 --- a/meta-agl/recipes-connectivity/bluez5/bluez5/cve-2017-1000250.patch +++ /dev/null @@ -1,34 +0,0 @@ -All versions of the SDP server in BlueZ 5.46 and earlier are vulnerable to an -information disclosure vulnerability which allows remote attackers to obtain -sensitive information from the bluetoothd process memory. This vulnerability -lies in the processing of SDP search attribute requests. - -CVE: CVE-2017-1000250 -Upstream-Status: Backport -Signed-off-by: Ross Burton <ross.burton@intel.com> - -From 9e009647b14e810e06626dde7f1bb9ea3c375d09 Mon Sep 17 00:00:00 2001 -From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> -Date: Wed, 13 Sep 2017 10:01:40 +0300 -Subject: sdp: Fix Out-of-bounds heap read in service_search_attr_req function - -Check if there is enough data to continue otherwise return an error. ---- - src/sdpd-request.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/sdpd-request.c b/src/sdpd-request.c -index 1eefdce..318d044 100644 ---- a/src/sdpd-request.c -+++ b/src/sdpd-request.c -@@ -917,7 +917,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) - } else { - /* continuation State exists -> get from cache */ - sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); -- if (pCache) { -+ if (pCache && cstate->cStateValue.maxBytesSent < pCache->data_size) { - uint16_t sent = MIN(max, pCache->data_size - cstate->cStateValue.maxBytesSent); - pResponse = pCache->data; - memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); --- -cgit v1.1 diff --git a/meta-agl/recipes-connectivity/bluez5/bluez5_%.bbappend b/meta-agl/recipes-connectivity/bluez5/bluez5_%.bbappend index 543681550..ffb9d5b53 100644 --- a/meta-agl/recipes-connectivity/bluez5/bluez5_%.bbappend +++ b/meta-agl/recipes-connectivity/bluez5/bluez5_%.bbappend @@ -1,6 +1,5 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:" -SRC_URI_append = " file://bluetooth.conf \ - file://cve-2017-1000250.patch" +SRC_URI_append = " file://bluetooth.conf" do_install_append() { install -m 0644 ${WORKDIR}/bluetooth.conf ${D}${sysconfdir}/dbus-1/system.d/bluetooth.conf diff --git a/meta-agl/recipes-connectivity/connman/files/0001-disable-when-booting-over-nfs.patch b/meta-agl/recipes-connectivity/connman/files/0001-disable-when-booting-over-nfs.patch index b4704de68..95fc0a905 100644 --- a/meta-agl/recipes-connectivity/connman/files/0001-disable-when-booting-over-nfs.patch +++ b/meta-agl/recipes-connectivity/connman/files/0001-disable-when-booting-over-nfs.patch @@ -1,9 +1,10 @@ --- a/src/connman.service.in 2016-08-15 13:51:03.479478140 +0200 +++ b/src/connman.service.in 2016-08-15 13:51:33.469478267 +0200 -@@ -6,6 +6,7 @@ RequiresMountsFor=@localstatedir@/lib/co +@@ -7,6 +7,7 @@ RequiresMountsFor=@localstatedir@/lib/co After=dbus.service network-pre.target systemd-sysusers.service Before=network.target multi-user.target shutdown.target Wants=network.target + Conflicts=systemd-resolved.service +ConditionKernelCommandLine=!root=/dev/nfs [Service] diff --git a/meta-agl/recipes-connectivity/rygel/files/0001-Add-LightMediaScanner-plugin.patch b/meta-agl/recipes-connectivity/rygel/files/0001-Add-LightMediaScanner-plugin.patch deleted file mode 100644 index eca08ee84..000000000 --- a/meta-agl/recipes-connectivity/rygel/files/0001-Add-LightMediaScanner-plugin.patch +++ /dev/null @@ -1,2541 +0,0 @@ -From 8bb9ae73464dd76f5fa94f2e9ba76b0bd88114df Mon Sep 17 00:00:00 2001 -From: Manuel Bachmann <manuel.bachmann@iot.bzh> -Date: Mon, 26 Oct 2015 04:18:33 +0000 -Subject: [PATCH] Add LightMediaScanner plugin - -Add a new plugin based on LightMediaScanner : -https://github.com/profusion/lightmediascanner - -Shorty put, this plugin does not do the indexing itself as -"media-export" does, but defers this task to the -"lightmediascannerd" daemon, with which it communicates -via a D-Bus interface. -The remote indexing daemon installs itself as a separate -package, and is designed to be ultra-lightweight and fast. - -This commit is the rebase and fusion of all work done -first on Maemo (lms.garage.maemo.org), then on Tizen IVI -(review.tizen.org/git/?p=profile/ivi/rygel.git) and right -now on AGL (automotivelinux.org) where several components -depend on LightMediaScanner. -A splitted version (13 commits) can also be seen on : -https://github.com/Tarnyko/rygel - -It difffers mostly in that it lets "media-export" plugin -as the default, just adding itself in "rygel.conf" as an -alternative. - -(note : reporter is not code Author, see patch for details) -(note 2 : rebased on top of 0.26.1) - -Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -Author: Alexander Kanavin <alex.kanavin@gmail.com> -Signed-off-by: Manuel Bachmann <manuel.bachmann@iot.bzh> ---- - configure.ac | 18 + - data/rygel.conf | 6 +- - src/plugins/Makefile.am | 5 + - src/plugins/lms/Makefile.am | 46 +++ - src/plugins/lms/README | 17 + - src/plugins/lms/lms.plugin.in | 7 + - src/plugins/lms/rygel-lms-album.vala | 173 +++++++++ - src/plugins/lms/rygel-lms-albums.vala | 175 +++++++++ - src/plugins/lms/rygel-lms-all-images.vala | 95 +++++ - src/plugins/lms/rygel-lms-all-music.vala | 169 ++++++++ - src/plugins/lms/rygel-lms-all-videos.vala | 123 ++++++ - src/plugins/lms/rygel-lms-artist.vala | 75 ++++ - src/plugins/lms/rygel-lms-artists.vala | 62 +++ - src/plugins/lms/rygel-lms-category-container.vala | 428 +++++++++++++++++++++ - src/plugins/lms/rygel-lms-collate.c | 49 +++ - src/plugins/lms/rygel-lms-database.vala | 294 ++++++++++++++ - src/plugins/lms/rygel-lms-dbus-interfaces.vala | 30 ++ - src/plugins/lms/rygel-lms-image-root.vala | 35 ++ - src/plugins/lms/rygel-lms-image-year.vala | 114 ++++++ - src/plugins/lms/rygel-lms-image-years.vala | 59 +++ - src/plugins/lms/rygel-lms-music-root.vala | 36 ++ - src/plugins/lms/rygel-lms-plugin-factory.vala | 40 ++ - src/plugins/lms/rygel-lms-plugin.vala | 35 ++ - src/plugins/lms/rygel-lms-root-container.vala | 58 +++ - src/plugins/lms/rygel-lms-sql-function.vala | 31 ++ - src/plugins/lms/rygel-lms-sql-operator.vala | 73 ++++ - 26 files changed, 2252 insertions(+), 1 deletion(-) - create mode 100644 src/plugins/lms/Makefile.am - create mode 100644 src/plugins/lms/README - create mode 100644 src/plugins/lms/lms.plugin.in - create mode 100644 src/plugins/lms/rygel-lms-album.vala - create mode 100644 src/plugins/lms/rygel-lms-albums.vala - create mode 100644 src/plugins/lms/rygel-lms-all-images.vala - create mode 100644 src/plugins/lms/rygel-lms-all-music.vala - create mode 100644 src/plugins/lms/rygel-lms-all-videos.vala - create mode 100644 src/plugins/lms/rygel-lms-artist.vala - create mode 100644 src/plugins/lms/rygel-lms-artists.vala - create mode 100644 src/plugins/lms/rygel-lms-category-container.vala - create mode 100644 src/plugins/lms/rygel-lms-collate.c - create mode 100644 src/plugins/lms/rygel-lms-database.vala - create mode 100644 src/plugins/lms/rygel-lms-dbus-interfaces.vala - create mode 100644 src/plugins/lms/rygel-lms-image-root.vala - create mode 100644 src/plugins/lms/rygel-lms-image-year.vala - create mode 100644 src/plugins/lms/rygel-lms-image-years.vala - create mode 100644 src/plugins/lms/rygel-lms-music-root.vala - create mode 100644 src/plugins/lms/rygel-lms-plugin-factory.vala - create mode 100644 src/plugins/lms/rygel-lms-plugin.vala - create mode 100644 src/plugins/lms/rygel-lms-root-container.vala - create mode 100644 src/plugins/lms/rygel-lms-sql-function.vala - create mode 100644 src/plugins/lms/rygel-lms-sql-operator.vala - -diff --git a/configure.ac b/configure.ac -index 7ae1105..275fd99 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -170,6 +170,18 @@ AS_IF([test "x$enable_ruih_plugin" = "xyes"], - libxml-2.0 >= $LIBXML_REQUIRED]) - ]) - -+ -+RYGEL_ADD_PLUGIN([lms],[LightMediaScanner],[yes]) -+AS_IF([test "x$enable_lms_plugin" = "xyes"], -+ [ -+ PKG_CHECK_MODULES([RYGEL_PLUGIN_LMS_DEPS], -+ [$RYGEL_COMMON_MODULES -+ gio-2.0 >= $GIO_REQUIRED -+ sqlite3 >= $LIBSQLITE3_REQUIRED]) -+ RYGEL_PLUGIN_LMS_DEPS_VALAFLAGS="$RYGEL_COMMON_MODULES_VALAFLAGS --pkg gio-2.0 --pkg gee-0.8 --pkg sqlite3" -+ AC_SUBST([RYGEL_PLUGIN_LMS_DEPS_VALAFLAGS]) -+ ]) -+ - AS_IF([test "x$with_media_engine" = "xgstreamer"], - [ - RYGEL_ADD_PLUGIN([playbin],[GStreamer playbin],[yes]) -@@ -332,6 +344,11 @@ then - fi - fi - -+dnl Check additional requirements for LMS plugin -+if test "x$enable_lms_plugin" = "xyes"; -+then -+ RYGEL_CHECK_PACKAGES([sqlite3]) -+fi - - RYGEL_ADD_PLUGIN([tracker],[Tracker],[yes]) - AS_IF([test "x$enable_tracker_plugin" = "xyes"], -@@ -513,6 +530,7 @@ echo " - version: ${tracker_api_version} - mediathek: ${enable_mediathek_plugin} - media-export ${enable_media_export_plugin} -+ lightmediascanner ${enable_lms_plugin} - external: ${enable_external_plugin} - MPRIS2: ${enable_mpris_plugin} - gst-launch: ${enable_gst_launch_plugin} -diff --git a/data/rygel.conf b/data/rygel.conf -index 6b1c1c4..8677a0d 100644 ---- a/data/rygel.conf -+++ b/data/rygel.conf -@@ -99,7 +99,7 @@ strict-sharing=false - title=@REALNAME@'s media on @PRETTY_HOSTNAME@ - - [MediaExport] --enabled=true -+enabled=false - title=@REALNAME@'s media on @PRETTY_HOSTNAME@ - # List of URIs to export. Following variables are automatically substituted by - # the appropriate XDG standard media folders by Rygel for you. -@@ -114,6 +114,10 @@ monitor-changes=true - monitor-grace-timeout=5 - virtual-folders=true - -+[LightMediaScanner] -+enabled=true -+title=My Media -+ - [Playbin] - enabled=true - title=Audio/Video playback on @PRETTY_HOSTNAME@ -diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am -index d116f09..40791f0 100644 ---- a/src/plugins/Makefile.am -+++ b/src/plugins/Makefile.am -@@ -10,6 +10,10 @@ if BUILD_MEDIA_EXPORT_PLUGIN - MEDIA_EXPORT_PLUGIN = media-export - endif - -+if BUILD_LMS_PLUGIN -+LMS_PLUGIN = lms -+endif -+ - if BUILD_EXTERNAL_PLUGIN - EXTERNAL_PLUGIN = external - endif -@@ -33,6 +37,7 @@ endif - SUBDIRS = $(TRACKER_PLUGIN) \ - $(MEDIATHEK_PLUGIN) \ - $(MEDIA_EXPORT_PLUGIN) \ -+ $(LMS_PLUGIN) \ - $(EXTERNAL_PLUGIN) \ - $(MPRIS_PLUGIN) \ - $(GST_LAUNCH_PLUGIN) \ -diff --git a/src/plugins/lms/Makefile.am b/src/plugins/lms/Makefile.am -new file mode 100644 -index 0000000..f96a2ab ---- /dev/null -+++ b/src/plugins/lms/Makefile.am -@@ -0,0 +1,46 @@ -+include $(top_srcdir)/common.am -+ -+plugin_LTLIBRARIES = librygel-lms.la -+plugin_DATA = lms.plugin -+ -+librygel_lms_la_SOURCES = \ -+ rygel-lms-plugin.vala \ -+ rygel-lms-plugin-factory.vala \ -+ rygel-lms-root-container.vala \ -+ rygel-lms-music-root.vala \ -+ rygel-lms-image-root.vala \ -+ rygel-lms-category-container.vala \ -+ rygel-lms-all-music.vala \ -+ rygel-lms-album.vala \ -+ rygel-lms-albums.vala \ -+ rygel-lms-artist.vala \ -+ rygel-lms-artists.vala \ -+ rygel-lms-all-videos.vala \ -+ rygel-lms-database.vala \ -+ rygel-lms-all-images.vala \ -+ rygel-lms-image-years.vala \ -+ rygel-lms-image-year.vala \ -+ rygel-lms-sql-function.vala \ -+ rygel-lms-sql-operator.vala \ -+ rygel-lms-collate.c \ -+ rygel-lms-dbus-interfaces.vala -+ -+librygel_lms_la_VALAFLAGS = \ -+ --enable-experimental \ -+ $(RYGEL_PLUGIN_LMS_DEPS_VALAFLAGS) \ -+ $(RYGEL_COMMON_LIBRYGEL_SERVER_VALAFLAGS) \ -+ $(RYGEL_COMMON_VALAFLAGS) -+ -+librygel_lms_la_CFLAGS = \ -+ $(RYGEL_PLUGIN_LMS_DEPS_CFLAGS) \ -+ $(RYGEL_COMMON_LIBRYGEL_SERVER_CFLAGS) \ -+ -DG_LOG_DOMAIN='"Lms"' -+ -+librygel_lms_la_LIBADD = \ -+ $(RYGEL_PLUGIN_LMS_DEPS_LIBS) \ -+ $(RYGEL_COMMON_LIBRYGEL_SERVER_LIBS) -+ -+librygel_lms_la_LDFLAGS = \ -+ $(RYGEL_PLUGIN_LINKER_FLAGS) -+ -+EXTRA_DIST = lms.plugin.in -diff --git a/src/plugins/lms/README b/src/plugins/lms/README -new file mode 100644 -index 0000000..b741806 ---- /dev/null -+++ b/src/plugins/lms/README -@@ -0,0 +1,17 @@ -+rygel-lms -+========= -+ -+A rygel mediaserver plugin that exposes a lightmediascanner database -+as a Mediaserver. -+ -+Configuration in rygel.conf: -+ -+ [LightMediaScanner] -+ db-path=/path/to/lightmediascannerd.sqlite3 -+ title=My Media -+ -+* Supports browsing and searching (but in many cases searches will -+ still fall back to the inefficient simple_search()). -+* UpdateIDs are not yet supported as lightmediascanner seems to have -+ not change signal support yet -+* No real DLNA CTT testing has been done so far -diff --git a/src/plugins/lms/lms.plugin.in b/src/plugins/lms/lms.plugin.in -new file mode 100644 -index 0000000..9db9895 ---- /dev/null -+++ b/src/plugins/lms/lms.plugin.in -@@ -0,0 +1,7 @@ -+[Plugin] -+Version = @VERSION@ -+Module = lms -+Name = LMS -+License = LGPL -+Description = LMS DMS plugin for Rygel -+Copyright = Copyright © Intel -diff --git a/src/plugins/lms/rygel-lms-album.vala b/src/plugins/lms/rygel-lms-album.vala -new file mode 100644 -index 0000000..4fea17a ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-album.vala -@@ -0,0 +1,173 @@ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+using Sqlite; -+ -+public class Rygel.LMS.Album : Rygel.LMS.CategoryContainer { -+ private static const string SQL_ALL_TEMPLATE = -+ "SELECT files.id, files.path, files.size, " + -+ "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + -+ "audio_artists.name as artist, " + -+ "audio_albums.name " + -+ "FROM audios, files " + -+ "LEFT JOIN audio_artists " + -+ "ON audios.artist_id = audio_artists.id " + -+ "LEFT JOIN audio_albums " + -+ "ON audios.album_id = audio_albums.id " + -+ "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s " + -+ "LIMIT ? OFFSET ?;"; -+ -+ private static const string SQL_COUNT_TEMPLATE = -+ "SELECT COUNT(audios.id) " + -+ "FROM audios, files " + -+ "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s;"; -+ -+ private static const string SQL_COUNT_WITH_FILTER_TEMPLATE = -+ "SELECT COUNT(audios.id), audios.title as title, " + -+ "audio_artists.name as artist, " + -+ "audio_albums.name " + -+ "FROM audios, files " + -+ "LEFT JOIN audio_artists " + -+ "ON audios.artist_id = audio_artists.id " + -+ "LEFT JOIN audio_albums " + -+ "ON audios.album_id = audio_albums.id " + -+ "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s;"; -+ -+ private static const string SQL_FIND_OBJECT_TEMPLATE = -+ "SELECT files.id, files.path, files.size, " + -+ "audios.title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + -+ "audio_artists.name, " + -+ "audio_albums.name " + -+ "FROM audios, files " + -+ "LEFT JOIN audio_artists " + -+ "ON audios.artist_id = audio_artists.id " + -+ "LEFT JOIN audio_albums " + -+ "ON audios.album_id = audio_albums.id " + -+ "WHERE dtime = 0 AND files.id = ? AND audios.id = files.id AND audios.album_id = %s;"; -+ -+ private static const string SQL_ADDED_TEMPLATE = -+ "SELECT files.id, files.path, files.size, " + -+ "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + -+ "audio_artists.name as artist, " + -+ "audio_albums.name " + -+ "FROM audios, files " + -+ "LEFT JOIN audio_artists " + -+ "ON audios.artist_id = audio_artists.id " + -+ "LEFT JOIN audio_albums " + -+ "ON audios.album_id = audio_albums.id " + -+ "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s " + -+ "AND update_id > ? AND update_id <= ?;"; -+ -+ private static const string SQL_REMOVED_TEMPLATE = -+ "SELECT files.id, files.path, files.size, " + -+ "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + -+ "audio_artists.name as artist, " + -+ "audio_albums.name " + -+ "FROM audios, files " + -+ "LEFT JOIN audio_artists " + -+ "ON audios.artist_id = audio_artists.id " + -+ "LEFT JOIN audio_albums " + -+ "ON audios.album_id = audio_albums.id " + -+ "WHERE dtime <> 0 AND audios.id = files.id AND audios.album_id = %s " + -+ "AND update_id > ? AND update_id <= ?;"; -+ -+ protected override MediaObject? object_from_statement (Statement statement) { -+ var id = statement.column_int (0); -+ var path = statement.column_text (1); -+ var mime_type = statement.column_text(10); -+ -+ if (mime_type == null || mime_type.length == 0) { -+ /* TODO is this correct? */ -+ debug ("Music item %d (%s) has no MIME type", -+ id, -+ path); -+ } -+ -+ var title = statement.column_text(3); -+ var song_id = this.build_child_id (id); -+ var song = new MusicItem (song_id, this, title); -+ song.ref_id = this.build_reference_id (id); -+ song.size = statement.column_int(2); -+ song.track_number = statement.column_int(4); -+ song.duration = statement.column_int(5); -+ song.channels = statement.column_int(6); -+ song.sample_freq = statement.column_int(7); -+ song.bitrate = statement.column_int(8); -+ song.dlna_profile = statement.column_text(9); -+ song.mime_type = mime_type; -+ song.artist = statement.column_text(11); -+ song.album = statement.column_text(12); -+ File file = File.new_for_path (path); -+ song.add_uri (file.get_uri ()); -+ -+ return song; -+ } -+ -+ private static string get_sql_all (string db_id) { -+ return (SQL_ALL_TEMPLATE.printf (db_id)); -+ } -+ private static string get_sql_find_object (string db_id) { -+ return (SQL_FIND_OBJECT_TEMPLATE.printf (db_id)); -+ } -+ private static string get_sql_count (string db_id) { -+ return (SQL_COUNT_TEMPLATE.printf (db_id)); -+ } -+ private static string get_sql_added (string db_id) { -+ return (SQL_ADDED_TEMPLATE.printf (db_id)); -+ } -+ private static string get_sql_removed (string db_id) { -+ return (SQL_REMOVED_TEMPLATE.printf (db_id)); -+ } -+ -+ protected override string get_sql_all_with_filter (string filter) { -+ if (filter.length == 0) { -+ return this.sql_all; -+ } -+ var filter_str = "%s AND %s".printf (this.db_id, filter); -+ return (SQL_ALL_TEMPLATE.printf (filter_str)); -+ } -+ -+ protected override string get_sql_count_with_filter (string filter) { -+ if (filter.length == 0) { -+ return this.sql_count; -+ } -+ var filter_str = "%s AND %s".printf (this.db_id, filter); -+ return (SQL_COUNT_WITH_FILTER_TEMPLATE.printf (filter_str)); -+ } -+ -+ public Album (string db_id, -+ MediaContainer parent, -+ string title, -+ LMS.Database lms_db) { -+ base (db_id, -+ parent, -+ title, -+ lms_db, -+ get_sql_all (db_id), -+ get_sql_find_object (db_id), -+ get_sql_count (db_id), -+ get_sql_added (db_id), -+ get_sql_removed (db_id) -+ ); -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-albums.vala b/src/plugins/lms/rygel-lms-albums.vala -new file mode 100644 -index 0000000..309a352 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-albums.vala -@@ -0,0 +1,175 @@ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+using Sqlite; -+ -+public class Rygel.LMS.Albums : Rygel.LMS.CategoryContainer { -+ private static const string SQL_ALL = -+ "SELECT audio_albums.id, audio_albums.name as title, " + -+ "audio_artists.name as artist " + -+ "FROM audio_albums " + -+ "LEFT JOIN audio_artists " + -+ "ON audio_albums.artist_id = audio_artists.id " + -+ "LIMIT ? OFFSET ?;"; -+ -+ private static const string SQL_ALL_WITH_FILTER_TEMPLATE = -+ "SELECT audio_albums.id, audio_albums.name as title, " + -+ "audio_artists.name as artist " + -+ "FROM audio_albums " + -+ "LEFT JOIN audio_artists " + -+ "ON audio_albums.artist_id = audio_artists.id " + -+ "WHERE %s " + -+ "LIMIT ? OFFSET ?;"; -+ -+ private static const string SQL_COUNT = -+ "SELECT COUNT(audio_albums.id) " + -+ "FROM audio_albums;"; -+ -+ private static const string SQL_COUNT_WITH_FILTER_TEMPLATE = -+ "SELECT COUNT(audio_albums.id), audio_albums.name as title, " + -+ "audio_artists.name as artist " + -+ "FROM audio_albums " + -+ "LEFT JOIN audio_artists " + -+ "ON audio_albums.artist_id = audio_artists.id " + -+ "WHERE %s;"; -+ -+ /* count songs inside albums */ -+ private static const string SQL_CHILD_COUNT_WITH_FILTER_TEMPLATE = -+ "SELECT COUNT(audios.id), audios.title as title, " + -+ "audio_artists.name as artist " + -+ "FROM audios, files, audio_albums " + -+ "LEFT JOIN audio_artists " + -+ "ON audios.artist_id = audio_artists.id " + -+ "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = audio_albums.id %s;"; -+ -+ /* select songs inside albums */ -+ private static const string SQL_CHILD_ALL_WITH_FILTER_TEMPLATE = -+ "SELECT files.id, files.path, files.size, " + -+ "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + -+ "audio_artists.name as artist, " + -+ "audio_albums.name, audio_albums.id " + -+ "FROM audios, files, audio_albums " + -+ "LEFT JOIN audio_artists " + -+ "ON audios.artist_id = audio_artists.id " + -+ "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = audio_albums.id %s " + -+ "LIMIT ? OFFSET ?;"; -+ -+ -+ private static const string SQL_FIND_OBJECT = -+ "SELECT audio_albums.id, audio_albums.name " + -+ "FROM audio_albums " + -+ "WHERE audio_albums.id = ?;"; -+ -+ protected override string get_sql_all_with_filter (string filter) { -+ if (filter.length == 0) { -+ return Albums.SQL_ALL; -+ } -+ return (Albums.SQL_ALL_WITH_FILTER_TEMPLATE.printf (filter)); -+ } -+ -+ protected override string get_sql_count_with_filter (string filter) { -+ if (filter.length == 0) { -+ return Albums.SQL_COUNT; -+ } -+ return (Albums.SQL_COUNT_WITH_FILTER_TEMPLATE.printf (filter)); -+ } -+ -+ protected override uint get_child_count_with_filter (string where_filter, -+ ValueArray args) -+ { -+ -+ /* search the children (albums) as usual */ -+ var count = base.get_child_count_with_filter (where_filter, args); -+ -+ /* now search the album contents */ -+ var filter = ""; -+ if (where_filter.length > 0) { -+ filter = "AND %s".printf (where_filter); -+ } -+ var query = Albums.SQL_CHILD_COUNT_WITH_FILTER_TEMPLATE.printf (filter); -+ try { -+ var stmt = this.lms_db.prepare_and_init (query, args.values); -+ if (stmt.step () == Sqlite.ROW) { -+ count += stmt.column_int (0); -+ } -+ } catch (DatabaseError e) { -+ warning ("Query failed: %s", e.message); -+ } -+ -+ return count; -+ } -+ -+ protected override MediaObjects? get_children_with_filter (string where_filter, -+ ValueArray args, -+ string sort_criteria, -+ uint offset, -+ uint max_count) { -+ var children = base. get_children_with_filter (where_filter, -+ args, -+ sort_criteria, -+ offset, -+ max_count); -+ var filter = ""; -+ if (where_filter.length > 0) { -+ filter = "AND %s".printf (where_filter); -+ } -+ var query = Albums.SQL_CHILD_ALL_WITH_FILTER_TEMPLATE.printf (filter); -+ try { -+ var stmt = this.lms_db.prepare_and_init (query, args.values); -+ while (Database.get_children_step (stmt)) { -+ var album_id = stmt.column_text (13); -+ var album = new Album (album_id, this, "", this.lms_db); -+ -+ var song = album.object_from_statement (stmt); -+ song.parent_ref = song.parent; -+ children.add (song); -+ -+ } -+ } catch (DatabaseError e) { -+ warning ("Query failed: %s", e.message); -+ } -+ -+ return children; -+ } -+ -+ protected override MediaObject? object_from_statement (Statement statement) { -+ var id = "%d".printf (statement.column_int (0)); -+ LMS.Album album = new LMS.Album (id, -+ this, -+ statement.column_text (1), -+ this.lms_db); -+ return album; -+ } -+ -+ public Albums (MediaContainer parent, -+ LMS.Database lms_db) { -+ base ("albums", -+ parent, -+ _("Albums"), -+ lms_db, -+ Albums.SQL_ALL, -+ Albums.SQL_FIND_OBJECT, -+ Albums.SQL_COUNT, -+ null, null); -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-all-images.vala b/src/plugins/lms/rygel-lms-all-images.vala -new file mode 100644 -index 0000000..0b54c7f ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-all-images.vala -@@ -0,0 +1,95 @@ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+using Sqlite; -+ -+public class Rygel.LMS.AllImages : Rygel.LMS.CategoryContainer { -+ private static const string SQL_ALL = -+ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime " + -+ "FROM images, files " + -+ "WHERE dtime = 0 AND images.id = files.id " + -+ "LIMIT ? OFFSET ?;"; -+ -+ private static const string SQL_COUNT = -+ "SELECT count(images.id) " + -+ "FROM images, files " + -+ "WHERE dtime = 0 AND images.id = files.id;"; -+ -+ private static const string SQL_FIND_OBJECT = -+ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime " + -+ "FROM images, files " + -+ "WHERE dtime = 0 AND files.id = ? AND images.id = files.id;"; -+ -+ private static const string SQL_ADDED = -+ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime " + -+ "FROM images, files " + -+ "WHERE dtime = 0 AND images.id = files.id " + -+ "AND update_id > ? AND update_id <= ?;"; -+ -+ private static const string SQL_REMOVED = -+ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime " + -+ "FROM images, files " + -+ "WHERE dtime <> 0 AND images.id = files.id " + -+ "AND update_id > ? AND update_id <= ?;"; -+ -+ protected override MediaObject? object_from_statement (Statement statement) { -+ var id = statement.column_int(0); -+ var path = statement.column_text(6); -+ var mime_type = statement.column_text(9); -+ -+ if (mime_type == null || mime_type.length == 0){ -+ /* TODO is this correct? */ -+ debug ("Image item %d (%s) has no MIME type", -+ id, -+ path); -+ } -+ -+ var title = statement.column_text(1); -+ var image = new ImageItem(this.build_child_id (id), this, title); -+ image.creator = statement.column_text(2); -+ TimeVal tv = { (long) statement.column_int(3), (long) 0 }; -+ image.date = tv.to_iso8601 (); -+ image.width = statement.column_int(4); -+ image.height = statement.column_int(5); -+ image.size = statement.column_int(7); -+ image.mime_type = mime_type; -+ image.dlna_profile = statement.column_text(8); -+ File file = File.new_for_path(path); -+ image.add_uri (file.get_uri ()); -+ -+ return image; -+ } -+ -+ public AllImages (MediaContainer parent, LMS.Database lms_db) { -+ base ("all", -+ parent, -+ _("All"), -+ lms_db, -+ AllImages.SQL_ALL, -+ AllImages.SQL_FIND_OBJECT, -+ AllImages.SQL_COUNT, -+ AllImages.SQL_ADDED, -+ AllImages.SQL_REMOVED -+ ); -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-all-music.vala b/src/plugins/lms/rygel-lms-all-music.vala -new file mode 100644 -index 0000000..2a7226f ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-all-music.vala -@@ -0,0 +1,169 @@ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+using Sqlite; -+ -+public class Rygel.LMS.AllMusic : Rygel.LMS.CategoryContainer { -+ private static const string SQL_ALL_TEMPLATE = -+ "SELECT files.id, files.path, files.size, " + -+ "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + -+ "audio_artists.name as artist, " + -+ "audio_albums.name, " + -+ "files.mtime, " + -+ "audio_genres.name " + -+ "FROM audios, files " + -+ "LEFT JOIN audio_artists " + -+ "ON audios.artist_id = audio_artists.id " + -+ "LEFT JOIN audio_albums " + -+ "ON audios.album_id = audio_albums.id " + -+ "LEFT JOIN audio_genres " + -+ "ON audios.genre_id = audio_genres.id " + -+ "WHERE dtime = 0 AND audios.id = files.id %s " + -+ "LIMIT ? OFFSET ?;"; -+ -+ private static const string SQL_COUNT = -+ "SELECT COUNT(audios.id) " + -+ "FROM audios, files " + -+ "WHERE dtime = 0 AND audios.id = files.id;"; -+ -+ private static const string SQL_COUNT_WITH_FILTER_TEMPLATE = -+ "SELECT COUNT(audios.id), audios.title as title, " + -+ "audio_artists.name as artist " + -+ "FROM audios, files " + -+ "LEFT JOIN audio_artists " + -+ "ON audios.artist_id = audio_artists.id " + -+ "WHERE dtime = 0 AND audios.id = files.id %s;"; -+ -+ private static const string SQL_FIND_OBJECT = -+ "SELECT files.id, files.path, files.size, " + -+ "audios.title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + -+ "audio_artists.name, " + -+ "audio_albums.name, " + -+ "files.mtime, " + -+ "audio_genres.name " + -+ "FROM audios, files " + -+ "LEFT JOIN audio_artists " + -+ "ON audios.artist_id = audio_artists.id " + -+ "LEFT JOIN audio_albums " + -+ "ON audios.album_id = audio_albums.id " + -+ "LEFT JOIN audio_genres " + -+ "ON audios.genre_id = audio_genres.id " + -+ "WHERE dtime = 0 AND files.id = ? AND audios.id = files.id;"; -+ -+ private static const string SQL_ADDED = -+ "SELECT files.id, files.path, files.size, " + -+ "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + -+ "audio_artists.name as artist, " + -+ "audio_albums.name, " + -+ "files.mtime, " + -+ "audio_genres.name " + -+ "FROM audios, files " + -+ "LEFT JOIN audio_artists " + -+ "ON audios.artist_id = audio_artists.id " + -+ "LEFT JOIN audio_albums " + -+ "ON audios.album_id = audio_albums.id " + -+ "LEFT JOIN audio_genres " + -+ "ON audios.genre_id = audio_genres.id " + -+ "WHERE dtime = 0 AND audios.id = files.id " + -+ "AND update_id > ? AND update_id <= ?;"; -+ -+ private static const string SQL_REMOVED = -+ "SELECT files.id, files.path, files.size, " + -+ "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + -+ "audio_artists.name as artist, " + -+ "audio_albums.name, " + -+ "files.mtime, " + -+ "audio_genres.name " + -+ "FROM audios, files " + -+ "LEFT JOIN audio_artists " + -+ "ON audios.artist_id = audio_artists.id " + -+ "LEFT JOIN audio_albums " + -+ "ON audios.album_id = audio_albums.id " + -+ "LEFT JOIN audio_genres " + -+ "ON audios.genre_id = audio_genres.id " + -+ "WHERE dtime <> 0 AND audios.id = files.id " + -+ "AND update_id > ? AND update_id <= ?;"; -+ -+ protected override string get_sql_all_with_filter (string filter) { -+ if (filter.length == 0) { -+ return this.sql_all; -+ } -+ var filter_str = "AND %s".printf (filter); -+ return (AllMusic.SQL_ALL_TEMPLATE.printf (filter_str)); -+ } -+ -+ protected override string get_sql_count_with_filter (string filter) { -+ if (filter.length == 0) { -+ return this.sql_count; -+ } -+ var filter_str = "AND %s".printf (filter); -+ return (AllMusic.SQL_COUNT_WITH_FILTER_TEMPLATE.printf (filter_str)); -+ } -+ -+ protected override MediaObject? object_from_statement (Statement statement) { -+ var id = statement.column_int (0); -+ var path = statement.column_text (1); -+ var mime_type = statement.column_text(10); -+ -+ if (mime_type == null || mime_type.length == 0) { -+ /* TODO is this correct? */ -+ debug ("Music item %d (%s) has no MIME type", -+ id, -+ path); -+ } -+ -+ var title = statement.column_text(3); -+ var song_id = this.build_child_id (id); -+ var song = new MusicItem (song_id, this, title); -+ song.size = statement.column_int(2); -+ song.track_number = statement.column_int(4); -+ song.duration = statement.column_int(5); -+ song.channels = statement.column_int(6); -+ song.sample_freq = statement.column_int(7); -+ song.bitrate = statement.column_int(8); -+ song.dlna_profile = statement.column_text(9); -+ song.mime_type = mime_type; -+ song.artist = statement.column_text(11); -+ song.album = statement.column_text(12); -+ TimeVal tv = { (long) statement.column_int(13), (long) 0 }; -+ song.date = tv.to_iso8601 (); -+ song.genre = statement.column_text(14); -+ File file = File.new_for_path (path); -+ song.add_uri (file.get_uri ()); -+ -+ return song; -+ } -+ -+ public AllMusic (MediaContainer parent, LMS.Database lms_db) { -+ base("all", -+ parent, -+ _("All"), -+ lms_db, -+ AllMusic.SQL_ALL_TEMPLATE.printf (""), -+ AllMusic.SQL_FIND_OBJECT, -+ AllMusic.SQL_COUNT, -+ AllMusic.SQL_ADDED, -+ AllMusic.SQL_REMOVED -+ ); -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-all-videos.vala b/src/plugins/lms/rygel-lms-all-videos.vala -new file mode 100644 -index 0000000..dbde0db ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-all-videos.vala -@@ -0,0 +1,123 @@ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+using Sqlite; -+ -+public class Rygel.LMS.AllVideos : Rygel.LMS.CategoryContainer { -+ private static const string SQL_ALL = -+ "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profile, dlna_mime " + -+ "FROM videos, files " + -+ "WHERE dtime = 0 AND videos.id = files.id " + -+ "LIMIT ? OFFSET ?;"; -+ -+ private static const string SQL_COUNT = -+ "SELECT count(videos.id) " + -+ "FROM videos, files " + -+ "WHERE dtime = 0 AND videos.id = files.id;"; -+ -+ private static const string SQL_FIND_OBJECT = -+ "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profile, dlna_mime " + -+ "FROM videos, files " + -+ "WHERE dtime = 0 AND files.id = ? AND videos.id = files.id;"; -+ -+ private static const string SQL_ADDED = -+ "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profile, dlna_mime " + -+ "FROM videos, files " + -+ "WHERE dtime = 0 AND videos.id = files.id " + -+ "AND update_id > ? AND update_id <= ?;"; -+ -+ private static const string SQL_REMOVED = -+ "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profile, dlna_mime " + -+ "FROM videos, files " + -+ "WHERE dtime <> 0 AND videos.id = files.id " + -+ "AND update_id > ? AND update_id <= ?;"; -+ -+ protected override MediaObject? object_from_statement (Statement statement) { -+ var id = statement.column_int(0); -+ var mime_type = statement.column_text(8); -+ var path = statement.column_text(4); -+ var file = File.new_for_path(path); -+ -+ /* TODO: Temporary code to extract the MIME TYPE. LMS does not seem -+ to compute the mime type of videos. Don't know why. */ -+ -+/* if (mime_type == null || mime_type.length == 0) { -+ try { -+ FileInfo info = file.query_info(FileAttribute.STANDARD_CONTENT_TYPE, -+ FileQueryInfoFlags.NONE, null); -+ mime_type = info.get_content_type(); -+ } catch {} -+ } -+*/ -+ -+ if (mime_type == null || mime_type.length == 0) { -+ /* TODO is this correct? */ -+ debug ("Video item %d (%s) has no MIME type", -+ id, -+ path); -+ } -+ -+ var title = statement.column_text(1); -+ var video = new VideoItem(this.build_child_id (id), this, title); -+ video.creator = statement.column_text(2); -+ video.duration = statement.column_int(3); -+ TimeVal tv = { (long) statement.column_int(5), (long) 0 }; -+ video.date = tv.to_iso8601 (); -+ video.size = statement.column_int(6); -+ video.dlna_profile = statement.column_text(7); -+ video.mime_type = mime_type; -+ video.add_uri (file.get_uri ()); -+ -+ // Rygel does not support multiple video and audio tracks in a single file, -+ // so we just take the first one -+ var video_data = "select videos_videos.bitrate + videos_audios.bitrate, width, height, channels, sampling_rate " + -+ "from videos, videos_audios, videos_videos where videos.id = ? " + -+ "and videos.id = videos_audios.video_id and videos.id = videos_videos.video_id;"; -+ try { -+ var stmt = this.lms_db.prepare(video_data); -+ Rygel.LMS.Database.find_object("%d".printf(id), stmt); -+ video.bitrate = stmt.column_int(0) / 8; //convert bits per second into bytes per second -+ video.width = stmt.column_int(1); -+ video.height = stmt.column_int(2); -+ video.channels = stmt.column_int(3); -+ video.sample_freq = stmt.column_int(4); -+ } catch (DatabaseError e) { -+ warning ("Query failed: %s", e.message); -+ } -+ -+ return video; -+ } -+ -+ public AllVideos (string id, MediaContainer parent, string title, LMS.Database lms_db){ -+ base (id, -+ parent, -+ title, -+ lms_db, -+ AllVideos.SQL_ALL, -+ AllVideos.SQL_FIND_OBJECT, -+ AllVideos.SQL_COUNT, -+ AllVideos.SQL_ADDED, -+ AllVideos.SQL_REMOVED -+ ); -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-artist.vala b/src/plugins/lms/rygel-lms-artist.vala -new file mode 100644 -index 0000000..31e9070 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-artist.vala -@@ -0,0 +1,75 @@ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+using Sqlite; -+ -+public class Rygel.LMS.Artist : Rygel.LMS.CategoryContainer { -+ private static const string SQL_ALL_TEMPLATE = -+ "SELECT audio_albums.id, audio_albums.name " + -+ "FROM audio_albums " + -+ "WHERE audio_albums.artist_id = %s " + -+ "LIMIT ? OFFSET ?;"; -+ -+ private static const string SQL_COUNT_TEMPLATE = -+ "SELECT COUNT(audio_albums.id) " + -+ "FROM audio_albums " + -+ "WHERE audio_albums.artist_id = %s"; -+ -+ private static const string SQL_FIND_OBJECT_TEMPLATE = -+ "SELECT audio_albums.id, audio_albums.name " + -+ "FROM audio_albums " + -+ "WHERE audio_albums.id = ? AND audio_albums.artist_id = %s;"; -+ -+ private static string get_sql_all (string id) { -+ return (SQL_ALL_TEMPLATE.printf (id)); -+ } -+ private static string get_sql_find_object (string id) { -+ return (SQL_FIND_OBJECT_TEMPLATE.printf (id)); -+ } -+ private static string get_sql_count (string id) { -+ return (SQL_COUNT_TEMPLATE.printf (id)); -+ } -+ -+ protected override MediaObject? object_from_statement (Statement statement) { -+ var db_id = "%d".printf (statement.column_int (0)); -+ var title = statement.column_text (1); -+ return new LMS.Album (db_id, this, title, this.lms_db); -+ } -+ -+ public Artist (string id, -+ MediaContainer parent, -+ string title, -+ LMS.Database lms_db) { -+ -+ base (id, -+ parent, -+ title, -+ lms_db, -+ get_sql_all (id), -+ get_sql_find_object (id), -+ get_sql_count (id), -+ null, // LMS does not track adding or removing albums -+ null -+ ); -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-artists.vala b/src/plugins/lms/rygel-lms-artists.vala -new file mode 100644 -index 0000000..a00b2ce ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-artists.vala -@@ -0,0 +1,62 @@ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+using Sqlite; -+ -+public class Rygel.LMS.Artists : Rygel.LMS.CategoryContainer { -+ private static const string SQL_ALL = -+ "SELECT audio_artists.id, audio_artists.name " + -+ "FROM audio_artists " + -+ "LIMIT ? OFFSET ?;"; -+ -+ private static const string SQL_COUNT = -+ "SELECT COUNT(audio_artists.id) " + -+ "FROM audio_artists;"; -+ -+ private static const string SQL_FIND_OBJECT = -+ "SELECT audio_artists.id, audio_artists.name " + -+ "FROM audio_artists " + -+ "WHERE audio_artists.id = ?;"; -+ -+ protected override MediaObject? object_from_statement (Statement statement) { -+ var db_id = "%d".printf (statement.column_int (0)); -+ var title = statement.column_text (1); -+ -+ return new LMS.Artist (db_id, this, title, this.lms_db); -+ } -+ -+ public Artists (string id, -+ MediaContainer parent, -+ string title, -+ LMS.Database lms_db) { -+ base (id, -+ parent, -+ title, -+ lms_db, -+ Artists.SQL_ALL, -+ Artists.SQL_FIND_OBJECT, -+ Artists.SQL_COUNT, -+ null, null -+ ); -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-category-container.vala b/src/plugins/lms/rygel-lms-category-container.vala -new file mode 100644 -index 0000000..e5430d1 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-category-container.vala -@@ -0,0 +1,428 @@ -+/* -+ * Copyright (C) 2009,2010 Jens Georg <mail@jensge.org>, -+ * (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+using Gee; -+using Sqlite; -+ -+public errordomain Rygel.LMS.CategoryContainerError { -+ SQLITE_ERROR, -+ GENERAL_ERROR, -+ INVALID_TYPE, -+ UNSUPPORTED_SEARCH -+} -+ -+public abstract class Rygel.LMS.CategoryContainer : Rygel.MediaContainer, -+ Rygel.TrackableContainer, -+ Rygel.SearchableContainer { -+ public ArrayList<string> search_classes { get; set; } -+ -+ public unowned LMS.Database lms_db { get; construct; } -+ -+ public string db_id { get; construct; } -+ -+ public string sql_all { get; construct; } -+ public string sql_find_object { get; construct; } -+ public string sql_count { get; construct; } -+ public string sql_added { get; construct; } -+ public string sql_removed { get; construct; } -+ -+ protected Statement stmt_all; -+ protected Statement stmt_find_object; -+ protected Statement stmt_added; -+ protected Statement stmt_removed; -+ -+ protected string child_prefix; -+ protected string ref_prefix; -+ -+ protected abstract MediaObject? object_from_statement (Statement statement); -+ -+ /* TODO these should be abstract */ -+ protected virtual string get_sql_all_with_filter (string filter) { -+ return this.sql_all; -+ } -+ protected virtual string get_sql_count_with_filter (string filter) { -+ return this.sql_count; -+ } -+ -+ private static string? map_operand_to_column (string operand, -+ out string? collate = null, -+ bool for_sort = false) -+ throws Error { -+ string column = null; -+ bool use_collation = false; -+ -+ // TODO add all used aliases to sql queries -+ switch (operand) { -+ case "dc:title": -+ column = "title"; -+ use_collation = true; -+ break; -+ case "upnp:artist": -+ column = "artist"; -+ use_collation = true; -+ break; -+ case "dc:creator": -+ column = "creator"; -+ use_collation = true; -+ break; -+ default: -+ var message = "Unsupported column %s".printf (operand); -+ -+ throw new CategoryContainerError.UNSUPPORTED_SEARCH (message); -+ } -+ -+ if (use_collation) { -+ collate = "COLLATE CASEFOLD"; -+ } else { -+ collate = ""; -+ } -+ -+ return column; -+ } -+ -+ private static string? relational_expression_to_sql -+ (RelationalExpression exp, -+ GLib.ValueArray args) -+ throws Error { -+ GLib.Value? v = null; -+ string collate = null; -+ -+ string column = CategoryContainer.map_operand_to_column (exp.operand1, -+ out collate); -+ SqlOperator operator; -+ -+ switch (exp.op) { -+ case GUPnP.SearchCriteriaOp.EXISTS: -+ string sql_function; -+ if (exp.operand2 == "true") { -+ sql_function = "%s IS NOT NULL AND %s != ''"; -+ } else { -+ sql_function = "%s IS NULL OR %s = ''"; -+ } -+ -+ return sql_function.printf (column, column); -+ case GUPnP.SearchCriteriaOp.EQ: -+ case GUPnP.SearchCriteriaOp.NEQ: -+ case GUPnP.SearchCriteriaOp.LESS: -+ case GUPnP.SearchCriteriaOp.LEQ: -+ case GUPnP.SearchCriteriaOp.GREATER: -+ case GUPnP.SearchCriteriaOp.GEQ: -+ v = exp.operand2; -+ operator = new SqlOperator.from_search_criteria_op -+ (exp.op, column, collate); -+ break; -+ case GUPnP.SearchCriteriaOp.CONTAINS: -+ operator = new SqlFunction ("contains", column); -+ v = exp.operand2; -+ break; -+ case GUPnP.SearchCriteriaOp.DOES_NOT_CONTAIN: -+ operator = new SqlFunction ("NOT contains", column); -+ v = exp.operand2; -+ break; -+ case GUPnP.SearchCriteriaOp.DERIVED_FROM: -+ operator = new SqlOperator ("LIKE", column); -+ v = "%s%%".printf (exp.operand2); -+ break; -+ default: -+ warning ("Unsupported op %d", exp.op); -+ return null; -+ } -+ -+ if (v != null) { -+ args.append (v); -+ } -+ -+ return operator.to_string (); -+ } -+ -+ private static string logical_expression_to_sql -+ (LogicalExpression expression, -+ GLib.ValueArray args) -+ throws Error { -+ string left_sql_string = CategoryContainer.search_expression_to_sql -+ (expression.operand1, -+ args); -+ string right_sql_string = CategoryContainer.search_expression_to_sql -+ (expression.operand2, -+ args); -+ unowned string operator_sql_string = "OR"; -+ -+ if (expression.op == LogicalOperator.AND) { -+ operator_sql_string = "AND"; -+ } -+ -+ return "(%s %s %s)".printf (left_sql_string, -+ operator_sql_string, -+ right_sql_string); -+ } -+ -+ private static string? search_expression_to_sql -+ (SearchExpression? expression, -+ GLib.ValueArray args) -+ throws Error { -+ if (expression == null) { -+ return ""; -+ } -+ -+ if (expression is LogicalExpression) { -+ return CategoryContainer.logical_expression_to_sql -+ (expression as LogicalExpression, args); -+ } else { -+ return CategoryContainer.relational_expression_to_sql -+ (expression as RelationalExpression, -+ args); -+ } -+ } -+ -+ protected virtual uint get_child_count_with_filter (string where_filter, -+ ValueArray args) -+ { -+ var query = this.get_sql_count_with_filter (where_filter); -+ try { -+ var stmt = this.lms_db.prepare_and_init (query, args.values); -+ if (stmt.step () != Sqlite.ROW) { -+ return 0; -+ } -+ return stmt.column_int (0); -+ } catch (DatabaseError e) { -+ warning ("Query failed: %s", e.message); -+ return 0; -+ } -+ } -+ -+ protected virtual MediaObjects? get_children_with_filter (string where_filter, -+ ValueArray args, -+ string sort_criteria, -+ uint offset, -+ uint max_count) { -+ var children = new MediaObjects (); -+ GLib.Value v = max_count; -+ args.append (v); -+ v = offset; -+ args.append (v); -+ -+ var query = this.get_sql_all_with_filter (where_filter); -+ try { -+ var stmt = this.lms_db.prepare_and_init (query, args.values); -+ while (Database.get_children_step (stmt)) { -+ children.add (this.object_from_statement (stmt)); -+ } -+ } catch (DatabaseError e) { -+ warning ("Query failed: %s", e.message); -+ } -+ -+ return children; -+ } -+ -+ public async MediaObjects? search (SearchExpression? expression, -+ uint offset, -+ uint max_count, -+ out uint total_matches, -+ string sort_criteria, -+ Cancellable? cancellable) -+ throws Error { -+ debug ("search()"); -+ try { -+ var args = new GLib.ValueArray (0); -+ var filter = CategoryContainer.search_expression_to_sql (expression, -+ args); -+ total_matches = this.get_child_count_with_filter (filter, args); -+ -+ if (expression != null) { -+ debug (" Original search: %s", expression.to_string ()); -+ debug (" Parsed search expression: %s", filter); -+ debug (" Filtered cild count is %u", total_matches); -+ } -+ -+ if (max_count == 0) { -+ max_count = uint.MAX; -+ } -+ return this.get_children_with_filter (filter, -+ args, -+ sort_criteria, -+ offset, -+ max_count); -+ } catch (Error e) { -+ debug (" Falling back to simple_search(): %s", e.message); -+ return yield this.simple_search (expression, -+ offset, -+ max_count, -+ out total_matches, -+ sort_criteria, -+ cancellable); -+ } -+ } -+ -+ public async override MediaObjects? get_children (uint offset, -+ uint max_count, -+ string sort_criteria, -+ Cancellable? cancellable) -+ throws Error { -+ MediaObjects retval = new MediaObjects (); -+ -+ Database.get_children_init (this.stmt_all, -+ offset, -+ max_count, -+ sort_criteria); -+ while (Database.get_children_step (this.stmt_all)) { -+ retval.add (this.object_from_statement (this.stmt_all)); -+ } -+ -+ return retval; -+ } -+ -+ public async override MediaObject? find_object (string id, -+ Cancellable? cancellable) -+ throws Error { -+ if (!id.has_prefix (this.child_prefix)) { -+ /* can't match anything in this container */ -+ return null; -+ } -+ -+ MediaObject object = null; -+ -+ /* remove parent section from id */ -+ var real_id = id.substring (this.child_prefix.length); -+ /* remove grandchildren from id */ -+ var index = real_id.index_of_char (':'); -+ if (index > 0) { -+ real_id = real_id.slice (0, index); -+ } -+ -+ try { -+ Database.find_object (real_id, this.stmt_find_object); -+ var child = this.object_from_statement (this.stmt_find_object); -+ if (index < 0) { -+ object = child; -+ } else { -+ /* try grandchildren */ -+ var container = child as CategoryContainer; -+ object = yield container.find_object (id, cancellable); -+ -+ /* tell object to keep a reference to the parent -- -+ * otherwise parent is freed before object is serialized */ -+ object.parent_ref = object.parent; -+ } -+ } catch (DatabaseError e) { -+ debug ("find_object %s in %s: %s", id, this.id, e.message); -+ /* Happens e.g. if id is not an integer */ -+ } -+ -+ return object; -+ } -+ -+ protected string build_child_id (int db_id) { -+ return "%s%d".printf (this.child_prefix, db_id); -+ } -+ -+ protected string build_reference_id (int db_id) { -+ return "%s%d".printf (this.ref_prefix, db_id); -+ } -+ -+ protected async void add_child (MediaObject object) { -+ } -+ -+ protected async void remove_child (MediaObject object) { -+ } -+ -+ private void on_db_updated(uint64 old_id, uint64 new_id) { -+ try { -+ var stmt_count = this.lms_db.prepare (this.sql_count); -+ -+ if (stmt_count.step () == Sqlite.ROW) { -+ this.child_count = stmt_count.column_int (0); -+ } -+ -+ Database.get_children_with_update_id_init (this.stmt_added, -+ old_id, -+ new_id); -+ while (Database.get_children_step (this.stmt_added)) { -+ this.add_child_tracked.begin(this.object_from_statement (this.stmt_added)); -+ } -+ -+ Database.get_children_with_update_id_init (this.stmt_removed, -+ old_id, -+ new_id); -+ while (Database.get_children_step (this.stmt_removed)) { -+ this.remove_child_tracked.begin(this.object_from_statement (this.stmt_removed)); -+ } -+ -+ } catch (DatabaseError e) { -+ warning ("Can't perform container update: %s", e.message); -+ } -+ -+ } -+ -+ public CategoryContainer (string db_id, -+ MediaContainer parent, -+ string title, -+ LMS.Database lms_db, -+ string sql_all, -+ string sql_find_object, -+ string sql_count, -+ string? sql_added, -+ string? sql_removed -+ ) { -+ Object (id : "%s:%s".printf (parent.id, db_id), -+ db_id : db_id, -+ parent : parent, -+ title : title, -+ lms_db : lms_db, -+ sql_all : sql_all, -+ sql_find_object : sql_find_object, -+ sql_count : sql_count, -+ sql_added : sql_added, -+ sql_removed: sql_removed -+ ); -+ } -+ -+ construct { -+ this.search_classes = new ArrayList<string> (); -+ -+ this.child_prefix = "%s:".printf (this.id); -+ -+ var index = this.id.index_of_char (':'); -+ this.ref_prefix = this.id.slice (0, index) + ":all:"; -+ -+ try { -+ this.stmt_all = this.lms_db.prepare (this.sql_all); -+ this.stmt_find_object = this.lms_db.prepare (this.sql_find_object); -+ var stmt_count = this.lms_db.prepare (this.sql_count); -+ -+ if (stmt_count.step () == Sqlite.ROW) { -+ this.child_count = stmt_count.column_int (0); -+ } -+ // some container implementations don't have a reasonable way to provide -+ // id-based statements to fetch added or removed items -+ if (this.sql_added != null && this.sql_removed != null) { -+ this.stmt_added = this.lms_db.prepare (this.sql_added); -+ this.stmt_removed = this.lms_db.prepare (this.sql_removed); -+ lms_db.db_updated.connect(this.on_db_updated); -+ } -+ } catch (DatabaseError e) { -+ warning ("Container %s: %s", this.title, e.message); -+ } -+ -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-collate.c b/src/plugins/lms/rygel-lms-collate.c -new file mode 100644 -index 0000000..8eee80b ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-collate.c -@@ -0,0 +1,49 @@ -+/* -+ * Copyright (C) 2012 Jens Georg <mail@jensge.org>. -+ * -+ * Author: Jens Georg <mail@jensge.org> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+ -+#ifdef HAVE_UNISTRING -+# include <unistr.h> -+#endif -+ -+gint rygel_lms_utf8_collate_str (const char *a, gsize alen, -+ const char *b, gsize blen) -+{ -+ char *a_str, *b_str; -+ gint result; -+ -+ /* Make sure the passed strings are null terminated */ -+ a_str = g_strndup (a, alen); -+ b_str = g_strndup (b, blen); -+ -+#ifdef HAVE_UNISTRING -+ result = u8_strcoll (a_str, b_str); -+#else -+ return g_utf8_collate (a_str, b_str); -+#endif -+ -+ g_free (a_str); -+ g_free (b_str); -+ -+ return result; -+} -diff --git a/src/plugins/lms/rygel-lms-database.vala b/src/plugins/lms/rygel-lms-database.vala -new file mode 100644 -index 0000000..e898d66 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-database.vala -@@ -0,0 +1,294 @@ -+/* -+ * Copyright (C) 2009,2011 Jens Georg <mail@jensge.org>, -+ * (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+using Gee; -+using Sqlite; -+ -+public errordomain Rygel.LMS.DatabaseError { -+ OPEN, -+ PREPARE, -+ BIND, -+ STEP, -+ NOT_FOUND -+} -+ -+namespace Rygel.LMS { -+ extern static int utf8_collate_str (uint8[] a, uint8[] b); -+} -+ -+public class Rygel.LMS.Database { -+ -+ public signal void db_updated(uint64 old_update_id, uint64 new_update_id); -+ -+ private Sqlite.Database db; -+ private LMS.DBus lms_proxy; -+ private uint64 update_id; -+ -+ /** -+ * Function to implement the custom SQL function 'contains' -+ */ -+ private static void utf8_contains (Sqlite.Context context, -+ Sqlite.Value[] args) -+ requires (args.length == 2) { -+ if (args[0].to_text () == null || -+ args[1].to_text () == null) { -+ context.result_int (0); -+ -+ return; -+ } -+ -+ var pattern = Regex.escape_string (args[1].to_text ()); -+ if (Regex.match_simple (pattern, -+ args[0].to_text (), -+ RegexCompileFlags.CASELESS)) { -+ context.result_int (1); -+ } else { -+ context.result_int (0); -+ } -+ } -+ -+ /** -+ * Function to implement the custom SQLite collation 'CASEFOLD'. -+ * -+ * Uses utf8 case-fold to compare the strings. -+ */ -+ private static int utf8_collate (int alen, void* a, int blen, void* b) { -+ // unowned to prevent array copy -+ unowned uint8[] _a = (uint8[]) a; -+ _a.length = alen; -+ -+ unowned uint8[] _b = (uint8[]) b; -+ _b.length = blen; -+ -+ return LMS.utf8_collate_str (_a, _b); -+ } -+ -+ public Database () throws DatabaseError { -+ string db_path; -+ try { -+ lms_proxy = Bus.get_proxy_sync (BusType.SESSION, -+ "org.lightmediascanner", -+ "/org/lightmediascanner/Scanner1"); -+ db_path = lms_proxy.data_base_path; -+ debug ("Got db path %s from LMS over dbus", db_path); -+ update_id = lms_proxy.update_id; -+ debug ("Got updated id %lld from LMS over dbus", update_id); -+ lms_proxy.g_properties_changed.connect (this.on_lms_properties_changed); -+ -+ } catch (IOError e) { -+ warning("Couldn't get LMS Dbus proxy: %s", e.message); -+ db_path = Environment.get_user_config_dir() + -+ "/lightmediascannerd/db.sqlite3"; -+ debug ("Using default sqlite database location %s", db_path); -+ } -+ -+ Sqlite.Database.open (db_path, out this.db); -+ if (this.db.errcode () != Sqlite.OK) { -+ throw new DatabaseError.OPEN ("Failed to open '%s': %d", -+ db_path, -+ this.db.errcode () ); -+ } -+ -+ this.db.create_function ("contains", -+ 2, -+ Sqlite.UTF8, -+ null, -+ LMS.Database.utf8_contains, -+ null, -+ null); -+ -+ this.db.create_collation ("CASEFOLD", -+ Sqlite.UTF8, -+ LMS.Database.utf8_collate); -+ -+ } -+ -+ private void on_lms_properties_changed (DBusProxy lms_proxy, -+ Variant changed, -+ string[] invalidated) { -+ if (!changed.get_type().equal (VariantType.VARDICT)) { -+ return; -+ } -+ -+ foreach (var changed_prop in changed) { -+ var key = (string) changed_prop.get_child_value (0); -+ var value = changed_prop.get_child_value (1).get_child_value (0); -+ -+ debug ("LMS property %s changed value to %s", key, value.print(true)); -+ -+ switch (key) { -+ case "UpdateID": -+ db_updated(update_id, (uint64)value); -+ update_id = (uint64)value; -+ break; -+ } -+ } -+ } -+ -+ -+ public Statement prepare (string query_string) throws DatabaseError { -+ Statement statement; -+ -+ var err = this.db.prepare_v2 (query_string, -1, out statement); -+ if (err != Sqlite.OK) -+ throw new DatabaseError.PREPARE ("Unable to create statement '%s': %d", -+ query_string, -+ err); -+ return statement; -+ } -+ -+ -+ public Statement prepare_and_init (string query, -+ GLib.Value[]? arguments) -+ throws DatabaseError { -+ -+ Statement statement; -+ -+ var err = this.db.prepare_v2 (query, -1, out statement); -+ if (err != Sqlite.OK) -+ throw new DatabaseError.PREPARE ("Unable to create statement '%s': %d", -+ query, -+ err); -+ -+ for (var i = 1; i <= arguments.length; ++i) { -+ int sqlite_err; -+ unowned GLib.Value current_value = arguments[i - 1]; -+ -+ if (current_value.holds (typeof (int))) { -+ sqlite_err = statement.bind_int (i, current_value.get_int ()); -+ if (sqlite_err != Sqlite.OK) -+ throw new DatabaseError.BIND("Unable to bind value %d", -+ sqlite_err); -+ } else if (current_value.holds (typeof (int64))) { -+ sqlite_err = statement.bind_int64 (i, current_value.get_int64 ()); -+ if (sqlite_err != Sqlite.OK) -+ throw new DatabaseError.BIND("Unable to bind value %d", -+ sqlite_err); -+ } else if (current_value.holds (typeof (uint64))) { -+ sqlite_err = statement.bind_int64 (i, (int64) current_value.get_uint64 ()); -+ if (sqlite_err != Sqlite.OK) -+ throw new DatabaseError.BIND("Unable to bind value %d", -+ sqlite_err); -+ } else if (current_value.holds (typeof (long))) { -+ sqlite_err = statement.bind_int64 (i, current_value.get_long ()); -+ if (sqlite_err != Sqlite.OK) -+ throw new DatabaseError.BIND("Unable to bind value %d", -+ sqlite_err); -+ } else if (current_value.holds (typeof (uint))) { -+ sqlite_err = statement.bind_int64 (i, current_value.get_uint ()); -+ if (sqlite_err != Sqlite.OK) -+ throw new DatabaseError.BIND("Unable to bind value %d", -+ sqlite_err); -+ } else if (current_value.holds (typeof (string))) { -+ sqlite_err = statement.bind_text (i, current_value.get_string ()); -+ if (sqlite_err != Sqlite.OK) -+ throw new DatabaseError.BIND("Unable to bind value %d", -+ sqlite_err); -+ } else if (current_value.holds (typeof (void *))) { -+ if (current_value.peek_pointer () == null) { -+ sqlite_err = statement.bind_null (i); -+ if (sqlite_err != Sqlite.OK) -+ throw new DatabaseError.BIND("Unable to bind value %d", -+ sqlite_err); -+ } else { -+ assert_not_reached (); -+ } -+ } else { -+ var type = current_value.type (); -+ warning (_("Unsupported type %s"), type.name ()); -+ assert_not_reached (); -+ } -+ } -+ -+ return statement; -+ } -+ -+ public static void find_object(string id, Statement stmt) throws DatabaseError { -+ -+ (void) stmt.reset(); -+ -+ int integer_id = int.parse(id); -+ int sqlite_err = stmt.bind_int(1, integer_id); -+ if (sqlite_err != Sqlite.OK) -+ throw new DatabaseError.BIND("Unable to bind id %d", sqlite_err); -+ -+ sqlite_err = stmt.step(); -+ if (sqlite_err != Sqlite.ROW) -+ throw new DatabaseError.STEP("Unable to find id %s", id); -+ } -+ -+ public static void get_children_init (Statement stmt, -+ uint offset, uint max_count, string sort_criteria) throws DatabaseError { -+ -+ int sqlite_err; -+ -+ (void) stmt.reset(); -+ -+ sqlite_err = stmt.bind_int(1, (int) max_count); -+ if (sqlite_err != Sqlite.OK) -+ throw new DatabaseError.BIND("Unable to bind max_count %d", -+ sqlite_err); -+ -+ sqlite_err = stmt.bind_int(2, (int) offset); -+ if (sqlite_err != Sqlite.OK) -+ throw new DatabaseError.BIND("Unable to bind offset %d", -+ sqlite_err); -+ } -+ -+ public static void get_children_with_update_id_init (Statement stmt, -+ uint64 old_id, uint64 new_id) throws DatabaseError { -+ -+ int sqlite_err; -+ -+ (void) stmt.reset(); -+ -+ if (new_id < old_id) // id value wrapped over -+ sqlite_err = stmt.bind_int64(1, 0); -+ else -+ sqlite_err = stmt.bind_int64(1, (int64)old_id); -+ if (sqlite_err != Sqlite.OK) -+ throw new DatabaseError.BIND("Unable to bind old_id %d", -+ sqlite_err); -+ -+ sqlite_err = stmt.bind_int64(2, (int64)new_id); -+ if (sqlite_err != Sqlite.OK) -+ throw new DatabaseError.BIND("Unable to bind new_id %d", -+ sqlite_err); -+ } -+ -+ public static bool get_children_step(Statement stmt) throws DatabaseError { -+ -+ bool retval; -+ int sqlite_err; -+ -+ sqlite_err = stmt.step(); -+ retval = sqlite_err == Sqlite.ROW; -+ -+ if (!retval && (sqlite_err != Sqlite.DONE)) -+ throw new DatabaseError.STEP("Error iterating through rows %d", -+ sqlite_err); -+ -+ return retval; -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-dbus-interfaces.vala b/src/plugins/lms/rygel-lms-dbus-interfaces.vala -new file mode 100644 -index 0000000..13f00cb ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-dbus-interfaces.vala -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (C) 2014 Intel Corporation. -+ * -+ * Author: Alexander Kanavin <alex.kanavin@gmail.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+[DBus (name = "org.lightmediascanner.Scanner1")] -+interface Rygel.LMS.DBus : DBusProxy { -+ public abstract string data_base_path { owned get; } -+ [DBus (name = "UpdateID")] -+ public abstract uint64 update_id { get; } -+ -+ //TODO: add all the other API items which are currently unused -+} -\ No newline at end of file -diff --git a/src/plugins/lms/rygel-lms-image-root.vala b/src/plugins/lms/rygel-lms-image-root.vala -new file mode 100644 -index 0000000..466bbe2 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-image-root.vala -@@ -0,0 +1,35 @@ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+ -+public class Rygel.LMS.ImageRoot : Rygel.SimpleContainer { -+ public ImageRoot (string id, -+ MediaContainer parent, -+ string title, -+ LMS.Database lms_db) { -+ base (id, parent, title); -+ -+ this.add_child_container (new AllImages (this, lms_db)); -+ this.add_child_container (new ImageYears (this, lms_db)); -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-image-year.vala b/src/plugins/lms/rygel-lms-image-year.vala -new file mode 100644 -index 0000000..a7768f0 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-image-year.vala -@@ -0,0 +1,114 @@ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+using Sqlite; -+ -+public class Rygel.LMS.ImageYear : Rygel.LMS.CategoryContainer { -+ private static const string SQL_ALL_TEMPLATE = -+ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " + -+ "FROM images, files " + -+ "WHERE dtime = 0 AND images.id = files.id AND year = '%s' " + -+ "LIMIT ? OFFSET ?;"; -+ -+ private static const string SQL_COUNT_TEMPLATE = -+ "SELECT count(images.id), strftime('%Y', date, 'unixepoch') as year " + -+ "FROM images, files " + -+ "WHERE dtime = 0 AND images.id = files.id AND year = '%s';"; -+ -+ private static const string SQL_FIND_OBJECT_TEMPLATE = -+ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " + -+ "FROM images, files " + -+ "WHERE dtime = 0 AND files.id = ? AND images.id = files.id AND year = '%s';"; -+ -+ private static const string SQL_ADDED_TEMPLATE = -+ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " + -+ "FROM images, files " + -+ "WHERE dtime = 0 AND images.id = files.id AND year = '%s' " + -+ "AND update_id > ? AND update_id <= ?;"; -+ -+ private static const string SQL_REMOVED_TEMPLATE = -+ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " + -+ "FROM images, files " + -+ "WHERE dtime <> 0 AND images.id = files.id AND year = '%s' " + -+ "AND update_id > ? AND update_id <= ?;"; -+ -+ protected override MediaObject? object_from_statement (Statement statement) { -+ var id = statement.column_int(0); -+ var path = statement.column_text(6); -+ var mime_type = statement.column_text(9); -+ -+ if (mime_type == null || mime_type.length == 0){ -+ /* TODO is this correct? */ -+ debug ("Image item %d (%s) has no MIME type", -+ id, -+ path); -+ } -+ -+ var title = statement.column_text(1); -+ var image = new ImageItem(this.build_child_id (id), this, title); -+ image.ref_id = this.build_reference_id (id); -+ image.creator = statement.column_text(2); -+ TimeVal tv = { (long) statement.column_int(3), (long) 0 }; -+ image.date = tv.to_iso8601 (); -+ image.width = statement.column_int(4); -+ image.height = statement.column_int(5); -+ image.size = statement.column_int(7); -+ image.mime_type = mime_type; -+ image.dlna_profile = statement.column_text(8); -+ File file = File.new_for_path(path); -+ image.add_uri (file.get_uri ()); -+ -+ return image; -+ } -+ -+ private static string get_sql_all (string year) { -+ return (SQL_ALL_TEMPLATE.printf (year)); -+ } -+ private static string get_sql_find_object (string year) { -+ return (SQL_FIND_OBJECT_TEMPLATE.printf (year)); -+ } -+ private static string get_sql_count (string year) { -+ return (SQL_COUNT_TEMPLATE.printf (year)); -+ } -+ private static string get_sql_added (string year) { -+ return (SQL_ADDED_TEMPLATE.printf (year)); -+ } -+ private static string get_sql_removed (string year) { -+ return (SQL_REMOVED_TEMPLATE.printf (year)); -+ } -+ -+ public ImageYear (MediaContainer parent, -+ string year, -+ LMS.Database lms_db) { -+ base ("%s".printf (year), -+ parent, -+ year, -+ lms_db, -+ get_sql_all (year), -+ get_sql_find_object (year), -+ get_sql_count (year), -+ get_sql_added (year), -+ get_sql_removed (year) -+ ); -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-image-years.vala b/src/plugins/lms/rygel-lms-image-years.vala -new file mode 100644 -index 0000000..636f4d1 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-image-years.vala -@@ -0,0 +1,59 @@ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+using Sqlite; -+ -+public class Rygel.LMS.ImageYears : Rygel.LMS.CategoryContainer { -+ private static const string SQL_ALL = -+ "SELECT DISTINCT(strftime('%Y', images.date, 'unixepoch')) as year " + -+ "FROM images " + -+ "LIMIT ? OFFSET ?;"; -+ -+ private static const string SQL_COUNT = -+ "SELECT COUNT(DISTINCT(strftime('%Y', images.date, 'unixepoch'))) " + -+ "FROM images;"; -+ -+ /* actually returns multiple times the same result (because no DISTINCT) */ -+ /* Casting the year is a workaround so we can keep using -+ * Database.find_object() without making the argument a variant or something like it*/ -+ private static const string SQL_FIND_OBJECT = -+ "SELECT strftime('%Y', images.date, 'unixepoch') as year " + -+ "FROM images " + -+ "WHERE year = CAST(? AS TEXT)"; -+ -+ protected override MediaObject? object_from_statement (Statement statement) { -+ return new LMS.ImageYear (this, statement.column_text (0), this.lms_db); -+ } -+ -+ public ImageYears (MediaContainer parent, LMS.Database lms_db) { -+ base ("years", -+ parent, -+ _("Years"), -+ lms_db, -+ ImageYears.SQL_ALL, -+ ImageYears.SQL_FIND_OBJECT, -+ ImageYears.SQL_COUNT, -+ null, null -+ ); -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-music-root.vala b/src/plugins/lms/rygel-lms-music-root.vala -new file mode 100644 -index 0000000..7b1eb0f ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-music-root.vala -@@ -0,0 +1,36 @@ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+ -+public class Rygel.LMS.MusicRoot : Rygel.SimpleContainer { -+ public MusicRoot (string id, -+ MediaContainer parent, -+ string title, -+ LMS.Database lms_db) { -+ base (id, parent, title); -+ -+ this.add_child_container (new AllMusic (this, lms_db)); -+ this.add_child_container (new Artists ("artists", this, _("Artists"), lms_db)); -+ this.add_child_container (new Albums (this, lms_db)); -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-plugin-factory.vala b/src/plugins/lms/rygel-lms-plugin-factory.vala -new file mode 100644 -index 0000000..9fa8ccd ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-plugin-factory.vala -@@ -0,0 +1,40 @@ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+ -+private Rygel.LMS.PluginFactory plugin_factory; -+ -+public void module_init(PluginLoader loader) { -+ plugin_factory = new Rygel.LMS.PluginFactory(loader); -+} -+ -+public class Rygel.LMS.PluginFactory { -+ -+ PluginLoader loader; -+ -+ public PluginFactory(PluginLoader loader) { -+ this.loader = loader; -+ this.loader.add_plugin(new LMS.Plugin()); -+ } -+ -+} -diff --git a/src/plugins/lms/rygel-lms-plugin.vala b/src/plugins/lms/rygel-lms-plugin.vala -new file mode 100644 -index 0000000..8bf1284 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-plugin.vala -@@ -0,0 +1,35 @@ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+ -+public class Rygel.LMS.Plugin : Rygel.MediaServerPlugin { -+ public const string NAME = "LMS"; -+ -+ private static RootContainer root; -+ -+ public Plugin() { -+ if (root == null) -+ root = new RootContainer(); -+ base(root, Plugin.NAME, null, PluginCapabilities.TRACK_CHANGES); -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-root-container.vala b/src/plugins/lms/rygel-lms-root-container.vala -new file mode 100644 -index 0000000..1623fa3 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-root-container.vala -@@ -0,0 +1,58 @@ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using Rygel; -+ -+using Sqlite; -+ -+public class Rygel.LMS.RootContainer : Rygel.SimpleContainer { -+ -+ private LMS.Database lms_db = null; -+ -+ public RootContainer() { -+ var config = MetaConfig.get_default (); -+ -+ var title = _("Shared media"); -+ try { -+ title = config.get_string ("LightMediaScanner", "title"); -+ } catch (GLib.Error error) {} -+ -+ base.root(title); -+ -+ try { -+ this.lms_db = new LMS.Database (); -+ -+ this.add_child_container (new MusicRoot ("music", this, _("Music"), this.lms_db)); -+ this.add_child_container (new AllVideos ("all-videos", this, _("Videos"), this.lms_db)); -+ this.add_child_container (new ImageRoot ("images", this, _("Pictures"), this.lms_db)); -+ -+ } catch (DatabaseError e) { -+ warning ("%s\n", e.message); -+ -+ /* TODO if db does not exist we should -+ wait for it to be created and then add folders. Best to wait for the -+ LMS notification API. */ -+ } -+ -+ } -+ -+} -diff --git a/src/plugins/lms/rygel-lms-sql-function.vala b/src/plugins/lms/rygel-lms-sql-function.vala -new file mode 100644 -index 0000000..e8580cc ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-sql-function.vala -@@ -0,0 +1,31 @@ -+/* -+ * Copyright (C) 2010 Jens Georg <mail@jensge.org>. -+ * -+ * Author: Jens Georg <mail@jensge.org> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+internal class Rygel.LMS.SqlFunction : SqlOperator { -+ public SqlFunction (string name, string arg) { -+ base (name, arg); -+ } -+ -+ public override string to_string () { -+ return "%s(%s,?)".printf (name, arg); -+ } -+} -diff --git a/src/plugins/lms/rygel-lms-sql-operator.vala b/src/plugins/lms/rygel-lms-sql-operator.vala -new file mode 100644 -index 0000000..fc4e907 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-sql-operator.vala -@@ -0,0 +1,73 @@ -+/* -+ * Copyright (C) 2010 Jens Georg <mail@jensge.org>. -+ * -+ * Author: Jens Georg <mail@jensge.org> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+using GUPnP; -+ -+internal class Rygel.LMS.SqlOperator : GLib.Object { -+ protected string name; -+ protected string arg; -+ protected string collate; -+ -+ public SqlOperator (string name, -+ string arg, -+ string collate = "") { -+ this.name = name; -+ this.arg = arg; -+ this.collate = collate; -+ } -+ -+ public SqlOperator.from_search_criteria_op (SearchCriteriaOp op, -+ string arg, -+ string collate) { -+ string sql = null; -+ switch (op) { -+ case SearchCriteriaOp.EQ: -+ sql = "="; -+ break; -+ case SearchCriteriaOp.NEQ: -+ sql = "!="; -+ break; -+ case SearchCriteriaOp.LESS: -+ sql = "<"; -+ break; -+ case SearchCriteriaOp.LEQ: -+ sql = "<="; -+ break; -+ case SearchCriteriaOp.GREATER: -+ sql = ">"; -+ break; -+ case SearchCriteriaOp.GEQ: -+ sql = ">="; -+ break; -+ default: -+ assert_not_reached (); -+ } -+ -+ this (sql, arg, collate); -+ } -+ -+ public virtual string to_string () { -+ return "(%s %s ? %s)".printf (arg, name, collate); -+ } -+} -+ -+ --- -1.7.10.4 - diff --git a/meta-agl/recipes-connectivity/rygel/files/0002-lms-add-C-source-files.patch b/meta-agl/recipes-connectivity/rygel/files/0002-lms-add-C-source-files.patch deleted file mode 100644 index bbd61aa27..000000000 --- a/meta-agl/recipes-connectivity/rygel/files/0002-lms-add-C-source-files.patch +++ /dev/null @@ -1,9455 +0,0 @@ -From 5a91b6b6efdaf28a6640126a32e819aef7e10a74 Mon Sep 17 00:00:00 2001 -From: Manuel Bachmann <manuel.bachmann@iot.bzh> -Date: Sun, 25 Oct 2015 14:21:28 +0100 -Subject: [PATCH] lms: add C source files - -C source files are normally generated by Vala at compile -time, but we do not use Vala for Rygel under OpenEmbedded -(because it requires GObject-Introspection support in -dependencies such as GUPnP, and that is still buggy). - -A full tarball release would contain the C files anyway, -so let us include them so the build succeeds with OE. - -Signed-off-by: Manuel Bachmann <manuel.bachmann@iot.bzh> ---- - src/plugins/lms/librygel_lms_la_vala.stamp | 1 + - src/plugins/lms/rygel-lms-album.c | 514 +++++ - src/plugins/lms/rygel-lms-albums.c | 569 +++++ - src/plugins/lms/rygel-lms-all-images.c | 305 +++ - src/plugins/lms/rygel-lms-all-music.c | 417 ++++ - src/plugins/lms/rygel-lms-all-videos.c | 456 ++++ - src/plugins/lms/rygel-lms-artist.c | 274 +++ - src/plugins/lms/rygel-lms-artists.c | 214 ++ - src/plugins/lms/rygel-lms-category-container.c | 2772 ++++++++++++++++++++++++ - src/plugins/lms/rygel-lms-database.c | 1349 ++++++++++++ - src/plugins/lms/rygel-lms-dbus-interfaces.c | 261 +++ - src/plugins/lms/rygel-lms-image-root.c | 178 ++ - src/plugins/lms/rygel-lms-image-year.c | 422 ++++ - src/plugins/lms/rygel-lms-image-years.c | 196 ++ - src/plugins/lms/rygel-lms-music-root.c | 202 ++ - src/plugins/lms/rygel-lms-plugin-factory.c | 307 +++ - src/plugins/lms/rygel-lms-plugin.c | 134 ++ - src/plugins/lms/rygel-lms-root-container.c | 318 +++ - src/plugins/lms/rygel-lms-sql-function.c | 146 ++ - src/plugins/lms/rygel-lms-sql-operator.c | 240 ++ - 21 files changed, 9276 insertions(+), 1 deletion(-) - create mode 100644 src/plugins/lms/librygel_lms_la_vala.stamp - create mode 100644 src/plugins/lms/rygel-lms-album.c - create mode 100644 src/plugins/lms/rygel-lms-albums.c - create mode 100644 src/plugins/lms/rygel-lms-all-images.c - create mode 100644 src/plugins/lms/rygel-lms-all-music.c - create mode 100644 src/plugins/lms/rygel-lms-all-videos.c - create mode 100644 src/plugins/lms/rygel-lms-artist.c - create mode 100644 src/plugins/lms/rygel-lms-artists.c - create mode 100644 src/plugins/lms/rygel-lms-category-container.c - create mode 100644 src/plugins/lms/rygel-lms-database.c - create mode 100644 src/plugins/lms/rygel-lms-dbus-interfaces.c - create mode 100644 src/plugins/lms/rygel-lms-image-root.c - create mode 100644 src/plugins/lms/rygel-lms-image-year.c - create mode 100644 src/plugins/lms/rygel-lms-image-years.c - create mode 100644 src/plugins/lms/rygel-lms-music-root.c - create mode 100644 src/plugins/lms/rygel-lms-plugin-factory.c - create mode 100644 src/plugins/lms/rygel-lms-plugin.c - create mode 100644 src/plugins/lms/rygel-lms-root-container.c - create mode 100644 src/plugins/lms/rygel-lms-sql-function.c - create mode 100644 src/plugins/lms/rygel-lms-sql-operator.c - -diff --git a/src/plugins/lms/librygel_lms_la_vala.stamp b/src/plugins/lms/librygel_lms_la_vala.stamp -new file mode 100644 -index 0000000..859afb1 ---- /dev/null -+++ b/src/plugins/lms/librygel_lms_la_vala.stamp -@@ -0,0 +1 @@ -+stamp -diff --git a/src/plugins/lms/rygel-lms-album.c b/src/plugins/lms/rygel-lms-album.c -new file mode 100644 -index 0000000..9da60bc ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-album.c -@@ -0,0 +1,514 @@ -+/* rygel-lms-album.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-album.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-server.h> -+#include <sqlite3.h> -+#include <stdlib.h> -+#include <string.h> -+#include <gio/gio.h> -+ -+ -+#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) -+#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+ -+typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; -+typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; -+typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; -+ -+#define RYGEL_LMS_TYPE_ALBUM (rygel_lms_album_get_type ()) -+#define RYGEL_LMS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbum)) -+#define RYGEL_LMS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass)) -+#define RYGEL_LMS_IS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUM)) -+#define RYGEL_LMS_IS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUM)) -+#define RYGEL_LMS_ALBUM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass)) -+ -+typedef struct _RygelLMSAlbum RygelLMSAlbum; -+typedef struct _RygelLMSAlbumClass RygelLMSAlbumClass; -+typedef struct _RygelLMSAlbumPrivate RygelLMSAlbumPrivate; -+#define _g_free0(var) (var = (g_free (var), NULL)) -+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) -+ -+#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) -+#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) -+#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+ -+typedef struct _RygelLMSDatabase RygelLMSDatabase; -+typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; -+ -+struct _RygelLMSCategoryContainer { -+ RygelMediaContainer parent_instance; -+ RygelLMSCategoryContainerPrivate * priv; -+ sqlite3_stmt* stmt_all; -+ sqlite3_stmt* stmt_find_object; -+ sqlite3_stmt* stmt_added; -+ sqlite3_stmt* stmt_removed; -+ gchar* child_prefix; -+ gchar* ref_prefix; -+}; -+ -+struct _RygelLMSCategoryContainerClass { -+ RygelMediaContainerClass parent_class; -+ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); -+ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); -+ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); -+}; -+ -+struct _RygelLMSAlbum { -+ RygelLMSCategoryContainer parent_instance; -+ RygelLMSAlbumPrivate * priv; -+}; -+ -+struct _RygelLMSAlbumClass { -+ RygelLMSCategoryContainerClass parent_class; -+}; -+ -+ -+static gpointer rygel_lms_album_parent_class = NULL; -+ -+GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; -+GType rygel_lms_album_get_type (void) G_GNUC_CONST; -+enum { -+ RYGEL_LMS_ALBUM_DUMMY_PROPERTY -+}; -+#define RYGEL_LMS_ALBUM_SQL_ALL_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \ -+" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \ -+"a_mime, " "audio_artists.name as artist, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s " "LIMIT ? OFFSET ?;" -+#define RYGEL_LMS_ALBUM_SQL_COUNT_TEMPLATE "SELECT COUNT(audios.id) " "FROM audios, files " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s;" -+#define RYGEL_LMS_ALBUM_SQL_COUNT_WITH_FILTER_TEMPLATE "SELECT COUNT(audios.id), audios.title as title, " "audio_artists.name as artist, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s;" -+#define RYGEL_LMS_ALBUM_SQL_FIND_OBJECT_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title, audios.trackno, audios.length, audios.channels, audios.s" \ -+"ampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " "audio_artists.name, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime = 0 AND files.id = ? AND audios.id = files.id AND audios.a" \ -+"lbum_id = %s;" -+#define RYGEL_LMS_ALBUM_SQL_ADDED_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \ -+" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \ -+"a_mime, " "audio_artists.name as artist, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s " "AND update_id > ? AND update_id <= ?;" -+#define RYGEL_LMS_ALBUM_SQL_REMOVED_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \ -+" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \ -+"a_mime, " "audio_artists.name as artist, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime <> 0 AND audios.id = files.id AND audios.album_id = %s " "AND update_id > ? AND update_id <= ?;" -+static RygelMediaObject* rygel_lms_album_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); -+gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id); -+gchar* rygel_lms_category_container_build_reference_id (RygelLMSCategoryContainer* self, gint db_id); -+static gchar* rygel_lms_album_get_sql_all (const gchar* db_id); -+static gchar* rygel_lms_album_get_sql_find_object (const gchar* db_id); -+static gchar* rygel_lms_album_get_sql_count (const gchar* db_id); -+static gchar* rygel_lms_album_get_sql_added (const gchar* db_id); -+static gchar* rygel_lms_album_get_sql_removed (const gchar* db_id); -+static gchar* rygel_lms_album_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter); -+const gchar* rygel_lms_category_container_get_sql_all (RygelLMSCategoryContainer* self); -+const gchar* rygel_lms_category_container_get_db_id (RygelLMSCategoryContainer* self); -+static gchar* rygel_lms_album_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter); -+const gchar* rygel_lms_category_container_get_sql_count (RygelLMSCategoryContainer* self); -+gpointer rygel_lms_database_ref (gpointer instance); -+void rygel_lms_database_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_database (GValue* value, gpointer v_object); -+void rygel_lms_value_take_database (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_database (const GValue* value); -+GType rygel_lms_database_get_type (void) G_GNUC_CONST; -+RygelLMSAlbum* rygel_lms_album_new (const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSAlbum* rygel_lms_album_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); -+ -+ -+static RygelMediaObject* rygel_lms_album_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { -+ RygelLMSAlbum * self; -+ RygelMediaObject* result = NULL; -+ gint id = 0; -+ sqlite3_stmt* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gchar* path = NULL; -+ sqlite3_stmt* _tmp2_ = NULL; -+ const gchar* _tmp3_ = NULL; -+ gchar* _tmp4_ = NULL; -+ gchar* mime_type = NULL; -+ sqlite3_stmt* _tmp5_ = NULL; -+ const gchar* _tmp6_ = NULL; -+ gchar* _tmp7_ = NULL; -+ gboolean _tmp8_ = FALSE; -+ const gchar* _tmp9_ = NULL; -+ gchar* title = NULL; -+ sqlite3_stmt* _tmp15_ = NULL; -+ const gchar* _tmp16_ = NULL; -+ gchar* _tmp17_ = NULL; -+ gchar* song_id = NULL; -+ gint _tmp18_ = 0; -+ gchar* _tmp19_ = NULL; -+ RygelMusicItem* song = NULL; -+ RygelMusicItem* _tmp20_ = NULL; -+ gint _tmp21_ = 0; -+ gchar* _tmp22_ = NULL; -+ gchar* _tmp23_ = NULL; -+ sqlite3_stmt* _tmp24_ = NULL; -+ gint _tmp25_ = 0; -+ sqlite3_stmt* _tmp26_ = NULL; -+ gint _tmp27_ = 0; -+ sqlite3_stmt* _tmp28_ = NULL; -+ gint _tmp29_ = 0; -+ sqlite3_stmt* _tmp30_ = NULL; -+ gint _tmp31_ = 0; -+ sqlite3_stmt* _tmp32_ = NULL; -+ gint _tmp33_ = 0; -+ sqlite3_stmt* _tmp34_ = NULL; -+ gint _tmp35_ = 0; -+ sqlite3_stmt* _tmp36_ = NULL; -+ const gchar* _tmp37_ = NULL; -+ const gchar* _tmp38_ = NULL; -+ sqlite3_stmt* _tmp39_ = NULL; -+ const gchar* _tmp40_ = NULL; -+ sqlite3_stmt* _tmp41_ = NULL; -+ const gchar* _tmp42_ = NULL; -+ GFile* file = NULL; -+ const gchar* _tmp43_ = NULL; -+ GFile* _tmp44_ = NULL; -+ gchar* _tmp45_ = NULL; -+ gchar* _tmp46_ = NULL; -+ self = (RygelLMSAlbum*) base; -+ g_return_val_if_fail (statement != NULL, NULL); -+ _tmp0_ = statement; -+ _tmp1_ = sqlite3_column_int (_tmp0_, 0); -+ id = _tmp1_; -+ _tmp2_ = statement; -+ _tmp3_ = sqlite3_column_text (_tmp2_, 1); -+ _tmp4_ = g_strdup (_tmp3_); -+ path = _tmp4_; -+ _tmp5_ = statement; -+ _tmp6_ = sqlite3_column_text (_tmp5_, 10); -+ _tmp7_ = g_strdup (_tmp6_); -+ mime_type = _tmp7_; -+ _tmp9_ = mime_type; -+ if (_tmp9_ == NULL) { -+ _tmp8_ = TRUE; -+ } else { -+ const gchar* _tmp10_ = NULL; -+ gint _tmp11_ = 0; -+ gint _tmp12_ = 0; -+ _tmp10_ = mime_type; -+ _tmp11_ = strlen (_tmp10_); -+ _tmp12_ = _tmp11_; -+ _tmp8_ = _tmp12_ == 0; -+ } -+ if (_tmp8_) { -+ gint _tmp13_ = 0; -+ const gchar* _tmp14_ = NULL; -+ _tmp13_ = id; -+ _tmp14_ = path; -+ g_debug ("rygel-lms-album.vala:101: Music item %d (%s) has no MIME type", _tmp13_, _tmp14_); -+ } -+ _tmp15_ = statement; -+ _tmp16_ = sqlite3_column_text (_tmp15_, 3); -+ _tmp17_ = g_strdup (_tmp16_); -+ title = _tmp17_; -+ _tmp18_ = id; -+ _tmp19_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp18_); -+ song_id = _tmp19_; -+ _tmp20_ = rygel_music_item_new (song_id, (RygelMediaContainer*) self, title, RYGEL_MUSIC_ITEM_UPNP_CLASS); -+ song = _tmp20_; -+ _tmp21_ = id; -+ _tmp22_ = rygel_lms_category_container_build_reference_id ((RygelLMSCategoryContainer*) self, _tmp21_); -+ _tmp23_ = _tmp22_; -+ rygel_media_object_set_ref_id ((RygelMediaObject*) song, _tmp23_); -+ _g_free0 (_tmp23_); -+ _tmp24_ = statement; -+ _tmp25_ = sqlite3_column_int (_tmp24_, 2); -+ rygel_media_file_item_set_size ((RygelMediaFileItem*) song, (gint64) _tmp25_); -+ _tmp26_ = statement; -+ _tmp27_ = sqlite3_column_int (_tmp26_, 4); -+ rygel_music_item_set_track_number (song, _tmp27_); -+ _tmp28_ = statement; -+ _tmp29_ = sqlite3_column_int (_tmp28_, 5); -+ rygel_audio_item_set_duration ((RygelAudioItem*) song, (glong) _tmp29_); -+ _tmp30_ = statement; -+ _tmp31_ = sqlite3_column_int (_tmp30_, 6); -+ rygel_audio_item_set_channels ((RygelAudioItem*) song, _tmp31_); -+ _tmp32_ = statement; -+ _tmp33_ = sqlite3_column_int (_tmp32_, 7); -+ rygel_audio_item_set_sample_freq ((RygelAudioItem*) song, _tmp33_); -+ _tmp34_ = statement; -+ _tmp35_ = sqlite3_column_int (_tmp34_, 8); -+ rygel_audio_item_set_bitrate ((RygelAudioItem*) song, _tmp35_); -+ _tmp36_ = statement; -+ _tmp37_ = sqlite3_column_text (_tmp36_, 9); -+ rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) song, _tmp37_); -+ _tmp38_ = mime_type; -+ rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) song, _tmp38_); -+ _tmp39_ = statement; -+ _tmp40_ = sqlite3_column_text (_tmp39_, 11); -+ rygel_media_object_set_artist ((RygelMediaObject*) song, _tmp40_); -+ _tmp41_ = statement; -+ _tmp42_ = sqlite3_column_text (_tmp41_, 12); -+ rygel_audio_item_set_album ((RygelAudioItem*) song, _tmp42_); -+ _tmp43_ = path; -+ _tmp44_ = g_file_new_for_path (_tmp43_); -+ file = _tmp44_; -+ _tmp45_ = g_file_get_uri (file); -+ _tmp46_ = _tmp45_; -+ rygel_media_object_add_uri ((RygelMediaObject*) song, _tmp46_); -+ _g_free0 (_tmp46_); -+ result = (RygelMediaObject*) song; -+ _g_object_unref0 (file); -+ _g_free0 (song_id); -+ _g_free0 (title); -+ _g_free0 (mime_type); -+ _g_free0 (path); -+ return result; -+} -+ -+ -+static gchar* rygel_lms_album_get_sql_all (const gchar* db_id) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (db_id != NULL, NULL); -+ _tmp0_ = db_id; -+ _tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_ALL_TEMPLATE, _tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+static gchar* rygel_lms_album_get_sql_find_object (const gchar* db_id) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (db_id != NULL, NULL); -+ _tmp0_ = db_id; -+ _tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_FIND_OBJECT_TEMPLATE, _tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+static gchar* rygel_lms_album_get_sql_count (const gchar* db_id) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (db_id != NULL, NULL); -+ _tmp0_ = db_id; -+ _tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_COUNT_TEMPLATE, _tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+static gchar* rygel_lms_album_get_sql_added (const gchar* db_id) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (db_id != NULL, NULL); -+ _tmp0_ = db_id; -+ _tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_ADDED_TEMPLATE, _tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+static gchar* rygel_lms_album_get_sql_removed (const gchar* db_id) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (db_id != NULL, NULL); -+ _tmp0_ = db_id; -+ _tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_REMOVED_TEMPLATE, _tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+static gchar* rygel_lms_album_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) { -+ RygelLMSAlbum * self; -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gint _tmp2_ = 0; -+ gchar* filter_str = NULL; -+ const gchar* _tmp6_ = NULL; -+ const gchar* _tmp7_ = NULL; -+ const gchar* _tmp8_ = NULL; -+ gchar* _tmp9_ = NULL; -+ const gchar* _tmp10_ = NULL; -+ gchar* _tmp11_ = NULL; -+ self = (RygelLMSAlbum*) base; -+ g_return_val_if_fail (filter != NULL, NULL); -+ _tmp0_ = filter; -+ _tmp1_ = strlen (_tmp0_); -+ _tmp2_ = _tmp1_; -+ if (_tmp2_ == 0) { -+ const gchar* _tmp3_ = NULL; -+ const gchar* _tmp4_ = NULL; -+ gchar* _tmp5_ = NULL; -+ _tmp3_ = rygel_lms_category_container_get_sql_all ((RygelLMSCategoryContainer*) self); -+ _tmp4_ = _tmp3_; -+ _tmp5_ = g_strdup (_tmp4_); -+ result = _tmp5_; -+ return result; -+ } -+ _tmp6_ = rygel_lms_category_container_get_db_id ((RygelLMSCategoryContainer*) self); -+ _tmp7_ = _tmp6_; -+ _tmp8_ = filter; -+ _tmp9_ = g_strdup_printf ("%s AND %s", _tmp7_, _tmp8_); -+ filter_str = _tmp9_; -+ _tmp10_ = filter_str; -+ _tmp11_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_ALL_TEMPLATE, _tmp10_); -+ result = _tmp11_; -+ _g_free0 (filter_str); -+ return result; -+} -+ -+ -+static gchar* rygel_lms_album_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) { -+ RygelLMSAlbum * self; -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gint _tmp2_ = 0; -+ gchar* filter_str = NULL; -+ const gchar* _tmp6_ = NULL; -+ const gchar* _tmp7_ = NULL; -+ const gchar* _tmp8_ = NULL; -+ gchar* _tmp9_ = NULL; -+ const gchar* _tmp10_ = NULL; -+ gchar* _tmp11_ = NULL; -+ self = (RygelLMSAlbum*) base; -+ g_return_val_if_fail (filter != NULL, NULL); -+ _tmp0_ = filter; -+ _tmp1_ = strlen (_tmp0_); -+ _tmp2_ = _tmp1_; -+ if (_tmp2_ == 0) { -+ const gchar* _tmp3_ = NULL; -+ const gchar* _tmp4_ = NULL; -+ gchar* _tmp5_ = NULL; -+ _tmp3_ = rygel_lms_category_container_get_sql_count ((RygelLMSCategoryContainer*) self); -+ _tmp4_ = _tmp3_; -+ _tmp5_ = g_strdup (_tmp4_); -+ result = _tmp5_; -+ return result; -+ } -+ _tmp6_ = rygel_lms_category_container_get_db_id ((RygelLMSCategoryContainer*) self); -+ _tmp7_ = _tmp6_; -+ _tmp8_ = filter; -+ _tmp9_ = g_strdup_printf ("%s AND %s", _tmp7_, _tmp8_); -+ filter_str = _tmp9_; -+ _tmp10_ = filter_str; -+ _tmp11_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_COUNT_WITH_FILTER_TEMPLATE, _tmp10_); -+ result = _tmp11_; -+ _g_free0 (filter_str); -+ return result; -+} -+ -+ -+RygelLMSAlbum* rygel_lms_album_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { -+ RygelLMSAlbum * self = NULL; -+ const gchar* _tmp0_ = NULL; -+ RygelMediaContainer* _tmp1_ = NULL; -+ const gchar* _tmp2_ = NULL; -+ RygelLMSDatabase* _tmp3_ = NULL; -+ const gchar* _tmp4_ = NULL; -+ gchar* _tmp5_ = NULL; -+ gchar* _tmp6_ = NULL; -+ const gchar* _tmp7_ = NULL; -+ gchar* _tmp8_ = NULL; -+ gchar* _tmp9_ = NULL; -+ const gchar* _tmp10_ = NULL; -+ gchar* _tmp11_ = NULL; -+ gchar* _tmp12_ = NULL; -+ const gchar* _tmp13_ = NULL; -+ gchar* _tmp14_ = NULL; -+ gchar* _tmp15_ = NULL; -+ const gchar* _tmp16_ = NULL; -+ gchar* _tmp17_ = NULL; -+ gchar* _tmp18_ = NULL; -+ g_return_val_if_fail (db_id != NULL, NULL); -+ g_return_val_if_fail (parent != NULL, NULL); -+ g_return_val_if_fail (title != NULL, NULL); -+ g_return_val_if_fail (lms_db != NULL, NULL); -+ _tmp0_ = db_id; -+ _tmp1_ = parent; -+ _tmp2_ = title; -+ _tmp3_ = lms_db; -+ _tmp4_ = db_id; -+ _tmp5_ = rygel_lms_album_get_sql_all (_tmp4_); -+ _tmp6_ = _tmp5_; -+ _tmp7_ = db_id; -+ _tmp8_ = rygel_lms_album_get_sql_find_object (_tmp7_); -+ _tmp9_ = _tmp8_; -+ _tmp10_ = db_id; -+ _tmp11_ = rygel_lms_album_get_sql_count (_tmp10_); -+ _tmp12_ = _tmp11_; -+ _tmp13_ = db_id; -+ _tmp14_ = rygel_lms_album_get_sql_added (_tmp13_); -+ _tmp15_ = _tmp14_; -+ _tmp16_ = db_id; -+ _tmp17_ = rygel_lms_album_get_sql_removed (_tmp16_); -+ _tmp18_ = _tmp17_; -+ self = (RygelLMSAlbum*) rygel_lms_category_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_, _tmp3_, _tmp6_, _tmp9_, _tmp12_, _tmp15_, _tmp18_); -+ _g_free0 (_tmp18_); -+ _g_free0 (_tmp15_); -+ _g_free0 (_tmp12_); -+ _g_free0 (_tmp9_); -+ _g_free0 (_tmp6_); -+ return self; -+} -+ -+ -+RygelLMSAlbum* rygel_lms_album_new (const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { -+ return rygel_lms_album_construct (RYGEL_LMS_TYPE_ALBUM, db_id, parent, title, lms_db); -+} -+ -+ -+static void rygel_lms_album_class_init (RygelLMSAlbumClass * klass) { -+ rygel_lms_album_parent_class = g_type_class_peek_parent (klass); -+ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_album_real_object_from_statement; -+ ((RygelLMSCategoryContainerClass *) klass)->get_sql_all_with_filter = rygel_lms_album_real_get_sql_all_with_filter; -+ ((RygelLMSCategoryContainerClass *) klass)->get_sql_count_with_filter = rygel_lms_album_real_get_sql_count_with_filter; -+} -+ -+ -+static void rygel_lms_album_instance_init (RygelLMSAlbum * self) { -+} -+ -+ -+GType rygel_lms_album_get_type (void) { -+ static volatile gsize rygel_lms_album_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_album_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAlbumClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_album_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAlbum), 0, (GInstanceInitFunc) rygel_lms_album_instance_init, NULL }; -+ GType rygel_lms_album_type_id; -+ rygel_lms_album_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAlbum", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_album_type_id__volatile, rygel_lms_album_type_id); -+ } -+ return rygel_lms_album_type_id__volatile; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-albums.c b/src/plugins/lms/rygel-lms-albums.c -new file mode 100644 -index 0000000..f9fabe7 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-albums.c -@@ -0,0 +1,569 @@ -+/* rygel-lms-albums.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-albums.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-server.h> -+#include <sqlite3.h> -+#include <stdlib.h> -+#include <string.h> -+#include <gee.h> -+#include <glib/gi18n-lib.h> -+ -+ -+#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) -+#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+ -+typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; -+typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; -+typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; -+ -+#define RYGEL_LMS_TYPE_ALBUMS (rygel_lms_albums_get_type ()) -+#define RYGEL_LMS_ALBUMS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbums)) -+#define RYGEL_LMS_ALBUMS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbumsClass)) -+#define RYGEL_LMS_IS_ALBUMS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUMS)) -+#define RYGEL_LMS_IS_ALBUMS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUMS)) -+#define RYGEL_LMS_ALBUMS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbumsClass)) -+ -+typedef struct _RygelLMSAlbums RygelLMSAlbums; -+typedef struct _RygelLMSAlbumsClass RygelLMSAlbumsClass; -+typedef struct _RygelLMSAlbumsPrivate RygelLMSAlbumsPrivate; -+#define _g_free0(var) (var = (g_free (var), NULL)) -+ -+#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) -+#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) -+#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+ -+typedef struct _RygelLMSDatabase RygelLMSDatabase; -+typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; -+#define _sqlite3_finalize0(var) ((var == NULL) ? NULL : (var = (sqlite3_finalize (var), NULL))) -+#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) -+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) -+ -+#define RYGEL_LMS_TYPE_ALBUM (rygel_lms_album_get_type ()) -+#define RYGEL_LMS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbum)) -+#define RYGEL_LMS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass)) -+#define RYGEL_LMS_IS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUM)) -+#define RYGEL_LMS_IS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUM)) -+#define RYGEL_LMS_ALBUM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass)) -+ -+typedef struct _RygelLMSAlbum RygelLMSAlbum; -+typedef struct _RygelLMSAlbumClass RygelLMSAlbumClass; -+ -+struct _RygelLMSCategoryContainer { -+ RygelMediaContainer parent_instance; -+ RygelLMSCategoryContainerPrivate * priv; -+ sqlite3_stmt* stmt_all; -+ sqlite3_stmt* stmt_find_object; -+ sqlite3_stmt* stmt_added; -+ sqlite3_stmt* stmt_removed; -+ gchar* child_prefix; -+ gchar* ref_prefix; -+}; -+ -+struct _RygelLMSCategoryContainerClass { -+ RygelMediaContainerClass parent_class; -+ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); -+ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); -+ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); -+}; -+ -+struct _RygelLMSAlbums { -+ RygelLMSCategoryContainer parent_instance; -+ RygelLMSAlbumsPrivate * priv; -+}; -+ -+struct _RygelLMSAlbumsClass { -+ RygelLMSCategoryContainerClass parent_class; -+}; -+ -+typedef enum { -+ RYGEL_LMS_DATABASE_ERROR_OPEN, -+ RYGEL_LMS_DATABASE_ERROR_PREPARE, -+ RYGEL_LMS_DATABASE_ERROR_BIND, -+ RYGEL_LMS_DATABASE_ERROR_STEP, -+ RYGEL_LMS_DATABASE_ERROR_NOT_FOUND -+} RygelLMSDatabaseError; -+#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark () -+ -+static gpointer rygel_lms_albums_parent_class = NULL; -+ -+GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; -+GType rygel_lms_albums_get_type (void) G_GNUC_CONST; -+enum { -+ RYGEL_LMS_ALBUMS_DUMMY_PROPERTY -+}; -+#define RYGEL_LMS_ALBUMS_SQL_ALL "SELECT audio_albums.id, audio_albums.name as title, " "audio_artists.name as artist " "FROM audio_albums " "LEFT JOIN audio_artists " "ON audio_albums.artist_id = audio_artists.id " "LIMIT ? OFFSET ?;" -+#define RYGEL_LMS_ALBUMS_SQL_ALL_WITH_FILTER_TEMPLATE "SELECT audio_albums.id, audio_albums.name as title, " "audio_artists.name as artist " "FROM audio_albums " "LEFT JOIN audio_artists " "ON audio_albums.artist_id = audio_artists.id " "WHERE %s " "LIMIT ? OFFSET ?;" -+#define RYGEL_LMS_ALBUMS_SQL_COUNT "SELECT COUNT(audio_albums.id) " "FROM audio_albums;" -+#define RYGEL_LMS_ALBUMS_SQL_COUNT_WITH_FILTER_TEMPLATE "SELECT COUNT(audio_albums.id), audio_albums.name as title, " "audio_artists.name as artist " "FROM audio_albums " "LEFT JOIN audio_artists " "ON audio_albums.artist_id = audio_artists.id " "WHERE %s;" -+#define RYGEL_LMS_ALBUMS_SQL_CHILD_COUNT_WITH_FILTER_TEMPLATE "SELECT COUNT(audios.id), audios.title as title, " "audio_artists.name as artist " "FROM audios, files, audio_albums " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = audio_a" \ -+"lbums.id %s;" -+#define RYGEL_LMS_ALBUMS_SQL_CHILD_ALL_WITH_FILTER_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \ -+" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \ -+"a_mime, " "audio_artists.name as artist, " "audio_albums.name, audio_albums.id " "FROM audios, files, audio_albums " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = audio_a" \ -+"lbums.id %s " "LIMIT ? OFFSET ?;" -+#define RYGEL_LMS_ALBUMS_SQL_FIND_OBJECT "SELECT audio_albums.id, audio_albums.name " "FROM audio_albums " "WHERE audio_albums.id = ?;" -+static gchar* rygel_lms_albums_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter); -+static gchar* rygel_lms_albums_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter); -+static guint rygel_lms_albums_real_get_child_count_with_filter (RygelLMSCategoryContainer* base, const gchar* where_filter, GValueArray* args); -+guint rygel_lms_category_container_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); -+gpointer rygel_lms_database_ref (gpointer instance); -+void rygel_lms_database_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_database (GValue* value, gpointer v_object); -+void rygel_lms_value_take_database (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_database (const GValue* value); -+GType rygel_lms_database_get_type (void) G_GNUC_CONST; -+RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self); -+GQuark rygel_lms_database_error_quark (void); -+sqlite3_stmt* rygel_lms_database_prepare_and_init (RygelLMSDatabase* self, const gchar* query, GValue* arguments, int arguments_length1, GError** error); -+static RygelMediaObjects* rygel_lms_albums_real_get_children_with_filter (RygelLMSCategoryContainer* base, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); -+RygelMediaObjects* rygel_lms_category_container_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); -+gboolean rygel_lms_database_get_children_step (sqlite3_stmt* stmt, GError** error); -+GType rygel_lms_album_get_type (void) G_GNUC_CONST; -+RygelLMSAlbum* rygel_lms_album_new (const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSAlbum* rygel_lms_album_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelMediaObject* rygel_lms_category_container_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); -+static RygelMediaObject* rygel_lms_albums_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); -+RygelLMSAlbums* rygel_lms_albums_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+RygelLMSAlbums* rygel_lms_albums_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); -+ -+ -+static gchar* rygel_lms_albums_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) { -+ RygelLMSAlbums * self; -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gint _tmp2_ = 0; -+ const gchar* _tmp4_ = NULL; -+ gchar* _tmp5_ = NULL; -+ self = (RygelLMSAlbums*) base; -+ g_return_val_if_fail (filter != NULL, NULL); -+ _tmp0_ = filter; -+ _tmp1_ = strlen (_tmp0_); -+ _tmp2_ = _tmp1_; -+ if (_tmp2_ == 0) { -+ gchar* _tmp3_ = NULL; -+ _tmp3_ = g_strdup (RYGEL_LMS_ALBUMS_SQL_ALL); -+ result = _tmp3_; -+ return result; -+ } -+ _tmp4_ = filter; -+ _tmp5_ = g_strdup_printf (RYGEL_LMS_ALBUMS_SQL_ALL_WITH_FILTER_TEMPLATE, _tmp4_); -+ result = _tmp5_; -+ return result; -+} -+ -+ -+static gchar* rygel_lms_albums_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) { -+ RygelLMSAlbums * self; -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gint _tmp2_ = 0; -+ const gchar* _tmp4_ = NULL; -+ gchar* _tmp5_ = NULL; -+ self = (RygelLMSAlbums*) base; -+ g_return_val_if_fail (filter != NULL, NULL); -+ _tmp0_ = filter; -+ _tmp1_ = strlen (_tmp0_); -+ _tmp2_ = _tmp1_; -+ if (_tmp2_ == 0) { -+ gchar* _tmp3_ = NULL; -+ _tmp3_ = g_strdup (RYGEL_LMS_ALBUMS_SQL_COUNT); -+ result = _tmp3_; -+ return result; -+ } -+ _tmp4_ = filter; -+ _tmp5_ = g_strdup_printf (RYGEL_LMS_ALBUMS_SQL_COUNT_WITH_FILTER_TEMPLATE, _tmp4_); -+ result = _tmp5_; -+ return result; -+} -+ -+ -+static guint rygel_lms_albums_real_get_child_count_with_filter (RygelLMSCategoryContainer* base, const gchar* where_filter, GValueArray* args) { -+ RygelLMSAlbums * self; -+ guint result = 0U; -+ guint count = 0U; -+ const gchar* _tmp0_ = NULL; -+ GValueArray* _tmp1_ = NULL; -+ guint _tmp2_ = 0U; -+ gchar* filter = NULL; -+ gchar* _tmp3_ = NULL; -+ const gchar* _tmp4_ = NULL; -+ gint _tmp5_ = 0; -+ gint _tmp6_ = 0; -+ gchar* query = NULL; -+ const gchar* _tmp9_ = NULL; -+ gchar* _tmp10_ = NULL; -+ GError * _inner_error_ = NULL; -+ self = (RygelLMSAlbums*) base; -+ g_return_val_if_fail (where_filter != NULL, 0U); -+ g_return_val_if_fail (args != NULL, 0U); -+ _tmp0_ = where_filter; -+ _tmp1_ = args; -+ _tmp2_ = RYGEL_LMS_CATEGORY_CONTAINER_CLASS (rygel_lms_albums_parent_class)->get_child_count_with_filter (G_TYPE_CHECK_INSTANCE_CAST (self, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer), _tmp0_, _tmp1_); -+ count = _tmp2_; -+ _tmp3_ = g_strdup (""); -+ filter = _tmp3_; -+ _tmp4_ = where_filter; -+ _tmp5_ = strlen (_tmp4_); -+ _tmp6_ = _tmp5_; -+ if (_tmp6_ > 0) { -+ const gchar* _tmp7_ = NULL; -+ gchar* _tmp8_ = NULL; -+ _tmp7_ = where_filter; -+ _tmp8_ = g_strdup_printf ("AND %s", _tmp7_); -+ _g_free0 (filter); -+ filter = _tmp8_; -+ } -+ _tmp9_ = filter; -+ _tmp10_ = g_strdup_printf (RYGEL_LMS_ALBUMS_SQL_CHILD_COUNT_WITH_FILTER_TEMPLATE, _tmp9_); -+ query = _tmp10_; -+ { -+ sqlite3_stmt* stmt = NULL; -+ RygelLMSDatabase* _tmp11_ = NULL; -+ RygelLMSDatabase* _tmp12_ = NULL; -+ GValueArray* _tmp13_ = NULL; -+ GValue* _tmp14_ = NULL; -+ gint _tmp14__length1 = 0; -+ sqlite3_stmt* _tmp15_ = NULL; -+ gint _tmp16_ = 0; -+ _tmp11_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); -+ _tmp12_ = _tmp11_; -+ _tmp13_ = args; -+ _tmp14_ = _tmp13_->values; -+ _tmp14__length1 = (gint) _tmp13_->n_values; -+ _tmp15_ = rygel_lms_database_prepare_and_init (_tmp12_, query, _tmp14_, _tmp14__length1, &_inner_error_); -+ stmt = _tmp15_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch8_rygel_lms_database_error; -+ } -+ _g_free0 (query); -+ _g_free0 (filter); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return 0U; -+ } -+ _tmp16_ = sqlite3_step (stmt); -+ if (_tmp16_ == SQLITE_ROW) { -+ guint _tmp17_ = 0U; -+ gint _tmp18_ = 0; -+ _tmp17_ = count; -+ _tmp18_ = sqlite3_column_int (stmt, 0); -+ count = _tmp17_ + _tmp18_; -+ } -+ _sqlite3_finalize0 (stmt); -+ } -+ goto __finally8; -+ __catch8_rygel_lms_database_error: -+ { -+ GError* e = NULL; -+ GError* _tmp19_ = NULL; -+ const gchar* _tmp20_ = NULL; -+ e = _inner_error_; -+ _inner_error_ = NULL; -+ _tmp19_ = e; -+ _tmp20_ = _tmp19_->message; -+ g_warning ("rygel-lms-albums.vala:116: Query failed: %s", _tmp20_); -+ _g_error_free0 (e); -+ } -+ __finally8: -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _g_free0 (query); -+ _g_free0 (filter); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return 0U; -+ } -+ result = count; -+ _g_free0 (query); -+ _g_free0 (filter); -+ return result; -+} -+ -+ -+static RygelMediaObjects* rygel_lms_albums_real_get_children_with_filter (RygelLMSCategoryContainer* base, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count) { -+ RygelLMSAlbums * self; -+ RygelMediaObjects* result = NULL; -+ RygelMediaObjects* children = NULL; -+ const gchar* _tmp0_ = NULL; -+ GValueArray* _tmp1_ = NULL; -+ const gchar* _tmp2_ = NULL; -+ guint _tmp3_ = 0U; -+ guint _tmp4_ = 0U; -+ RygelMediaObjects* _tmp5_ = NULL; -+ gchar* filter = NULL; -+ gchar* _tmp6_ = NULL; -+ const gchar* _tmp7_ = NULL; -+ gint _tmp8_ = 0; -+ gint _tmp9_ = 0; -+ gchar* query = NULL; -+ const gchar* _tmp12_ = NULL; -+ gchar* _tmp13_ = NULL; -+ GError * _inner_error_ = NULL; -+ self = (RygelLMSAlbums*) base; -+ g_return_val_if_fail (where_filter != NULL, NULL); -+ g_return_val_if_fail (args != NULL, NULL); -+ g_return_val_if_fail (sort_criteria != NULL, NULL); -+ _tmp0_ = where_filter; -+ _tmp1_ = args; -+ _tmp2_ = sort_criteria; -+ _tmp3_ = offset; -+ _tmp4_ = max_count; -+ _tmp5_ = RYGEL_LMS_CATEGORY_CONTAINER_CLASS (rygel_lms_albums_parent_class)->get_children_with_filter (G_TYPE_CHECK_INSTANCE_CAST (self, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer), _tmp0_, _tmp1_, _tmp2_, _tmp3_, _tmp4_); -+ children = _tmp5_; -+ _tmp6_ = g_strdup (""); -+ filter = _tmp6_; -+ _tmp7_ = where_filter; -+ _tmp8_ = strlen (_tmp7_); -+ _tmp9_ = _tmp8_; -+ if (_tmp9_ > 0) { -+ const gchar* _tmp10_ = NULL; -+ gchar* _tmp11_ = NULL; -+ _tmp10_ = where_filter; -+ _tmp11_ = g_strdup_printf ("AND %s", _tmp10_); -+ _g_free0 (filter); -+ filter = _tmp11_; -+ } -+ _tmp12_ = filter; -+ _tmp13_ = g_strdup_printf (RYGEL_LMS_ALBUMS_SQL_CHILD_ALL_WITH_FILTER_TEMPLATE, _tmp12_); -+ query = _tmp13_; -+ { -+ sqlite3_stmt* stmt = NULL; -+ RygelLMSDatabase* _tmp14_ = NULL; -+ RygelLMSDatabase* _tmp15_ = NULL; -+ const gchar* _tmp16_ = NULL; -+ GValueArray* _tmp17_ = NULL; -+ GValue* _tmp18_ = NULL; -+ gint _tmp18__length1 = 0; -+ sqlite3_stmt* _tmp19_ = NULL; -+ _tmp14_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); -+ _tmp15_ = _tmp14_; -+ _tmp16_ = query; -+ _tmp17_ = args; -+ _tmp18_ = _tmp17_->values; -+ _tmp18__length1 = (gint) _tmp17_->n_values; -+ _tmp19_ = rygel_lms_database_prepare_and_init (_tmp15_, _tmp16_, _tmp18_, _tmp18__length1, &_inner_error_); -+ stmt = _tmp19_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch9_rygel_lms_database_error; -+ } -+ _g_free0 (query); -+ _g_free0 (filter); -+ _g_object_unref0 (children); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ while (TRUE) { -+ gboolean _tmp20_ = FALSE; -+ sqlite3_stmt* _tmp21_ = NULL; -+ gboolean _tmp22_ = FALSE; -+ gchar* album_id = NULL; -+ sqlite3_stmt* _tmp23_ = NULL; -+ const gchar* _tmp24_ = NULL; -+ gchar* _tmp25_ = NULL; -+ RygelLMSAlbum* album = NULL; -+ const gchar* _tmp26_ = NULL; -+ RygelLMSDatabase* _tmp27_ = NULL; -+ RygelLMSDatabase* _tmp28_ = NULL; -+ RygelLMSAlbum* _tmp29_ = NULL; -+ RygelMediaObject* song = NULL; -+ RygelLMSAlbum* _tmp30_ = NULL; -+ sqlite3_stmt* _tmp31_ = NULL; -+ RygelMediaObject* _tmp32_ = NULL; -+ RygelMediaObject* _tmp33_ = NULL; -+ RygelMediaObject* _tmp34_ = NULL; -+ RygelMediaContainer* _tmp35_ = NULL; -+ RygelMediaContainer* _tmp36_ = NULL; -+ RygelMediaObjects* _tmp37_ = NULL; -+ RygelMediaObject* _tmp38_ = NULL; -+ _tmp21_ = stmt; -+ _tmp22_ = rygel_lms_database_get_children_step (_tmp21_, &_inner_error_); -+ _tmp20_ = _tmp22_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _sqlite3_finalize0 (stmt); -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch9_rygel_lms_database_error; -+ } -+ _sqlite3_finalize0 (stmt); -+ _g_free0 (query); -+ _g_free0 (filter); -+ _g_object_unref0 (children); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ if (!_tmp20_) { -+ break; -+ } -+ _tmp23_ = stmt; -+ _tmp24_ = sqlite3_column_text (_tmp23_, 13); -+ _tmp25_ = g_strdup (_tmp24_); -+ album_id = _tmp25_; -+ _tmp26_ = album_id; -+ _tmp27_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); -+ _tmp28_ = _tmp27_; -+ _tmp29_ = rygel_lms_album_new (_tmp26_, (RygelMediaContainer*) self, "", _tmp28_); -+ album = _tmp29_; -+ _tmp30_ = album; -+ _tmp31_ = stmt; -+ _tmp32_ = rygel_lms_category_container_object_from_statement ((RygelLMSCategoryContainer*) _tmp30_, _tmp31_); -+ song = _tmp32_; -+ _tmp33_ = song; -+ _tmp34_ = song; -+ _tmp35_ = rygel_media_object_get_parent (_tmp34_); -+ _tmp36_ = _tmp35_; -+ rygel_media_object_set_parent_ref (_tmp33_, _tmp36_); -+ _tmp37_ = children; -+ _tmp38_ = song; -+ gee_abstract_collection_add ((GeeAbstractCollection*) _tmp37_, _tmp38_); -+ _g_object_unref0 (song); -+ _g_object_unref0 (album); -+ _g_free0 (album_id); -+ } -+ _sqlite3_finalize0 (stmt); -+ } -+ goto __finally9; -+ __catch9_rygel_lms_database_error: -+ { -+ GError* e = NULL; -+ GError* _tmp39_ = NULL; -+ const gchar* _tmp40_ = NULL; -+ e = _inner_error_; -+ _inner_error_ = NULL; -+ _tmp39_ = e; -+ _tmp40_ = _tmp39_->message; -+ g_warning ("rygel-lms-albums.vala:149: Query failed: %s", _tmp40_); -+ _g_error_free0 (e); -+ } -+ __finally9: -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _g_free0 (query); -+ _g_free0 (filter); -+ _g_object_unref0 (children); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ result = children; -+ _g_free0 (query); -+ _g_free0 (filter); -+ return result; -+} -+ -+ -+static RygelMediaObject* rygel_lms_albums_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { -+ RygelLMSAlbums * self; -+ RygelMediaObject* result = NULL; -+ gchar* id = NULL; -+ sqlite3_stmt* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gchar* _tmp2_ = NULL; -+ RygelLMSAlbum* album = NULL; -+ sqlite3_stmt* _tmp3_ = NULL; -+ const gchar* _tmp4_ = NULL; -+ RygelLMSDatabase* _tmp5_ = NULL; -+ RygelLMSDatabase* _tmp6_ = NULL; -+ RygelLMSAlbum* _tmp7_ = NULL; -+ self = (RygelLMSAlbums*) base; -+ g_return_val_if_fail (statement != NULL, NULL); -+ _tmp0_ = statement; -+ _tmp1_ = sqlite3_column_int (_tmp0_, 0); -+ _tmp2_ = g_strdup_printf ("%d", _tmp1_); -+ id = _tmp2_; -+ _tmp3_ = statement; -+ _tmp4_ = sqlite3_column_text (_tmp3_, 1); -+ _tmp5_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); -+ _tmp6_ = _tmp5_; -+ _tmp7_ = rygel_lms_album_new (id, (RygelMediaContainer*) self, _tmp4_, _tmp6_); -+ album = _tmp7_; -+ result = (RygelMediaObject*) album; -+ _g_free0 (id); -+ return result; -+} -+ -+ -+RygelLMSAlbums* rygel_lms_albums_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { -+ RygelLMSAlbums * self = NULL; -+ RygelMediaContainer* _tmp0_ = NULL; -+ const gchar* _tmp1_ = NULL; -+ RygelLMSDatabase* _tmp2_ = NULL; -+ g_return_val_if_fail (parent != NULL, NULL); -+ g_return_val_if_fail (lms_db != NULL, NULL); -+ _tmp0_ = parent; -+ _tmp1_ = _ ("Albums"); -+ _tmp2_ = lms_db; -+ self = (RygelLMSAlbums*) rygel_lms_category_container_construct (object_type, "albums", _tmp0_, _tmp1_, _tmp2_, RYGEL_LMS_ALBUMS_SQL_ALL, RYGEL_LMS_ALBUMS_SQL_FIND_OBJECT, RYGEL_LMS_ALBUMS_SQL_COUNT, NULL, NULL); -+ return self; -+} -+ -+ -+RygelLMSAlbums* rygel_lms_albums_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { -+ return rygel_lms_albums_construct (RYGEL_LMS_TYPE_ALBUMS, parent, lms_db); -+} -+ -+ -+static void rygel_lms_albums_class_init (RygelLMSAlbumsClass * klass) { -+ rygel_lms_albums_parent_class = g_type_class_peek_parent (klass); -+ ((RygelLMSCategoryContainerClass *) klass)->get_sql_all_with_filter = rygel_lms_albums_real_get_sql_all_with_filter; -+ ((RygelLMSCategoryContainerClass *) klass)->get_sql_count_with_filter = rygel_lms_albums_real_get_sql_count_with_filter; -+ ((RygelLMSCategoryContainerClass *) klass)->get_child_count_with_filter = rygel_lms_albums_real_get_child_count_with_filter; -+ ((RygelLMSCategoryContainerClass *) klass)->get_children_with_filter = rygel_lms_albums_real_get_children_with_filter; -+ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_albums_real_object_from_statement; -+} -+ -+ -+static void rygel_lms_albums_instance_init (RygelLMSAlbums * self) { -+} -+ -+ -+GType rygel_lms_albums_get_type (void) { -+ static volatile gsize rygel_lms_albums_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_albums_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAlbumsClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_albums_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAlbums), 0, (GInstanceInitFunc) rygel_lms_albums_instance_init, NULL }; -+ GType rygel_lms_albums_type_id; -+ rygel_lms_albums_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAlbums", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_albums_type_id__volatile, rygel_lms_albums_type_id); -+ } -+ return rygel_lms_albums_type_id__volatile; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-all-images.c b/src/plugins/lms/rygel-lms-all-images.c -new file mode 100644 -index 0000000..33fb8c1 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-all-images.c -@@ -0,0 +1,305 @@ -+/* rygel-lms-all-images.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-all-images.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-server.h> -+#include <sqlite3.h> -+#include <stdlib.h> -+#include <string.h> -+#include <gio/gio.h> -+#include <glib/gi18n-lib.h> -+ -+ -+#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) -+#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+ -+typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; -+typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; -+typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; -+ -+#define RYGEL_LMS_TYPE_ALL_IMAGES (rygel_lms_all_images_get_type ()) -+#define RYGEL_LMS_ALL_IMAGES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImages)) -+#define RYGEL_LMS_ALL_IMAGES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImagesClass)) -+#define RYGEL_LMS_IS_ALL_IMAGES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_IMAGES)) -+#define RYGEL_LMS_IS_ALL_IMAGES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_IMAGES)) -+#define RYGEL_LMS_ALL_IMAGES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImagesClass)) -+ -+typedef struct _RygelLMSAllImages RygelLMSAllImages; -+typedef struct _RygelLMSAllImagesClass RygelLMSAllImagesClass; -+typedef struct _RygelLMSAllImagesPrivate RygelLMSAllImagesPrivate; -+#define _g_free0(var) (var = (g_free (var), NULL)) -+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) -+ -+#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) -+#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) -+#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+ -+typedef struct _RygelLMSDatabase RygelLMSDatabase; -+typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; -+ -+struct _RygelLMSCategoryContainer { -+ RygelMediaContainer parent_instance; -+ RygelLMSCategoryContainerPrivate * priv; -+ sqlite3_stmt* stmt_all; -+ sqlite3_stmt* stmt_find_object; -+ sqlite3_stmt* stmt_added; -+ sqlite3_stmt* stmt_removed; -+ gchar* child_prefix; -+ gchar* ref_prefix; -+}; -+ -+struct _RygelLMSCategoryContainerClass { -+ RygelMediaContainerClass parent_class; -+ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); -+ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); -+ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); -+}; -+ -+struct _RygelLMSAllImages { -+ RygelLMSCategoryContainer parent_instance; -+ RygelLMSAllImagesPrivate * priv; -+}; -+ -+struct _RygelLMSAllImagesClass { -+ RygelLMSCategoryContainerClass parent_class; -+}; -+ -+ -+static gpointer rygel_lms_all_images_parent_class = NULL; -+ -+GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; -+GType rygel_lms_all_images_get_type (void) G_GNUC_CONST; -+enum { -+ RYGEL_LMS_ALL_IMAGES_DUMMY_PROPERTY -+}; -+#define RYGEL_LMS_ALL_IMAGES_SQL_ALL "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ -+"_profile, dlna_mime " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id " "LIMIT ? OFFSET ?;" -+#define RYGEL_LMS_ALL_IMAGES_SQL_COUNT "SELECT count(images.id) " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id;" -+#define RYGEL_LMS_ALL_IMAGES_SQL_FIND_OBJECT "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ -+"_profile, dlna_mime " "FROM images, files " "WHERE dtime = 0 AND files.id = ? AND images.id = files.id;" -+#define RYGEL_LMS_ALL_IMAGES_SQL_ADDED "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ -+"_profile, dlna_mime " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id " "AND update_id > ? AND update_id <= ?;" -+#define RYGEL_LMS_ALL_IMAGES_SQL_REMOVED "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ -+"_profile, dlna_mime " "FROM images, files " "WHERE dtime <> 0 AND images.id = files.id " "AND update_id > ? AND update_id <= ?;" -+static RygelMediaObject* rygel_lms_all_images_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); -+gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id); -+gpointer rygel_lms_database_ref (gpointer instance); -+void rygel_lms_database_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_database (GValue* value, gpointer v_object); -+void rygel_lms_value_take_database (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_database (const GValue* value); -+GType rygel_lms_database_get_type (void) G_GNUC_CONST; -+RygelLMSAllImages* rygel_lms_all_images_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+RygelLMSAllImages* rygel_lms_all_images_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); -+ -+ -+static RygelMediaObject* rygel_lms_all_images_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { -+ RygelLMSAllImages * self; -+ RygelMediaObject* result = NULL; -+ gint id = 0; -+ sqlite3_stmt* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gchar* path = NULL; -+ sqlite3_stmt* _tmp2_ = NULL; -+ const gchar* _tmp3_ = NULL; -+ gchar* _tmp4_ = NULL; -+ gchar* mime_type = NULL; -+ sqlite3_stmt* _tmp5_ = NULL; -+ const gchar* _tmp6_ = NULL; -+ gchar* _tmp7_ = NULL; -+ gboolean _tmp8_ = FALSE; -+ const gchar* _tmp9_ = NULL; -+ gchar* title = NULL; -+ sqlite3_stmt* _tmp15_ = NULL; -+ const gchar* _tmp16_ = NULL; -+ gchar* _tmp17_ = NULL; -+ RygelImageItem* image = NULL; -+ gint _tmp18_ = 0; -+ gchar* _tmp19_ = NULL; -+ gchar* _tmp20_ = NULL; -+ RygelImageItem* _tmp21_ = NULL; -+ RygelImageItem* _tmp22_ = NULL; -+ sqlite3_stmt* _tmp23_ = NULL; -+ const gchar* _tmp24_ = NULL; -+ GTimeVal tv = {0}; -+ sqlite3_stmt* _tmp25_ = NULL; -+ gint _tmp26_ = 0; -+ GTimeVal _tmp27_ = {0}; -+ gchar* _tmp28_ = NULL; -+ gchar* _tmp29_ = NULL; -+ sqlite3_stmt* _tmp30_ = NULL; -+ gint _tmp31_ = 0; -+ sqlite3_stmt* _tmp32_ = NULL; -+ gint _tmp33_ = 0; -+ sqlite3_stmt* _tmp34_ = NULL; -+ gint _tmp35_ = 0; -+ const gchar* _tmp36_ = NULL; -+ sqlite3_stmt* _tmp37_ = NULL; -+ const gchar* _tmp38_ = NULL; -+ GFile* file = NULL; -+ const gchar* _tmp39_ = NULL; -+ GFile* _tmp40_ = NULL; -+ gchar* _tmp41_ = NULL; -+ gchar* _tmp42_ = NULL; -+ self = (RygelLMSAllImages*) base; -+ g_return_val_if_fail (statement != NULL, NULL); -+ _tmp0_ = statement; -+ _tmp1_ = sqlite3_column_int (_tmp0_, 0); -+ id = _tmp1_; -+ _tmp2_ = statement; -+ _tmp3_ = sqlite3_column_text (_tmp2_, 6); -+ _tmp4_ = g_strdup (_tmp3_); -+ path = _tmp4_; -+ _tmp5_ = statement; -+ _tmp6_ = sqlite3_column_text (_tmp5_, 9); -+ _tmp7_ = g_strdup (_tmp6_); -+ mime_type = _tmp7_; -+ _tmp9_ = mime_type; -+ if (_tmp9_ == NULL) { -+ _tmp8_ = TRUE; -+ } else { -+ const gchar* _tmp10_ = NULL; -+ gint _tmp11_ = 0; -+ gint _tmp12_ = 0; -+ _tmp10_ = mime_type; -+ _tmp11_ = strlen (_tmp10_); -+ _tmp12_ = _tmp11_; -+ _tmp8_ = _tmp12_ == 0; -+ } -+ if (_tmp8_) { -+ gint _tmp13_ = 0; -+ const gchar* _tmp14_ = NULL; -+ _tmp13_ = id; -+ _tmp14_ = path; -+ g_debug ("rygel-lms-all-images.vala:62: Image item %d (%s) has no MIME type", _tmp13_, _tmp14_); -+ } -+ _tmp15_ = statement; -+ _tmp16_ = sqlite3_column_text (_tmp15_, 1); -+ _tmp17_ = g_strdup (_tmp16_); -+ title = _tmp17_; -+ _tmp18_ = id; -+ _tmp19_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp18_); -+ _tmp20_ = _tmp19_; -+ _tmp21_ = rygel_image_item_new (_tmp20_, (RygelMediaContainer*) self, title, RYGEL_IMAGE_ITEM_UPNP_CLASS); -+ _tmp22_ = _tmp21_; -+ _g_free0 (_tmp20_); -+ image = _tmp22_; -+ _tmp23_ = statement; -+ _tmp24_ = sqlite3_column_text (_tmp23_, 2); -+ rygel_media_object_set_creator ((RygelMediaObject*) image, _tmp24_); -+ _tmp25_ = statement; -+ _tmp26_ = sqlite3_column_int (_tmp25_, 3); -+ _tmp27_.tv_sec = (glong) _tmp26_; -+ _tmp27_.tv_usec = (glong) 0; -+ tv = _tmp27_; -+ _tmp28_ = g_time_val_to_iso8601 (&tv); -+ _tmp29_ = _tmp28_; -+ rygel_media_object_set_date ((RygelMediaObject*) image, _tmp29_); -+ _g_free0 (_tmp29_); -+ _tmp30_ = statement; -+ _tmp31_ = sqlite3_column_int (_tmp30_, 4); -+ rygel_visual_item_set_width ((RygelVisualItem*) image, _tmp31_); -+ _tmp32_ = statement; -+ _tmp33_ = sqlite3_column_int (_tmp32_, 5); -+ rygel_visual_item_set_height ((RygelVisualItem*) image, _tmp33_); -+ _tmp34_ = statement; -+ _tmp35_ = sqlite3_column_int (_tmp34_, 7); -+ rygel_media_file_item_set_size ((RygelMediaFileItem*) image, (gint64) _tmp35_); -+ _tmp36_ = mime_type; -+ rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) image, _tmp36_); -+ _tmp37_ = statement; -+ _tmp38_ = sqlite3_column_text (_tmp37_, 8); -+ rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) image, _tmp38_); -+ _tmp39_ = path; -+ _tmp40_ = g_file_new_for_path (_tmp39_); -+ file = _tmp40_; -+ _tmp41_ = g_file_get_uri (file); -+ _tmp42_ = _tmp41_; -+ rygel_media_object_add_uri ((RygelMediaObject*) image, _tmp42_); -+ _g_free0 (_tmp42_); -+ result = (RygelMediaObject*) image; -+ _g_object_unref0 (file); -+ _g_free0 (title); -+ _g_free0 (mime_type); -+ _g_free0 (path); -+ return result; -+} -+ -+ -+RygelLMSAllImages* rygel_lms_all_images_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { -+ RygelLMSAllImages * self = NULL; -+ RygelMediaContainer* _tmp0_ = NULL; -+ const gchar* _tmp1_ = NULL; -+ RygelLMSDatabase* _tmp2_ = NULL; -+ g_return_val_if_fail (parent != NULL, NULL); -+ g_return_val_if_fail (lms_db != NULL, NULL); -+ _tmp0_ = parent; -+ _tmp1_ = _ ("All"); -+ _tmp2_ = lms_db; -+ self = (RygelLMSAllImages*) rygel_lms_category_container_construct (object_type, "all", _tmp0_, _tmp1_, _tmp2_, RYGEL_LMS_ALL_IMAGES_SQL_ALL, RYGEL_LMS_ALL_IMAGES_SQL_FIND_OBJECT, RYGEL_LMS_ALL_IMAGES_SQL_COUNT, RYGEL_LMS_ALL_IMAGES_SQL_ADDED, RYGEL_LMS_ALL_IMAGES_SQL_REMOVED); -+ return self; -+} -+ -+ -+RygelLMSAllImages* rygel_lms_all_images_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { -+ return rygel_lms_all_images_construct (RYGEL_LMS_TYPE_ALL_IMAGES, parent, lms_db); -+} -+ -+ -+static void rygel_lms_all_images_class_init (RygelLMSAllImagesClass * klass) { -+ rygel_lms_all_images_parent_class = g_type_class_peek_parent (klass); -+ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_all_images_real_object_from_statement; -+} -+ -+ -+static void rygel_lms_all_images_instance_init (RygelLMSAllImages * self) { -+} -+ -+ -+GType rygel_lms_all_images_get_type (void) { -+ static volatile gsize rygel_lms_all_images_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_all_images_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAllImagesClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_all_images_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAllImages), 0, (GInstanceInitFunc) rygel_lms_all_images_instance_init, NULL }; -+ GType rygel_lms_all_images_type_id; -+ rygel_lms_all_images_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAllImages", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_all_images_type_id__volatile, rygel_lms_all_images_type_id); -+ } -+ return rygel_lms_all_images_type_id__volatile; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-all-music.c b/src/plugins/lms/rygel-lms-all-music.c -new file mode 100644 -index 0000000..ee6118f ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-all-music.c -@@ -0,0 +1,417 @@ -+/* rygel-lms-all-music.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-all-music.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-server.h> -+#include <sqlite3.h> -+#include <stdlib.h> -+#include <string.h> -+#include <gio/gio.h> -+#include <glib/gi18n-lib.h> -+ -+ -+#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) -+#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+ -+typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; -+typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; -+typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; -+ -+#define RYGEL_LMS_TYPE_ALL_MUSIC (rygel_lms_all_music_get_type ()) -+#define RYGEL_LMS_ALL_MUSIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusic)) -+#define RYGEL_LMS_ALL_MUSIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusicClass)) -+#define RYGEL_LMS_IS_ALL_MUSIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_MUSIC)) -+#define RYGEL_LMS_IS_ALL_MUSIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_MUSIC)) -+#define RYGEL_LMS_ALL_MUSIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusicClass)) -+ -+typedef struct _RygelLMSAllMusic RygelLMSAllMusic; -+typedef struct _RygelLMSAllMusicClass RygelLMSAllMusicClass; -+typedef struct _RygelLMSAllMusicPrivate RygelLMSAllMusicPrivate; -+#define _g_free0(var) (var = (g_free (var), NULL)) -+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) -+ -+#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) -+#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) -+#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+ -+typedef struct _RygelLMSDatabase RygelLMSDatabase; -+typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; -+ -+struct _RygelLMSCategoryContainer { -+ RygelMediaContainer parent_instance; -+ RygelLMSCategoryContainerPrivate * priv; -+ sqlite3_stmt* stmt_all; -+ sqlite3_stmt* stmt_find_object; -+ sqlite3_stmt* stmt_added; -+ sqlite3_stmt* stmt_removed; -+ gchar* child_prefix; -+ gchar* ref_prefix; -+}; -+ -+struct _RygelLMSCategoryContainerClass { -+ RygelMediaContainerClass parent_class; -+ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); -+ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); -+ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); -+}; -+ -+struct _RygelLMSAllMusic { -+ RygelLMSCategoryContainer parent_instance; -+ RygelLMSAllMusicPrivate * priv; -+}; -+ -+struct _RygelLMSAllMusicClass { -+ RygelLMSCategoryContainerClass parent_class; -+}; -+ -+ -+static gpointer rygel_lms_all_music_parent_class = NULL; -+ -+GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; -+GType rygel_lms_all_music_get_type (void) G_GNUC_CONST; -+enum { -+ RYGEL_LMS_ALL_MUSIC_DUMMY_PROPERTY -+}; -+#define RYGEL_LMS_ALL_MUSIC_SQL_ALL_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \ -+" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \ -+"a_mime, " "audio_artists.name as artist, " "audio_albums.name, " "files.mtime, " "audio_genres.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "LEFT JOIN audio_genres " "ON audios.genre_id = audio_genres.id " "WHERE dtime = 0 AND audios.id = files.id %s " "LIMIT ? OFFSET ?;" -+#define RYGEL_LMS_ALL_MUSIC_SQL_COUNT "SELECT COUNT(audios.id) " "FROM audios, files " "WHERE dtime = 0 AND audios.id = files.id;" -+#define RYGEL_LMS_ALL_MUSIC_SQL_COUNT_WITH_FILTER_TEMPLATE "SELECT COUNT(audios.id), audios.title as title, " "audio_artists.name as artist " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "WHERE dtime = 0 AND audios.id = files.id %s;" -+#define RYGEL_LMS_ALL_MUSIC_SQL_FIND_OBJECT "SELECT files.id, files.path, files.size, " "audios.title, audios.trackno, audios.length, audios.channels, audios.s" \ -+"ampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " "audio_artists.name, " "audio_albums.name, " "files.mtime, " "audio_genres.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "LEFT JOIN audio_genres " "ON audios.genre_id = audio_genres.id " "WHERE dtime = 0 AND files.id = ? AND audios.id = files.id;" -+#define RYGEL_LMS_ALL_MUSIC_SQL_ADDED "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \ -+" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \ -+"a_mime, " "audio_artists.name as artist, " "audio_albums.name, " "files.mtime, " "audio_genres.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "LEFT JOIN audio_genres " "ON audios.genre_id = audio_genres.id " "WHERE dtime = 0 AND audios.id = files.id " "AND update_id > ? AND update_id <= ?;" -+#define RYGEL_LMS_ALL_MUSIC_SQL_REMOVED "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \ -+" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \ -+"a_mime, " "audio_artists.name as artist, " "audio_albums.name, " "files.mtime, " "audio_genres.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "LEFT JOIN audio_genres " "ON audios.genre_id = audio_genres.id " "WHERE dtime <> 0 AND audios.id = files.id " "AND update_id > ? AND update_id <= ?;" -+static gchar* rygel_lms_all_music_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter); -+const gchar* rygel_lms_category_container_get_sql_all (RygelLMSCategoryContainer* self); -+static gchar* rygel_lms_all_music_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter); -+const gchar* rygel_lms_category_container_get_sql_count (RygelLMSCategoryContainer* self); -+static RygelMediaObject* rygel_lms_all_music_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); -+gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id); -+gpointer rygel_lms_database_ref (gpointer instance); -+void rygel_lms_database_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_database (GValue* value, gpointer v_object); -+void rygel_lms_value_take_database (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_database (const GValue* value); -+GType rygel_lms_database_get_type (void) G_GNUC_CONST; -+RygelLMSAllMusic* rygel_lms_all_music_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+RygelLMSAllMusic* rygel_lms_all_music_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); -+ -+ -+static gchar* rygel_lms_all_music_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) { -+ RygelLMSAllMusic * self; -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gint _tmp2_ = 0; -+ gchar* filter_str = NULL; -+ const gchar* _tmp6_ = NULL; -+ gchar* _tmp7_ = NULL; -+ const gchar* _tmp8_ = NULL; -+ gchar* _tmp9_ = NULL; -+ self = (RygelLMSAllMusic*) base; -+ g_return_val_if_fail (filter != NULL, NULL); -+ _tmp0_ = filter; -+ _tmp1_ = strlen (_tmp0_); -+ _tmp2_ = _tmp1_; -+ if (_tmp2_ == 0) { -+ const gchar* _tmp3_ = NULL; -+ const gchar* _tmp4_ = NULL; -+ gchar* _tmp5_ = NULL; -+ _tmp3_ = rygel_lms_category_container_get_sql_all ((RygelLMSCategoryContainer*) self); -+ _tmp4_ = _tmp3_; -+ _tmp5_ = g_strdup (_tmp4_); -+ result = _tmp5_; -+ return result; -+ } -+ _tmp6_ = filter; -+ _tmp7_ = g_strdup_printf ("AND %s", _tmp6_); -+ filter_str = _tmp7_; -+ _tmp8_ = filter_str; -+ _tmp9_ = g_strdup_printf (RYGEL_LMS_ALL_MUSIC_SQL_ALL_TEMPLATE, _tmp8_); -+ result = _tmp9_; -+ _g_free0 (filter_str); -+ return result; -+} -+ -+ -+static gchar* rygel_lms_all_music_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) { -+ RygelLMSAllMusic * self; -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gint _tmp2_ = 0; -+ gchar* filter_str = NULL; -+ const gchar* _tmp6_ = NULL; -+ gchar* _tmp7_ = NULL; -+ const gchar* _tmp8_ = NULL; -+ gchar* _tmp9_ = NULL; -+ self = (RygelLMSAllMusic*) base; -+ g_return_val_if_fail (filter != NULL, NULL); -+ _tmp0_ = filter; -+ _tmp1_ = strlen (_tmp0_); -+ _tmp2_ = _tmp1_; -+ if (_tmp2_ == 0) { -+ const gchar* _tmp3_ = NULL; -+ const gchar* _tmp4_ = NULL; -+ gchar* _tmp5_ = NULL; -+ _tmp3_ = rygel_lms_category_container_get_sql_count ((RygelLMSCategoryContainer*) self); -+ _tmp4_ = _tmp3_; -+ _tmp5_ = g_strdup (_tmp4_); -+ result = _tmp5_; -+ return result; -+ } -+ _tmp6_ = filter; -+ _tmp7_ = g_strdup_printf ("AND %s", _tmp6_); -+ filter_str = _tmp7_; -+ _tmp8_ = filter_str; -+ _tmp9_ = g_strdup_printf (RYGEL_LMS_ALL_MUSIC_SQL_COUNT_WITH_FILTER_TEMPLATE, _tmp8_); -+ result = _tmp9_; -+ _g_free0 (filter_str); -+ return result; -+} -+ -+ -+static RygelMediaObject* rygel_lms_all_music_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { -+ RygelLMSAllMusic * self; -+ RygelMediaObject* result = NULL; -+ gint id = 0; -+ sqlite3_stmt* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gchar* path = NULL; -+ sqlite3_stmt* _tmp2_ = NULL; -+ const gchar* _tmp3_ = NULL; -+ gchar* _tmp4_ = NULL; -+ gchar* mime_type = NULL; -+ sqlite3_stmt* _tmp5_ = NULL; -+ const gchar* _tmp6_ = NULL; -+ gchar* _tmp7_ = NULL; -+ gboolean _tmp8_ = FALSE; -+ const gchar* _tmp9_ = NULL; -+ gchar* title = NULL; -+ sqlite3_stmt* _tmp15_ = NULL; -+ const gchar* _tmp16_ = NULL; -+ gchar* _tmp17_ = NULL; -+ gchar* song_id = NULL; -+ gint _tmp18_ = 0; -+ gchar* _tmp19_ = NULL; -+ RygelMusicItem* song = NULL; -+ RygelMusicItem* _tmp20_ = NULL; -+ sqlite3_stmt* _tmp21_ = NULL; -+ gint _tmp22_ = 0; -+ sqlite3_stmt* _tmp23_ = NULL; -+ gint _tmp24_ = 0; -+ sqlite3_stmt* _tmp25_ = NULL; -+ gint _tmp26_ = 0; -+ sqlite3_stmt* _tmp27_ = NULL; -+ gint _tmp28_ = 0; -+ sqlite3_stmt* _tmp29_ = NULL; -+ gint _tmp30_ = 0; -+ sqlite3_stmt* _tmp31_ = NULL; -+ gint _tmp32_ = 0; -+ sqlite3_stmt* _tmp33_ = NULL; -+ const gchar* _tmp34_ = NULL; -+ const gchar* _tmp35_ = NULL; -+ sqlite3_stmt* _tmp36_ = NULL; -+ const gchar* _tmp37_ = NULL; -+ sqlite3_stmt* _tmp38_ = NULL; -+ const gchar* _tmp39_ = NULL; -+ GTimeVal tv = {0}; -+ sqlite3_stmt* _tmp40_ = NULL; -+ gint _tmp41_ = 0; -+ GTimeVal _tmp42_ = {0}; -+ gchar* _tmp43_ = NULL; -+ gchar* _tmp44_ = NULL; -+ sqlite3_stmt* _tmp45_ = NULL; -+ const gchar* _tmp46_ = NULL; -+ GFile* file = NULL; -+ const gchar* _tmp47_ = NULL; -+ GFile* _tmp48_ = NULL; -+ gchar* _tmp49_ = NULL; -+ gchar* _tmp50_ = NULL; -+ self = (RygelLMSAllMusic*) base; -+ g_return_val_if_fail (statement != NULL, NULL); -+ _tmp0_ = statement; -+ _tmp1_ = sqlite3_column_int (_tmp0_, 0); -+ id = _tmp1_; -+ _tmp2_ = statement; -+ _tmp3_ = sqlite3_column_text (_tmp2_, 1); -+ _tmp4_ = g_strdup (_tmp3_); -+ path = _tmp4_; -+ _tmp5_ = statement; -+ _tmp6_ = sqlite3_column_text (_tmp5_, 10); -+ _tmp7_ = g_strdup (_tmp6_); -+ mime_type = _tmp7_; -+ _tmp9_ = mime_type; -+ if (_tmp9_ == NULL) { -+ _tmp8_ = TRUE; -+ } else { -+ const gchar* _tmp10_ = NULL; -+ gint _tmp11_ = 0; -+ gint _tmp12_ = 0; -+ _tmp10_ = mime_type; -+ _tmp11_ = strlen (_tmp10_); -+ _tmp12_ = _tmp11_; -+ _tmp8_ = _tmp12_ == 0; -+ } -+ if (_tmp8_) { -+ gint _tmp13_ = 0; -+ const gchar* _tmp14_ = NULL; -+ _tmp13_ = id; -+ _tmp14_ = path; -+ g_debug ("rygel-lms-all-music.vala:130: Music item %d (%s) has no MIME type", _tmp13_, _tmp14_); -+ } -+ _tmp15_ = statement; -+ _tmp16_ = sqlite3_column_text (_tmp15_, 3); -+ _tmp17_ = g_strdup (_tmp16_); -+ title = _tmp17_; -+ _tmp18_ = id; -+ _tmp19_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp18_); -+ song_id = _tmp19_; -+ _tmp20_ = rygel_music_item_new (song_id, (RygelMediaContainer*) self, title, RYGEL_MUSIC_ITEM_UPNP_CLASS); -+ song = _tmp20_; -+ _tmp21_ = statement; -+ _tmp22_ = sqlite3_column_int (_tmp21_, 2); -+ rygel_media_file_item_set_size ((RygelMediaFileItem*) song, (gint64) _tmp22_); -+ _tmp23_ = statement; -+ _tmp24_ = sqlite3_column_int (_tmp23_, 4); -+ rygel_music_item_set_track_number (song, _tmp24_); -+ _tmp25_ = statement; -+ _tmp26_ = sqlite3_column_int (_tmp25_, 5); -+ rygel_audio_item_set_duration ((RygelAudioItem*) song, (glong) _tmp26_); -+ _tmp27_ = statement; -+ _tmp28_ = sqlite3_column_int (_tmp27_, 6); -+ rygel_audio_item_set_channels ((RygelAudioItem*) song, _tmp28_); -+ _tmp29_ = statement; -+ _tmp30_ = sqlite3_column_int (_tmp29_, 7); -+ rygel_audio_item_set_sample_freq ((RygelAudioItem*) song, _tmp30_); -+ _tmp31_ = statement; -+ _tmp32_ = sqlite3_column_int (_tmp31_, 8); -+ rygel_audio_item_set_bitrate ((RygelAudioItem*) song, _tmp32_); -+ _tmp33_ = statement; -+ _tmp34_ = sqlite3_column_text (_tmp33_, 9); -+ rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) song, _tmp34_); -+ _tmp35_ = mime_type; -+ rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) song, _tmp35_); -+ _tmp36_ = statement; -+ _tmp37_ = sqlite3_column_text (_tmp36_, 11); -+ rygel_media_object_set_artist ((RygelMediaObject*) song, _tmp37_); -+ _tmp38_ = statement; -+ _tmp39_ = sqlite3_column_text (_tmp38_, 12); -+ rygel_audio_item_set_album ((RygelAudioItem*) song, _tmp39_); -+ _tmp40_ = statement; -+ _tmp41_ = sqlite3_column_int (_tmp40_, 13); -+ _tmp42_.tv_sec = (glong) _tmp41_; -+ _tmp42_.tv_usec = (glong) 0; -+ tv = _tmp42_; -+ _tmp43_ = g_time_val_to_iso8601 (&tv); -+ _tmp44_ = _tmp43_; -+ rygel_media_object_set_date ((RygelMediaObject*) song, _tmp44_); -+ _g_free0 (_tmp44_); -+ _tmp45_ = statement; -+ _tmp46_ = sqlite3_column_text (_tmp45_, 14); -+ rygel_media_object_set_genre ((RygelMediaObject*) song, _tmp46_); -+ _tmp47_ = path; -+ _tmp48_ = g_file_new_for_path (_tmp47_); -+ file = _tmp48_; -+ _tmp49_ = g_file_get_uri (file); -+ _tmp50_ = _tmp49_; -+ rygel_media_object_add_uri ((RygelMediaObject*) song, _tmp50_); -+ _g_free0 (_tmp50_); -+ result = (RygelMediaObject*) song; -+ _g_object_unref0 (file); -+ _g_free0 (song_id); -+ _g_free0 (title); -+ _g_free0 (mime_type); -+ _g_free0 (path); -+ return result; -+} -+ -+ -+RygelLMSAllMusic* rygel_lms_all_music_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { -+ RygelLMSAllMusic * self = NULL; -+ RygelMediaContainer* _tmp0_ = NULL; -+ const gchar* _tmp1_ = NULL; -+ RygelLMSDatabase* _tmp2_ = NULL; -+ gchar* _tmp3_ = NULL; -+ gchar* _tmp4_ = NULL; -+ g_return_val_if_fail (parent != NULL, NULL); -+ g_return_val_if_fail (lms_db != NULL, NULL); -+ _tmp0_ = parent; -+ _tmp1_ = _ ("All"); -+ _tmp2_ = lms_db; -+ _tmp3_ = g_strdup_printf (RYGEL_LMS_ALL_MUSIC_SQL_ALL_TEMPLATE, ""); -+ _tmp4_ = _tmp3_; -+ self = (RygelLMSAllMusic*) rygel_lms_category_container_construct (object_type, "all", _tmp0_, _tmp1_, _tmp2_, _tmp4_, RYGEL_LMS_ALL_MUSIC_SQL_FIND_OBJECT, RYGEL_LMS_ALL_MUSIC_SQL_COUNT, RYGEL_LMS_ALL_MUSIC_SQL_ADDED, RYGEL_LMS_ALL_MUSIC_SQL_REMOVED); -+ _g_free0 (_tmp4_); -+ return self; -+} -+ -+ -+RygelLMSAllMusic* rygel_lms_all_music_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { -+ return rygel_lms_all_music_construct (RYGEL_LMS_TYPE_ALL_MUSIC, parent, lms_db); -+} -+ -+ -+static void rygel_lms_all_music_class_init (RygelLMSAllMusicClass * klass) { -+ rygel_lms_all_music_parent_class = g_type_class_peek_parent (klass); -+ ((RygelLMSCategoryContainerClass *) klass)->get_sql_all_with_filter = rygel_lms_all_music_real_get_sql_all_with_filter; -+ ((RygelLMSCategoryContainerClass *) klass)->get_sql_count_with_filter = rygel_lms_all_music_real_get_sql_count_with_filter; -+ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_all_music_real_object_from_statement; -+} -+ -+ -+static void rygel_lms_all_music_instance_init (RygelLMSAllMusic * self) { -+} -+ -+ -+GType rygel_lms_all_music_get_type (void) { -+ static volatile gsize rygel_lms_all_music_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_all_music_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAllMusicClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_all_music_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAllMusic), 0, (GInstanceInitFunc) rygel_lms_all_music_instance_init, NULL }; -+ GType rygel_lms_all_music_type_id; -+ rygel_lms_all_music_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAllMusic", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_all_music_type_id__volatile, rygel_lms_all_music_type_id); -+ } -+ return rygel_lms_all_music_type_id__volatile; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-all-videos.c b/src/plugins/lms/rygel-lms-all-videos.c -new file mode 100644 -index 0000000..51ba52c ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-all-videos.c -@@ -0,0 +1,456 @@ -+/* rygel-lms-all-videos.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-all-videos.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-server.h> -+#include <sqlite3.h> -+#include <stdlib.h> -+#include <string.h> -+#include <gio/gio.h> -+ -+ -+#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) -+#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+ -+typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; -+typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; -+typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; -+ -+#define RYGEL_LMS_TYPE_ALL_VIDEOS (rygel_lms_all_videos_get_type ()) -+#define RYGEL_LMS_ALL_VIDEOS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideos)) -+#define RYGEL_LMS_ALL_VIDEOS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideosClass)) -+#define RYGEL_LMS_IS_ALL_VIDEOS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS)) -+#define RYGEL_LMS_IS_ALL_VIDEOS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_VIDEOS)) -+#define RYGEL_LMS_ALL_VIDEOS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideosClass)) -+ -+typedef struct _RygelLMSAllVideos RygelLMSAllVideos; -+typedef struct _RygelLMSAllVideosClass RygelLMSAllVideosClass; -+typedef struct _RygelLMSAllVideosPrivate RygelLMSAllVideosPrivate; -+#define _g_free0(var) (var = (g_free (var), NULL)) -+ -+#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) -+#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) -+#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+ -+typedef struct _RygelLMSDatabase RygelLMSDatabase; -+typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; -+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) -+#define _sqlite3_finalize0(var) ((var == NULL) ? NULL : (var = (sqlite3_finalize (var), NULL))) -+#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) -+ -+struct _RygelLMSCategoryContainer { -+ RygelMediaContainer parent_instance; -+ RygelLMSCategoryContainerPrivate * priv; -+ sqlite3_stmt* stmt_all; -+ sqlite3_stmt* stmt_find_object; -+ sqlite3_stmt* stmt_added; -+ sqlite3_stmt* stmt_removed; -+ gchar* child_prefix; -+ gchar* ref_prefix; -+}; -+ -+struct _RygelLMSCategoryContainerClass { -+ RygelMediaContainerClass parent_class; -+ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); -+ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); -+ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); -+}; -+ -+struct _RygelLMSAllVideos { -+ RygelLMSCategoryContainer parent_instance; -+ RygelLMSAllVideosPrivate * priv; -+}; -+ -+struct _RygelLMSAllVideosClass { -+ RygelLMSCategoryContainerClass parent_class; -+}; -+ -+typedef enum { -+ RYGEL_LMS_DATABASE_ERROR_OPEN, -+ RYGEL_LMS_DATABASE_ERROR_PREPARE, -+ RYGEL_LMS_DATABASE_ERROR_BIND, -+ RYGEL_LMS_DATABASE_ERROR_STEP, -+ RYGEL_LMS_DATABASE_ERROR_NOT_FOUND -+} RygelLMSDatabaseError; -+#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark () -+ -+static gpointer rygel_lms_all_videos_parent_class = NULL; -+ -+GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; -+GType rygel_lms_all_videos_get_type (void) G_GNUC_CONST; -+enum { -+ RYGEL_LMS_ALL_VIDEOS_DUMMY_PROPERTY -+}; -+#define RYGEL_LMS_ALL_VIDEOS_SQL_ALL "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profi" \ -+"le, dlna_mime " "FROM videos, files " "WHERE dtime = 0 AND videos.id = files.id " "LIMIT ? OFFSET ?;" -+#define RYGEL_LMS_ALL_VIDEOS_SQL_COUNT "SELECT count(videos.id) " "FROM videos, files " "WHERE dtime = 0 AND videos.id = files.id;" -+#define RYGEL_LMS_ALL_VIDEOS_SQL_FIND_OBJECT "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profi" \ -+"le, dlna_mime " "FROM videos, files " "WHERE dtime = 0 AND files.id = ? AND videos.id = files.id;" -+#define RYGEL_LMS_ALL_VIDEOS_SQL_ADDED "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profi" \ -+"le, dlna_mime " "FROM videos, files " "WHERE dtime = 0 AND videos.id = files.id " "AND update_id > ? AND update_id <= ?;" -+#define RYGEL_LMS_ALL_VIDEOS_SQL_REMOVED "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profi" \ -+"le, dlna_mime " "FROM videos, files " "WHERE dtime <> 0 AND videos.id = files.id " "AND update_id > ? AND update_id <= ?;" -+static RygelMediaObject* rygel_lms_all_videos_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); -+gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id); -+gpointer rygel_lms_database_ref (gpointer instance); -+void rygel_lms_database_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_database (GValue* value, gpointer v_object); -+void rygel_lms_value_take_database (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_database (const GValue* value); -+GType rygel_lms_database_get_type (void) G_GNUC_CONST; -+RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self); -+GQuark rygel_lms_database_error_quark (void); -+sqlite3_stmt* rygel_lms_database_prepare (RygelLMSDatabase* self, const gchar* query_string, GError** error); -+void rygel_lms_database_find_object (const gchar* id, sqlite3_stmt* stmt, GError** error); -+RygelLMSAllVideos* rygel_lms_all_videos_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSAllVideos* rygel_lms_all_videos_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); -+ -+ -+static RygelMediaObject* rygel_lms_all_videos_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { -+ RygelLMSAllVideos * self; -+ RygelMediaObject* result = NULL; -+ gint id = 0; -+ sqlite3_stmt* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gchar* mime_type = NULL; -+ sqlite3_stmt* _tmp2_ = NULL; -+ const gchar* _tmp3_ = NULL; -+ gchar* _tmp4_ = NULL; -+ gchar* path = NULL; -+ sqlite3_stmt* _tmp5_ = NULL; -+ const gchar* _tmp6_ = NULL; -+ gchar* _tmp7_ = NULL; -+ GFile* file = NULL; -+ const gchar* _tmp8_ = NULL; -+ GFile* _tmp9_ = NULL; -+ gboolean _tmp10_ = FALSE; -+ const gchar* _tmp11_ = NULL; -+ gchar* title = NULL; -+ sqlite3_stmt* _tmp17_ = NULL; -+ const gchar* _tmp18_ = NULL; -+ gchar* _tmp19_ = NULL; -+ RygelVideoItem* video = NULL; -+ gint _tmp20_ = 0; -+ gchar* _tmp21_ = NULL; -+ gchar* _tmp22_ = NULL; -+ const gchar* _tmp23_ = NULL; -+ RygelVideoItem* _tmp24_ = NULL; -+ RygelVideoItem* _tmp25_ = NULL; -+ RygelVideoItem* _tmp26_ = NULL; -+ sqlite3_stmt* _tmp27_ = NULL; -+ const gchar* _tmp28_ = NULL; -+ RygelVideoItem* _tmp29_ = NULL; -+ sqlite3_stmt* _tmp30_ = NULL; -+ gint _tmp31_ = 0; -+ GTimeVal tv = {0}; -+ sqlite3_stmt* _tmp32_ = NULL; -+ gint _tmp33_ = 0; -+ GTimeVal _tmp34_ = {0}; -+ RygelVideoItem* _tmp35_ = NULL; -+ gchar* _tmp36_ = NULL; -+ gchar* _tmp37_ = NULL; -+ RygelVideoItem* _tmp38_ = NULL; -+ sqlite3_stmt* _tmp39_ = NULL; -+ gint _tmp40_ = 0; -+ RygelVideoItem* _tmp41_ = NULL; -+ sqlite3_stmt* _tmp42_ = NULL; -+ const gchar* _tmp43_ = NULL; -+ RygelVideoItem* _tmp44_ = NULL; -+ const gchar* _tmp45_ = NULL; -+ RygelVideoItem* _tmp46_ = NULL; -+ GFile* _tmp47_ = NULL; -+ gchar* _tmp48_ = NULL; -+ gchar* _tmp49_ = NULL; -+ gchar* video_data = NULL; -+ gchar* _tmp50_ = NULL; -+ GError * _inner_error_ = NULL; -+ self = (RygelLMSAllVideos*) base; -+ g_return_val_if_fail (statement != NULL, NULL); -+ _tmp0_ = statement; -+ _tmp1_ = sqlite3_column_int (_tmp0_, 0); -+ id = _tmp1_; -+ _tmp2_ = statement; -+ _tmp3_ = sqlite3_column_text (_tmp2_, 8); -+ _tmp4_ = g_strdup (_tmp3_); -+ mime_type = _tmp4_; -+ _tmp5_ = statement; -+ _tmp6_ = sqlite3_column_text (_tmp5_, 4); -+ _tmp7_ = g_strdup (_tmp6_); -+ path = _tmp7_; -+ _tmp8_ = path; -+ _tmp9_ = g_file_new_for_path (_tmp8_); -+ file = _tmp9_; -+ _tmp11_ = mime_type; -+ if (_tmp11_ == NULL) { -+ _tmp10_ = TRUE; -+ } else { -+ const gchar* _tmp12_ = NULL; -+ gint _tmp13_ = 0; -+ gint _tmp14_ = 0; -+ _tmp12_ = mime_type; -+ _tmp13_ = strlen (_tmp12_); -+ _tmp14_ = _tmp13_; -+ _tmp10_ = _tmp14_ == 0; -+ } -+ if (_tmp10_) { -+ gint _tmp15_ = 0; -+ const gchar* _tmp16_ = NULL; -+ _tmp15_ = id; -+ _tmp16_ = path; -+ g_debug ("rygel-lms-all-videos.vala:75: Video item %d (%s) has no MIME type", _tmp15_, _tmp16_); -+ } -+ _tmp17_ = statement; -+ _tmp18_ = sqlite3_column_text (_tmp17_, 1); -+ _tmp19_ = g_strdup (_tmp18_); -+ title = _tmp19_; -+ _tmp20_ = id; -+ _tmp21_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp20_); -+ _tmp22_ = _tmp21_; -+ _tmp23_ = title; -+ _tmp24_ = rygel_video_item_new (_tmp22_, (RygelMediaContainer*) self, _tmp23_, RYGEL_VIDEO_ITEM_UPNP_CLASS); -+ _tmp25_ = _tmp24_; -+ _g_free0 (_tmp22_); -+ video = _tmp25_; -+ _tmp26_ = video; -+ _tmp27_ = statement; -+ _tmp28_ = sqlite3_column_text (_tmp27_, 2); -+ rygel_media_object_set_creator ((RygelMediaObject*) _tmp26_, _tmp28_); -+ _tmp29_ = video; -+ _tmp30_ = statement; -+ _tmp31_ = sqlite3_column_int (_tmp30_, 3); -+ rygel_audio_item_set_duration ((RygelAudioItem*) _tmp29_, (glong) _tmp31_); -+ _tmp32_ = statement; -+ _tmp33_ = sqlite3_column_int (_tmp32_, 5); -+ _tmp34_.tv_sec = (glong) _tmp33_; -+ _tmp34_.tv_usec = (glong) 0; -+ tv = _tmp34_; -+ _tmp35_ = video; -+ _tmp36_ = g_time_val_to_iso8601 (&tv); -+ _tmp37_ = _tmp36_; -+ rygel_media_object_set_date ((RygelMediaObject*) _tmp35_, _tmp37_); -+ _g_free0 (_tmp37_); -+ _tmp38_ = video; -+ _tmp39_ = statement; -+ _tmp40_ = sqlite3_column_int (_tmp39_, 6); -+ rygel_media_file_item_set_size ((RygelMediaFileItem*) _tmp38_, (gint64) _tmp40_); -+ _tmp41_ = video; -+ _tmp42_ = statement; -+ _tmp43_ = sqlite3_column_text (_tmp42_, 7); -+ rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) _tmp41_, _tmp43_); -+ _tmp44_ = video; -+ _tmp45_ = mime_type; -+ rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) _tmp44_, _tmp45_); -+ _tmp46_ = video; -+ _tmp47_ = file; -+ _tmp48_ = g_file_get_uri (_tmp47_); -+ _tmp49_ = _tmp48_; -+ rygel_media_object_add_uri ((RygelMediaObject*) _tmp46_, _tmp49_); -+ _g_free0 (_tmp49_); -+ _tmp50_ = g_strdup ("select videos_videos.bitrate + videos_audios.bitrate, width, height, c" \ -+"hannels, sampling_rate " "from videos, videos_audios, videos_videos where videos.id = ? " "and videos.id = videos_audios.video_id and videos.id = videos_videos.v" \ -+"ideo_id;"); -+ video_data = _tmp50_; -+ { -+ sqlite3_stmt* stmt = NULL; -+ RygelLMSDatabase* _tmp51_ = NULL; -+ RygelLMSDatabase* _tmp52_ = NULL; -+ const gchar* _tmp53_ = NULL; -+ sqlite3_stmt* _tmp54_ = NULL; -+ gint _tmp55_ = 0; -+ gchar* _tmp56_ = NULL; -+ gchar* _tmp57_ = NULL; -+ sqlite3_stmt* _tmp58_ = NULL; -+ RygelVideoItem* _tmp59_ = NULL; -+ sqlite3_stmt* _tmp60_ = NULL; -+ gint _tmp61_ = 0; -+ RygelVideoItem* _tmp62_ = NULL; -+ sqlite3_stmt* _tmp63_ = NULL; -+ gint _tmp64_ = 0; -+ RygelVideoItem* _tmp65_ = NULL; -+ sqlite3_stmt* _tmp66_ = NULL; -+ gint _tmp67_ = 0; -+ RygelVideoItem* _tmp68_ = NULL; -+ sqlite3_stmt* _tmp69_ = NULL; -+ gint _tmp70_ = 0; -+ RygelVideoItem* _tmp71_ = NULL; -+ sqlite3_stmt* _tmp72_ = NULL; -+ gint _tmp73_ = 0; -+ _tmp51_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); -+ _tmp52_ = _tmp51_; -+ _tmp53_ = video_data; -+ _tmp54_ = rygel_lms_database_prepare (_tmp52_, _tmp53_, &_inner_error_); -+ stmt = _tmp54_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch10_rygel_lms_database_error; -+ } -+ _g_free0 (video_data); -+ _g_object_unref0 (video); -+ _g_free0 (title); -+ _g_object_unref0 (file); -+ _g_free0 (path); -+ _g_free0 (mime_type); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ _tmp55_ = id; -+ _tmp56_ = g_strdup_printf ("%d", _tmp55_); -+ _tmp57_ = _tmp56_; -+ _tmp58_ = stmt; -+ rygel_lms_database_find_object (_tmp57_, _tmp58_, &_inner_error_); -+ _g_free0 (_tmp57_); -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _sqlite3_finalize0 (stmt); -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch10_rygel_lms_database_error; -+ } -+ _sqlite3_finalize0 (stmt); -+ _g_free0 (video_data); -+ _g_object_unref0 (video); -+ _g_free0 (title); -+ _g_object_unref0 (file); -+ _g_free0 (path); -+ _g_free0 (mime_type); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ _tmp59_ = video; -+ _tmp60_ = stmt; -+ _tmp61_ = sqlite3_column_int (_tmp60_, 0); -+ rygel_audio_item_set_bitrate ((RygelAudioItem*) _tmp59_, _tmp61_ / 8); -+ _tmp62_ = video; -+ _tmp63_ = stmt; -+ _tmp64_ = sqlite3_column_int (_tmp63_, 1); -+ rygel_visual_item_set_width ((RygelVisualItem*) _tmp62_, _tmp64_); -+ _tmp65_ = video; -+ _tmp66_ = stmt; -+ _tmp67_ = sqlite3_column_int (_tmp66_, 2); -+ rygel_visual_item_set_height ((RygelVisualItem*) _tmp65_, _tmp67_); -+ _tmp68_ = video; -+ _tmp69_ = stmt; -+ _tmp70_ = sqlite3_column_int (_tmp69_, 3); -+ rygel_audio_item_set_channels ((RygelAudioItem*) _tmp68_, _tmp70_); -+ _tmp71_ = video; -+ _tmp72_ = stmt; -+ _tmp73_ = sqlite3_column_int (_tmp72_, 4); -+ rygel_audio_item_set_sample_freq ((RygelAudioItem*) _tmp71_, _tmp73_); -+ _sqlite3_finalize0 (stmt); -+ } -+ goto __finally10; -+ __catch10_rygel_lms_database_error: -+ { -+ GError* e = NULL; -+ GError* _tmp74_ = NULL; -+ const gchar* _tmp75_ = NULL; -+ e = _inner_error_; -+ _inner_error_ = NULL; -+ _tmp74_ = e; -+ _tmp75_ = _tmp74_->message; -+ g_warning ("rygel-lms-all-videos.vala:105: Query failed: %s", _tmp75_); -+ _g_error_free0 (e); -+ } -+ __finally10: -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _g_free0 (video_data); -+ _g_object_unref0 (video); -+ _g_free0 (title); -+ _g_object_unref0 (file); -+ _g_free0 (path); -+ _g_free0 (mime_type); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ result = (RygelMediaObject*) video; -+ _g_free0 (video_data); -+ _g_free0 (title); -+ _g_object_unref0 (file); -+ _g_free0 (path); -+ _g_free0 (mime_type); -+ return result; -+} -+ -+ -+RygelLMSAllVideos* rygel_lms_all_videos_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { -+ RygelLMSAllVideos * self = NULL; -+ const gchar* _tmp0_ = NULL; -+ RygelMediaContainer* _tmp1_ = NULL; -+ const gchar* _tmp2_ = NULL; -+ RygelLMSDatabase* _tmp3_ = NULL; -+ g_return_val_if_fail (id != NULL, NULL); -+ g_return_val_if_fail (parent != NULL, NULL); -+ g_return_val_if_fail (title != NULL, NULL); -+ g_return_val_if_fail (lms_db != NULL, NULL); -+ _tmp0_ = id; -+ _tmp1_ = parent; -+ _tmp2_ = title; -+ _tmp3_ = lms_db; -+ self = (RygelLMSAllVideos*) rygel_lms_category_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_, _tmp3_, RYGEL_LMS_ALL_VIDEOS_SQL_ALL, RYGEL_LMS_ALL_VIDEOS_SQL_FIND_OBJECT, RYGEL_LMS_ALL_VIDEOS_SQL_COUNT, RYGEL_LMS_ALL_VIDEOS_SQL_ADDED, RYGEL_LMS_ALL_VIDEOS_SQL_REMOVED); -+ return self; -+} -+ -+ -+RygelLMSAllVideos* rygel_lms_all_videos_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { -+ return rygel_lms_all_videos_construct (RYGEL_LMS_TYPE_ALL_VIDEOS, id, parent, title, lms_db); -+} -+ -+ -+static void rygel_lms_all_videos_class_init (RygelLMSAllVideosClass * klass) { -+ rygel_lms_all_videos_parent_class = g_type_class_peek_parent (klass); -+ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_all_videos_real_object_from_statement; -+} -+ -+ -+static void rygel_lms_all_videos_instance_init (RygelLMSAllVideos * self) { -+} -+ -+ -+GType rygel_lms_all_videos_get_type (void) { -+ static volatile gsize rygel_lms_all_videos_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_all_videos_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAllVideosClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_all_videos_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAllVideos), 0, (GInstanceInitFunc) rygel_lms_all_videos_instance_init, NULL }; -+ GType rygel_lms_all_videos_type_id; -+ rygel_lms_all_videos_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAllVideos", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_all_videos_type_id__volatile, rygel_lms_all_videos_type_id); -+ } -+ return rygel_lms_all_videos_type_id__volatile; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-artist.c b/src/plugins/lms/rygel-lms-artist.c -new file mode 100644 -index 0000000..e686ea4 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-artist.c -@@ -0,0 +1,274 @@ -+/* rygel-lms-artist.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-artist.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-server.h> -+#include <sqlite3.h> -+#include <stdlib.h> -+#include <string.h> -+ -+ -+#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) -+#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+ -+typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; -+typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; -+typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; -+ -+#define RYGEL_LMS_TYPE_ARTIST (rygel_lms_artist_get_type ()) -+#define RYGEL_LMS_ARTIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtist)) -+#define RYGEL_LMS_ARTIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtistClass)) -+#define RYGEL_LMS_IS_ARTIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ARTIST)) -+#define RYGEL_LMS_IS_ARTIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ARTIST)) -+#define RYGEL_LMS_ARTIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtistClass)) -+ -+typedef struct _RygelLMSArtist RygelLMSArtist; -+typedef struct _RygelLMSArtistClass RygelLMSArtistClass; -+typedef struct _RygelLMSArtistPrivate RygelLMSArtistPrivate; -+ -+#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) -+#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) -+#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+ -+typedef struct _RygelLMSDatabase RygelLMSDatabase; -+typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; -+ -+#define RYGEL_LMS_TYPE_ALBUM (rygel_lms_album_get_type ()) -+#define RYGEL_LMS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbum)) -+#define RYGEL_LMS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass)) -+#define RYGEL_LMS_IS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUM)) -+#define RYGEL_LMS_IS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUM)) -+#define RYGEL_LMS_ALBUM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass)) -+ -+typedef struct _RygelLMSAlbum RygelLMSAlbum; -+typedef struct _RygelLMSAlbumClass RygelLMSAlbumClass; -+#define _g_free0(var) (var = (g_free (var), NULL)) -+ -+struct _RygelLMSCategoryContainer { -+ RygelMediaContainer parent_instance; -+ RygelLMSCategoryContainerPrivate * priv; -+ sqlite3_stmt* stmt_all; -+ sqlite3_stmt* stmt_find_object; -+ sqlite3_stmt* stmt_added; -+ sqlite3_stmt* stmt_removed; -+ gchar* child_prefix; -+ gchar* ref_prefix; -+}; -+ -+struct _RygelLMSCategoryContainerClass { -+ RygelMediaContainerClass parent_class; -+ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); -+ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); -+ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); -+}; -+ -+struct _RygelLMSArtist { -+ RygelLMSCategoryContainer parent_instance; -+ RygelLMSArtistPrivate * priv; -+}; -+ -+struct _RygelLMSArtistClass { -+ RygelLMSCategoryContainerClass parent_class; -+}; -+ -+ -+static gpointer rygel_lms_artist_parent_class = NULL; -+ -+GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; -+GType rygel_lms_artist_get_type (void) G_GNUC_CONST; -+enum { -+ RYGEL_LMS_ARTIST_DUMMY_PROPERTY -+}; -+#define RYGEL_LMS_ARTIST_SQL_ALL_TEMPLATE "SELECT audio_albums.id, audio_albums.name " "FROM audio_albums " "WHERE audio_albums.artist_id = %s " "LIMIT ? OFFSET ?;" -+#define RYGEL_LMS_ARTIST_SQL_COUNT_TEMPLATE "SELECT COUNT(audio_albums.id) " "FROM audio_albums " "WHERE audio_albums.artist_id = %s" -+#define RYGEL_LMS_ARTIST_SQL_FIND_OBJECT_TEMPLATE "SELECT audio_albums.id, audio_albums.name " "FROM audio_albums " "WHERE audio_albums.id = ? AND audio_albums.artist_id = %s;" -+static gchar* rygel_lms_artist_get_sql_all (const gchar* id); -+static gchar* rygel_lms_artist_get_sql_find_object (const gchar* id); -+static gchar* rygel_lms_artist_get_sql_count (const gchar* id); -+static RygelMediaObject* rygel_lms_artist_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); -+gpointer rygel_lms_database_ref (gpointer instance); -+void rygel_lms_database_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_database (GValue* value, gpointer v_object); -+void rygel_lms_value_take_database (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_database (const GValue* value); -+GType rygel_lms_database_get_type (void) G_GNUC_CONST; -+RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self); -+RygelLMSAlbum* rygel_lms_album_new (const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSAlbum* rygel_lms_album_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+GType rygel_lms_album_get_type (void) G_GNUC_CONST; -+RygelLMSArtist* rygel_lms_artist_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSArtist* rygel_lms_artist_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); -+ -+ -+static gchar* rygel_lms_artist_get_sql_all (const gchar* id) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (id != NULL, NULL); -+ _tmp0_ = id; -+ _tmp1_ = g_strdup_printf (RYGEL_LMS_ARTIST_SQL_ALL_TEMPLATE, _tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+static gchar* rygel_lms_artist_get_sql_find_object (const gchar* id) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (id != NULL, NULL); -+ _tmp0_ = id; -+ _tmp1_ = g_strdup_printf (RYGEL_LMS_ARTIST_SQL_FIND_OBJECT_TEMPLATE, _tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+static gchar* rygel_lms_artist_get_sql_count (const gchar* id) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (id != NULL, NULL); -+ _tmp0_ = id; -+ _tmp1_ = g_strdup_printf (RYGEL_LMS_ARTIST_SQL_COUNT_TEMPLATE, _tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+static RygelMediaObject* rygel_lms_artist_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { -+ RygelLMSArtist * self; -+ RygelMediaObject* result = NULL; -+ gchar* db_id = NULL; -+ sqlite3_stmt* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gchar* _tmp2_ = NULL; -+ gchar* title = NULL; -+ sqlite3_stmt* _tmp3_ = NULL; -+ const gchar* _tmp4_ = NULL; -+ gchar* _tmp5_ = NULL; -+ RygelLMSDatabase* _tmp6_ = NULL; -+ RygelLMSDatabase* _tmp7_ = NULL; -+ RygelLMSAlbum* _tmp8_ = NULL; -+ self = (RygelLMSArtist*) base; -+ g_return_val_if_fail (statement != NULL, NULL); -+ _tmp0_ = statement; -+ _tmp1_ = sqlite3_column_int (_tmp0_, 0); -+ _tmp2_ = g_strdup_printf ("%d", _tmp1_); -+ db_id = _tmp2_; -+ _tmp3_ = statement; -+ _tmp4_ = sqlite3_column_text (_tmp3_, 1); -+ _tmp5_ = g_strdup (_tmp4_); -+ title = _tmp5_; -+ _tmp6_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); -+ _tmp7_ = _tmp6_; -+ _tmp8_ = rygel_lms_album_new (db_id, (RygelMediaContainer*) self, title, _tmp7_); -+ result = (RygelMediaObject*) _tmp8_; -+ _g_free0 (title); -+ _g_free0 (db_id); -+ return result; -+} -+ -+ -+RygelLMSArtist* rygel_lms_artist_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { -+ RygelLMSArtist * self = NULL; -+ const gchar* _tmp0_ = NULL; -+ RygelMediaContainer* _tmp1_ = NULL; -+ const gchar* _tmp2_ = NULL; -+ RygelLMSDatabase* _tmp3_ = NULL; -+ const gchar* _tmp4_ = NULL; -+ gchar* _tmp5_ = NULL; -+ gchar* _tmp6_ = NULL; -+ const gchar* _tmp7_ = NULL; -+ gchar* _tmp8_ = NULL; -+ gchar* _tmp9_ = NULL; -+ const gchar* _tmp10_ = NULL; -+ gchar* _tmp11_ = NULL; -+ gchar* _tmp12_ = NULL; -+ g_return_val_if_fail (id != NULL, NULL); -+ g_return_val_if_fail (parent != NULL, NULL); -+ g_return_val_if_fail (title != NULL, NULL); -+ g_return_val_if_fail (lms_db != NULL, NULL); -+ _tmp0_ = id; -+ _tmp1_ = parent; -+ _tmp2_ = title; -+ _tmp3_ = lms_db; -+ _tmp4_ = id; -+ _tmp5_ = rygel_lms_artist_get_sql_all (_tmp4_); -+ _tmp6_ = _tmp5_; -+ _tmp7_ = id; -+ _tmp8_ = rygel_lms_artist_get_sql_find_object (_tmp7_); -+ _tmp9_ = _tmp8_; -+ _tmp10_ = id; -+ _tmp11_ = rygel_lms_artist_get_sql_count (_tmp10_); -+ _tmp12_ = _tmp11_; -+ self = (RygelLMSArtist*) rygel_lms_category_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_, _tmp3_, _tmp6_, _tmp9_, _tmp12_, NULL, NULL); -+ _g_free0 (_tmp12_); -+ _g_free0 (_tmp9_); -+ _g_free0 (_tmp6_); -+ return self; -+} -+ -+ -+RygelLMSArtist* rygel_lms_artist_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { -+ return rygel_lms_artist_construct (RYGEL_LMS_TYPE_ARTIST, id, parent, title, lms_db); -+} -+ -+ -+static void rygel_lms_artist_class_init (RygelLMSArtistClass * klass) { -+ rygel_lms_artist_parent_class = g_type_class_peek_parent (klass); -+ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_artist_real_object_from_statement; -+} -+ -+ -+static void rygel_lms_artist_instance_init (RygelLMSArtist * self) { -+} -+ -+ -+GType rygel_lms_artist_get_type (void) { -+ static volatile gsize rygel_lms_artist_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_artist_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSArtistClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_artist_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSArtist), 0, (GInstanceInitFunc) rygel_lms_artist_instance_init, NULL }; -+ GType rygel_lms_artist_type_id; -+ rygel_lms_artist_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSArtist", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_artist_type_id__volatile, rygel_lms_artist_type_id); -+ } -+ return rygel_lms_artist_type_id__volatile; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-artists.c b/src/plugins/lms/rygel-lms-artists.c -new file mode 100644 -index 0000000..3ac85bc ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-artists.c -@@ -0,0 +1,214 @@ -+/* rygel-lms-artists.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-artists.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-server.h> -+#include <sqlite3.h> -+#include <stdlib.h> -+#include <string.h> -+ -+ -+#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) -+#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+ -+typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; -+typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; -+typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; -+ -+#define RYGEL_LMS_TYPE_ARTISTS (rygel_lms_artists_get_type ()) -+#define RYGEL_LMS_ARTISTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtists)) -+#define RYGEL_LMS_ARTISTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtistsClass)) -+#define RYGEL_LMS_IS_ARTISTS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ARTISTS)) -+#define RYGEL_LMS_IS_ARTISTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ARTISTS)) -+#define RYGEL_LMS_ARTISTS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtistsClass)) -+ -+typedef struct _RygelLMSArtists RygelLMSArtists; -+typedef struct _RygelLMSArtistsClass RygelLMSArtistsClass; -+typedef struct _RygelLMSArtistsPrivate RygelLMSArtistsPrivate; -+ -+#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) -+#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) -+#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+ -+typedef struct _RygelLMSDatabase RygelLMSDatabase; -+typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; -+ -+#define RYGEL_LMS_TYPE_ARTIST (rygel_lms_artist_get_type ()) -+#define RYGEL_LMS_ARTIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtist)) -+#define RYGEL_LMS_ARTIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtistClass)) -+#define RYGEL_LMS_IS_ARTIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ARTIST)) -+#define RYGEL_LMS_IS_ARTIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ARTIST)) -+#define RYGEL_LMS_ARTIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtistClass)) -+ -+typedef struct _RygelLMSArtist RygelLMSArtist; -+typedef struct _RygelLMSArtistClass RygelLMSArtistClass; -+#define _g_free0(var) (var = (g_free (var), NULL)) -+ -+struct _RygelLMSCategoryContainer { -+ RygelMediaContainer parent_instance; -+ RygelLMSCategoryContainerPrivate * priv; -+ sqlite3_stmt* stmt_all; -+ sqlite3_stmt* stmt_find_object; -+ sqlite3_stmt* stmt_added; -+ sqlite3_stmt* stmt_removed; -+ gchar* child_prefix; -+ gchar* ref_prefix; -+}; -+ -+struct _RygelLMSCategoryContainerClass { -+ RygelMediaContainerClass parent_class; -+ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); -+ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); -+ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); -+}; -+ -+struct _RygelLMSArtists { -+ RygelLMSCategoryContainer parent_instance; -+ RygelLMSArtistsPrivate * priv; -+}; -+ -+struct _RygelLMSArtistsClass { -+ RygelLMSCategoryContainerClass parent_class; -+}; -+ -+ -+static gpointer rygel_lms_artists_parent_class = NULL; -+ -+GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; -+GType rygel_lms_artists_get_type (void) G_GNUC_CONST; -+enum { -+ RYGEL_LMS_ARTISTS_DUMMY_PROPERTY -+}; -+#define RYGEL_LMS_ARTISTS_SQL_ALL "SELECT audio_artists.id, audio_artists.name " "FROM audio_artists " "LIMIT ? OFFSET ?;" -+#define RYGEL_LMS_ARTISTS_SQL_COUNT "SELECT COUNT(audio_artists.id) " "FROM audio_artists;" -+#define RYGEL_LMS_ARTISTS_SQL_FIND_OBJECT "SELECT audio_artists.id, audio_artists.name " "FROM audio_artists " "WHERE audio_artists.id = ?;" -+static RygelMediaObject* rygel_lms_artists_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); -+gpointer rygel_lms_database_ref (gpointer instance); -+void rygel_lms_database_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_database (GValue* value, gpointer v_object); -+void rygel_lms_value_take_database (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_database (const GValue* value); -+GType rygel_lms_database_get_type (void) G_GNUC_CONST; -+RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self); -+RygelLMSArtist* rygel_lms_artist_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSArtist* rygel_lms_artist_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+GType rygel_lms_artist_get_type (void) G_GNUC_CONST; -+RygelLMSArtists* rygel_lms_artists_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSArtists* rygel_lms_artists_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); -+ -+ -+static RygelMediaObject* rygel_lms_artists_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { -+ RygelLMSArtists * self; -+ RygelMediaObject* result = NULL; -+ gchar* db_id = NULL; -+ sqlite3_stmt* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gchar* _tmp2_ = NULL; -+ gchar* title = NULL; -+ sqlite3_stmt* _tmp3_ = NULL; -+ const gchar* _tmp4_ = NULL; -+ gchar* _tmp5_ = NULL; -+ RygelLMSDatabase* _tmp6_ = NULL; -+ RygelLMSDatabase* _tmp7_ = NULL; -+ RygelLMSArtist* _tmp8_ = NULL; -+ self = (RygelLMSArtists*) base; -+ g_return_val_if_fail (statement != NULL, NULL); -+ _tmp0_ = statement; -+ _tmp1_ = sqlite3_column_int (_tmp0_, 0); -+ _tmp2_ = g_strdup_printf ("%d", _tmp1_); -+ db_id = _tmp2_; -+ _tmp3_ = statement; -+ _tmp4_ = sqlite3_column_text (_tmp3_, 1); -+ _tmp5_ = g_strdup (_tmp4_); -+ title = _tmp5_; -+ _tmp6_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); -+ _tmp7_ = _tmp6_; -+ _tmp8_ = rygel_lms_artist_new (db_id, (RygelMediaContainer*) self, title, _tmp7_); -+ result = (RygelMediaObject*) _tmp8_; -+ _g_free0 (title); -+ _g_free0 (db_id); -+ return result; -+} -+ -+ -+RygelLMSArtists* rygel_lms_artists_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { -+ RygelLMSArtists * self = NULL; -+ const gchar* _tmp0_ = NULL; -+ RygelMediaContainer* _tmp1_ = NULL; -+ const gchar* _tmp2_ = NULL; -+ RygelLMSDatabase* _tmp3_ = NULL; -+ g_return_val_if_fail (id != NULL, NULL); -+ g_return_val_if_fail (parent != NULL, NULL); -+ g_return_val_if_fail (title != NULL, NULL); -+ g_return_val_if_fail (lms_db != NULL, NULL); -+ _tmp0_ = id; -+ _tmp1_ = parent; -+ _tmp2_ = title; -+ _tmp3_ = lms_db; -+ self = (RygelLMSArtists*) rygel_lms_category_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_, _tmp3_, RYGEL_LMS_ARTISTS_SQL_ALL, RYGEL_LMS_ARTISTS_SQL_FIND_OBJECT, RYGEL_LMS_ARTISTS_SQL_COUNT, NULL, NULL); -+ return self; -+} -+ -+ -+RygelLMSArtists* rygel_lms_artists_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { -+ return rygel_lms_artists_construct (RYGEL_LMS_TYPE_ARTISTS, id, parent, title, lms_db); -+} -+ -+ -+static void rygel_lms_artists_class_init (RygelLMSArtistsClass * klass) { -+ rygel_lms_artists_parent_class = g_type_class_peek_parent (klass); -+ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_artists_real_object_from_statement; -+} -+ -+ -+static void rygel_lms_artists_instance_init (RygelLMSArtists * self) { -+} -+ -+ -+GType rygel_lms_artists_get_type (void) { -+ static volatile gsize rygel_lms_artists_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_artists_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSArtistsClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_artists_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSArtists), 0, (GInstanceInitFunc) rygel_lms_artists_instance_init, NULL }; -+ GType rygel_lms_artists_type_id; -+ rygel_lms_artists_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSArtists", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_artists_type_id__volatile, rygel_lms_artists_type_id); -+ } -+ return rygel_lms_artists_type_id__volatile; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-category-container.c b/src/plugins/lms/rygel-lms-category-container.c -new file mode 100644 -index 0000000..21692d0 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-category-container.c -@@ -0,0 +1,2772 @@ -+/* rygel-lms-category-container.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-category-container.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2009,2010 Jens Georg <mail@jensge.org>, -+ * (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-server.h> -+#include <sqlite3.h> -+#include <stdlib.h> -+#include <string.h> -+#include <gee.h> -+#include <libgupnp-av/gupnp-av.h> -+#include <gio/gio.h> -+ -+ -+#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) -+#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+ -+typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; -+typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; -+typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; -+ -+#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) -+#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) -+#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+ -+typedef struct _RygelLMSDatabase RygelLMSDatabase; -+typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; -+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) -+#define _g_free0(var) (var = (g_free (var), NULL)) -+#define _sqlite3_finalize0(var) ((var == NULL) ? NULL : (var = (sqlite3_finalize (var), NULL))) -+#define __vala_GValue_free0(var) ((var == NULL) ? NULL : (var = (_vala_GValue_free (var), NULL))) -+ -+#define RYGEL_LMS_TYPE_SQL_OPERATOR (rygel_lms_sql_operator_get_type ()) -+#define RYGEL_LMS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperator)) -+#define RYGEL_LMS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass)) -+#define RYGEL_LMS_IS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR)) -+#define RYGEL_LMS_IS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR)) -+#define RYGEL_LMS_SQL_OPERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass)) -+ -+typedef struct _RygelLMSSqlOperator RygelLMSSqlOperator; -+typedef struct _RygelLMSSqlOperatorClass RygelLMSSqlOperatorClass; -+ -+#define RYGEL_LMS_TYPE_SQL_FUNCTION (rygel_lms_sql_function_get_type ()) -+#define RYGEL_LMS_SQL_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunction)) -+#define RYGEL_LMS_SQL_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunctionClass)) -+#define RYGEL_LMS_IS_SQL_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION)) -+#define RYGEL_LMS_IS_SQL_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_FUNCTION)) -+#define RYGEL_LMS_SQL_FUNCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunctionClass)) -+ -+typedef struct _RygelLMSSqlFunction RygelLMSSqlFunction; -+typedef struct _RygelLMSSqlFunctionClass RygelLMSSqlFunctionClass; -+#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) -+#define _rygel_search_expression_unref0(var) ((var == NULL) ? NULL : (var = (rygel_search_expression_unref (var), NULL))) -+#define _g_value_array_free0(var) ((var == NULL) ? NULL : (var = (g_value_array_free (var), NULL))) -+typedef struct _RygelLmsCategoryContainerSearchData RygelLmsCategoryContainerSearchData; -+typedef struct _RygelLmsCategoryContainerGetChildrenData RygelLmsCategoryContainerGetChildrenData; -+typedef struct _RygelLmsCategoryContainerFindObjectData RygelLmsCategoryContainerFindObjectData; -+typedef struct _RygelLmsCategoryContainerAddChildData RygelLmsCategoryContainerAddChildData; -+typedef struct _RygelLmsCategoryContainerRemoveChildData RygelLmsCategoryContainerRemoveChildData; -+ -+typedef enum { -+ RYGEL_LMS_CATEGORY_CONTAINER_ERROR_SQLITE_ERROR, -+ RYGEL_LMS_CATEGORY_CONTAINER_ERROR_GENERAL_ERROR, -+ RYGEL_LMS_CATEGORY_CONTAINER_ERROR_INVALID_TYPE, -+ RYGEL_LMS_CATEGORY_CONTAINER_ERROR_UNSUPPORTED_SEARCH -+} RygelLMSCategoryContainerError; -+#define RYGEL_LMS_CATEGORY_CONTAINER_ERROR rygel_lms_category_container_error_quark () -+struct _RygelLMSCategoryContainer { -+ RygelMediaContainer parent_instance; -+ RygelLMSCategoryContainerPrivate * priv; -+ sqlite3_stmt* stmt_all; -+ sqlite3_stmt* stmt_find_object; -+ sqlite3_stmt* stmt_added; -+ sqlite3_stmt* stmt_removed; -+ gchar* child_prefix; -+ gchar* ref_prefix; -+}; -+ -+struct _RygelLMSCategoryContainerClass { -+ RygelMediaContainerClass parent_class; -+ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); -+ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); -+ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); -+}; -+ -+struct _RygelLMSCategoryContainerPrivate { -+ GeeArrayList* _search_classes; -+ RygelLMSDatabase* _lms_db; -+ gchar* _db_id; -+ gchar* _sql_all; -+ gchar* _sql_find_object; -+ gchar* _sql_count; -+ gchar* _sql_added; -+ gchar* _sql_removed; -+}; -+ -+typedef enum { -+ RYGEL_LMS_DATABASE_ERROR_OPEN, -+ RYGEL_LMS_DATABASE_ERROR_PREPARE, -+ RYGEL_LMS_DATABASE_ERROR_BIND, -+ RYGEL_LMS_DATABASE_ERROR_STEP, -+ RYGEL_LMS_DATABASE_ERROR_NOT_FOUND -+} RygelLMSDatabaseError; -+#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark () -+struct _RygelLmsCategoryContainerSearchData { -+ int _state_; -+ GObject* _source_object_; -+ GAsyncResult* _res_; -+ GSimpleAsyncResult* _async_result; -+ RygelLMSCategoryContainer* self; -+ RygelSearchExpression* expression; -+ guint offset; -+ guint max_count; -+ guint total_matches; -+ gchar* sort_criteria; -+ GCancellable* cancellable; -+ RygelMediaObjects* result; -+ GValueArray* args; -+ GValueArray* _tmp0_; -+ gchar* filter; -+ RygelSearchExpression* _tmp1_; -+ GValueArray* _tmp2_; -+ gchar* _tmp3_; -+ const gchar* _tmp4_; -+ GValueArray* _tmp5_; -+ guint _tmp6_; -+ RygelSearchExpression* _tmp7_; -+ RygelSearchExpression* _tmp8_; -+ gchar* _tmp9_; -+ gchar* _tmp10_; -+ const gchar* _tmp11_; -+ guint _tmp12_; -+ guint _tmp13_; -+ const gchar* _tmp14_; -+ GValueArray* _tmp15_; -+ const gchar* _tmp16_; -+ guint _tmp17_; -+ guint _tmp18_; -+ RygelMediaObjects* _tmp19_; -+ GError* e; -+ GError* _tmp20_; -+ const gchar* _tmp21_; -+ RygelMediaObjects* _tmp22_; -+ RygelSearchExpression* _tmp23_; -+ guint _tmp24_; -+ guint _tmp25_; -+ const gchar* _tmp26_; -+ GCancellable* _tmp27_; -+ guint _tmp28_; -+ RygelMediaObjects* _tmp29_; -+ RygelMediaObjects* _tmp30_; -+ GError * _inner_error_; -+}; -+ -+struct _RygelLmsCategoryContainerGetChildrenData { -+ int _state_; -+ GObject* _source_object_; -+ GAsyncResult* _res_; -+ GSimpleAsyncResult* _async_result; -+ RygelLMSCategoryContainer* self; -+ guint offset; -+ guint max_count; -+ gchar* sort_criteria; -+ GCancellable* cancellable; -+ RygelMediaObjects* result; -+ RygelMediaObjects* retval; -+ RygelMediaObjects* _tmp0_; -+ sqlite3_stmt* _tmp1_; -+ guint _tmp2_; -+ guint _tmp3_; -+ const gchar* _tmp4_; -+ gboolean _tmp5_; -+ sqlite3_stmt* _tmp6_; -+ gboolean _tmp7_; -+ RygelMediaObjects* _tmp8_; -+ sqlite3_stmt* _tmp9_; -+ RygelMediaObject* _tmp10_; -+ RygelMediaObject* _tmp11_; -+ GError * _inner_error_; -+}; -+ -+struct _RygelLmsCategoryContainerFindObjectData { -+ int _state_; -+ GObject* _source_object_; -+ GAsyncResult* _res_; -+ GSimpleAsyncResult* _async_result; -+ RygelLMSCategoryContainer* self; -+ gchar* id; -+ GCancellable* cancellable; -+ RygelMediaObject* result; -+ const gchar* _tmp0_; -+ const gchar* _tmp1_; -+ gboolean _tmp2_; -+ RygelMediaObject* object; -+ gchar* real_id; -+ const gchar* _tmp3_; -+ const gchar* _tmp4_; -+ gint _tmp5_; -+ gint _tmp6_; -+ gchar* _tmp7_; -+ gint index; -+ const gchar* _tmp8_; -+ gint _tmp9_; -+ gint _tmp10_; -+ const gchar* _tmp11_; -+ gint _tmp12_; -+ gchar* _tmp13_; -+ const gchar* _tmp14_; -+ sqlite3_stmt* _tmp15_; -+ RygelMediaObject* child; -+ sqlite3_stmt* _tmp16_; -+ RygelMediaObject* _tmp17_; -+ gint _tmp18_; -+ RygelMediaObject* _tmp19_; -+ RygelMediaObject* _tmp20_; -+ RygelLMSCategoryContainer* container; -+ RygelMediaObject* _tmp21_; -+ RygelLMSCategoryContainer* _tmp22_; -+ RygelMediaObject* _tmp23_; -+ RygelLMSCategoryContainer* _tmp24_; -+ const gchar* _tmp25_; -+ GCancellable* _tmp26_; -+ RygelMediaObject* _tmp27_; -+ RygelMediaObject* _tmp28_; -+ RygelMediaObject* _tmp29_; -+ RygelMediaObject* _tmp30_; -+ RygelMediaContainer* _tmp31_; -+ RygelMediaContainer* _tmp32_; -+ GError* e; -+ const gchar* _tmp33_; -+ const gchar* _tmp34_; -+ const gchar* _tmp35_; -+ GError* _tmp36_; -+ const gchar* _tmp37_; -+ GError * _inner_error_; -+}; -+ -+struct _RygelLmsCategoryContainerAddChildData { -+ int _state_; -+ GObject* _source_object_; -+ GAsyncResult* _res_; -+ GSimpleAsyncResult* _async_result; -+ RygelLMSCategoryContainer* self; -+ RygelMediaObject* object; -+}; -+ -+struct _RygelLmsCategoryContainerRemoveChildData { -+ int _state_; -+ GObject* _source_object_; -+ GAsyncResult* _res_; -+ GSimpleAsyncResult* _async_result; -+ RygelLMSCategoryContainer* self; -+ RygelMediaObject* object; -+}; -+ -+ -+static gpointer rygel_lms_category_container_parent_class = NULL; -+static RygelTrackableContainerIface* rygel_lms_category_container_rygel_trackable_container_parent_iface = NULL; -+static RygelSearchableContainerIface* rygel_lms_category_container_rygel_searchable_container_parent_iface = NULL; -+ -+GQuark rygel_lms_category_container_error_quark (void); -+GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; -+gpointer rygel_lms_database_ref (gpointer instance); -+void rygel_lms_database_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_database (GValue* value, gpointer v_object); -+void rygel_lms_value_take_database (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_database (const GValue* value); -+GType rygel_lms_database_get_type (void) G_GNUC_CONST; -+#define RYGEL_LMS_CATEGORY_CONTAINER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerPrivate)) -+enum { -+ RYGEL_LMS_CATEGORY_CONTAINER_DUMMY_PROPERTY, -+ RYGEL_LMS_CATEGORY_CONTAINER_SEARCH_CLASSES, -+ RYGEL_LMS_CATEGORY_CONTAINER_LMS_DB, -+ RYGEL_LMS_CATEGORY_CONTAINER_DB_ID, -+ RYGEL_LMS_CATEGORY_CONTAINER_SQL_ALL, -+ RYGEL_LMS_CATEGORY_CONTAINER_SQL_FIND_OBJECT, -+ RYGEL_LMS_CATEGORY_CONTAINER_SQL_COUNT, -+ RYGEL_LMS_CATEGORY_CONTAINER_SQL_ADDED, -+ RYGEL_LMS_CATEGORY_CONTAINER_SQL_REMOVED -+}; -+RygelMediaObject* rygel_lms_category_container_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); -+static RygelMediaObject* rygel_lms_category_container_real_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); -+gchar* rygel_lms_category_container_get_sql_all_with_filter (RygelLMSCategoryContainer* self, const gchar* filter); -+static gchar* rygel_lms_category_container_real_get_sql_all_with_filter (RygelLMSCategoryContainer* self, const gchar* filter); -+const gchar* rygel_lms_category_container_get_sql_all (RygelLMSCategoryContainer* self); -+gchar* rygel_lms_category_container_get_sql_count_with_filter (RygelLMSCategoryContainer* self, const gchar* filter); -+static gchar* rygel_lms_category_container_real_get_sql_count_with_filter (RygelLMSCategoryContainer* self, const gchar* filter); -+const gchar* rygel_lms_category_container_get_sql_count (RygelLMSCategoryContainer* self); -+static gchar* rygel_lms_category_container_map_operand_to_column (const gchar* operand, gchar** collate, gboolean for_sort, GError** error); -+static gchar* rygel_lms_category_container_relational_expression_to_sql (RygelRelationalExpression* exp, GValueArray* args, GError** error); -+static void _vala_GValue_free (GValue* self); -+GType rygel_lms_sql_operator_get_type (void) G_GNUC_CONST; -+RygelLMSSqlOperator* rygel_lms_sql_operator_new_from_search_criteria_op (GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate); -+RygelLMSSqlOperator* rygel_lms_sql_operator_construct_from_search_criteria_op (GType object_type, GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate); -+RygelLMSSqlFunction* rygel_lms_sql_function_new (const gchar* name, const gchar* arg); -+RygelLMSSqlFunction* rygel_lms_sql_function_construct (GType object_type, const gchar* name, const gchar* arg); -+GType rygel_lms_sql_function_get_type (void) G_GNUC_CONST; -+RygelLMSSqlOperator* rygel_lms_sql_operator_new (const gchar* name, const gchar* arg, const gchar* collate); -+RygelLMSSqlOperator* rygel_lms_sql_operator_construct (GType object_type, const gchar* name, const gchar* arg, const gchar* collate); -+gchar* rygel_lms_sql_operator_to_string (RygelLMSSqlOperator* self); -+static gchar* rygel_lms_category_container_logical_expression_to_sql (RygelLogicalExpression* expression, GValueArray* args, GError** error); -+static gchar* rygel_lms_category_container_search_expression_to_sql (RygelSearchExpression* expression, GValueArray* args, GError** error); -+guint rygel_lms_category_container_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); -+static guint rygel_lms_category_container_real_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); -+RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self); -+GQuark rygel_lms_database_error_quark (void); -+sqlite3_stmt* rygel_lms_database_prepare_and_init (RygelLMSDatabase* self, const gchar* query, GValue* arguments, int arguments_length1, GError** error); -+RygelMediaObjects* rygel_lms_category_container_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); -+static RygelMediaObjects* rygel_lms_category_container_real_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); -+gboolean rygel_lms_database_get_children_step (sqlite3_stmt* stmt, GError** error); -+static void rygel_lms_category_container_real_search_data_free (gpointer _data); -+static void rygel_lms_category_container_real_search (RygelSearchableContainer* base, RygelSearchExpression* expression, guint offset, guint max_count, const gchar* sort_criteria, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_); -+static gboolean rygel_lms_category_container_real_search_co (RygelLmsCategoryContainerSearchData* _data_); -+static void rygel_lms_category_container_search_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_); -+static void rygel_lms_category_container_real_get_children_data_free (gpointer _data); -+static void rygel_lms_category_container_real_get_children (RygelMediaContainer* base, guint offset, guint max_count, const gchar* sort_criteria, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_); -+static gboolean rygel_lms_category_container_real_get_children_co (RygelLmsCategoryContainerGetChildrenData* _data_); -+void rygel_lms_database_get_children_init (sqlite3_stmt* stmt, guint offset, guint max_count, const gchar* sort_criteria, GError** error); -+static void rygel_lms_category_container_real_find_object_data_free (gpointer _data); -+static void rygel_lms_category_container_real_find_object (RygelMediaContainer* base, const gchar* id, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_); -+static gboolean rygel_lms_category_container_real_find_object_co (RygelLmsCategoryContainerFindObjectData* _data_); -+void rygel_lms_database_find_object (const gchar* id, sqlite3_stmt* stmt, GError** error); -+static void rygel_lms_category_container_find_object_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_); -+gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id); -+gchar* rygel_lms_category_container_build_reference_id (RygelLMSCategoryContainer* self, gint db_id); -+static void rygel_lms_category_container_real_add_child_data_free (gpointer _data); -+static void rygel_lms_category_container_real_add_child (RygelTrackableContainer* base, RygelMediaObject* object, GAsyncReadyCallback _callback_, gpointer _user_data_); -+static gboolean rygel_lms_category_container_real_add_child_co (RygelLmsCategoryContainerAddChildData* _data_); -+static void rygel_lms_category_container_real_remove_child_data_free (gpointer _data); -+static void rygel_lms_category_container_real_remove_child (RygelTrackableContainer* base, RygelMediaObject* object, GAsyncReadyCallback _callback_, gpointer _user_data_); -+static gboolean rygel_lms_category_container_real_remove_child_co (RygelLmsCategoryContainerRemoveChildData* _data_); -+static void rygel_lms_category_container_on_db_updated (RygelLMSCategoryContainer* self, guint64 old_id, guint64 new_id); -+sqlite3_stmt* rygel_lms_database_prepare (RygelLMSDatabase* self, const gchar* query_string, GError** error); -+void rygel_lms_database_get_children_with_update_id_init (sqlite3_stmt* stmt, guint64 old_id, guint64 new_id, GError** error); -+RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); -+static void rygel_lms_category_container_set_lms_db (RygelLMSCategoryContainer* self, RygelLMSDatabase* value); -+const gchar* rygel_lms_category_container_get_db_id (RygelLMSCategoryContainer* self); -+static void rygel_lms_category_container_set_db_id (RygelLMSCategoryContainer* self, const gchar* value); -+static void rygel_lms_category_container_set_sql_all (RygelLMSCategoryContainer* self, const gchar* value); -+const gchar* rygel_lms_category_container_get_sql_find_object (RygelLMSCategoryContainer* self); -+static void rygel_lms_category_container_set_sql_find_object (RygelLMSCategoryContainer* self, const gchar* value); -+static void rygel_lms_category_container_set_sql_count (RygelLMSCategoryContainer* self, const gchar* value); -+const gchar* rygel_lms_category_container_get_sql_added (RygelLMSCategoryContainer* self); -+static void rygel_lms_category_container_set_sql_added (RygelLMSCategoryContainer* self, const gchar* value); -+const gchar* rygel_lms_category_container_get_sql_removed (RygelLMSCategoryContainer* self); -+static void rygel_lms_category_container_set_sql_removed (RygelLMSCategoryContainer* self, const gchar* value); -+static GObject * rygel_lms_category_container_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties); -+static void _rygel_lms_category_container_on_db_updated_rygel_lms_database_db_updated (RygelLMSDatabase* _sender, guint64 old_update_id, guint64 new_update_id, gpointer self); -+static void rygel_lms_category_container_finalize (GObject* obj); -+static void _vala_rygel_lms_category_container_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec); -+static void _vala_rygel_lms_category_container_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec); -+ -+ -+GQuark rygel_lms_category_container_error_quark (void) { -+ return g_quark_from_static_string ("rygel_lms_category_container_error-quark"); -+} -+ -+ -+static RygelMediaObject* rygel_lms_category_container_real_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement) { -+ g_critical ("Type `%s' does not implement abstract method `rygel_lms_category_container_object_from_statement'", g_type_name (G_TYPE_FROM_INSTANCE (self))); -+ return NULL; -+} -+ -+ -+RygelMediaObject* rygel_lms_category_container_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement) { -+ g_return_val_if_fail (self != NULL, NULL); -+ return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->object_from_statement (self, statement); -+} -+ -+ -+static gchar* rygel_lms_category_container_real_get_sql_all_with_filter (RygelLMSCategoryContainer* self, const gchar* filter) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (filter != NULL, NULL); -+ _tmp0_ = self->priv->_sql_all; -+ _tmp1_ = g_strdup (_tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+gchar* rygel_lms_category_container_get_sql_all_with_filter (RygelLMSCategoryContainer* self, const gchar* filter) { -+ g_return_val_if_fail (self != NULL, NULL); -+ return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->get_sql_all_with_filter (self, filter); -+} -+ -+ -+static gchar* rygel_lms_category_container_real_get_sql_count_with_filter (RygelLMSCategoryContainer* self, const gchar* filter) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (filter != NULL, NULL); -+ _tmp0_ = self->priv->_sql_count; -+ _tmp1_ = g_strdup (_tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+gchar* rygel_lms_category_container_get_sql_count_with_filter (RygelLMSCategoryContainer* self, const gchar* filter) { -+ g_return_val_if_fail (self != NULL, NULL); -+ return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->get_sql_count_with_filter (self, filter); -+} -+ -+ -+static gchar* rygel_lms_category_container_map_operand_to_column (const gchar* operand, gchar** collate, gboolean for_sort, GError** error) { -+ gchar* _vala_collate = NULL; -+ gchar* result = NULL; -+ gchar* column = NULL; -+ gboolean use_collation = FALSE; -+ const gchar* _tmp0_ = NULL; -+ const gchar* _tmp1_ = NULL; -+ GQuark _tmp3_ = 0U; -+ static GQuark _tmp2_label0 = 0; -+ static GQuark _tmp2_label1 = 0; -+ static GQuark _tmp2_label2 = 0; -+ gboolean _tmp11_ = FALSE; -+ GError * _inner_error_ = NULL; -+ g_return_val_if_fail (operand != NULL, NULL); -+ column = NULL; -+ use_collation = FALSE; -+ _tmp0_ = operand; -+ _tmp1_ = _tmp0_; -+ _tmp3_ = (NULL == _tmp1_) ? 0 : g_quark_from_string (_tmp1_); -+ if (_tmp3_ == ((0 != _tmp2_label0) ? _tmp2_label0 : (_tmp2_label0 = g_quark_from_static_string ("dc:title")))) { -+ switch (0) { -+ default: -+ { -+ gchar* _tmp4_ = NULL; -+ _tmp4_ = g_strdup ("title"); -+ _g_free0 (column); -+ column = _tmp4_; -+ use_collation = TRUE; -+ break; -+ } -+ } -+ } else if (_tmp3_ == ((0 != _tmp2_label1) ? _tmp2_label1 : (_tmp2_label1 = g_quark_from_static_string ("upnp:artist")))) { -+ switch (0) { -+ default: -+ { -+ gchar* _tmp5_ = NULL; -+ _tmp5_ = g_strdup ("artist"); -+ _g_free0 (column); -+ column = _tmp5_; -+ use_collation = TRUE; -+ break; -+ } -+ } -+ } else if (_tmp3_ == ((0 != _tmp2_label2) ? _tmp2_label2 : (_tmp2_label2 = g_quark_from_static_string ("dc:creator")))) { -+ switch (0) { -+ default: -+ { -+ gchar* _tmp6_ = NULL; -+ _tmp6_ = g_strdup ("creator"); -+ _g_free0 (column); -+ column = _tmp6_; -+ use_collation = TRUE; -+ break; -+ } -+ } -+ } else { -+ switch (0) { -+ default: -+ { -+ gchar* message = NULL; -+ const gchar* _tmp7_ = NULL; -+ gchar* _tmp8_ = NULL; -+ const gchar* _tmp9_ = NULL; -+ GError* _tmp10_ = NULL; -+ _tmp7_ = operand; -+ _tmp8_ = g_strdup_printf ("Unsupported column %s", _tmp7_); -+ message = _tmp8_; -+ _tmp9_ = message; -+ _tmp10_ = g_error_new_literal (RYGEL_LMS_CATEGORY_CONTAINER_ERROR, RYGEL_LMS_CATEGORY_CONTAINER_ERROR_UNSUPPORTED_SEARCH, _tmp9_); -+ _inner_error_ = _tmp10_; -+ g_propagate_error (error, _inner_error_); -+ _g_free0 (message); -+ _g_free0 (column); -+ return NULL; -+ } -+ } -+ } -+ _tmp11_ = use_collation; -+ if (_tmp11_) { -+ gchar* _tmp12_ = NULL; -+ _tmp12_ = g_strdup ("COLLATE CASEFOLD"); -+ _g_free0 (_vala_collate); -+ _vala_collate = _tmp12_; -+ } else { -+ gchar* _tmp13_ = NULL; -+ _tmp13_ = g_strdup (""); -+ _g_free0 (_vala_collate); -+ _vala_collate = _tmp13_; -+ } -+ result = column; -+ if (collate) { -+ *collate = _vala_collate; -+ } else { -+ _g_free0 (_vala_collate); -+ } -+ return result; -+} -+ -+ -+static void _vala_GValue_free (GValue* self) { -+ g_value_unset (self); -+ g_free (self); -+} -+ -+ -+static gchar* rygel_lms_category_container_relational_expression_to_sql (RygelRelationalExpression* exp, GValueArray* args, GError** error) { -+ gchar* result = NULL; -+ GValue* v = NULL; -+ gchar* collate = NULL; -+ gchar* column = NULL; -+ RygelRelationalExpression* _tmp0_ = NULL; -+ gconstpointer _tmp1_ = NULL; -+ gchar* _tmp2_ = NULL; -+ gchar* _tmp3_ = NULL; -+ RygelLMSSqlOperator* operator = NULL; -+ RygelRelationalExpression* _tmp4_ = NULL; -+ gconstpointer _tmp5_ = NULL; -+ GValue* _tmp40_ = NULL; -+ RygelLMSSqlOperator* _tmp44_ = NULL; -+ gchar* _tmp45_ = NULL; -+ GError * _inner_error_ = NULL; -+ g_return_val_if_fail (exp != NULL, NULL); -+ g_return_val_if_fail (args != NULL, NULL); -+ v = NULL; -+ collate = NULL; -+ _tmp0_ = exp; -+ _tmp1_ = ((RygelSearchExpression*) _tmp0_)->operand1; -+ _tmp3_ = rygel_lms_category_container_map_operand_to_column ((const gchar*) _tmp1_, &_tmp2_, FALSE, &_inner_error_); -+ _g_free0 (collate); -+ collate = _tmp2_; -+ column = _tmp3_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ g_propagate_error (error, _inner_error_); -+ _g_free0 (collate); -+ __vala_GValue_free0 (v); -+ return NULL; -+ } -+ _tmp4_ = exp; -+ _tmp5_ = ((RygelSearchExpression*) _tmp4_)->op; -+ switch ((GUPnPSearchCriteriaOp) ((gintptr) _tmp5_)) { -+ case GUPNP_SEARCH_CRITERIA_OP_EXISTS: -+ { -+ gchar* sql_function = NULL; -+ RygelRelationalExpression* _tmp6_ = NULL; -+ gconstpointer _tmp7_ = NULL; -+ const gchar* _tmp10_ = NULL; -+ const gchar* _tmp11_ = NULL; -+ const gchar* _tmp12_ = NULL; -+ gchar* _tmp13_ = NULL; -+ _tmp6_ = exp; -+ _tmp7_ = ((RygelSearchExpression*) _tmp6_)->operand2; -+ if (g_strcmp0 ((const gchar*) _tmp7_, "true") == 0) { -+ gchar* _tmp8_ = NULL; -+ _tmp8_ = g_strdup ("%s IS NOT NULL AND %s != ''"); -+ _g_free0 (sql_function); -+ sql_function = _tmp8_; -+ } else { -+ gchar* _tmp9_ = NULL; -+ _tmp9_ = g_strdup ("%s IS NULL OR %s = ''"); -+ _g_free0 (sql_function); -+ sql_function = _tmp9_; -+ } -+ _tmp10_ = sql_function; -+ _tmp11_ = column; -+ _tmp12_ = column; -+ _tmp13_ = g_strdup_printf (_tmp10_, _tmp11_, _tmp12_); -+ result = _tmp13_; -+ _g_free0 (sql_function); -+ _g_object_unref0 (operator); -+ _g_free0 (column); -+ _g_free0 (collate); -+ __vala_GValue_free0 (v); -+ return result; -+ } -+ case GUPNP_SEARCH_CRITERIA_OP_EQ: -+ case GUPNP_SEARCH_CRITERIA_OP_NEQ: -+ case GUPNP_SEARCH_CRITERIA_OP_LESS: -+ case GUPNP_SEARCH_CRITERIA_OP_LEQ: -+ case GUPNP_SEARCH_CRITERIA_OP_GREATER: -+ case GUPNP_SEARCH_CRITERIA_OP_GEQ: -+ { -+ RygelRelationalExpression* _tmp14_ = NULL; -+ gconstpointer _tmp15_ = NULL; -+ GValue* _tmp16_ = NULL; -+ RygelRelationalExpression* _tmp17_ = NULL; -+ gconstpointer _tmp18_ = NULL; -+ const gchar* _tmp19_ = NULL; -+ const gchar* _tmp20_ = NULL; -+ RygelLMSSqlOperator* _tmp21_ = NULL; -+ _tmp14_ = exp; -+ _tmp15_ = ((RygelSearchExpression*) _tmp14_)->operand2; -+ _tmp16_ = g_new0 (GValue, 1); -+ g_value_init (_tmp16_, G_TYPE_STRING); -+ g_value_set_string (_tmp16_, (const gchar*) _tmp15_); -+ __vala_GValue_free0 (v); -+ v = _tmp16_; -+ _tmp17_ = exp; -+ _tmp18_ = ((RygelSearchExpression*) _tmp17_)->op; -+ _tmp19_ = column; -+ _tmp20_ = collate; -+ _tmp21_ = rygel_lms_sql_operator_new_from_search_criteria_op ((GUPnPSearchCriteriaOp) ((gintptr) _tmp18_), _tmp19_, _tmp20_); -+ _g_object_unref0 (operator); -+ operator = _tmp21_; -+ break; -+ } -+ case GUPNP_SEARCH_CRITERIA_OP_CONTAINS: -+ { -+ const gchar* _tmp22_ = NULL; -+ RygelLMSSqlFunction* _tmp23_ = NULL; -+ RygelRelationalExpression* _tmp24_ = NULL; -+ gconstpointer _tmp25_ = NULL; -+ GValue* _tmp26_ = NULL; -+ _tmp22_ = column; -+ _tmp23_ = rygel_lms_sql_function_new ("contains", _tmp22_); -+ _g_object_unref0 (operator); -+ operator = (RygelLMSSqlOperator*) _tmp23_; -+ _tmp24_ = exp; -+ _tmp25_ = ((RygelSearchExpression*) _tmp24_)->operand2; -+ _tmp26_ = g_new0 (GValue, 1); -+ g_value_init (_tmp26_, G_TYPE_STRING); -+ g_value_set_string (_tmp26_, (const gchar*) _tmp25_); -+ __vala_GValue_free0 (v); -+ v = _tmp26_; -+ break; -+ } -+ case GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN: -+ { -+ const gchar* _tmp27_ = NULL; -+ RygelLMSSqlFunction* _tmp28_ = NULL; -+ RygelRelationalExpression* _tmp29_ = NULL; -+ gconstpointer _tmp30_ = NULL; -+ GValue* _tmp31_ = NULL; -+ _tmp27_ = column; -+ _tmp28_ = rygel_lms_sql_function_new ("NOT contains", _tmp27_); -+ _g_object_unref0 (operator); -+ operator = (RygelLMSSqlOperator*) _tmp28_; -+ _tmp29_ = exp; -+ _tmp30_ = ((RygelSearchExpression*) _tmp29_)->operand2; -+ _tmp31_ = g_new0 (GValue, 1); -+ g_value_init (_tmp31_, G_TYPE_STRING); -+ g_value_set_string (_tmp31_, (const gchar*) _tmp30_); -+ __vala_GValue_free0 (v); -+ v = _tmp31_; -+ break; -+ } -+ case GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM: -+ { -+ const gchar* _tmp32_ = NULL; -+ RygelLMSSqlOperator* _tmp33_ = NULL; -+ RygelRelationalExpression* _tmp34_ = NULL; -+ gconstpointer _tmp35_ = NULL; -+ gchar* _tmp36_ = NULL; -+ GValue* _tmp37_ = NULL; -+ _tmp32_ = column; -+ _tmp33_ = rygel_lms_sql_operator_new ("LIKE", _tmp32_, ""); -+ _g_object_unref0 (operator); -+ operator = _tmp33_; -+ _tmp34_ = exp; -+ _tmp35_ = ((RygelSearchExpression*) _tmp34_)->operand2; -+ _tmp36_ = g_strdup_printf ("%s%%", (const gchar*) _tmp35_); -+ _tmp37_ = g_new0 (GValue, 1); -+ g_value_init (_tmp37_, G_TYPE_STRING); -+ g_value_take_string (_tmp37_, _tmp36_); -+ __vala_GValue_free0 (v); -+ v = _tmp37_; -+ break; -+ } -+ default: -+ { -+ RygelRelationalExpression* _tmp38_ = NULL; -+ gconstpointer _tmp39_ = NULL; -+ _tmp38_ = exp; -+ _tmp39_ = ((RygelSearchExpression*) _tmp38_)->op; -+ g_warning ("rygel-lms-category-container.vala:148: Unsupported op %d", (gint) ((GUPnPSearchCriteriaOp) ((gintptr) _tmp39_))); -+ result = NULL; -+ _g_object_unref0 (operator); -+ _g_free0 (column); -+ _g_free0 (collate); -+ __vala_GValue_free0 (v); -+ return result; -+ } -+ } -+ _tmp40_ = v; -+ if (_tmp40_ != NULL) { -+ GValueArray* _tmp41_ = NULL; -+ GValue* _tmp42_ = NULL; -+ GValue _tmp43_ = {0}; -+ _tmp41_ = args; -+ _tmp42_ = v; -+ _tmp43_ = *_tmp42_; -+ g_value_array_append (_tmp41_, &_tmp43_); -+ } -+ _tmp44_ = operator; -+ _tmp45_ = rygel_lms_sql_operator_to_string (_tmp44_); -+ result = _tmp45_; -+ _g_object_unref0 (operator); -+ _g_free0 (column); -+ _g_free0 (collate); -+ __vala_GValue_free0 (v); -+ return result; -+} -+ -+ -+static gchar* rygel_lms_category_container_logical_expression_to_sql (RygelLogicalExpression* expression, GValueArray* args, GError** error) { -+ gchar* result = NULL; -+ gchar* left_sql_string = NULL; -+ RygelLogicalExpression* _tmp0_ = NULL; -+ gconstpointer _tmp1_ = NULL; -+ GValueArray* _tmp2_ = NULL; -+ gchar* _tmp3_ = NULL; -+ gchar* right_sql_string = NULL; -+ RygelLogicalExpression* _tmp4_ = NULL; -+ gconstpointer _tmp5_ = NULL; -+ GValueArray* _tmp6_ = NULL; -+ gchar* _tmp7_ = NULL; -+ const gchar* operator_sql_string = NULL; -+ RygelLogicalExpression* _tmp8_ = NULL; -+ gconstpointer _tmp9_ = NULL; -+ const gchar* _tmp10_ = NULL; -+ const gchar* _tmp11_ = NULL; -+ const gchar* _tmp12_ = NULL; -+ gchar* _tmp13_ = NULL; -+ GError * _inner_error_ = NULL; -+ g_return_val_if_fail (expression != NULL, NULL); -+ g_return_val_if_fail (args != NULL, NULL); -+ _tmp0_ = expression; -+ _tmp1_ = ((RygelSearchExpression*) _tmp0_)->operand1; -+ _tmp2_ = args; -+ _tmp3_ = rygel_lms_category_container_search_expression_to_sql ((RygelSearchExpression*) _tmp1_, _tmp2_, &_inner_error_); -+ left_sql_string = _tmp3_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ g_propagate_error (error, _inner_error_); -+ return NULL; -+ } -+ _tmp4_ = expression; -+ _tmp5_ = ((RygelSearchExpression*) _tmp4_)->operand2; -+ _tmp6_ = args; -+ _tmp7_ = rygel_lms_category_container_search_expression_to_sql ((RygelSearchExpression*) _tmp5_, _tmp6_, &_inner_error_); -+ right_sql_string = _tmp7_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ g_propagate_error (error, _inner_error_); -+ _g_free0 (left_sql_string); -+ return NULL; -+ } -+ operator_sql_string = "OR"; -+ _tmp8_ = expression; -+ _tmp9_ = ((RygelSearchExpression*) _tmp8_)->op; -+ if (((RygelLogicalOperator) ((gintptr) _tmp9_)) == RYGEL_LOGICAL_OPERATOR_AND) { -+ operator_sql_string = "AND"; -+ } -+ _tmp10_ = left_sql_string; -+ _tmp11_ = operator_sql_string; -+ _tmp12_ = right_sql_string; -+ _tmp13_ = g_strdup_printf ("(%s %s %s)", _tmp10_, _tmp11_, _tmp12_); -+ result = _tmp13_; -+ _g_free0 (right_sql_string); -+ _g_free0 (left_sql_string); -+ return result; -+} -+ -+ -+static gchar* rygel_lms_category_container_search_expression_to_sql (RygelSearchExpression* expression, GValueArray* args, GError** error) { -+ gchar* result = NULL; -+ RygelSearchExpression* _tmp0_ = NULL; -+ RygelSearchExpression* _tmp2_ = NULL; -+ GError * _inner_error_ = NULL; -+ g_return_val_if_fail (args != NULL, NULL); -+ _tmp0_ = expression; -+ if (_tmp0_ == NULL) { -+ gchar* _tmp1_ = NULL; -+ _tmp1_ = g_strdup (""); -+ result = _tmp1_; -+ return result; -+ } -+ _tmp2_ = expression; -+ if (G_TYPE_CHECK_INSTANCE_TYPE (_tmp2_, RYGEL_TYPE_LOGICAL_EXPRESSION)) { -+ gchar* _tmp3_ = NULL; -+ RygelSearchExpression* _tmp4_ = NULL; -+ GValueArray* _tmp5_ = NULL; -+ gchar* _tmp6_ = NULL; -+ gchar* _tmp7_ = NULL; -+ _tmp4_ = expression; -+ _tmp5_ = args; -+ _tmp6_ = rygel_lms_category_container_logical_expression_to_sql (G_TYPE_CHECK_INSTANCE_TYPE (_tmp4_, RYGEL_TYPE_LOGICAL_EXPRESSION) ? ((RygelLogicalExpression*) _tmp4_) : NULL, _tmp5_, &_inner_error_); -+ _tmp3_ = _tmp6_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ g_propagate_error (error, _inner_error_); -+ return NULL; -+ } -+ _tmp7_ = _tmp3_; -+ _tmp3_ = NULL; -+ result = _tmp7_; -+ _g_free0 (_tmp3_); -+ return result; -+ } else { -+ gchar* _tmp8_ = NULL; -+ RygelSearchExpression* _tmp9_ = NULL; -+ GValueArray* _tmp10_ = NULL; -+ gchar* _tmp11_ = NULL; -+ gchar* _tmp12_ = NULL; -+ _tmp9_ = expression; -+ _tmp10_ = args; -+ _tmp11_ = rygel_lms_category_container_relational_expression_to_sql (G_TYPE_CHECK_INSTANCE_TYPE (_tmp9_, RYGEL_TYPE_RELATIONAL_EXPRESSION) ? ((RygelRelationalExpression*) _tmp9_) : NULL, _tmp10_, &_inner_error_); -+ _tmp8_ = _tmp11_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ g_propagate_error (error, _inner_error_); -+ return NULL; -+ } -+ _tmp12_ = _tmp8_; -+ _tmp8_ = NULL; -+ result = _tmp12_; -+ _g_free0 (_tmp8_); -+ return result; -+ } -+} -+ -+ -+static guint rygel_lms_category_container_real_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args) { -+ guint result = 0U; -+ gchar* query = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ GError * _inner_error_ = NULL; -+ g_return_val_if_fail (where_filter != NULL, 0U); -+ g_return_val_if_fail (args != NULL, 0U); -+ _tmp0_ = where_filter; -+ _tmp1_ = rygel_lms_category_container_get_sql_count_with_filter (self, _tmp0_); -+ query = _tmp1_; -+ { -+ sqlite3_stmt* stmt = NULL; -+ RygelLMSDatabase* _tmp2_ = NULL; -+ const gchar* _tmp3_ = NULL; -+ GValueArray* _tmp4_ = NULL; -+ GValue* _tmp5_ = NULL; -+ gint _tmp5__length1 = 0; -+ sqlite3_stmt* _tmp6_ = NULL; -+ sqlite3_stmt* _tmp7_ = NULL; -+ gint _tmp8_ = 0; -+ sqlite3_stmt* _tmp9_ = NULL; -+ gint _tmp10_ = 0; -+ _tmp2_ = self->priv->_lms_db; -+ _tmp3_ = query; -+ _tmp4_ = args; -+ _tmp5_ = _tmp4_->values; -+ _tmp5__length1 = (gint) _tmp4_->n_values; -+ _tmp6_ = rygel_lms_database_prepare_and_init (_tmp2_, _tmp3_, _tmp5_, _tmp5__length1, &_inner_error_); -+ stmt = _tmp6_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch2_rygel_lms_database_error; -+ } -+ _g_free0 (query); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return 0U; -+ } -+ _tmp7_ = stmt; -+ _tmp8_ = sqlite3_step (_tmp7_); -+ if (_tmp8_ != SQLITE_ROW) { -+ result = (guint) 0; -+ _sqlite3_finalize0 (stmt); -+ _g_free0 (query); -+ return result; -+ } -+ _tmp9_ = stmt; -+ _tmp10_ = sqlite3_column_int (_tmp9_, 0); -+ result = (guint) _tmp10_; -+ _sqlite3_finalize0 (stmt); -+ _g_free0 (query); -+ return result; -+ } -+ goto __finally2; -+ __catch2_rygel_lms_database_error: -+ { -+ GError* e = NULL; -+ GError* _tmp11_ = NULL; -+ const gchar* _tmp12_ = NULL; -+ e = _inner_error_; -+ _inner_error_ = NULL; -+ _tmp11_ = e; -+ _tmp12_ = _tmp11_->message; -+ g_warning ("rygel-lms-category-container.vala:209: Query failed: %s", _tmp12_); -+ result = (guint) 0; -+ _g_error_free0 (e); -+ _g_free0 (query); -+ return result; -+ } -+ __finally2: -+ _g_free0 (query); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return 0U; -+} -+ -+ -+guint rygel_lms_category_container_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args) { -+ g_return_val_if_fail (self != NULL, 0U); -+ return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->get_child_count_with_filter (self, where_filter, args); -+} -+ -+ -+static RygelMediaObjects* rygel_lms_category_container_real_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count) { -+ RygelMediaObjects* result = NULL; -+ RygelMediaObjects* children = NULL; -+ RygelMediaObjects* _tmp0_ = NULL; -+ GValue v = {0}; -+ guint _tmp1_ = 0U; -+ GValue _tmp2_ = {0}; -+ GValueArray* _tmp3_ = NULL; -+ GValue _tmp4_ = {0}; -+ guint _tmp5_ = 0U; -+ GValue _tmp6_ = {0}; -+ GValueArray* _tmp7_ = NULL; -+ GValue _tmp8_ = {0}; -+ gchar* query = NULL; -+ const gchar* _tmp9_ = NULL; -+ gchar* _tmp10_ = NULL; -+ GError * _inner_error_ = NULL; -+ g_return_val_if_fail (where_filter != NULL, NULL); -+ g_return_val_if_fail (args != NULL, NULL); -+ g_return_val_if_fail (sort_criteria != NULL, NULL); -+ _tmp0_ = rygel_media_objects_new (); -+ children = _tmp0_; -+ _tmp1_ = max_count; -+ g_value_init (&_tmp2_, G_TYPE_UINT); -+ g_value_set_uint (&_tmp2_, _tmp1_); -+ v = _tmp2_; -+ _tmp3_ = args; -+ _tmp4_ = v; -+ g_value_array_append (_tmp3_, &_tmp4_); -+ _tmp5_ = offset; -+ g_value_init (&_tmp6_, G_TYPE_UINT); -+ g_value_set_uint (&_tmp6_, _tmp5_); -+ G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL; -+ v = _tmp6_; -+ _tmp7_ = args; -+ _tmp8_ = v; -+ g_value_array_append (_tmp7_, &_tmp8_); -+ _tmp9_ = where_filter; -+ _tmp10_ = rygel_lms_category_container_get_sql_all_with_filter (self, _tmp9_); -+ query = _tmp10_; -+ { -+ sqlite3_stmt* stmt = NULL; -+ RygelLMSDatabase* _tmp11_ = NULL; -+ const gchar* _tmp12_ = NULL; -+ GValueArray* _tmp13_ = NULL; -+ GValue* _tmp14_ = NULL; -+ gint _tmp14__length1 = 0; -+ sqlite3_stmt* _tmp15_ = NULL; -+ _tmp11_ = self->priv->_lms_db; -+ _tmp12_ = query; -+ _tmp13_ = args; -+ _tmp14_ = _tmp13_->values; -+ _tmp14__length1 = (gint) _tmp13_->n_values; -+ _tmp15_ = rygel_lms_database_prepare_and_init (_tmp11_, _tmp12_, _tmp14_, _tmp14__length1, &_inner_error_); -+ stmt = _tmp15_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch3_rygel_lms_database_error; -+ } -+ _g_free0 (query); -+ G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL; -+ _g_object_unref0 (children); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ while (TRUE) { -+ gboolean _tmp16_ = FALSE; -+ sqlite3_stmt* _tmp17_ = NULL; -+ gboolean _tmp18_ = FALSE; -+ RygelMediaObjects* _tmp19_ = NULL; -+ sqlite3_stmt* _tmp20_ = NULL; -+ RygelMediaObject* _tmp21_ = NULL; -+ RygelMediaObject* _tmp22_ = NULL; -+ _tmp17_ = stmt; -+ _tmp18_ = rygel_lms_database_get_children_step (_tmp17_, &_inner_error_); -+ _tmp16_ = _tmp18_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _sqlite3_finalize0 (stmt); -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch3_rygel_lms_database_error; -+ } -+ _sqlite3_finalize0 (stmt); -+ _g_free0 (query); -+ G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL; -+ _g_object_unref0 (children); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ if (!_tmp16_) { -+ break; -+ } -+ _tmp19_ = children; -+ _tmp20_ = stmt; -+ _tmp21_ = rygel_lms_category_container_object_from_statement (self, _tmp20_); -+ _tmp22_ = _tmp21_; -+ gee_abstract_collection_add ((GeeAbstractCollection*) _tmp19_, _tmp22_); -+ _g_object_unref0 (_tmp22_); -+ } -+ _sqlite3_finalize0 (stmt); -+ } -+ goto __finally3; -+ __catch3_rygel_lms_database_error: -+ { -+ GError* e = NULL; -+ GError* _tmp23_ = NULL; -+ const gchar* _tmp24_ = NULL; -+ e = _inner_error_; -+ _inner_error_ = NULL; -+ _tmp23_ = e; -+ _tmp24_ = _tmp23_->message; -+ g_warning ("rygel-lms-category-container.vala:232: Query failed: %s", _tmp24_); -+ _g_error_free0 (e); -+ } -+ __finally3: -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _g_free0 (query); -+ G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL; -+ _g_object_unref0 (children); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ result = children; -+ _g_free0 (query); -+ G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL; -+ return result; -+} -+ -+ -+RygelMediaObjects* rygel_lms_category_container_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count) { -+ g_return_val_if_fail (self != NULL, NULL); -+ return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->get_children_with_filter (self, where_filter, args, sort_criteria, offset, max_count); -+} -+ -+ -+static void rygel_lms_category_container_real_search_data_free (gpointer _data) { -+ RygelLmsCategoryContainerSearchData* _data_; -+ _data_ = _data; -+ _rygel_search_expression_unref0 (_data_->expression); -+ _g_free0 (_data_->sort_criteria); -+ _g_object_unref0 (_data_->cancellable); -+ _g_object_unref0 (_data_->result); -+ _g_object_unref0 (_data_->self); -+ g_slice_free (RygelLmsCategoryContainerSearchData, _data_); -+} -+ -+ -+static gpointer _g_object_ref0 (gpointer self) { -+ return self ? g_object_ref (self) : NULL; -+} -+ -+ -+static gpointer _rygel_search_expression_ref0 (gpointer self) { -+ return self ? rygel_search_expression_ref (self) : NULL; -+} -+ -+ -+static void rygel_lms_category_container_real_search (RygelSearchableContainer* base, RygelSearchExpression* expression, guint offset, guint max_count, const gchar* sort_criteria, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_) { -+ RygelLMSCategoryContainer * self; -+ RygelLmsCategoryContainerSearchData* _data_; -+ RygelLMSCategoryContainer* _tmp0_ = NULL; -+ RygelSearchExpression* _tmp1_ = NULL; -+ RygelSearchExpression* _tmp2_ = NULL; -+ guint _tmp3_ = 0U; -+ guint _tmp4_ = 0U; -+ const gchar* _tmp5_ = NULL; -+ gchar* _tmp6_ = NULL; -+ GCancellable* _tmp7_ = NULL; -+ GCancellable* _tmp8_ = NULL; -+ self = (RygelLMSCategoryContainer*) base; -+ _data_ = g_slice_new0 (RygelLmsCategoryContainerSearchData); -+ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_search); -+ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_search_data_free); -+ _tmp0_ = _g_object_ref0 (self); -+ _data_->self = _tmp0_; -+ _tmp1_ = expression; -+ _tmp2_ = _rygel_search_expression_ref0 (_tmp1_); -+ _rygel_search_expression_unref0 (_data_->expression); -+ _data_->expression = _tmp2_; -+ _tmp3_ = offset; -+ _data_->offset = _tmp3_; -+ _tmp4_ = max_count; -+ _data_->max_count = _tmp4_; -+ _tmp5_ = sort_criteria; -+ _tmp6_ = g_strdup (_tmp5_); -+ _g_free0 (_data_->sort_criteria); -+ _data_->sort_criteria = _tmp6_; -+ _tmp7_ = cancellable; -+ _tmp8_ = _g_object_ref0 (_tmp7_); -+ _g_object_unref0 (_data_->cancellable); -+ _data_->cancellable = _tmp8_; -+ rygel_lms_category_container_real_search_co (_data_); -+} -+ -+ -+static RygelMediaObjects* rygel_lms_category_container_real_search_finish (RygelSearchableContainer* base, GAsyncResult* _res_, guint* total_matches, GError** error) { -+ RygelMediaObjects* result; -+ RygelLmsCategoryContainerSearchData* _data_; -+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) { -+ return NULL; -+ } -+ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_)); -+ if (total_matches) { -+ *total_matches = _data_->total_matches; -+ } -+ result = _data_->result; -+ _data_->result = NULL; -+ return result; -+} -+ -+ -+static void rygel_lms_category_container_search_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) { -+ RygelLmsCategoryContainerSearchData* _data_; -+ _data_ = _user_data_; -+ _data_->_source_object_ = source_object; -+ _data_->_res_ = _res_; -+ rygel_lms_category_container_real_search_co (_data_); -+} -+ -+ -+static gboolean rygel_lms_category_container_real_search_co (RygelLmsCategoryContainerSearchData* _data_) { -+ switch (_data_->_state_) { -+ case 0: -+ goto _state_0; -+ case 1: -+ goto _state_1; -+ default: -+ g_assert_not_reached (); -+ } -+ _state_0: -+ g_debug ("rygel-lms-category-container.vala:245: search()"); -+ { -+ _data_->_tmp0_ = NULL; -+ _data_->_tmp0_ = g_value_array_new ((guint) 0); -+ _data_->args = _data_->_tmp0_; -+ _data_->_tmp1_ = NULL; -+ _data_->_tmp1_ = _data_->expression; -+ _data_->_tmp2_ = NULL; -+ _data_->_tmp2_ = _data_->args; -+ _data_->_tmp3_ = NULL; -+ _data_->_tmp3_ = rygel_lms_category_container_search_expression_to_sql (_data_->_tmp1_, _data_->_tmp2_, &_data_->_inner_error_); -+ _data_->filter = _data_->_tmp3_; -+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) { -+ _g_value_array_free0 (_data_->args); -+ goto __catch4_g_error; -+ } -+ _data_->_tmp4_ = NULL; -+ _data_->_tmp4_ = _data_->filter; -+ _data_->_tmp5_ = NULL; -+ _data_->_tmp5_ = _data_->args; -+ _data_->_tmp6_ = 0U; -+ _data_->_tmp6_ = rygel_lms_category_container_get_child_count_with_filter (_data_->self, _data_->_tmp4_, _data_->_tmp5_); -+ _data_->total_matches = _data_->_tmp6_; -+ _data_->_tmp7_ = NULL; -+ _data_->_tmp7_ = _data_->expression; -+ if (_data_->_tmp7_ != NULL) { -+ _data_->_tmp8_ = NULL; -+ _data_->_tmp8_ = _data_->expression; -+ _data_->_tmp9_ = NULL; -+ _data_->_tmp9_ = rygel_search_expression_to_string (_data_->_tmp8_); -+ _data_->_tmp10_ = NULL; -+ _data_->_tmp10_ = _data_->_tmp9_; -+ g_debug ("rygel-lms-category-container.vala:253: Original search: %s", _data_->_tmp10_); -+ _g_free0 (_data_->_tmp10_); -+ _data_->_tmp11_ = NULL; -+ _data_->_tmp11_ = _data_->filter; -+ g_debug ("rygel-lms-category-container.vala:254: Parsed search expression: %s", _data_->_tmp11_); -+ _data_->_tmp12_ = 0U; -+ _data_->_tmp12_ = _data_->total_matches; -+ g_debug ("rygel-lms-category-container.vala:255: Filtered cild count is %u", _data_->_tmp12_); -+ } -+ _data_->_tmp13_ = 0U; -+ _data_->_tmp13_ = _data_->max_count; -+ if (_data_->_tmp13_ == ((guint) 0)) { -+ _data_->max_count = G_MAXUINT; -+ } -+ _data_->_tmp14_ = NULL; -+ _data_->_tmp14_ = _data_->filter; -+ _data_->_tmp15_ = NULL; -+ _data_->_tmp15_ = _data_->args; -+ _data_->_tmp16_ = NULL; -+ _data_->_tmp16_ = _data_->sort_criteria; -+ _data_->_tmp17_ = 0U; -+ _data_->_tmp17_ = _data_->offset; -+ _data_->_tmp18_ = 0U; -+ _data_->_tmp18_ = _data_->max_count; -+ _data_->_tmp19_ = NULL; -+ _data_->_tmp19_ = rygel_lms_category_container_get_children_with_filter (_data_->self, _data_->_tmp14_, _data_->_tmp15_, _data_->_tmp16_, _data_->_tmp17_, _data_->_tmp18_); -+ _data_->result = _data_->_tmp19_; -+ _g_free0 (_data_->filter); -+ _g_value_array_free0 (_data_->args); -+ if (_data_->_state_ == 0) { -+ g_simple_async_result_complete_in_idle (_data_->_async_result); -+ } else { -+ g_simple_async_result_complete (_data_->_async_result); -+ } -+ g_object_unref (_data_->_async_result); -+ return FALSE; -+ } -+ goto __finally4; -+ __catch4_g_error: -+ { -+ _data_->e = _data_->_inner_error_; -+ _data_->_inner_error_ = NULL; -+ _data_->_tmp20_ = NULL; -+ _data_->_tmp20_ = _data_->e; -+ _data_->_tmp21_ = NULL; -+ _data_->_tmp21_ = _data_->_tmp20_->message; -+ g_debug ("rygel-lms-category-container.vala:267: Falling back to simple_search" \ -+"(): %s", _data_->_tmp21_); -+ _data_->_tmp23_ = NULL; -+ _data_->_tmp23_ = _data_->expression; -+ _data_->_tmp24_ = 0U; -+ _data_->_tmp24_ = _data_->offset; -+ _data_->_tmp25_ = 0U; -+ _data_->_tmp25_ = _data_->max_count; -+ _data_->_tmp26_ = NULL; -+ _data_->_tmp26_ = _data_->sort_criteria; -+ _data_->_tmp27_ = NULL; -+ _data_->_tmp27_ = _data_->cancellable; -+ _data_->_tmp28_ = 0U; -+ _data_->_state_ = 1; -+ rygel_searchable_container_simple_search ((RygelSearchableContainer*) _data_->self, _data_->_tmp23_, _data_->_tmp24_, _data_->_tmp25_, _data_->_tmp26_, _data_->_tmp27_, rygel_lms_category_container_search_ready, _data_); -+ return FALSE; -+ _state_1: -+ _data_->_tmp29_ = NULL; -+ _data_->_tmp29_ = rygel_searchable_container_simple_search_finish ((RygelSearchableContainer*) _data_->self, _data_->_res_, &_data_->_tmp28_, &_data_->_inner_error_); -+ _data_->total_matches = _data_->_tmp28_; -+ _data_->_tmp22_ = _data_->_tmp29_; -+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) { -+ _g_error_free0 (_data_->e); -+ goto __finally4; -+ } -+ _data_->_tmp30_ = NULL; -+ _data_->_tmp30_ = _data_->_tmp22_; -+ _data_->_tmp22_ = NULL; -+ _data_->result = _data_->_tmp30_; -+ _g_object_unref0 (_data_->_tmp22_); -+ _g_error_free0 (_data_->e); -+ if (_data_->_state_ == 0) { -+ g_simple_async_result_complete_in_idle (_data_->_async_result); -+ } else { -+ g_simple_async_result_complete (_data_->_async_result); -+ } -+ g_object_unref (_data_->_async_result); -+ return FALSE; -+ } -+ __finally4: -+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_); -+ g_error_free (_data_->_inner_error_); -+ if (_data_->_state_ == 0) { -+ g_simple_async_result_complete_in_idle (_data_->_async_result); -+ } else { -+ g_simple_async_result_complete (_data_->_async_result); -+ } -+ g_object_unref (_data_->_async_result); -+ return FALSE; -+ if (_data_->_state_ == 0) { -+ g_simple_async_result_complete_in_idle (_data_->_async_result); -+ } else { -+ g_simple_async_result_complete (_data_->_async_result); -+ } -+ g_object_unref (_data_->_async_result); -+ return FALSE; -+} -+ -+ -+static void rygel_lms_category_container_real_get_children_data_free (gpointer _data) { -+ RygelLmsCategoryContainerGetChildrenData* _data_; -+ _data_ = _data; -+ _g_free0 (_data_->sort_criteria); -+ _g_object_unref0 (_data_->cancellable); -+ _g_object_unref0 (_data_->result); -+ _g_object_unref0 (_data_->self); -+ g_slice_free (RygelLmsCategoryContainerGetChildrenData, _data_); -+} -+ -+ -+static void rygel_lms_category_container_real_get_children (RygelMediaContainer* base, guint offset, guint max_count, const gchar* sort_criteria, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_) { -+ RygelLMSCategoryContainer * self; -+ RygelLmsCategoryContainerGetChildrenData* _data_; -+ RygelLMSCategoryContainer* _tmp0_ = NULL; -+ guint _tmp1_ = 0U; -+ guint _tmp2_ = 0U; -+ const gchar* _tmp3_ = NULL; -+ gchar* _tmp4_ = NULL; -+ GCancellable* _tmp5_ = NULL; -+ GCancellable* _tmp6_ = NULL; -+ self = (RygelLMSCategoryContainer*) base; -+ _data_ = g_slice_new0 (RygelLmsCategoryContainerGetChildrenData); -+ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_get_children); -+ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_get_children_data_free); -+ _tmp0_ = _g_object_ref0 (self); -+ _data_->self = _tmp0_; -+ _tmp1_ = offset; -+ _data_->offset = _tmp1_; -+ _tmp2_ = max_count; -+ _data_->max_count = _tmp2_; -+ _tmp3_ = sort_criteria; -+ _tmp4_ = g_strdup (_tmp3_); -+ _g_free0 (_data_->sort_criteria); -+ _data_->sort_criteria = _tmp4_; -+ _tmp5_ = cancellable; -+ _tmp6_ = _g_object_ref0 (_tmp5_); -+ _g_object_unref0 (_data_->cancellable); -+ _data_->cancellable = _tmp6_; -+ rygel_lms_category_container_real_get_children_co (_data_); -+} -+ -+ -+static RygelMediaObjects* rygel_lms_category_container_real_get_children_finish (RygelMediaContainer* base, GAsyncResult* _res_, GError** error) { -+ RygelMediaObjects* result; -+ RygelLmsCategoryContainerGetChildrenData* _data_; -+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) { -+ return NULL; -+ } -+ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_)); -+ result = _data_->result; -+ _data_->result = NULL; -+ return result; -+} -+ -+ -+static gboolean rygel_lms_category_container_real_get_children_co (RygelLmsCategoryContainerGetChildrenData* _data_) { -+ switch (_data_->_state_) { -+ case 0: -+ goto _state_0; -+ default: -+ g_assert_not_reached (); -+ } -+ _state_0: -+ _data_->_tmp0_ = NULL; -+ _data_->_tmp0_ = rygel_media_objects_new (); -+ _data_->retval = _data_->_tmp0_; -+ _data_->_tmp1_ = NULL; -+ _data_->_tmp1_ = _data_->self->stmt_all; -+ _data_->_tmp2_ = 0U; -+ _data_->_tmp2_ = _data_->offset; -+ _data_->_tmp3_ = 0U; -+ _data_->_tmp3_ = _data_->max_count; -+ _data_->_tmp4_ = NULL; -+ _data_->_tmp4_ = _data_->sort_criteria; -+ rygel_lms_database_get_children_init (_data_->_tmp1_, _data_->_tmp2_, _data_->_tmp3_, _data_->_tmp4_, &_data_->_inner_error_); -+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) { -+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_); -+ g_error_free (_data_->_inner_error_); -+ _g_object_unref0 (_data_->retval); -+ if (_data_->_state_ == 0) { -+ g_simple_async_result_complete_in_idle (_data_->_async_result); -+ } else { -+ g_simple_async_result_complete (_data_->_async_result); -+ } -+ g_object_unref (_data_->_async_result); -+ return FALSE; -+ } -+ while (TRUE) { -+ _data_->_tmp6_ = NULL; -+ _data_->_tmp6_ = _data_->self->stmt_all; -+ _data_->_tmp7_ = FALSE; -+ _data_->_tmp7_ = rygel_lms_database_get_children_step (_data_->_tmp6_, &_data_->_inner_error_); -+ _data_->_tmp5_ = _data_->_tmp7_; -+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) { -+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_); -+ g_error_free (_data_->_inner_error_); -+ _g_object_unref0 (_data_->retval); -+ if (_data_->_state_ == 0) { -+ g_simple_async_result_complete_in_idle (_data_->_async_result); -+ } else { -+ g_simple_async_result_complete (_data_->_async_result); -+ } -+ g_object_unref (_data_->_async_result); -+ return FALSE; -+ } -+ if (!_data_->_tmp5_) { -+ break; -+ } -+ _data_->_tmp8_ = NULL; -+ _data_->_tmp8_ = _data_->retval; -+ _data_->_tmp9_ = NULL; -+ _data_->_tmp9_ = _data_->self->stmt_all; -+ _data_->_tmp10_ = NULL; -+ _data_->_tmp10_ = rygel_lms_category_container_object_from_statement (_data_->self, _data_->_tmp9_); -+ _data_->_tmp11_ = NULL; -+ _data_->_tmp11_ = _data_->_tmp10_; -+ gee_abstract_collection_add ((GeeAbstractCollection*) _data_->_tmp8_, _data_->_tmp11_); -+ _g_object_unref0 (_data_->_tmp11_); -+ } -+ _data_->result = _data_->retval; -+ if (_data_->_state_ == 0) { -+ g_simple_async_result_complete_in_idle (_data_->_async_result); -+ } else { -+ g_simple_async_result_complete (_data_->_async_result); -+ } -+ g_object_unref (_data_->_async_result); -+ return FALSE; -+ _g_object_unref0 (_data_->retval); -+ if (_data_->_state_ == 0) { -+ g_simple_async_result_complete_in_idle (_data_->_async_result); -+ } else { -+ g_simple_async_result_complete (_data_->_async_result); -+ } -+ g_object_unref (_data_->_async_result); -+ return FALSE; -+} -+ -+ -+static void rygel_lms_category_container_real_find_object_data_free (gpointer _data) { -+ RygelLmsCategoryContainerFindObjectData* _data_; -+ _data_ = _data; -+ _g_free0 (_data_->id); -+ _g_object_unref0 (_data_->cancellable); -+ _g_object_unref0 (_data_->result); -+ _g_object_unref0 (_data_->self); -+ g_slice_free (RygelLmsCategoryContainerFindObjectData, _data_); -+} -+ -+ -+static void rygel_lms_category_container_real_find_object (RygelMediaContainer* base, const gchar* id, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_) { -+ RygelLMSCategoryContainer * self; -+ RygelLmsCategoryContainerFindObjectData* _data_; -+ RygelLMSCategoryContainer* _tmp0_ = NULL; -+ const gchar* _tmp1_ = NULL; -+ gchar* _tmp2_ = NULL; -+ GCancellable* _tmp3_ = NULL; -+ GCancellable* _tmp4_ = NULL; -+ self = (RygelLMSCategoryContainer*) base; -+ _data_ = g_slice_new0 (RygelLmsCategoryContainerFindObjectData); -+ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_find_object); -+ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_find_object_data_free); -+ _tmp0_ = _g_object_ref0 (self); -+ _data_->self = _tmp0_; -+ _tmp1_ = id; -+ _tmp2_ = g_strdup (_tmp1_); -+ _g_free0 (_data_->id); -+ _data_->id = _tmp2_; -+ _tmp3_ = cancellable; -+ _tmp4_ = _g_object_ref0 (_tmp3_); -+ _g_object_unref0 (_data_->cancellable); -+ _data_->cancellable = _tmp4_; -+ rygel_lms_category_container_real_find_object_co (_data_); -+} -+ -+ -+static RygelMediaObject* rygel_lms_category_container_real_find_object_finish (RygelMediaContainer* base, GAsyncResult* _res_, GError** error) { -+ RygelMediaObject* result; -+ RygelLmsCategoryContainerFindObjectData* _data_; -+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) { -+ return NULL; -+ } -+ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_)); -+ result = _data_->result; -+ _data_->result = NULL; -+ return result; -+} -+ -+ -+static glong string_strnlen (gchar* str, glong maxlen) { -+ glong result = 0L; -+ gchar* end = NULL; -+ gchar* _tmp0_ = NULL; -+ glong _tmp1_ = 0L; -+ gchar* _tmp2_ = NULL; -+ gchar* _tmp3_ = NULL; -+ _tmp0_ = str; -+ _tmp1_ = maxlen; -+ _tmp2_ = memchr (_tmp0_, 0, (gsize) _tmp1_); -+ end = _tmp2_; -+ _tmp3_ = end; -+ if (_tmp3_ == NULL) { -+ glong _tmp4_ = 0L; -+ _tmp4_ = maxlen; -+ result = _tmp4_; -+ return result; -+ } else { -+ gchar* _tmp5_ = NULL; -+ gchar* _tmp6_ = NULL; -+ _tmp5_ = end; -+ _tmp6_ = str; -+ result = (glong) (_tmp5_ - _tmp6_); -+ return result; -+ } -+} -+ -+ -+static gchar* string_substring (const gchar* self, glong offset, glong len) { -+ gchar* result = NULL; -+ glong string_length = 0L; -+ gboolean _tmp0_ = FALSE; -+ glong _tmp1_ = 0L; -+ glong _tmp8_ = 0L; -+ glong _tmp14_ = 0L; -+ glong _tmp17_ = 0L; -+ glong _tmp18_ = 0L; -+ glong _tmp19_ = 0L; -+ glong _tmp20_ = 0L; -+ glong _tmp21_ = 0L; -+ gchar* _tmp22_ = NULL; -+ g_return_val_if_fail (self != NULL, NULL); -+ _tmp1_ = offset; -+ if (_tmp1_ >= ((glong) 0)) { -+ glong _tmp2_ = 0L; -+ _tmp2_ = len; -+ _tmp0_ = _tmp2_ >= ((glong) 0); -+ } else { -+ _tmp0_ = FALSE; -+ } -+ if (_tmp0_) { -+ glong _tmp3_ = 0L; -+ glong _tmp4_ = 0L; -+ glong _tmp5_ = 0L; -+ _tmp3_ = offset; -+ _tmp4_ = len; -+ _tmp5_ = string_strnlen ((gchar*) self, _tmp3_ + _tmp4_); -+ string_length = _tmp5_; -+ } else { -+ gint _tmp6_ = 0; -+ gint _tmp7_ = 0; -+ _tmp6_ = strlen (self); -+ _tmp7_ = _tmp6_; -+ string_length = (glong) _tmp7_; -+ } -+ _tmp8_ = offset; -+ if (_tmp8_ < ((glong) 0)) { -+ glong _tmp9_ = 0L; -+ glong _tmp10_ = 0L; -+ glong _tmp11_ = 0L; -+ _tmp9_ = string_length; -+ _tmp10_ = offset; -+ offset = _tmp9_ + _tmp10_; -+ _tmp11_ = offset; -+ g_return_val_if_fail (_tmp11_ >= ((glong) 0), NULL); -+ } else { -+ glong _tmp12_ = 0L; -+ glong _tmp13_ = 0L; -+ _tmp12_ = offset; -+ _tmp13_ = string_length; -+ g_return_val_if_fail (_tmp12_ <= _tmp13_, NULL); -+ } -+ _tmp14_ = len; -+ if (_tmp14_ < ((glong) 0)) { -+ glong _tmp15_ = 0L; -+ glong _tmp16_ = 0L; -+ _tmp15_ = string_length; -+ _tmp16_ = offset; -+ len = _tmp15_ - _tmp16_; -+ } -+ _tmp17_ = offset; -+ _tmp18_ = len; -+ _tmp19_ = string_length; -+ g_return_val_if_fail ((_tmp17_ + _tmp18_) <= _tmp19_, NULL); -+ _tmp20_ = offset; -+ _tmp21_ = len; -+ _tmp22_ = g_strndup (((gchar*) self) + _tmp20_, (gsize) _tmp21_); -+ result = _tmp22_; -+ return result; -+} -+ -+ -+static gint string_index_of_char (const gchar* self, gunichar c, gint start_index) { -+ gint result = 0; -+ gchar* _result_ = NULL; -+ gint _tmp0_ = 0; -+ gunichar _tmp1_ = 0U; -+ gchar* _tmp2_ = NULL; -+ gchar* _tmp3_ = NULL; -+ g_return_val_if_fail (self != NULL, 0); -+ _tmp0_ = start_index; -+ _tmp1_ = c; -+ _tmp2_ = g_utf8_strchr (((gchar*) self) + _tmp0_, (gssize) (-1), _tmp1_); -+ _result_ = _tmp2_; -+ _tmp3_ = _result_; -+ if (_tmp3_ != NULL) { -+ gchar* _tmp4_ = NULL; -+ _tmp4_ = _result_; -+ result = (gint) (_tmp4_ - ((gchar*) self)); -+ return result; -+ } else { -+ result = -1; -+ return result; -+ } -+} -+ -+ -+static gchar* string_slice (const gchar* self, glong start, glong end) { -+ gchar* result = NULL; -+ glong string_length = 0L; -+ gint _tmp0_ = 0; -+ gint _tmp1_ = 0; -+ glong _tmp2_ = 0L; -+ glong _tmp5_ = 0L; -+ gboolean _tmp8_ = FALSE; -+ glong _tmp9_ = 0L; -+ gboolean _tmp12_ = FALSE; -+ glong _tmp13_ = 0L; -+ glong _tmp16_ = 0L; -+ glong _tmp17_ = 0L; -+ glong _tmp18_ = 0L; -+ glong _tmp19_ = 0L; -+ glong _tmp20_ = 0L; -+ gchar* _tmp21_ = NULL; -+ g_return_val_if_fail (self != NULL, NULL); -+ _tmp0_ = strlen (self); -+ _tmp1_ = _tmp0_; -+ string_length = (glong) _tmp1_; -+ _tmp2_ = start; -+ if (_tmp2_ < ((glong) 0)) { -+ glong _tmp3_ = 0L; -+ glong _tmp4_ = 0L; -+ _tmp3_ = string_length; -+ _tmp4_ = start; -+ start = _tmp3_ + _tmp4_; -+ } -+ _tmp5_ = end; -+ if (_tmp5_ < ((glong) 0)) { -+ glong _tmp6_ = 0L; -+ glong _tmp7_ = 0L; -+ _tmp6_ = string_length; -+ _tmp7_ = end; -+ end = _tmp6_ + _tmp7_; -+ } -+ _tmp9_ = start; -+ if (_tmp9_ >= ((glong) 0)) { -+ glong _tmp10_ = 0L; -+ glong _tmp11_ = 0L; -+ _tmp10_ = start; -+ _tmp11_ = string_length; -+ _tmp8_ = _tmp10_ <= _tmp11_; -+ } else { -+ _tmp8_ = FALSE; -+ } -+ g_return_val_if_fail (_tmp8_, NULL); -+ _tmp13_ = end; -+ if (_tmp13_ >= ((glong) 0)) { -+ glong _tmp14_ = 0L; -+ glong _tmp15_ = 0L; -+ _tmp14_ = end; -+ _tmp15_ = string_length; -+ _tmp12_ = _tmp14_ <= _tmp15_; -+ } else { -+ _tmp12_ = FALSE; -+ } -+ g_return_val_if_fail (_tmp12_, NULL); -+ _tmp16_ = start; -+ _tmp17_ = end; -+ g_return_val_if_fail (_tmp16_ <= _tmp17_, NULL); -+ _tmp18_ = start; -+ _tmp19_ = end; -+ _tmp20_ = start; -+ _tmp21_ = g_strndup (((gchar*) self) + _tmp18_, (gsize) (_tmp19_ - _tmp20_)); -+ result = _tmp21_; -+ return result; -+} -+ -+ -+static void rygel_lms_category_container_find_object_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) { -+ RygelLmsCategoryContainerFindObjectData* _data_; -+ _data_ = _user_data_; -+ _data_->_source_object_ = source_object; -+ _data_->_res_ = _res_; -+ rygel_lms_category_container_real_find_object_co (_data_); -+} -+ -+ -+static gboolean rygel_lms_category_container_real_find_object_co (RygelLmsCategoryContainerFindObjectData* _data_) { -+ switch (_data_->_state_) { -+ case 0: -+ goto _state_0; -+ case 1: -+ goto _state_1; -+ default: -+ g_assert_not_reached (); -+ } -+ _state_0: -+ _data_->_tmp0_ = NULL; -+ _data_->_tmp0_ = _data_->id; -+ _data_->_tmp1_ = NULL; -+ _data_->_tmp1_ = _data_->self->child_prefix; -+ _data_->_tmp2_ = FALSE; -+ _data_->_tmp2_ = g_str_has_prefix (_data_->_tmp0_, _data_->_tmp1_); -+ if (!_data_->_tmp2_) { -+ _data_->result = NULL; -+ if (_data_->_state_ == 0) { -+ g_simple_async_result_complete_in_idle (_data_->_async_result); -+ } else { -+ g_simple_async_result_complete (_data_->_async_result); -+ } -+ g_object_unref (_data_->_async_result); -+ return FALSE; -+ } -+ _data_->object = NULL; -+ _data_->_tmp3_ = NULL; -+ _data_->_tmp3_ = _data_->id; -+ _data_->_tmp4_ = NULL; -+ _data_->_tmp4_ = _data_->self->child_prefix; -+ _data_->_tmp5_ = 0; -+ _data_->_tmp5_ = strlen (_data_->_tmp4_); -+ _data_->_tmp6_ = 0; -+ _data_->_tmp6_ = _data_->_tmp5_; -+ _data_->_tmp7_ = NULL; -+ _data_->_tmp7_ = string_substring (_data_->_tmp3_, (glong) _data_->_tmp6_, (glong) (-1)); -+ _data_->real_id = _data_->_tmp7_; -+ _data_->_tmp8_ = NULL; -+ _data_->_tmp8_ = _data_->real_id; -+ _data_->_tmp9_ = 0; -+ _data_->_tmp9_ = string_index_of_char (_data_->_tmp8_, (gunichar) ':', 0); -+ _data_->index = _data_->_tmp9_; -+ _data_->_tmp10_ = 0; -+ _data_->_tmp10_ = _data_->index; -+ if (_data_->_tmp10_ > 0) { -+ _data_->_tmp11_ = NULL; -+ _data_->_tmp11_ = _data_->real_id; -+ _data_->_tmp12_ = 0; -+ _data_->_tmp12_ = _data_->index; -+ _data_->_tmp13_ = NULL; -+ _data_->_tmp13_ = string_slice (_data_->_tmp11_, (glong) 0, (glong) _data_->_tmp12_); -+ _g_free0 (_data_->real_id); -+ _data_->real_id = _data_->_tmp13_; -+ } -+ { -+ _data_->_tmp14_ = NULL; -+ _data_->_tmp14_ = _data_->real_id; -+ _data_->_tmp15_ = NULL; -+ _data_->_tmp15_ = _data_->self->stmt_find_object; -+ rygel_lms_database_find_object (_data_->_tmp14_, _data_->_tmp15_, &_data_->_inner_error_); -+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) { -+ if (_data_->_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch5_rygel_lms_database_error; -+ } -+ _g_free0 (_data_->real_id); -+ _g_object_unref0 (_data_->object); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error_->message, g_quark_to_string (_data_->_inner_error_->domain), _data_->_inner_error_->code); -+ g_clear_error (&_data_->_inner_error_); -+ return FALSE; -+ } -+ _data_->_tmp16_ = NULL; -+ _data_->_tmp16_ = _data_->self->stmt_find_object; -+ _data_->_tmp17_ = NULL; -+ _data_->_tmp17_ = rygel_lms_category_container_object_from_statement (_data_->self, _data_->_tmp16_); -+ _data_->child = _data_->_tmp17_; -+ _data_->_tmp18_ = 0; -+ _data_->_tmp18_ = _data_->index; -+ if (_data_->_tmp18_ < 0) { -+ _data_->_tmp19_ = NULL; -+ _data_->_tmp19_ = _data_->child; -+ _data_->_tmp20_ = NULL; -+ _data_->_tmp20_ = _g_object_ref0 (_data_->_tmp19_); -+ _g_object_unref0 (_data_->object); -+ _data_->object = _data_->_tmp20_; -+ } else { -+ _data_->_tmp21_ = NULL; -+ _data_->_tmp21_ = _data_->child; -+ _data_->_tmp22_ = NULL; -+ _data_->_tmp22_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (_data_->_tmp21_, RYGEL_LMS_TYPE_CATEGORY_CONTAINER) ? ((RygelLMSCategoryContainer*) _data_->_tmp21_) : NULL); -+ _data_->container = _data_->_tmp22_; -+ _data_->_tmp24_ = NULL; -+ _data_->_tmp24_ = _data_->container; -+ _data_->_tmp25_ = NULL; -+ _data_->_tmp25_ = _data_->id; -+ _data_->_tmp26_ = NULL; -+ _data_->_tmp26_ = _data_->cancellable; -+ _data_->_state_ = 1; -+ rygel_media_container_find_object ((RygelMediaContainer*) _data_->_tmp24_, _data_->_tmp25_, _data_->_tmp26_, rygel_lms_category_container_find_object_ready, _data_); -+ return FALSE; -+ _state_1: -+ _data_->_tmp27_ = NULL; -+ _data_->_tmp27_ = rygel_media_container_find_object_finish ((RygelMediaContainer*) _data_->_tmp24_, _data_->_res_, &_data_->_inner_error_); -+ _data_->_tmp23_ = _data_->_tmp27_; -+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) { -+ _g_object_unref0 (_data_->container); -+ _g_object_unref0 (_data_->child); -+ if (_data_->_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch5_rygel_lms_database_error; -+ } -+ goto __finally5; -+ } -+ _data_->_tmp28_ = NULL; -+ _data_->_tmp28_ = _data_->_tmp23_; -+ _data_->_tmp23_ = NULL; -+ _g_object_unref0 (_data_->object); -+ _data_->object = _data_->_tmp28_; -+ _data_->_tmp29_ = NULL; -+ _data_->_tmp29_ = _data_->object; -+ _data_->_tmp30_ = NULL; -+ _data_->_tmp30_ = _data_->object; -+ _data_->_tmp31_ = NULL; -+ _data_->_tmp31_ = rygel_media_object_get_parent (_data_->_tmp30_); -+ _data_->_tmp32_ = NULL; -+ _data_->_tmp32_ = _data_->_tmp31_; -+ rygel_media_object_set_parent_ref (_data_->_tmp29_, _data_->_tmp32_); -+ _g_object_unref0 (_data_->_tmp23_); -+ _g_object_unref0 (_data_->container); -+ } -+ _g_object_unref0 (_data_->child); -+ } -+ goto __finally5; -+ __catch5_rygel_lms_database_error: -+ { -+ _data_->e = _data_->_inner_error_; -+ _data_->_inner_error_ = NULL; -+ _data_->_tmp33_ = NULL; -+ _data_->_tmp33_ = _data_->id; -+ _data_->_tmp34_ = NULL; -+ _data_->_tmp34_ = rygel_media_object_get_id ((RygelMediaObject*) _data_->self); -+ _data_->_tmp35_ = NULL; -+ _data_->_tmp35_ = _data_->_tmp34_; -+ _data_->_tmp36_ = NULL; -+ _data_->_tmp36_ = _data_->e; -+ _data_->_tmp37_ = NULL; -+ _data_->_tmp37_ = _data_->_tmp36_->message; -+ g_debug ("rygel-lms-category-container.vala:328: find_object %s in %s: %s", _data_->_tmp33_, _data_->_tmp35_, _data_->_tmp37_); -+ _g_error_free0 (_data_->e); -+ } -+ __finally5: -+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) { -+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_); -+ g_error_free (_data_->_inner_error_); -+ _g_free0 (_data_->real_id); -+ _g_object_unref0 (_data_->object); -+ if (_data_->_state_ == 0) { -+ g_simple_async_result_complete_in_idle (_data_->_async_result); -+ } else { -+ g_simple_async_result_complete (_data_->_async_result); -+ } -+ g_object_unref (_data_->_async_result); -+ return FALSE; -+ } -+ _data_->result = _data_->object; -+ _g_free0 (_data_->real_id); -+ if (_data_->_state_ == 0) { -+ g_simple_async_result_complete_in_idle (_data_->_async_result); -+ } else { -+ g_simple_async_result_complete (_data_->_async_result); -+ } -+ g_object_unref (_data_->_async_result); -+ return FALSE; -+ _g_free0 (_data_->real_id); -+ _g_object_unref0 (_data_->object); -+ if (_data_->_state_ == 0) { -+ g_simple_async_result_complete_in_idle (_data_->_async_result); -+ } else { -+ g_simple_async_result_complete (_data_->_async_result); -+ } -+ g_object_unref (_data_->_async_result); -+ return FALSE; -+} -+ -+ -+gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gchar* _tmp2_ = NULL; -+ g_return_val_if_fail (self != NULL, NULL); -+ _tmp0_ = self->child_prefix; -+ _tmp1_ = db_id; -+ _tmp2_ = g_strdup_printf ("%s%d", _tmp0_, _tmp1_); -+ result = _tmp2_; -+ return result; -+} -+ -+ -+gchar* rygel_lms_category_container_build_reference_id (RygelLMSCategoryContainer* self, gint db_id) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gchar* _tmp2_ = NULL; -+ g_return_val_if_fail (self != NULL, NULL); -+ _tmp0_ = self->ref_prefix; -+ _tmp1_ = db_id; -+ _tmp2_ = g_strdup_printf ("%s%d", _tmp0_, _tmp1_); -+ result = _tmp2_; -+ return result; -+} -+ -+ -+static void rygel_lms_category_container_real_add_child_data_free (gpointer _data) { -+ RygelLmsCategoryContainerAddChildData* _data_; -+ _data_ = _data; -+ _g_object_unref0 (_data_->object); -+ _g_object_unref0 (_data_->self); -+ g_slice_free (RygelLmsCategoryContainerAddChildData, _data_); -+} -+ -+ -+static void rygel_lms_category_container_real_add_child (RygelTrackableContainer* base, RygelMediaObject* object, GAsyncReadyCallback _callback_, gpointer _user_data_) { -+ RygelLMSCategoryContainer * self; -+ RygelLmsCategoryContainerAddChildData* _data_; -+ RygelLMSCategoryContainer* _tmp0_ = NULL; -+ RygelMediaObject* _tmp1_ = NULL; -+ RygelMediaObject* _tmp2_ = NULL; -+ self = (RygelLMSCategoryContainer*) base; -+ _data_ = g_slice_new0 (RygelLmsCategoryContainerAddChildData); -+ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_add_child); -+ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_add_child_data_free); -+ _tmp0_ = _g_object_ref0 (self); -+ _data_->self = _tmp0_; -+ _tmp1_ = object; -+ _tmp2_ = _g_object_ref0 (_tmp1_); -+ _g_object_unref0 (_data_->object); -+ _data_->object = _tmp2_; -+ rygel_lms_category_container_real_add_child_co (_data_); -+} -+ -+ -+static void rygel_lms_category_container_real_add_child_finish (RygelTrackableContainer* base, GAsyncResult* _res_) { -+ RygelLmsCategoryContainerAddChildData* _data_; -+ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_)); -+} -+ -+ -+static gboolean rygel_lms_category_container_real_add_child_co (RygelLmsCategoryContainerAddChildData* _data_) { -+ switch (_data_->_state_) { -+ case 0: -+ goto _state_0; -+ default: -+ g_assert_not_reached (); -+ } -+ _state_0: -+ if (_data_->_state_ == 0) { -+ g_simple_async_result_complete_in_idle (_data_->_async_result); -+ } else { -+ g_simple_async_result_complete (_data_->_async_result); -+ } -+ g_object_unref (_data_->_async_result); -+ return FALSE; -+} -+ -+ -+static void rygel_lms_category_container_real_remove_child_data_free (gpointer _data) { -+ RygelLmsCategoryContainerRemoveChildData* _data_; -+ _data_ = _data; -+ _g_object_unref0 (_data_->object); -+ _g_object_unref0 (_data_->self); -+ g_slice_free (RygelLmsCategoryContainerRemoveChildData, _data_); -+} -+ -+ -+static void rygel_lms_category_container_real_remove_child (RygelTrackableContainer* base, RygelMediaObject* object, GAsyncReadyCallback _callback_, gpointer _user_data_) { -+ RygelLMSCategoryContainer * self; -+ RygelLmsCategoryContainerRemoveChildData* _data_; -+ RygelLMSCategoryContainer* _tmp0_ = NULL; -+ RygelMediaObject* _tmp1_ = NULL; -+ RygelMediaObject* _tmp2_ = NULL; -+ self = (RygelLMSCategoryContainer*) base; -+ _data_ = g_slice_new0 (RygelLmsCategoryContainerRemoveChildData); -+ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_remove_child); -+ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_remove_child_data_free); -+ _tmp0_ = _g_object_ref0 (self); -+ _data_->self = _tmp0_; -+ _tmp1_ = object; -+ _tmp2_ = _g_object_ref0 (_tmp1_); -+ _g_object_unref0 (_data_->object); -+ _data_->object = _tmp2_; -+ rygel_lms_category_container_real_remove_child_co (_data_); -+} -+ -+ -+static void rygel_lms_category_container_real_remove_child_finish (RygelTrackableContainer* base, GAsyncResult* _res_) { -+ RygelLmsCategoryContainerRemoveChildData* _data_; -+ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_)); -+} -+ -+ -+static gboolean rygel_lms_category_container_real_remove_child_co (RygelLmsCategoryContainerRemoveChildData* _data_) { -+ switch (_data_->_state_) { -+ case 0: -+ goto _state_0; -+ default: -+ g_assert_not_reached (); -+ } -+ _state_0: -+ if (_data_->_state_ == 0) { -+ g_simple_async_result_complete_in_idle (_data_->_async_result); -+ } else { -+ g_simple_async_result_complete (_data_->_async_result); -+ } -+ g_object_unref (_data_->_async_result); -+ return FALSE; -+} -+ -+ -+static void rygel_lms_category_container_on_db_updated (RygelLMSCategoryContainer* self, guint64 old_id, guint64 new_id) { -+ GError * _inner_error_ = NULL; -+ g_return_if_fail (self != NULL); -+ { -+ sqlite3_stmt* stmt_count = NULL; -+ RygelLMSDatabase* _tmp0_ = NULL; -+ const gchar* _tmp1_ = NULL; -+ sqlite3_stmt* _tmp2_ = NULL; -+ sqlite3_stmt* _tmp3_ = NULL; -+ gint _tmp4_ = 0; -+ sqlite3_stmt* _tmp7_ = NULL; -+ guint64 _tmp8_ = 0ULL; -+ guint64 _tmp9_ = 0ULL; -+ sqlite3_stmt* _tmp16_ = NULL; -+ guint64 _tmp17_ = 0ULL; -+ guint64 _tmp18_ = 0ULL; -+ _tmp0_ = self->priv->_lms_db; -+ _tmp1_ = self->priv->_sql_count; -+ _tmp2_ = rygel_lms_database_prepare (_tmp0_, _tmp1_, &_inner_error_); -+ stmt_count = _tmp2_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch6_rygel_lms_database_error; -+ } -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return; -+ } -+ _tmp3_ = stmt_count; -+ _tmp4_ = sqlite3_step (_tmp3_); -+ if (_tmp4_ == SQLITE_ROW) { -+ sqlite3_stmt* _tmp5_ = NULL; -+ gint _tmp6_ = 0; -+ _tmp5_ = stmt_count; -+ _tmp6_ = sqlite3_column_int (_tmp5_, 0); -+ rygel_media_container_set_child_count ((RygelMediaContainer*) self, _tmp6_); -+ } -+ _tmp7_ = self->stmt_added; -+ _tmp8_ = old_id; -+ _tmp9_ = new_id; -+ rygel_lms_database_get_children_with_update_id_init (_tmp7_, _tmp8_, _tmp9_, &_inner_error_); -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _sqlite3_finalize0 (stmt_count); -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch6_rygel_lms_database_error; -+ } -+ _sqlite3_finalize0 (stmt_count); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return; -+ } -+ while (TRUE) { -+ gboolean _tmp10_ = FALSE; -+ sqlite3_stmt* _tmp11_ = NULL; -+ gboolean _tmp12_ = FALSE; -+ sqlite3_stmt* _tmp13_ = NULL; -+ RygelMediaObject* _tmp14_ = NULL; -+ RygelMediaObject* _tmp15_ = NULL; -+ _tmp11_ = self->stmt_added; -+ _tmp12_ = rygel_lms_database_get_children_step (_tmp11_, &_inner_error_); -+ _tmp10_ = _tmp12_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _sqlite3_finalize0 (stmt_count); -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch6_rygel_lms_database_error; -+ } -+ _sqlite3_finalize0 (stmt_count); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return; -+ } -+ if (!_tmp10_) { -+ break; -+ } -+ _tmp13_ = self->stmt_added; -+ _tmp14_ = rygel_lms_category_container_object_from_statement (self, _tmp13_); -+ _tmp15_ = _tmp14_; -+ rygel_trackable_container_add_child_tracked ((RygelTrackableContainer*) self, _tmp15_, NULL, NULL); -+ _g_object_unref0 (_tmp15_); -+ } -+ _tmp16_ = self->stmt_removed; -+ _tmp17_ = old_id; -+ _tmp18_ = new_id; -+ rygel_lms_database_get_children_with_update_id_init (_tmp16_, _tmp17_, _tmp18_, &_inner_error_); -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _sqlite3_finalize0 (stmt_count); -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch6_rygel_lms_database_error; -+ } -+ _sqlite3_finalize0 (stmt_count); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return; -+ } -+ while (TRUE) { -+ gboolean _tmp19_ = FALSE; -+ sqlite3_stmt* _tmp20_ = NULL; -+ gboolean _tmp21_ = FALSE; -+ sqlite3_stmt* _tmp22_ = NULL; -+ RygelMediaObject* _tmp23_ = NULL; -+ RygelMediaObject* _tmp24_ = NULL; -+ _tmp20_ = self->stmt_removed; -+ _tmp21_ = rygel_lms_database_get_children_step (_tmp20_, &_inner_error_); -+ _tmp19_ = _tmp21_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _sqlite3_finalize0 (stmt_count); -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch6_rygel_lms_database_error; -+ } -+ _sqlite3_finalize0 (stmt_count); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return; -+ } -+ if (!_tmp19_) { -+ break; -+ } -+ _tmp22_ = self->stmt_removed; -+ _tmp23_ = rygel_lms_category_container_object_from_statement (self, _tmp22_); -+ _tmp24_ = _tmp23_; -+ rygel_trackable_container_remove_child_tracked ((RygelTrackableContainer*) self, _tmp24_, NULL, NULL); -+ _g_object_unref0 (_tmp24_); -+ } -+ _sqlite3_finalize0 (stmt_count); -+ } -+ goto __finally6; -+ __catch6_rygel_lms_database_error: -+ { -+ GError* e = NULL; -+ GError* _tmp25_ = NULL; -+ const gchar* _tmp26_ = NULL; -+ e = _inner_error_; -+ _inner_error_ = NULL; -+ _tmp25_ = e; -+ _tmp26_ = _tmp25_->message; -+ g_warning ("rygel-lms-category-container.vala:372: Can't perform container update:" \ -+" %s", _tmp26_); -+ _g_error_free0 (e); -+ } -+ __finally6: -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return; -+ } -+} -+ -+ -+RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed) { -+ RygelLMSCategoryContainer * self = NULL; -+ RygelMediaContainer* _tmp0_ = NULL; -+ const gchar* _tmp1_ = NULL; -+ const gchar* _tmp2_ = NULL; -+ const gchar* _tmp3_ = NULL; -+ gchar* _tmp4_ = NULL; -+ gchar* _tmp5_ = NULL; -+ const gchar* _tmp6_ = NULL; -+ RygelMediaContainer* _tmp7_ = NULL; -+ const gchar* _tmp8_ = NULL; -+ RygelLMSDatabase* _tmp9_ = NULL; -+ const gchar* _tmp10_ = NULL; -+ const gchar* _tmp11_ = NULL; -+ const gchar* _tmp12_ = NULL; -+ const gchar* _tmp13_ = NULL; -+ const gchar* _tmp14_ = NULL; -+ g_return_val_if_fail (db_id != NULL, NULL); -+ g_return_val_if_fail (parent != NULL, NULL); -+ g_return_val_if_fail (title != NULL, NULL); -+ g_return_val_if_fail (lms_db != NULL, NULL); -+ g_return_val_if_fail (sql_all != NULL, NULL); -+ g_return_val_if_fail (sql_find_object != NULL, NULL); -+ g_return_val_if_fail (sql_count != NULL, NULL); -+ _tmp0_ = parent; -+ _tmp1_ = rygel_media_object_get_id ((RygelMediaObject*) _tmp0_); -+ _tmp2_ = _tmp1_; -+ _tmp3_ = db_id; -+ _tmp4_ = g_strdup_printf ("%s:%s", _tmp2_, _tmp3_); -+ _tmp5_ = _tmp4_; -+ _tmp6_ = db_id; -+ _tmp7_ = parent; -+ _tmp8_ = title; -+ _tmp9_ = lms_db; -+ _tmp10_ = sql_all; -+ _tmp11_ = sql_find_object; -+ _tmp12_ = sql_count; -+ _tmp13_ = sql_added; -+ _tmp14_ = sql_removed; -+ self = (RygelLMSCategoryContainer*) g_object_new (object_type, "id", _tmp5_, "db-id", _tmp6_, "parent", _tmp7_, "title", _tmp8_, "lms-db", _tmp9_, "sql-all", _tmp10_, "sql-find-object", _tmp11_, "sql-count", _tmp12_, "sql-added", _tmp13_, "sql-removed", _tmp14_, NULL); -+ _g_free0 (_tmp5_); -+ return self; -+} -+ -+ -+static GeeArrayList* rygel_lms_category_container_real_get_search_classes (RygelSearchableContainer* base) { -+ GeeArrayList* result; -+ RygelLMSCategoryContainer* self; -+ GeeArrayList* _tmp0_ = NULL; -+ self = (RygelLMSCategoryContainer*) base; -+ _tmp0_ = self->priv->_search_classes; -+ result = _tmp0_; -+ return result; -+} -+ -+ -+static void rygel_lms_category_container_real_set_search_classes (RygelSearchableContainer* base, GeeArrayList* value) { -+ RygelLMSCategoryContainer* self; -+ GeeArrayList* _tmp0_ = NULL; -+ GeeArrayList* _tmp1_ = NULL; -+ self = (RygelLMSCategoryContainer*) base; -+ _tmp0_ = value; -+ _tmp1_ = _g_object_ref0 (_tmp0_); -+ _g_object_unref0 (self->priv->_search_classes); -+ self->priv->_search_classes = _tmp1_; -+ g_object_notify ((GObject *) self, "search-classes"); -+} -+ -+ -+RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self) { -+ RygelLMSDatabase* result; -+ RygelLMSDatabase* _tmp0_ = NULL; -+ g_return_val_if_fail (self != NULL, NULL); -+ _tmp0_ = self->priv->_lms_db; -+ result = _tmp0_; -+ return result; -+} -+ -+ -+static void rygel_lms_category_container_set_lms_db (RygelLMSCategoryContainer* self, RygelLMSDatabase* value) { -+ RygelLMSDatabase* _tmp0_ = NULL; -+ g_return_if_fail (self != NULL); -+ _tmp0_ = value; -+ self->priv->_lms_db = _tmp0_; -+ g_object_notify ((GObject *) self, "lms-db"); -+} -+ -+ -+const gchar* rygel_lms_category_container_get_db_id (RygelLMSCategoryContainer* self) { -+ const gchar* result; -+ const gchar* _tmp0_ = NULL; -+ g_return_val_if_fail (self != NULL, NULL); -+ _tmp0_ = self->priv->_db_id; -+ result = _tmp0_; -+ return result; -+} -+ -+ -+static void rygel_lms_category_container_set_db_id (RygelLMSCategoryContainer* self, const gchar* value) { -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_if_fail (self != NULL); -+ _tmp0_ = value; -+ _tmp1_ = g_strdup (_tmp0_); -+ _g_free0 (self->priv->_db_id); -+ self->priv->_db_id = _tmp1_; -+ g_object_notify ((GObject *) self, "db-id"); -+} -+ -+ -+const gchar* rygel_lms_category_container_get_sql_all (RygelLMSCategoryContainer* self) { -+ const gchar* result; -+ const gchar* _tmp0_ = NULL; -+ g_return_val_if_fail (self != NULL, NULL); -+ _tmp0_ = self->priv->_sql_all; -+ result = _tmp0_; -+ return result; -+} -+ -+ -+static void rygel_lms_category_container_set_sql_all (RygelLMSCategoryContainer* self, const gchar* value) { -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_if_fail (self != NULL); -+ _tmp0_ = value; -+ _tmp1_ = g_strdup (_tmp0_); -+ _g_free0 (self->priv->_sql_all); -+ self->priv->_sql_all = _tmp1_; -+ g_object_notify ((GObject *) self, "sql-all"); -+} -+ -+ -+const gchar* rygel_lms_category_container_get_sql_find_object (RygelLMSCategoryContainer* self) { -+ const gchar* result; -+ const gchar* _tmp0_ = NULL; -+ g_return_val_if_fail (self != NULL, NULL); -+ _tmp0_ = self->priv->_sql_find_object; -+ result = _tmp0_; -+ return result; -+} -+ -+ -+static void rygel_lms_category_container_set_sql_find_object (RygelLMSCategoryContainer* self, const gchar* value) { -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_if_fail (self != NULL); -+ _tmp0_ = value; -+ _tmp1_ = g_strdup (_tmp0_); -+ _g_free0 (self->priv->_sql_find_object); -+ self->priv->_sql_find_object = _tmp1_; -+ g_object_notify ((GObject *) self, "sql-find-object"); -+} -+ -+ -+const gchar* rygel_lms_category_container_get_sql_count (RygelLMSCategoryContainer* self) { -+ const gchar* result; -+ const gchar* _tmp0_ = NULL; -+ g_return_val_if_fail (self != NULL, NULL); -+ _tmp0_ = self->priv->_sql_count; -+ result = _tmp0_; -+ return result; -+} -+ -+ -+static void rygel_lms_category_container_set_sql_count (RygelLMSCategoryContainer* self, const gchar* value) { -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_if_fail (self != NULL); -+ _tmp0_ = value; -+ _tmp1_ = g_strdup (_tmp0_); -+ _g_free0 (self->priv->_sql_count); -+ self->priv->_sql_count = _tmp1_; -+ g_object_notify ((GObject *) self, "sql-count"); -+} -+ -+ -+const gchar* rygel_lms_category_container_get_sql_added (RygelLMSCategoryContainer* self) { -+ const gchar* result; -+ const gchar* _tmp0_ = NULL; -+ g_return_val_if_fail (self != NULL, NULL); -+ _tmp0_ = self->priv->_sql_added; -+ result = _tmp0_; -+ return result; -+} -+ -+ -+static void rygel_lms_category_container_set_sql_added (RygelLMSCategoryContainer* self, const gchar* value) { -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_if_fail (self != NULL); -+ _tmp0_ = value; -+ _tmp1_ = g_strdup (_tmp0_); -+ _g_free0 (self->priv->_sql_added); -+ self->priv->_sql_added = _tmp1_; -+ g_object_notify ((GObject *) self, "sql-added"); -+} -+ -+ -+const gchar* rygel_lms_category_container_get_sql_removed (RygelLMSCategoryContainer* self) { -+ const gchar* result; -+ const gchar* _tmp0_ = NULL; -+ g_return_val_if_fail (self != NULL, NULL); -+ _tmp0_ = self->priv->_sql_removed; -+ result = _tmp0_; -+ return result; -+} -+ -+ -+static void rygel_lms_category_container_set_sql_removed (RygelLMSCategoryContainer* self, const gchar* value) { -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_if_fail (self != NULL); -+ _tmp0_ = value; -+ _tmp1_ = g_strdup (_tmp0_); -+ _g_free0 (self->priv->_sql_removed); -+ self->priv->_sql_removed = _tmp1_; -+ g_object_notify ((GObject *) self, "sql-removed"); -+} -+ -+ -+static void _rygel_lms_category_container_on_db_updated_rygel_lms_database_db_updated (RygelLMSDatabase* _sender, guint64 old_update_id, guint64 new_update_id, gpointer self) { -+ rygel_lms_category_container_on_db_updated ((RygelLMSCategoryContainer*) self, old_update_id, new_update_id); -+} -+ -+ -+static GObject * rygel_lms_category_container_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) { -+ GObject * obj; -+ GObjectClass * parent_class; -+ RygelLMSCategoryContainer * self; -+ GeeArrayList* _tmp0_ = NULL; -+ GeeArrayList* _tmp1_ = NULL; -+ const gchar* _tmp2_ = NULL; -+ const gchar* _tmp3_ = NULL; -+ gchar* _tmp4_ = NULL; -+ gint index = 0; -+ const gchar* _tmp5_ = NULL; -+ const gchar* _tmp6_ = NULL; -+ gint _tmp7_ = 0; -+ const gchar* _tmp8_ = NULL; -+ const gchar* _tmp9_ = NULL; -+ gint _tmp10_ = 0; -+ gchar* _tmp11_ = NULL; -+ gchar* _tmp12_ = NULL; -+ gchar* _tmp13_ = NULL; -+ GError * _inner_error_ = NULL; -+ parent_class = G_OBJECT_CLASS (rygel_lms_category_container_parent_class); -+ obj = parent_class->constructor (type, n_construct_properties, construct_properties); -+ self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer); -+ _tmp0_ = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL, NULL, NULL); -+ _tmp1_ = _tmp0_; -+ rygel_searchable_container_set_search_classes ((RygelSearchableContainer*) self, _tmp1_); -+ _g_object_unref0 (_tmp1_); -+ _tmp2_ = rygel_media_object_get_id ((RygelMediaObject*) self); -+ _tmp3_ = _tmp2_; -+ _tmp4_ = g_strdup_printf ("%s:", _tmp3_); -+ _g_free0 (self->child_prefix); -+ self->child_prefix = _tmp4_; -+ _tmp5_ = rygel_media_object_get_id ((RygelMediaObject*) self); -+ _tmp6_ = _tmp5_; -+ _tmp7_ = string_index_of_char (_tmp6_, (gunichar) ':', 0); -+ index = _tmp7_; -+ _tmp8_ = rygel_media_object_get_id ((RygelMediaObject*) self); -+ _tmp9_ = _tmp8_; -+ _tmp10_ = index; -+ _tmp11_ = string_slice (_tmp9_, (glong) 0, (glong) _tmp10_); -+ _tmp12_ = _tmp11_; -+ _tmp13_ = g_strconcat (_tmp12_, ":all:", NULL); -+ _g_free0 (self->ref_prefix); -+ self->ref_prefix = _tmp13_; -+ _g_free0 (_tmp12_); -+ { -+ sqlite3_stmt* _tmp14_ = NULL; -+ RygelLMSDatabase* _tmp15_ = NULL; -+ const gchar* _tmp16_ = NULL; -+ sqlite3_stmt* _tmp17_ = NULL; -+ sqlite3_stmt* _tmp18_ = NULL; -+ sqlite3_stmt* _tmp19_ = NULL; -+ RygelLMSDatabase* _tmp20_ = NULL; -+ const gchar* _tmp21_ = NULL; -+ sqlite3_stmt* _tmp22_ = NULL; -+ sqlite3_stmt* _tmp23_ = NULL; -+ sqlite3_stmt* stmt_count = NULL; -+ RygelLMSDatabase* _tmp24_ = NULL; -+ const gchar* _tmp25_ = NULL; -+ sqlite3_stmt* _tmp26_ = NULL; -+ sqlite3_stmt* _tmp27_ = NULL; -+ gint _tmp28_ = 0; -+ gboolean _tmp31_ = FALSE; -+ const gchar* _tmp32_ = NULL; -+ _tmp15_ = self->priv->_lms_db; -+ _tmp16_ = self->priv->_sql_all; -+ _tmp17_ = rygel_lms_database_prepare (_tmp15_, _tmp16_, &_inner_error_); -+ _tmp14_ = _tmp17_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch7_rygel_lms_database_error; -+ } -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ } -+ _tmp18_ = _tmp14_; -+ _tmp14_ = NULL; -+ _sqlite3_finalize0 (self->stmt_all); -+ self->stmt_all = _tmp18_; -+ _tmp20_ = self->priv->_lms_db; -+ _tmp21_ = self->priv->_sql_find_object; -+ _tmp22_ = rygel_lms_database_prepare (_tmp20_, _tmp21_, &_inner_error_); -+ _tmp19_ = _tmp22_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _sqlite3_finalize0 (_tmp14_); -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch7_rygel_lms_database_error; -+ } -+ _sqlite3_finalize0 (_tmp14_); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ } -+ _tmp23_ = _tmp19_; -+ _tmp19_ = NULL; -+ _sqlite3_finalize0 (self->stmt_find_object); -+ self->stmt_find_object = _tmp23_; -+ _tmp24_ = self->priv->_lms_db; -+ _tmp25_ = self->priv->_sql_count; -+ _tmp26_ = rygel_lms_database_prepare (_tmp24_, _tmp25_, &_inner_error_); -+ stmt_count = _tmp26_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _sqlite3_finalize0 (_tmp19_); -+ _sqlite3_finalize0 (_tmp14_); -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch7_rygel_lms_database_error; -+ } -+ _sqlite3_finalize0 (_tmp19_); -+ _sqlite3_finalize0 (_tmp14_); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ } -+ _tmp27_ = stmt_count; -+ _tmp28_ = sqlite3_step (_tmp27_); -+ if (_tmp28_ == SQLITE_ROW) { -+ sqlite3_stmt* _tmp29_ = NULL; -+ gint _tmp30_ = 0; -+ _tmp29_ = stmt_count; -+ _tmp30_ = sqlite3_column_int (_tmp29_, 0); -+ rygel_media_container_set_child_count ((RygelMediaContainer*) self, _tmp30_); -+ } -+ _tmp32_ = self->priv->_sql_added; -+ if (_tmp32_ != NULL) { -+ const gchar* _tmp33_ = NULL; -+ _tmp33_ = self->priv->_sql_removed; -+ _tmp31_ = _tmp33_ != NULL; -+ } else { -+ _tmp31_ = FALSE; -+ } -+ if (_tmp31_) { -+ sqlite3_stmt* _tmp34_ = NULL; -+ RygelLMSDatabase* _tmp35_ = NULL; -+ const gchar* _tmp36_ = NULL; -+ sqlite3_stmt* _tmp37_ = NULL; -+ sqlite3_stmt* _tmp38_ = NULL; -+ sqlite3_stmt* _tmp39_ = NULL; -+ RygelLMSDatabase* _tmp40_ = NULL; -+ const gchar* _tmp41_ = NULL; -+ sqlite3_stmt* _tmp42_ = NULL; -+ sqlite3_stmt* _tmp43_ = NULL; -+ RygelLMSDatabase* _tmp44_ = NULL; -+ _tmp35_ = self->priv->_lms_db; -+ _tmp36_ = self->priv->_sql_added; -+ _tmp37_ = rygel_lms_database_prepare (_tmp35_, _tmp36_, &_inner_error_); -+ _tmp34_ = _tmp37_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _sqlite3_finalize0 (stmt_count); -+ _sqlite3_finalize0 (_tmp19_); -+ _sqlite3_finalize0 (_tmp14_); -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch7_rygel_lms_database_error; -+ } -+ _sqlite3_finalize0 (stmt_count); -+ _sqlite3_finalize0 (_tmp19_); -+ _sqlite3_finalize0 (_tmp14_); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ } -+ _tmp38_ = _tmp34_; -+ _tmp34_ = NULL; -+ _sqlite3_finalize0 (self->stmt_added); -+ self->stmt_added = _tmp38_; -+ _tmp40_ = self->priv->_lms_db; -+ _tmp41_ = self->priv->_sql_removed; -+ _tmp42_ = rygel_lms_database_prepare (_tmp40_, _tmp41_, &_inner_error_); -+ _tmp39_ = _tmp42_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _sqlite3_finalize0 (_tmp34_); -+ _sqlite3_finalize0 (stmt_count); -+ _sqlite3_finalize0 (_tmp19_); -+ _sqlite3_finalize0 (_tmp14_); -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch7_rygel_lms_database_error; -+ } -+ _sqlite3_finalize0 (_tmp34_); -+ _sqlite3_finalize0 (stmt_count); -+ _sqlite3_finalize0 (_tmp19_); -+ _sqlite3_finalize0 (_tmp14_); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ } -+ _tmp43_ = _tmp39_; -+ _tmp39_ = NULL; -+ _sqlite3_finalize0 (self->stmt_removed); -+ self->stmt_removed = _tmp43_; -+ _tmp44_ = self->priv->_lms_db; -+ g_signal_connect_object (_tmp44_, "db-updated", (GCallback) _rygel_lms_category_container_on_db_updated_rygel_lms_database_db_updated, self, 0); -+ _sqlite3_finalize0 (_tmp39_); -+ _sqlite3_finalize0 (_tmp34_); -+ } -+ _sqlite3_finalize0 (stmt_count); -+ _sqlite3_finalize0 (_tmp19_); -+ _sqlite3_finalize0 (_tmp14_); -+ } -+ goto __finally7; -+ __catch7_rygel_lms_database_error: -+ { -+ GError* e = NULL; -+ const gchar* _tmp45_ = NULL; -+ const gchar* _tmp46_ = NULL; -+ GError* _tmp47_ = NULL; -+ const gchar* _tmp48_ = NULL; -+ e = _inner_error_; -+ _inner_error_ = NULL; -+ _tmp45_ = rygel_media_object_get_title ((RygelMediaObject*) self); -+ _tmp46_ = _tmp45_; -+ _tmp47_ = e; -+ _tmp48_ = _tmp47_->message; -+ g_warning ("rygel-lms-category-container.vala:424: Container %s: %s", _tmp46_, _tmp48_); -+ _g_error_free0 (e); -+ } -+ __finally7: -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ } -+ return obj; -+} -+ -+ -+static void rygel_lms_category_container_class_init (RygelLMSCategoryContainerClass * klass) { -+ rygel_lms_category_container_parent_class = g_type_class_peek_parent (klass); -+ g_type_class_add_private (klass, sizeof (RygelLMSCategoryContainerPrivate)); -+ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_category_container_real_object_from_statement; -+ ((RygelLMSCategoryContainerClass *) klass)->get_sql_all_with_filter = rygel_lms_category_container_real_get_sql_all_with_filter; -+ ((RygelLMSCategoryContainerClass *) klass)->get_sql_count_with_filter = rygel_lms_category_container_real_get_sql_count_with_filter; -+ ((RygelLMSCategoryContainerClass *) klass)->get_child_count_with_filter = rygel_lms_category_container_real_get_child_count_with_filter; -+ ((RygelLMSCategoryContainerClass *) klass)->get_children_with_filter = rygel_lms_category_container_real_get_children_with_filter; -+ ((RygelMediaContainerClass *) klass)->get_children = rygel_lms_category_container_real_get_children; -+ ((RygelMediaContainerClass *) klass)->get_children_finish = rygel_lms_category_container_real_get_children_finish; -+ ((RygelMediaContainerClass *) klass)->find_object = rygel_lms_category_container_real_find_object; -+ ((RygelMediaContainerClass *) klass)->find_object_finish = rygel_lms_category_container_real_find_object_finish; -+ G_OBJECT_CLASS (klass)->get_property = _vala_rygel_lms_category_container_get_property; -+ G_OBJECT_CLASS (klass)->set_property = _vala_rygel_lms_category_container_set_property; -+ G_OBJECT_CLASS (klass)->constructor = rygel_lms_category_container_constructor; -+ G_OBJECT_CLASS (klass)->finalize = rygel_lms_category_container_finalize; -+ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SEARCH_CLASSES, g_param_spec_object ("search-classes", "search-classes", "search-classes", GEE_TYPE_ARRAY_LIST, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE)); -+ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_LMS_DB, rygel_lms_param_spec_database ("lms-db", "lms-db", "lms-db", RYGEL_LMS_TYPE_DATABASE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); -+ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_DB_ID, g_param_spec_string ("db-id", "db-id", "db-id", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); -+ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_ALL, g_param_spec_string ("sql-all", "sql-all", "sql-all", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); -+ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_FIND_OBJECT, g_param_spec_string ("sql-find-object", "sql-find-object", "sql-find-object", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); -+ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_COUNT, g_param_spec_string ("sql-count", "sql-count", "sql-count", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); -+ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_ADDED, g_param_spec_string ("sql-added", "sql-added", "sql-added", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); -+ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_REMOVED, g_param_spec_string ("sql-removed", "sql-removed", "sql-removed", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); -+} -+ -+ -+static void rygel_lms_category_container_rygel_trackable_container_interface_init (RygelTrackableContainerIface * iface) { -+ rygel_lms_category_container_rygel_trackable_container_parent_iface = g_type_interface_peek_parent (iface); -+ iface->add_child = (void (*)(RygelTrackableContainer*, RygelMediaObject*)) rygel_lms_category_container_real_add_child; -+ iface->add_child_finish = rygel_lms_category_container_real_add_child_finish; -+ iface->remove_child = (void (*)(RygelTrackableContainer*, RygelMediaObject*)) rygel_lms_category_container_real_remove_child; -+ iface->remove_child_finish = rygel_lms_category_container_real_remove_child_finish; -+} -+ -+ -+static void rygel_lms_category_container_rygel_searchable_container_interface_init (RygelSearchableContainerIface * iface) { -+ rygel_lms_category_container_rygel_searchable_container_parent_iface = g_type_interface_peek_parent (iface); -+ iface->search = (RygelMediaObjects* (*)(RygelSearchableContainer*, RygelSearchExpression*, guint, guint, guint*, const gchar*, GCancellable*, GError**)) rygel_lms_category_container_real_search; -+ iface->search_finish = rygel_lms_category_container_real_search_finish; -+ iface->get_search_classes = rygel_lms_category_container_real_get_search_classes; -+ iface->set_search_classes = rygel_lms_category_container_real_set_search_classes; -+} -+ -+ -+static void rygel_lms_category_container_instance_init (RygelLMSCategoryContainer * self) { -+ self->priv = RYGEL_LMS_CATEGORY_CONTAINER_GET_PRIVATE (self); -+} -+ -+ -+static void rygel_lms_category_container_finalize (GObject* obj) { -+ RygelLMSCategoryContainer * self; -+ self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer); -+ _g_object_unref0 (self->priv->_search_classes); -+ _g_free0 (self->priv->_db_id); -+ _g_free0 (self->priv->_sql_all); -+ _g_free0 (self->priv->_sql_find_object); -+ _g_free0 (self->priv->_sql_count); -+ _g_free0 (self->priv->_sql_added); -+ _g_free0 (self->priv->_sql_removed); -+ _sqlite3_finalize0 (self->stmt_all); -+ _sqlite3_finalize0 (self->stmt_find_object); -+ _sqlite3_finalize0 (self->stmt_added); -+ _sqlite3_finalize0 (self->stmt_removed); -+ _g_free0 (self->child_prefix); -+ _g_free0 (self->ref_prefix); -+ G_OBJECT_CLASS (rygel_lms_category_container_parent_class)->finalize (obj); -+} -+ -+ -+GType rygel_lms_category_container_get_type (void) { -+ static volatile gsize rygel_lms_category_container_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_category_container_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSCategoryContainerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_category_container_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSCategoryContainer), 0, (GInstanceInitFunc) rygel_lms_category_container_instance_init, NULL }; -+ static const GInterfaceInfo rygel_trackable_container_info = { (GInterfaceInitFunc) rygel_lms_category_container_rygel_trackable_container_interface_init, (GInterfaceFinalizeFunc) NULL, NULL}; -+ static const GInterfaceInfo rygel_searchable_container_info = { (GInterfaceInitFunc) rygel_lms_category_container_rygel_searchable_container_interface_init, (GInterfaceFinalizeFunc) NULL, NULL}; -+ GType rygel_lms_category_container_type_id; -+ rygel_lms_category_container_type_id = g_type_register_static (RYGEL_TYPE_MEDIA_CONTAINER, "RygelLMSCategoryContainer", &g_define_type_info, G_TYPE_FLAG_ABSTRACT); -+ g_type_add_interface_static (rygel_lms_category_container_type_id, RYGEL_TYPE_TRACKABLE_CONTAINER, &rygel_trackable_container_info); -+ g_type_add_interface_static (rygel_lms_category_container_type_id, RYGEL_TYPE_SEARCHABLE_CONTAINER, &rygel_searchable_container_info); -+ g_once_init_leave (&rygel_lms_category_container_type_id__volatile, rygel_lms_category_container_type_id); -+ } -+ return rygel_lms_category_container_type_id__volatile; -+} -+ -+ -+static void _vala_rygel_lms_category_container_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { -+ RygelLMSCategoryContainer * self; -+ self = G_TYPE_CHECK_INSTANCE_CAST (object, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer); -+ switch (property_id) { -+ case RYGEL_LMS_CATEGORY_CONTAINER_SEARCH_CLASSES: -+ g_value_set_object (value, rygel_searchable_container_get_search_classes ((RygelSearchableContainer*) self)); -+ break; -+ case RYGEL_LMS_CATEGORY_CONTAINER_LMS_DB: -+ rygel_lms_value_set_database (value, rygel_lms_category_container_get_lms_db (self)); -+ break; -+ case RYGEL_LMS_CATEGORY_CONTAINER_DB_ID: -+ g_value_set_string (value, rygel_lms_category_container_get_db_id (self)); -+ break; -+ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_ALL: -+ g_value_set_string (value, rygel_lms_category_container_get_sql_all (self)); -+ break; -+ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_FIND_OBJECT: -+ g_value_set_string (value, rygel_lms_category_container_get_sql_find_object (self)); -+ break; -+ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_COUNT: -+ g_value_set_string (value, rygel_lms_category_container_get_sql_count (self)); -+ break; -+ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_ADDED: -+ g_value_set_string (value, rygel_lms_category_container_get_sql_added (self)); -+ break; -+ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_REMOVED: -+ g_value_set_string (value, rygel_lms_category_container_get_sql_removed (self)); -+ break; -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -+ break; -+ } -+} -+ -+ -+static void _vala_rygel_lms_category_container_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) { -+ RygelLMSCategoryContainer * self; -+ self = G_TYPE_CHECK_INSTANCE_CAST (object, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer); -+ switch (property_id) { -+ case RYGEL_LMS_CATEGORY_CONTAINER_SEARCH_CLASSES: -+ rygel_searchable_container_set_search_classes ((RygelSearchableContainer*) self, g_value_get_object (value)); -+ break; -+ case RYGEL_LMS_CATEGORY_CONTAINER_LMS_DB: -+ rygel_lms_category_container_set_lms_db (self, rygel_lms_value_get_database (value)); -+ break; -+ case RYGEL_LMS_CATEGORY_CONTAINER_DB_ID: -+ rygel_lms_category_container_set_db_id (self, g_value_get_string (value)); -+ break; -+ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_ALL: -+ rygel_lms_category_container_set_sql_all (self, g_value_get_string (value)); -+ break; -+ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_FIND_OBJECT: -+ rygel_lms_category_container_set_sql_find_object (self, g_value_get_string (value)); -+ break; -+ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_COUNT: -+ rygel_lms_category_container_set_sql_count (self, g_value_get_string (value)); -+ break; -+ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_ADDED: -+ rygel_lms_category_container_set_sql_added (self, g_value_get_string (value)); -+ break; -+ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_REMOVED: -+ rygel_lms_category_container_set_sql_removed (self, g_value_get_string (value)); -+ break; -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -+ break; -+ } -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-database.c b/src/plugins/lms/rygel-lms-database.c -new file mode 100644 -index 0000000..687ef64 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-database.c -@@ -0,0 +1,1349 @@ -+/* rygel-lms-database.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-database.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2009,2011 Jens Georg <mail@jensge.org>, -+ * (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <sqlite3.h> -+#include <gio/gio.h> -+#include <stdlib.h> -+#include <string.h> -+#include <glib/gi18n-lib.h> -+#include <gobject/gvaluecollector.h> -+ -+ -+#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) -+#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) -+#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+ -+typedef struct _RygelLMSDatabase RygelLMSDatabase; -+typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; -+typedef struct _RygelLMSDatabasePrivate RygelLMSDatabasePrivate; -+ -+#define RYGEL_LMS_TYPE_DBUS (rygel_lms_dbus_get_type ()) -+#define RYGEL_LMS_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DBUS, RygelLMSDBus)) -+#define RYGEL_LMS_IS_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DBUS)) -+#define RYGEL_LMS_DBUS_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), RYGEL_LMS_TYPE_DBUS, RygelLMSDBusIface)) -+ -+typedef struct _RygelLMSDBus RygelLMSDBus; -+typedef struct _RygelLMSDBusIface RygelLMSDBusIface; -+ -+#define RYGEL_LMS_TYPE_DBUS_PROXY (rygel_lms_dbus_proxy_get_type ()) -+#define _sqlite3_close0(var) ((var == NULL) ? NULL : (var = (sqlite3_close (var), NULL))) -+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) -+#define _g_free0(var) (var = (g_free (var), NULL)) -+#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) -+#define _rygel_lms_database_unref0(var) ((var == NULL) ? NULL : (var = (rygel_lms_database_unref (var), NULL))) -+#define _g_variant_unref0(var) ((var == NULL) ? NULL : (var = (g_variant_unref (var), NULL))) -+#define _g_variant_iter_free0(var) ((var == NULL) ? NULL : (var = (g_variant_iter_free (var), NULL))) -+#define _sqlite3_finalize0(var) ((var == NULL) ? NULL : (var = (sqlite3_finalize (var), NULL))) -+typedef struct _RygelLMSParamSpecDatabase RygelLMSParamSpecDatabase; -+#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); -+#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; } -+#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; } -+#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); -+ -+typedef enum { -+ RYGEL_LMS_DATABASE_ERROR_OPEN, -+ RYGEL_LMS_DATABASE_ERROR_PREPARE, -+ RYGEL_LMS_DATABASE_ERROR_BIND, -+ RYGEL_LMS_DATABASE_ERROR_STEP, -+ RYGEL_LMS_DATABASE_ERROR_NOT_FOUND -+} RygelLMSDatabaseError; -+#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark () -+struct _RygelLMSDatabase { -+ GTypeInstance parent_instance; -+ volatile int ref_count; -+ RygelLMSDatabasePrivate * priv; -+}; -+ -+struct _RygelLMSDatabaseClass { -+ GTypeClass parent_class; -+ void (*finalize) (RygelLMSDatabase *self); -+}; -+ -+struct _RygelLMSDBusIface { -+ GTypeInterface parent_iface; -+ gchar* (*get_data_base_path) (RygelLMSDBus* self); -+ guint64 (*get_update_id) (RygelLMSDBus* self); -+}; -+ -+struct _RygelLMSDatabasePrivate { -+ sqlite3* db; -+ RygelLMSDBus* lms_proxy; -+ guint64 update_id; -+}; -+ -+struct _RygelLMSParamSpecDatabase { -+ GParamSpec parent_instance; -+}; -+ -+ -+static gpointer rygel_lms_database_parent_class = NULL; -+ -+GQuark rygel_lms_database_error_quark (void); -+gint rygel_lms_utf8_collate_str (guint8* a, int a_length1, guint8* b, int b_length1); -+gpointer rygel_lms_database_ref (gpointer instance); -+void rygel_lms_database_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_database (GValue* value, gpointer v_object); -+void rygel_lms_value_take_database (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_database (const GValue* value); -+GType rygel_lms_database_get_type (void) G_GNUC_CONST; -+GType rygel_lms_dbus_get_type (void) G_GNUC_CONST; -+GType rygel_lms_dbus_proxy_get_type (void) G_GNUC_CONST; -+guint rygel_lms_dbus_register_object (void* object, GDBusConnection* connection, const gchar* path, GError** error); -+#define RYGEL_LMS_DATABASE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabasePrivate)) -+enum { -+ RYGEL_LMS_DATABASE_DUMMY_PROPERTY -+}; -+static void rygel_lms_database_utf8_contains (sqlite3_context* context, sqlite3_value** args, int args_length1); -+static gint rygel_lms_database_utf8_collate (gint alen, void* a, gint blen, void* b); -+RygelLMSDatabase* rygel_lms_database_new (GError** error); -+RygelLMSDatabase* rygel_lms_database_construct (GType object_type, GError** error); -+gchar* rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self); -+guint64 rygel_lms_dbus_get_update_id (RygelLMSDBus* self); -+static void rygel_lms_database_on_lms_properties_changed (RygelLMSDatabase* self, GDBusProxy* lms_proxy, GVariant* changed, gchar** invalidated, int invalidated_length1); -+static void _rygel_lms_database_on_lms_properties_changed_g_dbus_proxy_g_properties_changed (GDBusProxy* _sender, GVariant* changed_properties, gchar** invalidated_properties, gpointer self); -+static void _rygel_lms_database_utf8_contains_sqlite_user_func_callback (sqlite3_context* context, int values_length1, sqlite3_value** values); -+static gint _rygel_lms_database_utf8_collate_sqlite_compare_callback (gpointer self, gint alen, void* a, gint blen, void* b); -+static gchar* _variant_get1 (GVariant* value); -+static guint64 _variant_get2 (GVariant* value); -+static guint64 _variant_get3 (GVariant* value); -+sqlite3_stmt* rygel_lms_database_prepare (RygelLMSDatabase* self, const gchar* query_string, GError** error); -+sqlite3_stmt* rygel_lms_database_prepare_and_init (RygelLMSDatabase* self, const gchar* query, GValue* arguments, int arguments_length1, GError** error); -+void rygel_lms_database_find_object (const gchar* id, sqlite3_stmt* stmt, GError** error); -+void rygel_lms_database_get_children_init (sqlite3_stmt* stmt, guint offset, guint max_count, const gchar* sort_criteria, GError** error); -+void rygel_lms_database_get_children_with_update_id_init (sqlite3_stmt* stmt, guint64 old_id, guint64 new_id, GError** error); -+gboolean rygel_lms_database_get_children_step (sqlite3_stmt* stmt, GError** error); -+static void g_cclosure_user_marshal_VOID__UINT64_UINT64 (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data); -+static void rygel_lms_database_finalize (RygelLMSDatabase* obj); -+static gint _vala_array_length (gpointer array); -+ -+ -+GQuark rygel_lms_database_error_quark (void) { -+ return g_quark_from_static_string ("rygel_lms_database_error-quark"); -+} -+ -+ -+/** -+ * Function to implement the custom SQL function 'contains' -+ */ -+static void rygel_lms_database_utf8_contains (sqlite3_context* context, sqlite3_value** args, int args_length1) { -+ sqlite3_value** _tmp0_ = NULL; -+ gint _tmp0__length1 = 0; -+ gboolean _tmp1_ = FALSE; -+ sqlite3_value** _tmp2_ = NULL; -+ gint _tmp2__length1 = 0; -+ sqlite3_value* _tmp3_ = NULL; -+ const gchar* _tmp4_ = NULL; -+ gchar* pattern = NULL; -+ sqlite3_value** _tmp9_ = NULL; -+ gint _tmp9__length1 = 0; -+ sqlite3_value* _tmp10_ = NULL; -+ const gchar* _tmp11_ = NULL; -+ gchar* _tmp12_ = NULL; -+ const gchar* _tmp13_ = NULL; -+ sqlite3_value** _tmp14_ = NULL; -+ gint _tmp14__length1 = 0; -+ sqlite3_value* _tmp15_ = NULL; -+ const gchar* _tmp16_ = NULL; -+ gboolean _tmp17_ = FALSE; -+ g_return_if_fail (context != NULL); -+ _tmp0_ = args; -+ _tmp0__length1 = args_length1; -+ _vala_return_if_fail (_tmp0__length1 == 2, "args.length == 2"); -+ _tmp2_ = args; -+ _tmp2__length1 = args_length1; -+ _tmp3_ = _tmp2_[0]; -+ _tmp4_ = sqlite3_value_text (_tmp3_); -+ if (_tmp4_ == NULL) { -+ _tmp1_ = TRUE; -+ } else { -+ sqlite3_value** _tmp5_ = NULL; -+ gint _tmp5__length1 = 0; -+ sqlite3_value* _tmp6_ = NULL; -+ const gchar* _tmp7_ = NULL; -+ _tmp5_ = args; -+ _tmp5__length1 = args_length1; -+ _tmp6_ = _tmp5_[1]; -+ _tmp7_ = sqlite3_value_text (_tmp6_); -+ _tmp1_ = _tmp7_ == NULL; -+ } -+ if (_tmp1_) { -+ sqlite3_context* _tmp8_ = NULL; -+ _tmp8_ = context; -+ sqlite3_result_int (_tmp8_, 0); -+ return; -+ } -+ _tmp9_ = args; -+ _tmp9__length1 = args_length1; -+ _tmp10_ = _tmp9_[1]; -+ _tmp11_ = sqlite3_value_text (_tmp10_); -+ _tmp12_ = g_regex_escape_string (_tmp11_, -1); -+ pattern = _tmp12_; -+ _tmp13_ = pattern; -+ _tmp14_ = args; -+ _tmp14__length1 = args_length1; -+ _tmp15_ = _tmp14_[0]; -+ _tmp16_ = sqlite3_value_text (_tmp15_); -+ _tmp17_ = g_regex_match_simple (_tmp13_, _tmp16_, G_REGEX_CASELESS, 0); -+ if (_tmp17_) { -+ sqlite3_context* _tmp18_ = NULL; -+ _tmp18_ = context; -+ sqlite3_result_int (_tmp18_, 1); -+ } else { -+ sqlite3_context* _tmp19_ = NULL; -+ _tmp19_ = context; -+ sqlite3_result_int (_tmp19_, 0); -+ } -+ _g_free0 (pattern); -+} -+ -+ -+/** -+ * Function to implement the custom SQLite collation 'CASEFOLD'. -+ * -+ * Uses utf8 case-fold to compare the strings. -+ */ -+static gint rygel_lms_database_utf8_collate (gint alen, void* a, gint blen, void* b) { -+ gint result = 0; -+ guint8* _a = NULL; -+ void* _tmp0_ = NULL; -+ gint _a_length1 = 0; -+ gint __a_size_ = 0; -+ gint _tmp1_ = 0; -+ gint _tmp2_ = 0; -+ guint8* _b = NULL; -+ void* _tmp3_ = NULL; -+ gint _b_length1 = 0; -+ gint __b_size_ = 0; -+ gint _tmp4_ = 0; -+ gint _tmp5_ = 0; -+ gint _tmp6_ = 0; -+ _tmp0_ = a; -+ _a = (guint8*) _tmp0_; -+ _a_length1 = -1; -+ __a_size_ = _a_length1; -+ _tmp1_ = alen; -+ _a_length1 = _tmp1_; -+ _tmp2_ = _a_length1; -+ _tmp3_ = b; -+ _b = (guint8*) _tmp3_; -+ _b_length1 = -1; -+ __b_size_ = _b_length1; -+ _tmp4_ = blen; -+ _b_length1 = _tmp4_; -+ _tmp5_ = _b_length1; -+ _tmp6_ = rygel_lms_utf8_collate_str (_a, _a_length1, _b, _b_length1); -+ result = _tmp6_; -+ return result; -+} -+ -+ -+static void _rygel_lms_database_on_lms_properties_changed_g_dbus_proxy_g_properties_changed (GDBusProxy* _sender, GVariant* changed_properties, gchar** invalidated_properties, gpointer self) { -+ rygel_lms_database_on_lms_properties_changed ((RygelLMSDatabase*) self, _sender, changed_properties, invalidated_properties, _vala_array_length (invalidated_properties)); -+} -+ -+ -+static void _rygel_lms_database_utf8_contains_sqlite_user_func_callback (sqlite3_context* context, int values_length1, sqlite3_value** values) { -+ rygel_lms_database_utf8_contains (context, values, values_length1); -+} -+ -+ -+static gint _rygel_lms_database_utf8_collate_sqlite_compare_callback (gpointer self, gint alen, void* a, gint blen, void* b) { -+ gint result; -+ result = rygel_lms_database_utf8_collate (alen, a, blen, b); -+ return result; -+} -+ -+ -+RygelLMSDatabase* rygel_lms_database_construct (GType object_type, GError** error) { -+ RygelLMSDatabase* self = NULL; -+ gchar* db_path = NULL; -+ const gchar* _tmp17_ = NULL; -+ sqlite3* _tmp18_ = NULL; -+ sqlite3* _tmp19_ = NULL; -+ gint _tmp20_ = 0; -+ sqlite3* _tmp25_ = NULL; -+ sqlite3* _tmp26_ = NULL; -+ GError * _inner_error_ = NULL; -+ self = (RygelLMSDatabase*) g_type_create_instance (object_type); -+ { -+ RygelLMSDBus* _tmp0_ = NULL; -+ RygelLMSDBus* _tmp1_ = NULL; -+ RygelLMSDBus* _tmp2_ = NULL; -+ RygelLMSDBus* _tmp3_ = NULL; -+ gchar* _tmp4_ = NULL; -+ gchar* _tmp5_ = NULL; -+ const gchar* _tmp6_ = NULL; -+ RygelLMSDBus* _tmp7_ = NULL; -+ guint64 _tmp8_ = 0ULL; -+ guint64 _tmp9_ = 0ULL; -+ guint64 _tmp10_ = 0ULL; -+ RygelLMSDBus* _tmp11_ = NULL; -+ _tmp1_ = g_initable_new (RYGEL_LMS_TYPE_DBUS_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.lightmediascanner", "g-bus-type", G_BUS_TYPE_SESSION, "g-object-path", "/org/lightmediascanner/Scanner1", "g-interface-name", "org.lightmediascanner.Scanner1", "g-interface-info", g_type_get_qdata (RYGEL_LMS_TYPE_DBUS, g_quark_from_static_string ("vala-dbus-interface-info")), NULL); -+ _tmp0_ = (RygelLMSDBus*) _tmp1_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ if (_inner_error_->domain == G_IO_ERROR) { -+ goto __catch11_g_io_error; -+ } -+ _g_free0 (db_path); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ _tmp2_ = _tmp0_; -+ _tmp0_ = NULL; -+ _g_object_unref0 (self->priv->lms_proxy); -+ self->priv->lms_proxy = _tmp2_; -+ _tmp3_ = self->priv->lms_proxy; -+ _tmp4_ = rygel_lms_dbus_get_data_base_path (_tmp3_); -+ _tmp5_ = _tmp4_; -+ _g_free0 (db_path); -+ db_path = _tmp5_; -+ _tmp6_ = db_path; -+ g_debug ("rygel-lms-database.vala:94: Got db path %s from LMS over dbus", _tmp6_); -+ _tmp7_ = self->priv->lms_proxy; -+ _tmp8_ = rygel_lms_dbus_get_update_id (_tmp7_); -+ _tmp9_ = _tmp8_; -+ self->priv->update_id = _tmp9_; -+ _tmp10_ = self->priv->update_id; -+ g_debug ("rygel-lms-database.vala:96: Got updated id %lld from LMS over dbus", _tmp10_); -+ _tmp11_ = self->priv->lms_proxy; -+ g_signal_connect ((GDBusProxy*) _tmp11_, "g-properties-changed", (GCallback) _rygel_lms_database_on_lms_properties_changed_g_dbus_proxy_g_properties_changed, self); -+ _g_object_unref0 (_tmp0_); -+ } -+ goto __finally11; -+ __catch11_g_io_error: -+ { -+ GError* e = NULL; -+ GError* _tmp12_ = NULL; -+ const gchar* _tmp13_ = NULL; -+ const gchar* _tmp14_ = NULL; -+ gchar* _tmp15_ = NULL; -+ const gchar* _tmp16_ = NULL; -+ e = _inner_error_; -+ _inner_error_ = NULL; -+ _tmp12_ = e; -+ _tmp13_ = _tmp12_->message; -+ g_warning ("rygel-lms-database.vala:100: Couldn't get LMS Dbus proxy: %s", _tmp13_); -+ _tmp14_ = g_get_user_config_dir (); -+ _tmp15_ = g_strconcat (_tmp14_, "/lightmediascannerd/db.sqlite3", NULL); -+ _g_free0 (db_path); -+ db_path = _tmp15_; -+ _tmp16_ = db_path; -+ g_debug ("rygel-lms-database.vala:103: Using default sqlite database location %s", _tmp16_); -+ _g_error_free0 (e); -+ } -+ __finally11: -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ _g_free0 (db_path); -+ _rygel_lms_database_unref0 (self); -+ return NULL; -+ } else { -+ _g_free0 (db_path); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ } -+ _tmp17_ = db_path; -+ sqlite3_open (_tmp17_, &_tmp18_); -+ _sqlite3_close0 (self->priv->db); -+ self->priv->db = _tmp18_; -+ _tmp19_ = self->priv->db; -+ _tmp20_ = sqlite3_errcode (_tmp19_); -+ if (_tmp20_ != SQLITE_OK) { -+ const gchar* _tmp21_ = NULL; -+ sqlite3* _tmp22_ = NULL; -+ gint _tmp23_ = 0; -+ GError* _tmp24_ = NULL; -+ _tmp21_ = db_path; -+ _tmp22_ = self->priv->db; -+ _tmp23_ = sqlite3_errcode (_tmp22_); -+ _tmp24_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_OPEN, "Failed to open '%s': %d", _tmp21_, _tmp23_); -+ _inner_error_ = _tmp24_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ _g_free0 (db_path); -+ _rygel_lms_database_unref0 (self); -+ return NULL; -+ } else { -+ _g_free0 (db_path); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ } -+ _tmp25_ = self->priv->db; -+ sqlite3_create_function (_tmp25_, "contains", 2, SQLITE_UTF8, NULL, _rygel_lms_database_utf8_contains_sqlite_user_func_callback, NULL, NULL); -+ _tmp26_ = self->priv->db; -+ sqlite3_create_collation (_tmp26_, "CASEFOLD", SQLITE_UTF8, NULL, (int (*)(void *, int, const void *, int, const void *)) _rygel_lms_database_utf8_collate_sqlite_compare_callback); -+ _g_free0 (db_path); -+ return self; -+} -+ -+ -+RygelLMSDatabase* rygel_lms_database_new (GError** error) { -+ return rygel_lms_database_construct (RYGEL_LMS_TYPE_DATABASE, error); -+} -+ -+ -+static gchar* _variant_get1 (GVariant* value) { -+ return g_variant_dup_string (value, NULL); -+} -+ -+ -+static guint64 _variant_get2 (GVariant* value) { -+ return g_variant_get_uint64 (value); -+} -+ -+ -+static guint64 _variant_get3 (GVariant* value) { -+ return g_variant_get_uint64 (value); -+} -+ -+ -+static void rygel_lms_database_on_lms_properties_changed (RygelLMSDatabase* self, GDBusProxy* lms_proxy, GVariant* changed, gchar** invalidated, int invalidated_length1) { -+ GVariant* _tmp0_ = NULL; -+ const GVariantType* _tmp1_ = NULL; -+ const GVariantType* _tmp2_ = NULL; -+ gboolean _tmp3_ = FALSE; -+ g_return_if_fail (self != NULL); -+ g_return_if_fail (lms_proxy != NULL); -+ g_return_if_fail (changed != NULL); -+ _tmp0_ = changed; -+ _tmp1_ = g_variant_get_type (_tmp0_); -+ _tmp2_ = G_VARIANT_TYPE_VARDICT; -+ _tmp3_ = g_variant_type_equal (_tmp1_, _tmp2_); -+ if (!_tmp3_) { -+ return; -+ } -+ { -+ GVariantIter* _changed_prop_it = NULL; -+ GVariant* _tmp4_ = NULL; -+ GVariantIter* _tmp5_ = NULL; -+ GVariant* changed_prop = NULL; -+ _tmp4_ = changed; -+ _tmp5_ = g_variant_iter_new (_tmp4_); -+ _changed_prop_it = _tmp5_; -+ while (TRUE) { -+ GVariantIter* _tmp6_ = NULL; -+ GVariant* _tmp7_ = NULL; -+ GVariant* _tmp8_ = NULL; -+ gchar* key = NULL; -+ GVariant* _tmp9_ = NULL; -+ GVariant* _tmp10_ = NULL; -+ GVariant* _tmp11_ = NULL; -+ gchar* _tmp12_ = NULL; -+ gchar* _tmp13_ = NULL; -+ GVariant* value = NULL; -+ GVariant* _tmp14_ = NULL; -+ GVariant* _tmp15_ = NULL; -+ GVariant* _tmp16_ = NULL; -+ GVariant* _tmp17_ = NULL; -+ GVariant* _tmp18_ = NULL; -+ const gchar* _tmp19_ = NULL; -+ GVariant* _tmp20_ = NULL; -+ gchar* _tmp21_ = NULL; -+ gchar* _tmp22_ = NULL; -+ const gchar* _tmp23_ = NULL; -+ const gchar* _tmp24_ = NULL; -+ GQuark _tmp26_ = 0U; -+ static GQuark _tmp25_label0 = 0; -+ _tmp6_ = _changed_prop_it; -+ _tmp7_ = g_variant_iter_next_value (_tmp6_); -+ _g_variant_unref0 (changed_prop); -+ changed_prop = _tmp7_; -+ _tmp8_ = changed_prop; -+ if (!(_tmp8_ != NULL)) { -+ break; -+ } -+ _tmp9_ = changed_prop; -+ _tmp10_ = g_variant_get_child_value (_tmp9_, (gsize) 0); -+ _tmp11_ = _tmp10_; -+ _tmp12_ = _variant_get1 (_tmp11_); -+ _tmp13_ = _tmp12_; -+ _g_variant_unref0 (_tmp11_); -+ key = _tmp13_; -+ _tmp14_ = changed_prop; -+ _tmp15_ = g_variant_get_child_value (_tmp14_, (gsize) 1); -+ _tmp16_ = _tmp15_; -+ _tmp17_ = g_variant_get_child_value (_tmp16_, (gsize) 0); -+ _tmp18_ = _tmp17_; -+ _g_variant_unref0 (_tmp16_); -+ value = _tmp18_; -+ _tmp19_ = key; -+ _tmp20_ = value; -+ _tmp21_ = g_variant_print (_tmp20_, TRUE); -+ _tmp22_ = _tmp21_; -+ g_debug ("rygel-lms-database.vala:138: LMS property %s changed value to %s", _tmp19_, _tmp22_); -+ _g_free0 (_tmp22_); -+ _tmp23_ = key; -+ _tmp24_ = _tmp23_; -+ _tmp26_ = (NULL == _tmp24_) ? 0 : g_quark_from_string (_tmp24_); -+ if (_tmp26_ == ((0 != _tmp25_label0) ? _tmp25_label0 : (_tmp25_label0 = g_quark_from_static_string ("UpdateID")))) { -+ switch (0) { -+ default: -+ { -+ guint64 _tmp27_ = 0ULL; -+ GVariant* _tmp28_ = NULL; -+ guint64 _tmp29_ = 0ULL; -+ GVariant* _tmp30_ = NULL; -+ guint64 _tmp31_ = 0ULL; -+ _tmp27_ = self->priv->update_id; -+ _tmp28_ = value; -+ _tmp29_ = _variant_get2 (_tmp28_); -+ g_signal_emit_by_name (self, "db-updated", _tmp27_, _tmp29_); -+ _tmp30_ = value; -+ _tmp31_ = _variant_get3 (_tmp30_); -+ self->priv->update_id = _tmp31_; -+ break; -+ } -+ } -+ } -+ _g_variant_unref0 (value); -+ _g_free0 (key); -+ } -+ _g_variant_unref0 (changed_prop); -+ _g_variant_iter_free0 (_changed_prop_it); -+ } -+} -+ -+ -+sqlite3_stmt* rygel_lms_database_prepare (RygelLMSDatabase* self, const gchar* query_string, GError** error) { -+ sqlite3_stmt* result = NULL; -+ sqlite3_stmt* statement = NULL; -+ gint err = 0; -+ sqlite3* _tmp0_ = NULL; -+ const gchar* _tmp1_ = NULL; -+ sqlite3_stmt* _tmp2_ = NULL; -+ gint _tmp3_ = 0; -+ gint _tmp4_ = 0; -+ GError * _inner_error_ = NULL; -+ g_return_val_if_fail (self != NULL, NULL); -+ g_return_val_if_fail (query_string != NULL, NULL); -+ _tmp0_ = self->priv->db; -+ _tmp1_ = query_string; -+ _tmp3_ = sqlite3_prepare_v2 (_tmp0_, _tmp1_, -1, &_tmp2_, NULL); -+ _sqlite3_finalize0 (statement); -+ statement = _tmp2_; -+ err = _tmp3_; -+ _tmp4_ = err; -+ if (_tmp4_ != SQLITE_OK) { -+ const gchar* _tmp5_ = NULL; -+ gint _tmp6_ = 0; -+ GError* _tmp7_ = NULL; -+ _tmp5_ = query_string; -+ _tmp6_ = err; -+ _tmp7_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_PREPARE, "Unable to create statement '%s': %d", _tmp5_, _tmp6_); -+ _inner_error_ = _tmp7_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ _sqlite3_finalize0 (statement); -+ return NULL; -+ } else { -+ _sqlite3_finalize0 (statement); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ } -+ result = statement; -+ return result; -+} -+ -+ -+sqlite3_stmt* rygel_lms_database_prepare_and_init (RygelLMSDatabase* self, const gchar* query, GValue* arguments, int arguments_length1, GError** error) { -+ sqlite3_stmt* result = NULL; -+ sqlite3_stmt* statement = NULL; -+ gint err = 0; -+ sqlite3* _tmp0_ = NULL; -+ const gchar* _tmp1_ = NULL; -+ sqlite3_stmt* _tmp2_ = NULL; -+ gint _tmp3_ = 0; -+ gint _tmp4_ = 0; -+ GError * _inner_error_ = NULL; -+ g_return_val_if_fail (self != NULL, NULL); -+ g_return_val_if_fail (query != NULL, NULL); -+ _tmp0_ = self->priv->db; -+ _tmp1_ = query; -+ _tmp3_ = sqlite3_prepare_v2 (_tmp0_, _tmp1_, -1, &_tmp2_, NULL); -+ _sqlite3_finalize0 (statement); -+ statement = _tmp2_; -+ err = _tmp3_; -+ _tmp4_ = err; -+ if (_tmp4_ != SQLITE_OK) { -+ const gchar* _tmp5_ = NULL; -+ gint _tmp6_ = 0; -+ GError* _tmp7_ = NULL; -+ _tmp5_ = query; -+ _tmp6_ = err; -+ _tmp7_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_PREPARE, "Unable to create statement '%s': %d", _tmp5_, _tmp6_); -+ _inner_error_ = _tmp7_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ _sqlite3_finalize0 (statement); -+ return NULL; -+ } else { -+ _sqlite3_finalize0 (statement); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ } -+ { -+ gint i = 0; -+ i = 1; -+ { -+ gboolean _tmp8_ = FALSE; -+ _tmp8_ = TRUE; -+ while (TRUE) { -+ gint _tmp10_ = 0; -+ GValue* _tmp11_ = NULL; -+ gint _tmp11__length1 = 0; -+ gint sqlite_err = 0; -+ GValue current_value = {0}; -+ GValue* _tmp12_ = NULL; -+ gint _tmp12__length1 = 0; -+ gint _tmp13_ = 0; -+ GValue _tmp14_ = {0}; -+ gboolean _tmp15_ = FALSE; -+ if (!_tmp8_) { -+ gint _tmp9_ = 0; -+ _tmp9_ = i; -+ i = _tmp9_ + 1; -+ } -+ _tmp8_ = FALSE; -+ _tmp10_ = i; -+ _tmp11_ = arguments; -+ _tmp11__length1 = arguments_length1; -+ if (!(_tmp10_ <= _tmp11__length1)) { -+ break; -+ } -+ _tmp12_ = arguments; -+ _tmp12__length1 = arguments_length1; -+ _tmp13_ = i; -+ _tmp14_ = _tmp12_[_tmp13_ - 1]; -+ current_value = _tmp14_; -+ _tmp15_ = G_VALUE_HOLDS (¤t_value, G_TYPE_INT); -+ if (_tmp15_) { -+ sqlite3_stmt* _tmp16_ = NULL; -+ gint _tmp17_ = 0; -+ gint _tmp18_ = 0; -+ gint _tmp19_ = 0; -+ gint _tmp20_ = 0; -+ _tmp16_ = statement; -+ _tmp17_ = i; -+ _tmp18_ = g_value_get_int (¤t_value); -+ _tmp19_ = sqlite3_bind_int (_tmp16_, _tmp17_, _tmp18_); -+ sqlite_err = _tmp19_; -+ _tmp20_ = sqlite_err; -+ if (_tmp20_ != SQLITE_OK) { -+ gint _tmp21_ = 0; -+ GError* _tmp22_ = NULL; -+ _tmp21_ = sqlite_err; -+ _tmp22_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp21_); -+ _inner_error_ = _tmp22_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ _sqlite3_finalize0 (statement); -+ return NULL; -+ } else { -+ _sqlite3_finalize0 (statement); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ } -+ } else { -+ gboolean _tmp23_ = FALSE; -+ _tmp23_ = G_VALUE_HOLDS (¤t_value, G_TYPE_INT64); -+ if (_tmp23_) { -+ sqlite3_stmt* _tmp24_ = NULL; -+ gint _tmp25_ = 0; -+ gint64 _tmp26_ = 0LL; -+ gint _tmp27_ = 0; -+ gint _tmp28_ = 0; -+ _tmp24_ = statement; -+ _tmp25_ = i; -+ _tmp26_ = g_value_get_int64 (¤t_value); -+ _tmp27_ = sqlite3_bind_int64 (_tmp24_, _tmp25_, _tmp26_); -+ sqlite_err = _tmp27_; -+ _tmp28_ = sqlite_err; -+ if (_tmp28_ != SQLITE_OK) { -+ gint _tmp29_ = 0; -+ GError* _tmp30_ = NULL; -+ _tmp29_ = sqlite_err; -+ _tmp30_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp29_); -+ _inner_error_ = _tmp30_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ _sqlite3_finalize0 (statement); -+ return NULL; -+ } else { -+ _sqlite3_finalize0 (statement); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ } -+ } else { -+ gboolean _tmp31_ = FALSE; -+ _tmp31_ = G_VALUE_HOLDS (¤t_value, G_TYPE_UINT64); -+ if (_tmp31_) { -+ sqlite3_stmt* _tmp32_ = NULL; -+ gint _tmp33_ = 0; -+ guint64 _tmp34_ = 0ULL; -+ gint _tmp35_ = 0; -+ gint _tmp36_ = 0; -+ _tmp32_ = statement; -+ _tmp33_ = i; -+ _tmp34_ = g_value_get_uint64 (¤t_value); -+ _tmp35_ = sqlite3_bind_int64 (_tmp32_, _tmp33_, (gint64) _tmp34_); -+ sqlite_err = _tmp35_; -+ _tmp36_ = sqlite_err; -+ if (_tmp36_ != SQLITE_OK) { -+ gint _tmp37_ = 0; -+ GError* _tmp38_ = NULL; -+ _tmp37_ = sqlite_err; -+ _tmp38_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp37_); -+ _inner_error_ = _tmp38_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ _sqlite3_finalize0 (statement); -+ return NULL; -+ } else { -+ _sqlite3_finalize0 (statement); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ } -+ } else { -+ gboolean _tmp39_ = FALSE; -+ _tmp39_ = G_VALUE_HOLDS (¤t_value, G_TYPE_LONG); -+ if (_tmp39_) { -+ sqlite3_stmt* _tmp40_ = NULL; -+ gint _tmp41_ = 0; -+ glong _tmp42_ = 0L; -+ gint _tmp43_ = 0; -+ gint _tmp44_ = 0; -+ _tmp40_ = statement; -+ _tmp41_ = i; -+ _tmp42_ = g_value_get_long (¤t_value); -+ _tmp43_ = sqlite3_bind_int64 (_tmp40_, _tmp41_, (gint64) _tmp42_); -+ sqlite_err = _tmp43_; -+ _tmp44_ = sqlite_err; -+ if (_tmp44_ != SQLITE_OK) { -+ gint _tmp45_ = 0; -+ GError* _tmp46_ = NULL; -+ _tmp45_ = sqlite_err; -+ _tmp46_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp45_); -+ _inner_error_ = _tmp46_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ _sqlite3_finalize0 (statement); -+ return NULL; -+ } else { -+ _sqlite3_finalize0 (statement); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ } -+ } else { -+ gboolean _tmp47_ = FALSE; -+ _tmp47_ = G_VALUE_HOLDS (¤t_value, G_TYPE_UINT); -+ if (_tmp47_) { -+ sqlite3_stmt* _tmp48_ = NULL; -+ gint _tmp49_ = 0; -+ guint _tmp50_ = 0U; -+ gint _tmp51_ = 0; -+ gint _tmp52_ = 0; -+ _tmp48_ = statement; -+ _tmp49_ = i; -+ _tmp50_ = g_value_get_uint (¤t_value); -+ _tmp51_ = sqlite3_bind_int64 (_tmp48_, _tmp49_, (gint64) _tmp50_); -+ sqlite_err = _tmp51_; -+ _tmp52_ = sqlite_err; -+ if (_tmp52_ != SQLITE_OK) { -+ gint _tmp53_ = 0; -+ GError* _tmp54_ = NULL; -+ _tmp53_ = sqlite_err; -+ _tmp54_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp53_); -+ _inner_error_ = _tmp54_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ _sqlite3_finalize0 (statement); -+ return NULL; -+ } else { -+ _sqlite3_finalize0 (statement); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ } -+ } else { -+ gboolean _tmp55_ = FALSE; -+ _tmp55_ = G_VALUE_HOLDS (¤t_value, G_TYPE_STRING); -+ if (_tmp55_) { -+ sqlite3_stmt* _tmp56_ = NULL; -+ gint _tmp57_ = 0; -+ const gchar* _tmp58_ = NULL; -+ gchar* _tmp59_ = NULL; -+ GDestroyNotify _tmp60_ = NULL; -+ gint _tmp61_ = 0; -+ gint _tmp62_ = 0; -+ _tmp56_ = statement; -+ _tmp57_ = i; -+ _tmp58_ = g_value_get_string (¤t_value); -+ _tmp59_ = g_strdup (_tmp58_); -+ _tmp60_ = g_free; -+ _tmp61_ = sqlite3_bind_text (_tmp56_, _tmp57_, _tmp59_, -1, _tmp60_); -+ sqlite_err = _tmp61_; -+ _tmp62_ = sqlite_err; -+ if (_tmp62_ != SQLITE_OK) { -+ gint _tmp63_ = 0; -+ GError* _tmp64_ = NULL; -+ _tmp63_ = sqlite_err; -+ _tmp64_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp63_); -+ _inner_error_ = _tmp64_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ _sqlite3_finalize0 (statement); -+ return NULL; -+ } else { -+ _sqlite3_finalize0 (statement); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ } -+ } else { -+ gboolean _tmp65_ = FALSE; -+ _tmp65_ = G_VALUE_HOLDS (¤t_value, G_TYPE_POINTER); -+ if (_tmp65_) { -+ void* _tmp66_ = NULL; -+ _tmp66_ = g_value_peek_pointer (¤t_value); -+ if (_tmp66_ == NULL) { -+ sqlite3_stmt* _tmp67_ = NULL; -+ gint _tmp68_ = 0; -+ gint _tmp69_ = 0; -+ gint _tmp70_ = 0; -+ _tmp67_ = statement; -+ _tmp68_ = i; -+ _tmp69_ = sqlite3_bind_null (_tmp67_, _tmp68_); -+ sqlite_err = _tmp69_; -+ _tmp70_ = sqlite_err; -+ if (_tmp70_ != SQLITE_OK) { -+ gint _tmp71_ = 0; -+ GError* _tmp72_ = NULL; -+ _tmp71_ = sqlite_err; -+ _tmp72_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp71_); -+ _inner_error_ = _tmp72_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ _sqlite3_finalize0 (statement); -+ return NULL; -+ } else { -+ _sqlite3_finalize0 (statement); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ } -+ } else { -+ g_assert_not_reached (); -+ } -+ } else { -+ GType type = 0UL; -+ GType _tmp73_ = 0UL; -+ const gchar* _tmp74_ = NULL; -+ const gchar* _tmp75_ = NULL; -+ _tmp73_ = G_VALUE_TYPE (¤t_value); -+ type = _tmp73_; -+ _tmp74_ = _ ("Unsupported type %s"); -+ _tmp75_ = g_type_name (type); -+ g_warning (_tmp74_, _tmp75_); -+ g_assert_not_reached (); -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ result = statement; -+ return result; -+} -+ -+ -+void rygel_lms_database_find_object (const gchar* id, sqlite3_stmt* stmt, GError** error) { -+ sqlite3_stmt* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gint integer_id = 0; -+ const gchar* _tmp2_ = NULL; -+ gint _tmp3_ = 0; -+ gint sqlite_err = 0; -+ sqlite3_stmt* _tmp4_ = NULL; -+ gint _tmp5_ = 0; -+ gint _tmp6_ = 0; -+ gint _tmp7_ = 0; -+ sqlite3_stmt* _tmp10_ = NULL; -+ gint _tmp11_ = 0; -+ gint _tmp12_ = 0; -+ GError * _inner_error_ = NULL; -+ g_return_if_fail (id != NULL); -+ g_return_if_fail (stmt != NULL); -+ _tmp0_ = stmt; -+ _tmp1_ = sqlite3_reset (_tmp0_); -+ _tmp2_ = id; -+ _tmp3_ = atoi (_tmp2_); -+ integer_id = _tmp3_; -+ _tmp4_ = stmt; -+ _tmp5_ = integer_id; -+ _tmp6_ = sqlite3_bind_int (_tmp4_, 1, _tmp5_); -+ sqlite_err = _tmp6_; -+ _tmp7_ = sqlite_err; -+ if (_tmp7_ != SQLITE_OK) { -+ gint _tmp8_ = 0; -+ GError* _tmp9_ = NULL; -+ _tmp8_ = sqlite_err; -+ _tmp9_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind id %d", _tmp8_); -+ _inner_error_ = _tmp9_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ return; -+ } else { -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return; -+ } -+ } -+ _tmp10_ = stmt; -+ _tmp11_ = sqlite3_step (_tmp10_); -+ sqlite_err = _tmp11_; -+ _tmp12_ = sqlite_err; -+ if (_tmp12_ != SQLITE_ROW) { -+ const gchar* _tmp13_ = NULL; -+ GError* _tmp14_ = NULL; -+ _tmp13_ = id; -+ _tmp14_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_STEP, "Unable to find id %s", _tmp13_); -+ _inner_error_ = _tmp14_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ return; -+ } else { -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return; -+ } -+ } -+} -+ -+ -+void rygel_lms_database_get_children_init (sqlite3_stmt* stmt, guint offset, guint max_count, const gchar* sort_criteria, GError** error) { -+ gint sqlite_err = 0; -+ sqlite3_stmt* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ sqlite3_stmt* _tmp2_ = NULL; -+ guint _tmp3_ = 0U; -+ gint _tmp4_ = 0; -+ gint _tmp5_ = 0; -+ sqlite3_stmt* _tmp8_ = NULL; -+ guint _tmp9_ = 0U; -+ gint _tmp10_ = 0; -+ gint _tmp11_ = 0; -+ GError * _inner_error_ = NULL; -+ g_return_if_fail (stmt != NULL); -+ g_return_if_fail (sort_criteria != NULL); -+ _tmp0_ = stmt; -+ _tmp1_ = sqlite3_reset (_tmp0_); -+ _tmp2_ = stmt; -+ _tmp3_ = max_count; -+ _tmp4_ = sqlite3_bind_int (_tmp2_, 1, (gint) _tmp3_); -+ sqlite_err = _tmp4_; -+ _tmp5_ = sqlite_err; -+ if (_tmp5_ != SQLITE_OK) { -+ gint _tmp6_ = 0; -+ GError* _tmp7_ = NULL; -+ _tmp6_ = sqlite_err; -+ _tmp7_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind max_count %d", _tmp6_); -+ _inner_error_ = _tmp7_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ return; -+ } else { -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return; -+ } -+ } -+ _tmp8_ = stmt; -+ _tmp9_ = offset; -+ _tmp10_ = sqlite3_bind_int (_tmp8_, 2, (gint) _tmp9_); -+ sqlite_err = _tmp10_; -+ _tmp11_ = sqlite_err; -+ if (_tmp11_ != SQLITE_OK) { -+ gint _tmp12_ = 0; -+ GError* _tmp13_ = NULL; -+ _tmp12_ = sqlite_err; -+ _tmp13_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind offset %d", _tmp12_); -+ _inner_error_ = _tmp13_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ return; -+ } else { -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return; -+ } -+ } -+} -+ -+ -+void rygel_lms_database_get_children_with_update_id_init (sqlite3_stmt* stmt, guint64 old_id, guint64 new_id, GError** error) { -+ gint sqlite_err = 0; -+ sqlite3_stmt* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ guint64 _tmp2_ = 0ULL; -+ guint64 _tmp3_ = 0ULL; -+ gint _tmp9_ = 0; -+ sqlite3_stmt* _tmp12_ = NULL; -+ guint64 _tmp13_ = 0ULL; -+ gint _tmp14_ = 0; -+ gint _tmp15_ = 0; -+ GError * _inner_error_ = NULL; -+ g_return_if_fail (stmt != NULL); -+ _tmp0_ = stmt; -+ _tmp1_ = sqlite3_reset (_tmp0_); -+ _tmp2_ = new_id; -+ _tmp3_ = old_id; -+ if (_tmp2_ < _tmp3_) { -+ sqlite3_stmt* _tmp4_ = NULL; -+ gint _tmp5_ = 0; -+ _tmp4_ = stmt; -+ _tmp5_ = sqlite3_bind_int64 (_tmp4_, 1, (gint64) 0); -+ sqlite_err = _tmp5_; -+ } else { -+ sqlite3_stmt* _tmp6_ = NULL; -+ guint64 _tmp7_ = 0ULL; -+ gint _tmp8_ = 0; -+ _tmp6_ = stmt; -+ _tmp7_ = old_id; -+ _tmp8_ = sqlite3_bind_int64 (_tmp6_, 1, (gint64) _tmp7_); -+ sqlite_err = _tmp8_; -+ } -+ _tmp9_ = sqlite_err; -+ if (_tmp9_ != SQLITE_OK) { -+ gint _tmp10_ = 0; -+ GError* _tmp11_ = NULL; -+ _tmp10_ = sqlite_err; -+ _tmp11_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind old_id %d", _tmp10_); -+ _inner_error_ = _tmp11_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ return; -+ } else { -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return; -+ } -+ } -+ _tmp12_ = stmt; -+ _tmp13_ = new_id; -+ _tmp14_ = sqlite3_bind_int64 (_tmp12_, 2, (gint64) _tmp13_); -+ sqlite_err = _tmp14_; -+ _tmp15_ = sqlite_err; -+ if (_tmp15_ != SQLITE_OK) { -+ gint _tmp16_ = 0; -+ GError* _tmp17_ = NULL; -+ _tmp16_ = sqlite_err; -+ _tmp17_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind new_id %d", _tmp16_); -+ _inner_error_ = _tmp17_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ return; -+ } else { -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return; -+ } -+ } -+} -+ -+ -+gboolean rygel_lms_database_get_children_step (sqlite3_stmt* stmt, GError** error) { -+ gboolean result = FALSE; -+ gboolean retval = FALSE; -+ gint sqlite_err = 0; -+ sqlite3_stmt* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gint _tmp2_ = 0; -+ gboolean _tmp3_ = FALSE; -+ gboolean _tmp4_ = FALSE; -+ GError * _inner_error_ = NULL; -+ g_return_val_if_fail (stmt != NULL, FALSE); -+ _tmp0_ = stmt; -+ _tmp1_ = sqlite3_step (_tmp0_); -+ sqlite_err = _tmp1_; -+ _tmp2_ = sqlite_err; -+ retval = _tmp2_ == SQLITE_ROW; -+ _tmp4_ = retval; -+ if (!_tmp4_) { -+ gint _tmp5_ = 0; -+ _tmp5_ = sqlite_err; -+ _tmp3_ = _tmp5_ != SQLITE_DONE; -+ } else { -+ _tmp3_ = FALSE; -+ } -+ if (_tmp3_) { -+ gint _tmp6_ = 0; -+ GError* _tmp7_ = NULL; -+ _tmp6_ = sqlite_err; -+ _tmp7_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_STEP, "Error iterating through rows %d", _tmp6_); -+ _inner_error_ = _tmp7_; -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ g_propagate_error (error, _inner_error_); -+ return FALSE; -+ } else { -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return FALSE; -+ } -+ } -+ result = retval; -+ return result; -+} -+ -+ -+static void g_cclosure_user_marshal_VOID__UINT64_UINT64 (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) { -+ typedef void (*GMarshalFunc_VOID__UINT64_UINT64) (gpointer data1, guint64 arg_1, guint64 arg_2, gpointer data2); -+ register GMarshalFunc_VOID__UINT64_UINT64 callback; -+ register GCClosure * cc; -+ register gpointer data1; -+ register gpointer data2; -+ cc = (GCClosure *) closure; -+ g_return_if_fail (n_param_values == 3); -+ if (G_CCLOSURE_SWAP_DATA (closure)) { -+ data1 = closure->data; -+ data2 = param_values->data[0].v_pointer; -+ } else { -+ data1 = param_values->data[0].v_pointer; -+ data2 = closure->data; -+ } -+ callback = (GMarshalFunc_VOID__UINT64_UINT64) (marshal_data ? marshal_data : cc->callback); -+ callback (data1, g_value_get_uint64 (param_values + 1), g_value_get_uint64 (param_values + 2), data2); -+} -+ -+ -+static void rygel_lms_value_database_init (GValue* value) { -+ value->data[0].v_pointer = NULL; -+} -+ -+ -+static void rygel_lms_value_database_free_value (GValue* value) { -+ if (value->data[0].v_pointer) { -+ rygel_lms_database_unref (value->data[0].v_pointer); -+ } -+} -+ -+ -+static void rygel_lms_value_database_copy_value (const GValue* src_value, GValue* dest_value) { -+ if (src_value->data[0].v_pointer) { -+ dest_value->data[0].v_pointer = rygel_lms_database_ref (src_value->data[0].v_pointer); -+ } else { -+ dest_value->data[0].v_pointer = NULL; -+ } -+} -+ -+ -+static gpointer rygel_lms_value_database_peek_pointer (const GValue* value) { -+ return value->data[0].v_pointer; -+} -+ -+ -+static gchar* rygel_lms_value_database_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) { -+ if (collect_values[0].v_pointer) { -+ RygelLMSDatabase* object; -+ object = collect_values[0].v_pointer; -+ if (object->parent_instance.g_class == NULL) { -+ return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL); -+ } else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) { -+ return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL); -+ } -+ value->data[0].v_pointer = rygel_lms_database_ref (object); -+ } else { -+ value->data[0].v_pointer = NULL; -+ } -+ return NULL; -+} -+ -+ -+static gchar* rygel_lms_value_database_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) { -+ RygelLMSDatabase** object_p; -+ object_p = collect_values[0].v_pointer; -+ if (!object_p) { -+ return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); -+ } -+ if (!value->data[0].v_pointer) { -+ *object_p = NULL; -+ } else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) { -+ *object_p = value->data[0].v_pointer; -+ } else { -+ *object_p = rygel_lms_database_ref (value->data[0].v_pointer); -+ } -+ return NULL; -+} -+ -+ -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) { -+ RygelLMSParamSpecDatabase* spec; -+ g_return_val_if_fail (g_type_is_a (object_type, RYGEL_LMS_TYPE_DATABASE), NULL); -+ spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags); -+ G_PARAM_SPEC (spec)->value_type = object_type; -+ return G_PARAM_SPEC (spec); -+} -+ -+ -+gpointer rygel_lms_value_get_database (const GValue* value) { -+ g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_DATABASE), NULL); -+ return value->data[0].v_pointer; -+} -+ -+ -+void rygel_lms_value_set_database (GValue* value, gpointer v_object) { -+ RygelLMSDatabase* old; -+ g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_DATABASE)); -+ old = value->data[0].v_pointer; -+ if (v_object) { -+ g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RYGEL_LMS_TYPE_DATABASE)); -+ g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); -+ value->data[0].v_pointer = v_object; -+ rygel_lms_database_ref (value->data[0].v_pointer); -+ } else { -+ value->data[0].v_pointer = NULL; -+ } -+ if (old) { -+ rygel_lms_database_unref (old); -+ } -+} -+ -+ -+void rygel_lms_value_take_database (GValue* value, gpointer v_object) { -+ RygelLMSDatabase* old; -+ g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_DATABASE)); -+ old = value->data[0].v_pointer; -+ if (v_object) { -+ g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RYGEL_LMS_TYPE_DATABASE)); -+ g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); -+ value->data[0].v_pointer = v_object; -+ } else { -+ value->data[0].v_pointer = NULL; -+ } -+ if (old) { -+ rygel_lms_database_unref (old); -+ } -+} -+ -+ -+static void rygel_lms_database_class_init (RygelLMSDatabaseClass * klass) { -+ rygel_lms_database_parent_class = g_type_class_peek_parent (klass); -+ ((RygelLMSDatabaseClass *) klass)->finalize = rygel_lms_database_finalize; -+ g_type_class_add_private (klass, sizeof (RygelLMSDatabasePrivate)); -+ g_signal_new ("db_updated", RYGEL_LMS_TYPE_DATABASE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__UINT64_UINT64, G_TYPE_NONE, 2, G_TYPE_UINT64, G_TYPE_UINT64); -+} -+ -+ -+static void rygel_lms_database_instance_init (RygelLMSDatabase * self) { -+ self->priv = RYGEL_LMS_DATABASE_GET_PRIVATE (self); -+ self->ref_count = 1; -+} -+ -+ -+static void rygel_lms_database_finalize (RygelLMSDatabase* obj) { -+ RygelLMSDatabase * self; -+ self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase); -+ g_signal_handlers_destroy (self); -+ _sqlite3_close0 (self->priv->db); -+ _g_object_unref0 (self->priv->lms_proxy); -+} -+ -+ -+GType rygel_lms_database_get_type (void) { -+ static volatile gsize rygel_lms_database_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_database_type_id__volatile)) { -+ static const GTypeValueTable g_define_type_value_table = { rygel_lms_value_database_init, rygel_lms_value_database_free_value, rygel_lms_value_database_copy_value, rygel_lms_value_database_peek_pointer, "p", rygel_lms_value_database_collect_value, "p", rygel_lms_value_database_lcopy_value }; -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSDatabaseClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_database_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSDatabase), 0, (GInstanceInitFunc) rygel_lms_database_instance_init, &g_define_type_value_table }; -+ static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }; -+ GType rygel_lms_database_type_id; -+ rygel_lms_database_type_id = g_type_register_fundamental (g_type_fundamental_next (), "RygelLMSDatabase", &g_define_type_info, &g_define_type_fundamental_info, 0); -+ g_once_init_leave (&rygel_lms_database_type_id__volatile, rygel_lms_database_type_id); -+ } -+ return rygel_lms_database_type_id__volatile; -+} -+ -+ -+gpointer rygel_lms_database_ref (gpointer instance) { -+ RygelLMSDatabase* self; -+ self = instance; -+ g_atomic_int_inc (&self->ref_count); -+ return instance; -+} -+ -+ -+void rygel_lms_database_unref (gpointer instance) { -+ RygelLMSDatabase* self; -+ self = instance; -+ if (g_atomic_int_dec_and_test (&self->ref_count)) { -+ RYGEL_LMS_DATABASE_GET_CLASS (self)->finalize (self); -+ g_type_free_instance ((GTypeInstance *) self); -+ } -+} -+ -+ -+static gint _vala_array_length (gpointer array) { -+ int length; -+ length = 0; -+ if (array) { -+ while (((gpointer*) array)[length]) { -+ length++; -+ } -+ } -+ return length; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-dbus-interfaces.c b/src/plugins/lms/rygel-lms-dbus-interfaces.c -new file mode 100644 -index 0000000..b511b17 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-dbus-interfaces.c -@@ -0,0 +1,261 @@ -+/* rygel-lms-dbus-interfaces.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-dbus-interfaces.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2014 Intel Corporation. -+ * -+ * Author: Alexander Kanavin <alex.kanavin@gmail.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <gio/gio.h> -+#include <stdlib.h> -+#include <string.h> -+ -+ -+#define RYGEL_LMS_TYPE_DBUS (rygel_lms_dbus_get_type ()) -+#define RYGEL_LMS_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DBUS, RygelLMSDBus)) -+#define RYGEL_LMS_IS_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DBUS)) -+#define RYGEL_LMS_DBUS_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), RYGEL_LMS_TYPE_DBUS, RygelLMSDBusIface)) -+ -+typedef struct _RygelLMSDBus RygelLMSDBus; -+typedef struct _RygelLMSDBusIface RygelLMSDBusIface; -+ -+#define RYGEL_LMS_TYPE_DBUS_PROXY (rygel_lms_dbus_proxy_get_type ()) -+typedef GDBusProxy RygelLMSDBusProxy; -+typedef GDBusProxyClass RygelLMSDBusProxyClass; -+#define _g_free0(var) (var = (g_free (var), NULL)) -+ -+struct _RygelLMSDBusIface { -+ GTypeInterface parent_iface; -+ gchar* (*get_data_base_path) (RygelLMSDBus* self); -+ guint64 (*get_update_id) (RygelLMSDBus* self); -+}; -+ -+ -+ -+GType rygel_lms_dbus_get_type (void) G_GNUC_CONST; -+GType rygel_lms_dbus_proxy_get_type (void) G_GNUC_CONST; -+guint rygel_lms_dbus_register_object (void* object, GDBusConnection* connection, const gchar* path, GError** error); -+gchar* rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self); -+guint64 rygel_lms_dbus_get_update_id (RygelLMSDBus* self); -+static void rygel_lms_dbus_proxy_g_signal (GDBusProxy* proxy, const gchar* sender_name, const gchar* signal_name, GVariant* parameters); -+static gchar* rygel_lms_dbus_dbus_proxy_get_data_base_path (RygelLMSDBus* self); -+static guint64 rygel_lms_dbus_dbus_proxy_get_update_id (RygelLMSDBus* self); -+static void rygel_lms_dbus_proxy_rygel_lms_dbus_interface_init (RygelLMSDBusIface* iface); -+static void rygel_lms_dbus_dbus_interface_method_call (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data); -+static GVariant* rygel_lms_dbus_dbus_interface_get_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GError** error, gpointer user_data); -+static GVariant* _dbus_rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self); -+static GVariant* _dbus_rygel_lms_dbus_get_update_id (RygelLMSDBus* self); -+static gboolean rygel_lms_dbus_dbus_interface_set_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GVariant* value, GError** error, gpointer user_data); -+static void _rygel_lms_dbus_unregister_object (gpointer user_data); -+ -+static const GDBusMethodInfo * const _rygel_lms_dbus_dbus_method_info[] = {NULL}; -+static const GDBusSignalInfo * const _rygel_lms_dbus_dbus_signal_info[] = {NULL}; -+static const GDBusPropertyInfo _rygel_lms_dbus_dbus_property_info_data_base_path = {-1, "DataBasePath", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; -+static const GDBusPropertyInfo _rygel_lms_dbus_dbus_property_info_update_id = {-1, "UpdateID", "t", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; -+static const GDBusPropertyInfo * const _rygel_lms_dbus_dbus_property_info[] = {&_rygel_lms_dbus_dbus_property_info_data_base_path, &_rygel_lms_dbus_dbus_property_info_update_id, NULL}; -+static const GDBusInterfaceInfo _rygel_lms_dbus_dbus_interface_info = {-1, "org.lightmediascanner.Scanner1", (GDBusMethodInfo **) (&_rygel_lms_dbus_dbus_method_info), (GDBusSignalInfo **) (&_rygel_lms_dbus_dbus_signal_info), (GDBusPropertyInfo **) (&_rygel_lms_dbus_dbus_property_info)}; -+static const GDBusInterfaceVTable _rygel_lms_dbus_dbus_interface_vtable = {rygel_lms_dbus_dbus_interface_method_call, rygel_lms_dbus_dbus_interface_get_property, rygel_lms_dbus_dbus_interface_set_property}; -+ -+gchar* rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self) { -+ g_return_val_if_fail (self != NULL, NULL); -+ return RYGEL_LMS_DBUS_GET_INTERFACE (self)->get_data_base_path (self); -+} -+ -+ -+guint64 rygel_lms_dbus_get_update_id (RygelLMSDBus* self) { -+ g_return_val_if_fail (self != NULL, 0ULL); -+ return RYGEL_LMS_DBUS_GET_INTERFACE (self)->get_update_id (self); -+} -+ -+ -+static void rygel_lms_dbus_base_init (RygelLMSDBusIface * iface) { -+ static gboolean initialized = FALSE; -+ if (!initialized) { -+ initialized = TRUE; -+ } -+} -+ -+ -+GType rygel_lms_dbus_get_type (void) { -+ static volatile gsize rygel_lms_dbus_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_dbus_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSDBusIface), (GBaseInitFunc) rygel_lms_dbus_base_init, (GBaseFinalizeFunc) NULL, (GClassInitFunc) NULL, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL }; -+ GType rygel_lms_dbus_type_id; -+ rygel_lms_dbus_type_id = g_type_register_static (G_TYPE_INTERFACE, "RygelLMSDBus", &g_define_type_info, 0); -+ g_type_interface_add_prerequisite (rygel_lms_dbus_type_id, G_TYPE_DBUS_PROXY); -+ g_type_set_qdata (rygel_lms_dbus_type_id, g_quark_from_static_string ("vala-dbus-proxy-type"), (void*) rygel_lms_dbus_proxy_get_type); -+ g_type_set_qdata (rygel_lms_dbus_type_id, g_quark_from_static_string ("vala-dbus-interface-name"), "org.lightmediascanner.Scanner1"); -+ g_type_set_qdata (rygel_lms_dbus_type_id, g_quark_from_static_string ("vala-dbus-interface-info"), (void*) (&_rygel_lms_dbus_dbus_interface_info)); -+ g_type_set_qdata (rygel_lms_dbus_type_id, g_quark_from_static_string ("vala-dbus-register-object"), (void*) rygel_lms_dbus_register_object); -+ g_once_init_leave (&rygel_lms_dbus_type_id__volatile, rygel_lms_dbus_type_id); -+ } -+ return rygel_lms_dbus_type_id__volatile; -+} -+ -+ -+G_DEFINE_TYPE_EXTENDED (RygelLMSDBusProxy, rygel_lms_dbus_proxy, G_TYPE_DBUS_PROXY, 0, G_IMPLEMENT_INTERFACE (RYGEL_LMS_TYPE_DBUS, rygel_lms_dbus_proxy_rygel_lms_dbus_interface_init) ) -+static void rygel_lms_dbus_proxy_class_init (RygelLMSDBusProxyClass* klass) { -+ G_DBUS_PROXY_CLASS (klass)->g_signal = rygel_lms_dbus_proxy_g_signal; -+} -+ -+ -+static void rygel_lms_dbus_proxy_g_signal (GDBusProxy* proxy, const gchar* sender_name, const gchar* signal_name, GVariant* parameters) { -+} -+ -+ -+static void rygel_lms_dbus_proxy_init (RygelLMSDBusProxy* self) { -+} -+ -+ -+static gchar* rygel_lms_dbus_dbus_proxy_get_data_base_path (RygelLMSDBus* self) { -+ GVariant *_inner_reply; -+ gchar* _result; -+ _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "DataBasePath"); -+ if (!_inner_reply) { -+ GVariant *_arguments; -+ GVariant *_reply; -+ GVariantBuilder _arguments_builder; -+ g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); -+ g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.lightmediascanner.Scanner1")); -+ g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("DataBasePath")); -+ _arguments = g_variant_builder_end (&_arguments_builder); -+ _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); -+ if (!_reply) { -+ return NULL; -+ } -+ g_variant_get (_reply, "(v)", &_inner_reply); -+ g_variant_unref (_reply); -+ } -+ _result = g_variant_dup_string (_inner_reply, NULL); -+ g_variant_unref (_inner_reply); -+ return _result; -+} -+ -+ -+static guint64 rygel_lms_dbus_dbus_proxy_get_update_id (RygelLMSDBus* self) { -+ GVariant *_inner_reply; -+ guint64 _result; -+ _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "UpdateID"); -+ if (!_inner_reply) { -+ GVariant *_arguments; -+ GVariant *_reply; -+ GVariantBuilder _arguments_builder; -+ g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); -+ g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.lightmediascanner.Scanner1")); -+ g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("UpdateID")); -+ _arguments = g_variant_builder_end (&_arguments_builder); -+ _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); -+ if (!_reply) { -+ return 0ULL; -+ } -+ g_variant_get (_reply, "(v)", &_inner_reply); -+ g_variant_unref (_reply); -+ } -+ _result = g_variant_get_uint64 (_inner_reply); -+ g_variant_unref (_inner_reply); -+ return _result; -+} -+ -+ -+static void rygel_lms_dbus_proxy_rygel_lms_dbus_interface_init (RygelLMSDBusIface* iface) { -+ iface->get_data_base_path = rygel_lms_dbus_dbus_proxy_get_data_base_path; -+ iface->get_update_id = rygel_lms_dbus_dbus_proxy_get_update_id; -+} -+ -+ -+static void rygel_lms_dbus_dbus_interface_method_call (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data) { -+ gpointer* data; -+ gpointer object; -+ data = user_data; -+ object = data[0]; -+ g_object_unref (invocation); -+} -+ -+ -+static GVariant* _dbus_rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self) { -+ gchar* result; -+ GVariant* _reply; -+ result = rygel_lms_dbus_get_data_base_path (self); -+ _reply = g_variant_new_string (result); -+ _g_free0 (result); -+ return _reply; -+} -+ -+ -+static GVariant* _dbus_rygel_lms_dbus_get_update_id (RygelLMSDBus* self) { -+ guint64 result; -+ GVariant* _reply; -+ result = rygel_lms_dbus_get_update_id (self); -+ _reply = g_variant_new_uint64 (result); -+ return _reply; -+} -+ -+ -+static GVariant* rygel_lms_dbus_dbus_interface_get_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GError** error, gpointer user_data) { -+ gpointer* data; -+ gpointer object; -+ data = user_data; -+ object = data[0]; -+ if (strcmp (property_name, "DataBasePath") == 0) { -+ return _dbus_rygel_lms_dbus_get_data_base_path (object); -+ } else if (strcmp (property_name, "UpdateID") == 0) { -+ return _dbus_rygel_lms_dbus_get_update_id (object); -+ } -+ return NULL; -+} -+ -+ -+static gboolean rygel_lms_dbus_dbus_interface_set_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GVariant* value, GError** error, gpointer user_data) { -+ gpointer* data; -+ gpointer object; -+ data = user_data; -+ object = data[0]; -+ return FALSE; -+} -+ -+ -+guint rygel_lms_dbus_register_object (gpointer object, GDBusConnection* connection, const gchar* path, GError** error) { -+ guint result; -+ gpointer *data; -+ data = g_new (gpointer, 3); -+ data[0] = g_object_ref (object); -+ data[1] = g_object_ref (connection); -+ data[2] = g_strdup (path); -+ result = g_dbus_connection_register_object (connection, path, (GDBusInterfaceInfo *) (&_rygel_lms_dbus_dbus_interface_info), &_rygel_lms_dbus_dbus_interface_vtable, data, _rygel_lms_dbus_unregister_object, error); -+ if (!result) { -+ return 0; -+ } -+ return result; -+} -+ -+ -+static void _rygel_lms_dbus_unregister_object (gpointer user_data) { -+ gpointer* data; -+ data = user_data; -+ g_object_unref (data[0]); -+ g_object_unref (data[1]); -+ g_free (data[2]); -+ g_free (data); -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-image-root.c b/src/plugins/lms/rygel-lms-image-root.c -new file mode 100644 -index 0000000..5ef358a ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-image-root.c -@@ -0,0 +1,178 @@ -+/* rygel-lms-image-root.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-image-root.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-server.h> -+#include <stdlib.h> -+#include <string.h> -+ -+ -+#define RYGEL_LMS_TYPE_IMAGE_ROOT (rygel_lms_image_root_get_type ()) -+#define RYGEL_LMS_IMAGE_ROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRoot)) -+#define RYGEL_LMS_IMAGE_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRootClass)) -+#define RYGEL_LMS_IS_IMAGE_ROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT)) -+#define RYGEL_LMS_IS_IMAGE_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_ROOT)) -+#define RYGEL_LMS_IMAGE_ROOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRootClass)) -+ -+typedef struct _RygelLMSImageRoot RygelLMSImageRoot; -+typedef struct _RygelLMSImageRootClass RygelLMSImageRootClass; -+typedef struct _RygelLMSImageRootPrivate RygelLMSImageRootPrivate; -+ -+#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) -+#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) -+#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+ -+typedef struct _RygelLMSDatabase RygelLMSDatabase; -+typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; -+ -+#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) -+#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+ -+typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; -+typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; -+ -+#define RYGEL_LMS_TYPE_ALL_IMAGES (rygel_lms_all_images_get_type ()) -+#define RYGEL_LMS_ALL_IMAGES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImages)) -+#define RYGEL_LMS_ALL_IMAGES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImagesClass)) -+#define RYGEL_LMS_IS_ALL_IMAGES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_IMAGES)) -+#define RYGEL_LMS_IS_ALL_IMAGES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_IMAGES)) -+#define RYGEL_LMS_ALL_IMAGES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImagesClass)) -+ -+typedef struct _RygelLMSAllImages RygelLMSAllImages; -+typedef struct _RygelLMSAllImagesClass RygelLMSAllImagesClass; -+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) -+ -+#define RYGEL_LMS_TYPE_IMAGE_YEARS (rygel_lms_image_years_get_type ()) -+#define RYGEL_LMS_IMAGE_YEARS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYears)) -+#define RYGEL_LMS_IMAGE_YEARS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYearsClass)) -+#define RYGEL_LMS_IS_IMAGE_YEARS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS)) -+#define RYGEL_LMS_IS_IMAGE_YEARS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_YEARS)) -+#define RYGEL_LMS_IMAGE_YEARS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYearsClass)) -+ -+typedef struct _RygelLMSImageYears RygelLMSImageYears; -+typedef struct _RygelLMSImageYearsClass RygelLMSImageYearsClass; -+ -+struct _RygelLMSImageRoot { -+ RygelSimpleContainer parent_instance; -+ RygelLMSImageRootPrivate * priv; -+}; -+ -+struct _RygelLMSImageRootClass { -+ RygelSimpleContainerClass parent_class; -+}; -+ -+ -+static gpointer rygel_lms_image_root_parent_class = NULL; -+ -+GType rygel_lms_image_root_get_type (void) G_GNUC_CONST; -+enum { -+ RYGEL_LMS_IMAGE_ROOT_DUMMY_PROPERTY -+}; -+gpointer rygel_lms_database_ref (gpointer instance); -+void rygel_lms_database_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_database (GValue* value, gpointer v_object); -+void rygel_lms_value_take_database (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_database (const GValue* value); -+GType rygel_lms_database_get_type (void) G_GNUC_CONST; -+RygelLMSImageRoot* rygel_lms_image_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSImageRoot* rygel_lms_image_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSAllImages* rygel_lms_all_images_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+RygelLMSAllImages* rygel_lms_all_images_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; -+GType rygel_lms_all_images_get_type (void) G_GNUC_CONST; -+RygelLMSImageYears* rygel_lms_image_years_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+RygelLMSImageYears* rygel_lms_image_years_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+GType rygel_lms_image_years_get_type (void) G_GNUC_CONST; -+ -+ -+RygelLMSImageRoot* rygel_lms_image_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { -+ RygelLMSImageRoot * self = NULL; -+ const gchar* _tmp0_ = NULL; -+ RygelMediaContainer* _tmp1_ = NULL; -+ const gchar* _tmp2_ = NULL; -+ RygelLMSDatabase* _tmp3_ = NULL; -+ RygelLMSAllImages* _tmp4_ = NULL; -+ RygelLMSAllImages* _tmp5_ = NULL; -+ RygelLMSDatabase* _tmp6_ = NULL; -+ RygelLMSImageYears* _tmp7_ = NULL; -+ RygelLMSImageYears* _tmp8_ = NULL; -+ g_return_val_if_fail (id != NULL, NULL); -+ g_return_val_if_fail (parent != NULL, NULL); -+ g_return_val_if_fail (title != NULL, NULL); -+ g_return_val_if_fail (lms_db != NULL, NULL); -+ _tmp0_ = id; -+ _tmp1_ = parent; -+ _tmp2_ = title; -+ self = (RygelLMSImageRoot*) rygel_simple_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_); -+ _tmp3_ = lms_db; -+ _tmp4_ = rygel_lms_all_images_new ((RygelMediaContainer*) self, _tmp3_); -+ _tmp5_ = _tmp4_; -+ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp5_); -+ _g_object_unref0 (_tmp5_); -+ _tmp6_ = lms_db; -+ _tmp7_ = rygel_lms_image_years_new ((RygelMediaContainer*) self, _tmp6_); -+ _tmp8_ = _tmp7_; -+ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp8_); -+ _g_object_unref0 (_tmp8_); -+ return self; -+} -+ -+ -+RygelLMSImageRoot* rygel_lms_image_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { -+ return rygel_lms_image_root_construct (RYGEL_LMS_TYPE_IMAGE_ROOT, id, parent, title, lms_db); -+} -+ -+ -+static void rygel_lms_image_root_class_init (RygelLMSImageRootClass * klass) { -+ rygel_lms_image_root_parent_class = g_type_class_peek_parent (klass); -+} -+ -+ -+static void rygel_lms_image_root_instance_init (RygelLMSImageRoot * self) { -+} -+ -+ -+GType rygel_lms_image_root_get_type (void) { -+ static volatile gsize rygel_lms_image_root_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_image_root_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSImageRootClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_image_root_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSImageRoot), 0, (GInstanceInitFunc) rygel_lms_image_root_instance_init, NULL }; -+ GType rygel_lms_image_root_type_id; -+ rygel_lms_image_root_type_id = g_type_register_static (RYGEL_TYPE_SIMPLE_CONTAINER, "RygelLMSImageRoot", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_image_root_type_id__volatile, rygel_lms_image_root_type_id); -+ } -+ return rygel_lms_image_root_type_id__volatile; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-image-year.c b/src/plugins/lms/rygel-lms-image-year.c -new file mode 100644 -index 0000000..5eb2721 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-image-year.c -@@ -0,0 +1,422 @@ -+/* rygel-lms-image-year.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-image-year.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-server.h> -+#include <sqlite3.h> -+#include <stdlib.h> -+#include <string.h> -+#include <gio/gio.h> -+ -+ -+#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) -+#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+ -+typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; -+typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; -+typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; -+ -+#define RYGEL_LMS_TYPE_IMAGE_YEAR (rygel_lms_image_year_get_type ()) -+#define RYGEL_LMS_IMAGE_YEAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYear)) -+#define RYGEL_LMS_IMAGE_YEAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYearClass)) -+#define RYGEL_LMS_IS_IMAGE_YEAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR)) -+#define RYGEL_LMS_IS_IMAGE_YEAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_YEAR)) -+#define RYGEL_LMS_IMAGE_YEAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYearClass)) -+ -+typedef struct _RygelLMSImageYear RygelLMSImageYear; -+typedef struct _RygelLMSImageYearClass RygelLMSImageYearClass; -+typedef struct _RygelLMSImageYearPrivate RygelLMSImageYearPrivate; -+#define _g_free0(var) (var = (g_free (var), NULL)) -+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) -+ -+#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) -+#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) -+#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+ -+typedef struct _RygelLMSDatabase RygelLMSDatabase; -+typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; -+ -+struct _RygelLMSCategoryContainer { -+ RygelMediaContainer parent_instance; -+ RygelLMSCategoryContainerPrivate * priv; -+ sqlite3_stmt* stmt_all; -+ sqlite3_stmt* stmt_find_object; -+ sqlite3_stmt* stmt_added; -+ sqlite3_stmt* stmt_removed; -+ gchar* child_prefix; -+ gchar* ref_prefix; -+}; -+ -+struct _RygelLMSCategoryContainerClass { -+ RygelMediaContainerClass parent_class; -+ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); -+ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); -+ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); -+}; -+ -+struct _RygelLMSImageYear { -+ RygelLMSCategoryContainer parent_instance; -+ RygelLMSImageYearPrivate * priv; -+}; -+ -+struct _RygelLMSImageYearClass { -+ RygelLMSCategoryContainerClass parent_class; -+}; -+ -+ -+static gpointer rygel_lms_image_year_parent_class = NULL; -+ -+GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; -+GType rygel_lms_image_year_get_type (void) G_GNUC_CONST; -+enum { -+ RYGEL_LMS_IMAGE_YEAR_DUMMY_PROPERTY -+}; -+#define RYGEL_LMS_IMAGE_YEAR_SQL_ALL_TEMPLATE "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ -+"_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id AND year = '%s' " "LIMIT ? OFFSET ?;" -+#define RYGEL_LMS_IMAGE_YEAR_SQL_COUNT_TEMPLATE "SELECT count(images.id), strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id AND year = '%s';" -+#define RYGEL_LMS_IMAGE_YEAR_SQL_FIND_OBJECT_TEMPLATE "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ -+"_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime = 0 AND files.id = ? AND images.id = files.id AND year = '" \ -+"%s';" -+#define RYGEL_LMS_IMAGE_YEAR_SQL_ADDED_TEMPLATE "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ -+"_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id AND year = '%s' " "AND update_id > ? AND update_id <= ?;" -+#define RYGEL_LMS_IMAGE_YEAR_SQL_REMOVED_TEMPLATE "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ -+"_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime <> 0 AND images.id = files.id AND year = '%s' " "AND update_id > ? AND update_id <= ?;" -+static RygelMediaObject* rygel_lms_image_year_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); -+gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id); -+gchar* rygel_lms_category_container_build_reference_id (RygelLMSCategoryContainer* self, gint db_id); -+static gchar* rygel_lms_image_year_get_sql_all (const gchar* year); -+static gchar* rygel_lms_image_year_get_sql_find_object (const gchar* year); -+static gchar* rygel_lms_image_year_get_sql_count (const gchar* year); -+static gchar* rygel_lms_image_year_get_sql_added (const gchar* year); -+static gchar* rygel_lms_image_year_get_sql_removed (const gchar* year); -+gpointer rygel_lms_database_ref (gpointer instance); -+void rygel_lms_database_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_database (GValue* value, gpointer v_object); -+void rygel_lms_value_take_database (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_database (const GValue* value); -+GType rygel_lms_database_get_type (void) G_GNUC_CONST; -+RygelLMSImageYear* rygel_lms_image_year_new (RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db); -+RygelLMSImageYear* rygel_lms_image_year_construct (GType object_type, RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db); -+RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); -+ -+ -+static RygelMediaObject* rygel_lms_image_year_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { -+ RygelLMSImageYear * self; -+ RygelMediaObject* result = NULL; -+ gint id = 0; -+ sqlite3_stmt* _tmp0_ = NULL; -+ gint _tmp1_ = 0; -+ gchar* path = NULL; -+ sqlite3_stmt* _tmp2_ = NULL; -+ const gchar* _tmp3_ = NULL; -+ gchar* _tmp4_ = NULL; -+ gchar* mime_type = NULL; -+ sqlite3_stmt* _tmp5_ = NULL; -+ const gchar* _tmp6_ = NULL; -+ gchar* _tmp7_ = NULL; -+ gboolean _tmp8_ = FALSE; -+ const gchar* _tmp9_ = NULL; -+ gchar* title = NULL; -+ sqlite3_stmt* _tmp15_ = NULL; -+ const gchar* _tmp16_ = NULL; -+ gchar* _tmp17_ = NULL; -+ RygelImageItem* image = NULL; -+ gint _tmp18_ = 0; -+ gchar* _tmp19_ = NULL; -+ gchar* _tmp20_ = NULL; -+ RygelImageItem* _tmp21_ = NULL; -+ RygelImageItem* _tmp22_ = NULL; -+ gint _tmp23_ = 0; -+ gchar* _tmp24_ = NULL; -+ gchar* _tmp25_ = NULL; -+ sqlite3_stmt* _tmp26_ = NULL; -+ const gchar* _tmp27_ = NULL; -+ GTimeVal tv = {0}; -+ sqlite3_stmt* _tmp28_ = NULL; -+ gint _tmp29_ = 0; -+ GTimeVal _tmp30_ = {0}; -+ gchar* _tmp31_ = NULL; -+ gchar* _tmp32_ = NULL; -+ sqlite3_stmt* _tmp33_ = NULL; -+ gint _tmp34_ = 0; -+ sqlite3_stmt* _tmp35_ = NULL; -+ gint _tmp36_ = 0; -+ sqlite3_stmt* _tmp37_ = NULL; -+ gint _tmp38_ = 0; -+ const gchar* _tmp39_ = NULL; -+ sqlite3_stmt* _tmp40_ = NULL; -+ const gchar* _tmp41_ = NULL; -+ GFile* file = NULL; -+ const gchar* _tmp42_ = NULL; -+ GFile* _tmp43_ = NULL; -+ gchar* _tmp44_ = NULL; -+ gchar* _tmp45_ = NULL; -+ self = (RygelLMSImageYear*) base; -+ g_return_val_if_fail (statement != NULL, NULL); -+ _tmp0_ = statement; -+ _tmp1_ = sqlite3_column_int (_tmp0_, 0); -+ id = _tmp1_; -+ _tmp2_ = statement; -+ _tmp3_ = sqlite3_column_text (_tmp2_, 6); -+ _tmp4_ = g_strdup (_tmp3_); -+ path = _tmp4_; -+ _tmp5_ = statement; -+ _tmp6_ = sqlite3_column_text (_tmp5_, 9); -+ _tmp7_ = g_strdup (_tmp6_); -+ mime_type = _tmp7_; -+ _tmp9_ = mime_type; -+ if (_tmp9_ == NULL) { -+ _tmp8_ = TRUE; -+ } else { -+ const gchar* _tmp10_ = NULL; -+ gint _tmp11_ = 0; -+ gint _tmp12_ = 0; -+ _tmp10_ = mime_type; -+ _tmp11_ = strlen (_tmp10_); -+ _tmp12_ = _tmp11_; -+ _tmp8_ = _tmp12_ == 0; -+ } -+ if (_tmp8_) { -+ gint _tmp13_ = 0; -+ const gchar* _tmp14_ = NULL; -+ _tmp13_ = id; -+ _tmp14_ = path; -+ g_debug ("rygel-lms-image-year.vala:62: Image item %d (%s) has no MIME type", _tmp13_, _tmp14_); -+ } -+ _tmp15_ = statement; -+ _tmp16_ = sqlite3_column_text (_tmp15_, 1); -+ _tmp17_ = g_strdup (_tmp16_); -+ title = _tmp17_; -+ _tmp18_ = id; -+ _tmp19_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp18_); -+ _tmp20_ = _tmp19_; -+ _tmp21_ = rygel_image_item_new (_tmp20_, (RygelMediaContainer*) self, title, RYGEL_IMAGE_ITEM_UPNP_CLASS); -+ _tmp22_ = _tmp21_; -+ _g_free0 (_tmp20_); -+ image = _tmp22_; -+ _tmp23_ = id; -+ _tmp24_ = rygel_lms_category_container_build_reference_id ((RygelLMSCategoryContainer*) self, _tmp23_); -+ _tmp25_ = _tmp24_; -+ rygel_media_object_set_ref_id ((RygelMediaObject*) image, _tmp25_); -+ _g_free0 (_tmp25_); -+ _tmp26_ = statement; -+ _tmp27_ = sqlite3_column_text (_tmp26_, 2); -+ rygel_media_object_set_creator ((RygelMediaObject*) image, _tmp27_); -+ _tmp28_ = statement; -+ _tmp29_ = sqlite3_column_int (_tmp28_, 3); -+ _tmp30_.tv_sec = (glong) _tmp29_; -+ _tmp30_.tv_usec = (glong) 0; -+ tv = _tmp30_; -+ _tmp31_ = g_time_val_to_iso8601 (&tv); -+ _tmp32_ = _tmp31_; -+ rygel_media_object_set_date ((RygelMediaObject*) image, _tmp32_); -+ _g_free0 (_tmp32_); -+ _tmp33_ = statement; -+ _tmp34_ = sqlite3_column_int (_tmp33_, 4); -+ rygel_visual_item_set_width ((RygelVisualItem*) image, _tmp34_); -+ _tmp35_ = statement; -+ _tmp36_ = sqlite3_column_int (_tmp35_, 5); -+ rygel_visual_item_set_height ((RygelVisualItem*) image, _tmp36_); -+ _tmp37_ = statement; -+ _tmp38_ = sqlite3_column_int (_tmp37_, 7); -+ rygel_media_file_item_set_size ((RygelMediaFileItem*) image, (gint64) _tmp38_); -+ _tmp39_ = mime_type; -+ rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) image, _tmp39_); -+ _tmp40_ = statement; -+ _tmp41_ = sqlite3_column_text (_tmp40_, 8); -+ rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) image, _tmp41_); -+ _tmp42_ = path; -+ _tmp43_ = g_file_new_for_path (_tmp42_); -+ file = _tmp43_; -+ _tmp44_ = g_file_get_uri (file); -+ _tmp45_ = _tmp44_; -+ rygel_media_object_add_uri ((RygelMediaObject*) image, _tmp45_); -+ _g_free0 (_tmp45_); -+ result = (RygelMediaObject*) image; -+ _g_object_unref0 (file); -+ _g_free0 (title); -+ _g_free0 (mime_type); -+ _g_free0 (path); -+ return result; -+} -+ -+ -+static gchar* rygel_lms_image_year_get_sql_all (const gchar* year) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (year != NULL, NULL); -+ _tmp0_ = year; -+ _tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_ALL_TEMPLATE, _tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+static gchar* rygel_lms_image_year_get_sql_find_object (const gchar* year) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (year != NULL, NULL); -+ _tmp0_ = year; -+ _tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_FIND_OBJECT_TEMPLATE, _tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+static gchar* rygel_lms_image_year_get_sql_count (const gchar* year) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (year != NULL, NULL); -+ _tmp0_ = year; -+ _tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_COUNT_TEMPLATE, _tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+static gchar* rygel_lms_image_year_get_sql_added (const gchar* year) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (year != NULL, NULL); -+ _tmp0_ = year; -+ _tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_ADDED_TEMPLATE, _tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+static gchar* rygel_lms_image_year_get_sql_removed (const gchar* year) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (year != NULL, NULL); -+ _tmp0_ = year; -+ _tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_REMOVED_TEMPLATE, _tmp0_); -+ result = _tmp1_; -+ return result; -+} -+ -+ -+RygelLMSImageYear* rygel_lms_image_year_construct (GType object_type, RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db) { -+ RygelLMSImageYear * self = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ gchar* _tmp2_ = NULL; -+ RygelMediaContainer* _tmp3_ = NULL; -+ const gchar* _tmp4_ = NULL; -+ RygelLMSDatabase* _tmp5_ = NULL; -+ const gchar* _tmp6_ = NULL; -+ gchar* _tmp7_ = NULL; -+ gchar* _tmp8_ = NULL; -+ const gchar* _tmp9_ = NULL; -+ gchar* _tmp10_ = NULL; -+ gchar* _tmp11_ = NULL; -+ const gchar* _tmp12_ = NULL; -+ gchar* _tmp13_ = NULL; -+ gchar* _tmp14_ = NULL; -+ const gchar* _tmp15_ = NULL; -+ gchar* _tmp16_ = NULL; -+ gchar* _tmp17_ = NULL; -+ const gchar* _tmp18_ = NULL; -+ gchar* _tmp19_ = NULL; -+ gchar* _tmp20_ = NULL; -+ g_return_val_if_fail (parent != NULL, NULL); -+ g_return_val_if_fail (year != NULL, NULL); -+ g_return_val_if_fail (lms_db != NULL, NULL); -+ _tmp0_ = year; -+ _tmp1_ = g_strdup_printf ("%s", _tmp0_); -+ _tmp2_ = _tmp1_; -+ _tmp3_ = parent; -+ _tmp4_ = year; -+ _tmp5_ = lms_db; -+ _tmp6_ = year; -+ _tmp7_ = rygel_lms_image_year_get_sql_all (_tmp6_); -+ _tmp8_ = _tmp7_; -+ _tmp9_ = year; -+ _tmp10_ = rygel_lms_image_year_get_sql_find_object (_tmp9_); -+ _tmp11_ = _tmp10_; -+ _tmp12_ = year; -+ _tmp13_ = rygel_lms_image_year_get_sql_count (_tmp12_); -+ _tmp14_ = _tmp13_; -+ _tmp15_ = year; -+ _tmp16_ = rygel_lms_image_year_get_sql_added (_tmp15_); -+ _tmp17_ = _tmp16_; -+ _tmp18_ = year; -+ _tmp19_ = rygel_lms_image_year_get_sql_removed (_tmp18_); -+ _tmp20_ = _tmp19_; -+ self = (RygelLMSImageYear*) rygel_lms_category_container_construct (object_type, _tmp2_, _tmp3_, _tmp4_, _tmp5_, _tmp8_, _tmp11_, _tmp14_, _tmp17_, _tmp20_); -+ _g_free0 (_tmp20_); -+ _g_free0 (_tmp17_); -+ _g_free0 (_tmp14_); -+ _g_free0 (_tmp11_); -+ _g_free0 (_tmp8_); -+ _g_free0 (_tmp2_); -+ return self; -+} -+ -+ -+RygelLMSImageYear* rygel_lms_image_year_new (RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db) { -+ return rygel_lms_image_year_construct (RYGEL_LMS_TYPE_IMAGE_YEAR, parent, year, lms_db); -+} -+ -+ -+static void rygel_lms_image_year_class_init (RygelLMSImageYearClass * klass) { -+ rygel_lms_image_year_parent_class = g_type_class_peek_parent (klass); -+ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_image_year_real_object_from_statement; -+} -+ -+ -+static void rygel_lms_image_year_instance_init (RygelLMSImageYear * self) { -+} -+ -+ -+GType rygel_lms_image_year_get_type (void) { -+ static volatile gsize rygel_lms_image_year_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_image_year_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSImageYearClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_image_year_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSImageYear), 0, (GInstanceInitFunc) rygel_lms_image_year_instance_init, NULL }; -+ GType rygel_lms_image_year_type_id; -+ rygel_lms_image_year_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSImageYear", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_image_year_type_id__volatile, rygel_lms_image_year_type_id); -+ } -+ return rygel_lms_image_year_type_id__volatile; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-image-years.c b/src/plugins/lms/rygel-lms-image-years.c -new file mode 100644 -index 0000000..35033a0 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-image-years.c -@@ -0,0 +1,196 @@ -+/* rygel-lms-image-years.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-image-years.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-server.h> -+#include <sqlite3.h> -+#include <stdlib.h> -+#include <string.h> -+#include <glib/gi18n-lib.h> -+ -+ -+#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) -+#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+ -+typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; -+typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; -+typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; -+ -+#define RYGEL_LMS_TYPE_IMAGE_YEARS (rygel_lms_image_years_get_type ()) -+#define RYGEL_LMS_IMAGE_YEARS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYears)) -+#define RYGEL_LMS_IMAGE_YEARS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYearsClass)) -+#define RYGEL_LMS_IS_IMAGE_YEARS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS)) -+#define RYGEL_LMS_IS_IMAGE_YEARS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_YEARS)) -+#define RYGEL_LMS_IMAGE_YEARS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYearsClass)) -+ -+typedef struct _RygelLMSImageYears RygelLMSImageYears; -+typedef struct _RygelLMSImageYearsClass RygelLMSImageYearsClass; -+typedef struct _RygelLMSImageYearsPrivate RygelLMSImageYearsPrivate; -+ -+#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) -+#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) -+#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+ -+typedef struct _RygelLMSDatabase RygelLMSDatabase; -+typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; -+ -+#define RYGEL_LMS_TYPE_IMAGE_YEAR (rygel_lms_image_year_get_type ()) -+#define RYGEL_LMS_IMAGE_YEAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYear)) -+#define RYGEL_LMS_IMAGE_YEAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYearClass)) -+#define RYGEL_LMS_IS_IMAGE_YEAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR)) -+#define RYGEL_LMS_IS_IMAGE_YEAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_YEAR)) -+#define RYGEL_LMS_IMAGE_YEAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYearClass)) -+ -+typedef struct _RygelLMSImageYear RygelLMSImageYear; -+typedef struct _RygelLMSImageYearClass RygelLMSImageYearClass; -+ -+struct _RygelLMSCategoryContainer { -+ RygelMediaContainer parent_instance; -+ RygelLMSCategoryContainerPrivate * priv; -+ sqlite3_stmt* stmt_all; -+ sqlite3_stmt* stmt_find_object; -+ sqlite3_stmt* stmt_added; -+ sqlite3_stmt* stmt_removed; -+ gchar* child_prefix; -+ gchar* ref_prefix; -+}; -+ -+struct _RygelLMSCategoryContainerClass { -+ RygelMediaContainerClass parent_class; -+ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); -+ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); -+ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); -+ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); -+}; -+ -+struct _RygelLMSImageYears { -+ RygelLMSCategoryContainer parent_instance; -+ RygelLMSImageYearsPrivate * priv; -+}; -+ -+struct _RygelLMSImageYearsClass { -+ RygelLMSCategoryContainerClass parent_class; -+}; -+ -+ -+static gpointer rygel_lms_image_years_parent_class = NULL; -+ -+GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; -+GType rygel_lms_image_years_get_type (void) G_GNUC_CONST; -+enum { -+ RYGEL_LMS_IMAGE_YEARS_DUMMY_PROPERTY -+}; -+#define RYGEL_LMS_IMAGE_YEARS_SQL_ALL "SELECT DISTINCT(strftime('%Y', images.date, 'unixepoch')) as year " "FROM images " "LIMIT ? OFFSET ?;" -+#define RYGEL_LMS_IMAGE_YEARS_SQL_COUNT "SELECT COUNT(DISTINCT(strftime('%Y', images.date, 'unixepoch'))) " "FROM images;" -+#define RYGEL_LMS_IMAGE_YEARS_SQL_FIND_OBJECT "SELECT strftime('%Y', images.date, 'unixepoch') as year " "FROM images " "WHERE year = CAST(? AS TEXT)" -+static RygelMediaObject* rygel_lms_image_years_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); -+gpointer rygel_lms_database_ref (gpointer instance); -+void rygel_lms_database_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_database (GValue* value, gpointer v_object); -+void rygel_lms_value_take_database (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_database (const GValue* value); -+GType rygel_lms_database_get_type (void) G_GNUC_CONST; -+RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self); -+RygelLMSImageYear* rygel_lms_image_year_new (RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db); -+RygelLMSImageYear* rygel_lms_image_year_construct (GType object_type, RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db); -+GType rygel_lms_image_year_get_type (void) G_GNUC_CONST; -+RygelLMSImageYears* rygel_lms_image_years_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+RygelLMSImageYears* rygel_lms_image_years_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); -+ -+ -+static RygelMediaObject* rygel_lms_image_years_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { -+ RygelLMSImageYears * self; -+ RygelMediaObject* result = NULL; -+ sqlite3_stmt* _tmp0_ = NULL; -+ const gchar* _tmp1_ = NULL; -+ RygelLMSDatabase* _tmp2_ = NULL; -+ RygelLMSDatabase* _tmp3_ = NULL; -+ RygelLMSImageYear* _tmp4_ = NULL; -+ self = (RygelLMSImageYears*) base; -+ g_return_val_if_fail (statement != NULL, NULL); -+ _tmp0_ = statement; -+ _tmp1_ = sqlite3_column_text (_tmp0_, 0); -+ _tmp2_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); -+ _tmp3_ = _tmp2_; -+ _tmp4_ = rygel_lms_image_year_new ((RygelMediaContainer*) self, _tmp1_, _tmp3_); -+ result = (RygelMediaObject*) _tmp4_; -+ return result; -+} -+ -+ -+RygelLMSImageYears* rygel_lms_image_years_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { -+ RygelLMSImageYears * self = NULL; -+ RygelMediaContainer* _tmp0_ = NULL; -+ const gchar* _tmp1_ = NULL; -+ RygelLMSDatabase* _tmp2_ = NULL; -+ g_return_val_if_fail (parent != NULL, NULL); -+ g_return_val_if_fail (lms_db != NULL, NULL); -+ _tmp0_ = parent; -+ _tmp1_ = _ ("Years"); -+ _tmp2_ = lms_db; -+ self = (RygelLMSImageYears*) rygel_lms_category_container_construct (object_type, "years", _tmp0_, _tmp1_, _tmp2_, RYGEL_LMS_IMAGE_YEARS_SQL_ALL, RYGEL_LMS_IMAGE_YEARS_SQL_FIND_OBJECT, RYGEL_LMS_IMAGE_YEARS_SQL_COUNT, NULL, NULL); -+ return self; -+} -+ -+ -+RygelLMSImageYears* rygel_lms_image_years_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { -+ return rygel_lms_image_years_construct (RYGEL_LMS_TYPE_IMAGE_YEARS, parent, lms_db); -+} -+ -+ -+static void rygel_lms_image_years_class_init (RygelLMSImageYearsClass * klass) { -+ rygel_lms_image_years_parent_class = g_type_class_peek_parent (klass); -+ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_image_years_real_object_from_statement; -+} -+ -+ -+static void rygel_lms_image_years_instance_init (RygelLMSImageYears * self) { -+} -+ -+ -+GType rygel_lms_image_years_get_type (void) { -+ static volatile gsize rygel_lms_image_years_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_image_years_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSImageYearsClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_image_years_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSImageYears), 0, (GInstanceInitFunc) rygel_lms_image_years_instance_init, NULL }; -+ GType rygel_lms_image_years_type_id; -+ rygel_lms_image_years_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSImageYears", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_image_years_type_id__volatile, rygel_lms_image_years_type_id); -+ } -+ return rygel_lms_image_years_type_id__volatile; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-music-root.c b/src/plugins/lms/rygel-lms-music-root.c -new file mode 100644 -index 0000000..753906d ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-music-root.c -@@ -0,0 +1,202 @@ -+/* rygel-lms-music-root.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-music-root.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-server.h> -+#include <stdlib.h> -+#include <string.h> -+#include <glib/gi18n-lib.h> -+ -+ -+#define RYGEL_LMS_TYPE_MUSIC_ROOT (rygel_lms_music_root_get_type ()) -+#define RYGEL_LMS_MUSIC_ROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRoot)) -+#define RYGEL_LMS_MUSIC_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRootClass)) -+#define RYGEL_LMS_IS_MUSIC_ROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT)) -+#define RYGEL_LMS_IS_MUSIC_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_MUSIC_ROOT)) -+#define RYGEL_LMS_MUSIC_ROOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRootClass)) -+ -+typedef struct _RygelLMSMusicRoot RygelLMSMusicRoot; -+typedef struct _RygelLMSMusicRootClass RygelLMSMusicRootClass; -+typedef struct _RygelLMSMusicRootPrivate RygelLMSMusicRootPrivate; -+ -+#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) -+#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) -+#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+ -+typedef struct _RygelLMSDatabase RygelLMSDatabase; -+typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; -+ -+#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) -+#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+ -+typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; -+typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; -+ -+#define RYGEL_LMS_TYPE_ALL_MUSIC (rygel_lms_all_music_get_type ()) -+#define RYGEL_LMS_ALL_MUSIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusic)) -+#define RYGEL_LMS_ALL_MUSIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusicClass)) -+#define RYGEL_LMS_IS_ALL_MUSIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_MUSIC)) -+#define RYGEL_LMS_IS_ALL_MUSIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_MUSIC)) -+#define RYGEL_LMS_ALL_MUSIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusicClass)) -+ -+typedef struct _RygelLMSAllMusic RygelLMSAllMusic; -+typedef struct _RygelLMSAllMusicClass RygelLMSAllMusicClass; -+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) -+ -+#define RYGEL_LMS_TYPE_ARTISTS (rygel_lms_artists_get_type ()) -+#define RYGEL_LMS_ARTISTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtists)) -+#define RYGEL_LMS_ARTISTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtistsClass)) -+#define RYGEL_LMS_IS_ARTISTS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ARTISTS)) -+#define RYGEL_LMS_IS_ARTISTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ARTISTS)) -+#define RYGEL_LMS_ARTISTS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtistsClass)) -+ -+typedef struct _RygelLMSArtists RygelLMSArtists; -+typedef struct _RygelLMSArtistsClass RygelLMSArtistsClass; -+ -+#define RYGEL_LMS_TYPE_ALBUMS (rygel_lms_albums_get_type ()) -+#define RYGEL_LMS_ALBUMS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbums)) -+#define RYGEL_LMS_ALBUMS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbumsClass)) -+#define RYGEL_LMS_IS_ALBUMS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUMS)) -+#define RYGEL_LMS_IS_ALBUMS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUMS)) -+#define RYGEL_LMS_ALBUMS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbumsClass)) -+ -+typedef struct _RygelLMSAlbums RygelLMSAlbums; -+typedef struct _RygelLMSAlbumsClass RygelLMSAlbumsClass; -+ -+struct _RygelLMSMusicRoot { -+ RygelSimpleContainer parent_instance; -+ RygelLMSMusicRootPrivate * priv; -+}; -+ -+struct _RygelLMSMusicRootClass { -+ RygelSimpleContainerClass parent_class; -+}; -+ -+ -+static gpointer rygel_lms_music_root_parent_class = NULL; -+ -+GType rygel_lms_music_root_get_type (void) G_GNUC_CONST; -+enum { -+ RYGEL_LMS_MUSIC_ROOT_DUMMY_PROPERTY -+}; -+gpointer rygel_lms_database_ref (gpointer instance); -+void rygel_lms_database_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_database (GValue* value, gpointer v_object); -+void rygel_lms_value_take_database (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_database (const GValue* value); -+GType rygel_lms_database_get_type (void) G_GNUC_CONST; -+RygelLMSMusicRoot* rygel_lms_music_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSMusicRoot* rygel_lms_music_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSAllMusic* rygel_lms_all_music_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+RygelLMSAllMusic* rygel_lms_all_music_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; -+GType rygel_lms_all_music_get_type (void) G_GNUC_CONST; -+RygelLMSArtists* rygel_lms_artists_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSArtists* rygel_lms_artists_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+GType rygel_lms_artists_get_type (void) G_GNUC_CONST; -+RygelLMSAlbums* rygel_lms_albums_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+RygelLMSAlbums* rygel_lms_albums_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); -+GType rygel_lms_albums_get_type (void) G_GNUC_CONST; -+ -+ -+RygelLMSMusicRoot* rygel_lms_music_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { -+ RygelLMSMusicRoot * self = NULL; -+ const gchar* _tmp0_ = NULL; -+ RygelMediaContainer* _tmp1_ = NULL; -+ const gchar* _tmp2_ = NULL; -+ RygelLMSDatabase* _tmp3_ = NULL; -+ RygelLMSAllMusic* _tmp4_ = NULL; -+ RygelLMSAllMusic* _tmp5_ = NULL; -+ const gchar* _tmp6_ = NULL; -+ RygelLMSDatabase* _tmp7_ = NULL; -+ RygelLMSArtists* _tmp8_ = NULL; -+ RygelLMSArtists* _tmp9_ = NULL; -+ RygelLMSDatabase* _tmp10_ = NULL; -+ RygelLMSAlbums* _tmp11_ = NULL; -+ RygelLMSAlbums* _tmp12_ = NULL; -+ g_return_val_if_fail (id != NULL, NULL); -+ g_return_val_if_fail (parent != NULL, NULL); -+ g_return_val_if_fail (title != NULL, NULL); -+ g_return_val_if_fail (lms_db != NULL, NULL); -+ _tmp0_ = id; -+ _tmp1_ = parent; -+ _tmp2_ = title; -+ self = (RygelLMSMusicRoot*) rygel_simple_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_); -+ _tmp3_ = lms_db; -+ _tmp4_ = rygel_lms_all_music_new ((RygelMediaContainer*) self, _tmp3_); -+ _tmp5_ = _tmp4_; -+ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp5_); -+ _g_object_unref0 (_tmp5_); -+ _tmp6_ = _ ("Artists"); -+ _tmp7_ = lms_db; -+ _tmp8_ = rygel_lms_artists_new ("artists", (RygelMediaContainer*) self, _tmp6_, _tmp7_); -+ _tmp9_ = _tmp8_; -+ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp9_); -+ _g_object_unref0 (_tmp9_); -+ _tmp10_ = lms_db; -+ _tmp11_ = rygel_lms_albums_new ((RygelMediaContainer*) self, _tmp10_); -+ _tmp12_ = _tmp11_; -+ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp12_); -+ _g_object_unref0 (_tmp12_); -+ return self; -+} -+ -+ -+RygelLMSMusicRoot* rygel_lms_music_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { -+ return rygel_lms_music_root_construct (RYGEL_LMS_TYPE_MUSIC_ROOT, id, parent, title, lms_db); -+} -+ -+ -+static void rygel_lms_music_root_class_init (RygelLMSMusicRootClass * klass) { -+ rygel_lms_music_root_parent_class = g_type_class_peek_parent (klass); -+} -+ -+ -+static void rygel_lms_music_root_instance_init (RygelLMSMusicRoot * self) { -+} -+ -+ -+GType rygel_lms_music_root_get_type (void) { -+ static volatile gsize rygel_lms_music_root_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_music_root_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSMusicRootClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_music_root_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSMusicRoot), 0, (GInstanceInitFunc) rygel_lms_music_root_instance_init, NULL }; -+ GType rygel_lms_music_root_type_id; -+ rygel_lms_music_root_type_id = g_type_register_static (RYGEL_TYPE_SIMPLE_CONTAINER, "RygelLMSMusicRoot", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_music_root_type_id__volatile, rygel_lms_music_root_type_id); -+ } -+ return rygel_lms_music_root_type_id__volatile; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-plugin-factory.c b/src/plugins/lms/rygel-lms-plugin-factory.c -new file mode 100644 -index 0000000..de4a5ab ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-plugin-factory.c -@@ -0,0 +1,307 @@ -+/* rygel-lms-plugin-factory.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-plugin-factory.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-core.h> -+#include <rygel-server.h> -+#include <gobject/gvaluecollector.h> -+ -+ -+#define RYGEL_LMS_TYPE_PLUGIN_FACTORY (rygel_lms_plugin_factory_get_type ()) -+#define RYGEL_LMS_PLUGIN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactory)) -+#define RYGEL_LMS_PLUGIN_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactoryClass)) -+#define RYGEL_LMS_IS_PLUGIN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_PLUGIN_FACTORY)) -+#define RYGEL_LMS_IS_PLUGIN_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_PLUGIN_FACTORY)) -+#define RYGEL_LMS_PLUGIN_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactoryClass)) -+ -+typedef struct _RygelLMSPluginFactory RygelLMSPluginFactory; -+typedef struct _RygelLMSPluginFactoryClass RygelLMSPluginFactoryClass; -+#define _rygel_lms_plugin_factory_unref0(var) ((var == NULL) ? NULL : (var = (rygel_lms_plugin_factory_unref (var), NULL))) -+typedef struct _RygelLMSPluginFactoryPrivate RygelLMSPluginFactoryPrivate; -+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) -+ -+#define RYGEL_LMS_TYPE_PLUGIN (rygel_lms_plugin_get_type ()) -+#define RYGEL_LMS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPlugin)) -+#define RYGEL_LMS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPluginClass)) -+#define RYGEL_LMS_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_PLUGIN)) -+#define RYGEL_LMS_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_PLUGIN)) -+#define RYGEL_LMS_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPluginClass)) -+ -+typedef struct _RygelLMSPlugin RygelLMSPlugin; -+typedef struct _RygelLMSPluginClass RygelLMSPluginClass; -+typedef struct _RygelLMSParamSpecPluginFactory RygelLMSParamSpecPluginFactory; -+ -+struct _RygelLMSPluginFactory { -+ GTypeInstance parent_instance; -+ volatile int ref_count; -+ RygelLMSPluginFactoryPrivate * priv; -+}; -+ -+struct _RygelLMSPluginFactoryClass { -+ GTypeClass parent_class; -+ void (*finalize) (RygelLMSPluginFactory *self); -+}; -+ -+struct _RygelLMSPluginFactoryPrivate { -+ RygelPluginLoader* loader; -+}; -+ -+struct _RygelLMSParamSpecPluginFactory { -+ GParamSpec parent_instance; -+}; -+ -+ -+extern RygelLMSPluginFactory* plugin_factory; -+RygelLMSPluginFactory* plugin_factory = NULL; -+static gpointer rygel_lms_plugin_factory_parent_class = NULL; -+ -+gpointer rygel_lms_plugin_factory_ref (gpointer instance); -+void rygel_lms_plugin_factory_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_plugin_factory (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_plugin_factory (GValue* value, gpointer v_object); -+void rygel_lms_value_take_plugin_factory (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_plugin_factory (const GValue* value); -+GType rygel_lms_plugin_factory_get_type (void) G_GNUC_CONST; -+void module_init (RygelPluginLoader* loader); -+RygelLMSPluginFactory* rygel_lms_plugin_factory_new (RygelPluginLoader* loader); -+RygelLMSPluginFactory* rygel_lms_plugin_factory_construct (GType object_type, RygelPluginLoader* loader); -+#define RYGEL_LMS_PLUGIN_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactoryPrivate)) -+enum { -+ RYGEL_LMS_PLUGIN_FACTORY_DUMMY_PROPERTY -+}; -+RygelLMSPlugin* rygel_lms_plugin_new (void); -+RygelLMSPlugin* rygel_lms_plugin_construct (GType object_type); -+GType rygel_lms_plugin_get_type (void) G_GNUC_CONST; -+static void rygel_lms_plugin_factory_finalize (RygelLMSPluginFactory* obj); -+ -+ -+void module_init (RygelPluginLoader* loader) { -+ RygelPluginLoader* _tmp0_ = NULL; -+ RygelLMSPluginFactory* _tmp1_ = NULL; -+ g_return_if_fail (loader != NULL); -+ _tmp0_ = loader; -+ _tmp1_ = rygel_lms_plugin_factory_new (_tmp0_); -+ _rygel_lms_plugin_factory_unref0 (plugin_factory); -+ plugin_factory = _tmp1_; -+} -+ -+ -+static gpointer _g_object_ref0 (gpointer self) { -+ return self ? g_object_ref (self) : NULL; -+} -+ -+ -+RygelLMSPluginFactory* rygel_lms_plugin_factory_construct (GType object_type, RygelPluginLoader* loader) { -+ RygelLMSPluginFactory* self = NULL; -+ RygelPluginLoader* _tmp0_ = NULL; -+ RygelPluginLoader* _tmp1_ = NULL; -+ RygelPluginLoader* _tmp2_ = NULL; -+ RygelLMSPlugin* _tmp3_ = NULL; -+ RygelLMSPlugin* _tmp4_ = NULL; -+ g_return_val_if_fail (loader != NULL, NULL); -+ self = (RygelLMSPluginFactory*) g_type_create_instance (object_type); -+ _tmp0_ = loader; -+ _tmp1_ = _g_object_ref0 (_tmp0_); -+ _g_object_unref0 (self->priv->loader); -+ self->priv->loader = _tmp1_; -+ _tmp2_ = self->priv->loader; -+ _tmp3_ = rygel_lms_plugin_new (); -+ _tmp4_ = _tmp3_; -+ rygel_plugin_loader_add_plugin (_tmp2_, (RygelPlugin*) _tmp4_); -+ _g_object_unref0 (_tmp4_); -+ return self; -+} -+ -+ -+RygelLMSPluginFactory* rygel_lms_plugin_factory_new (RygelPluginLoader* loader) { -+ return rygel_lms_plugin_factory_construct (RYGEL_LMS_TYPE_PLUGIN_FACTORY, loader); -+} -+ -+ -+static void rygel_lms_value_plugin_factory_init (GValue* value) { -+ value->data[0].v_pointer = NULL; -+} -+ -+ -+static void rygel_lms_value_plugin_factory_free_value (GValue* value) { -+ if (value->data[0].v_pointer) { -+ rygel_lms_plugin_factory_unref (value->data[0].v_pointer); -+ } -+} -+ -+ -+static void rygel_lms_value_plugin_factory_copy_value (const GValue* src_value, GValue* dest_value) { -+ if (src_value->data[0].v_pointer) { -+ dest_value->data[0].v_pointer = rygel_lms_plugin_factory_ref (src_value->data[0].v_pointer); -+ } else { -+ dest_value->data[0].v_pointer = NULL; -+ } -+} -+ -+ -+static gpointer rygel_lms_value_plugin_factory_peek_pointer (const GValue* value) { -+ return value->data[0].v_pointer; -+} -+ -+ -+static gchar* rygel_lms_value_plugin_factory_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) { -+ if (collect_values[0].v_pointer) { -+ RygelLMSPluginFactory* object; -+ object = collect_values[0].v_pointer; -+ if (object->parent_instance.g_class == NULL) { -+ return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL); -+ } else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) { -+ return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL); -+ } -+ value->data[0].v_pointer = rygel_lms_plugin_factory_ref (object); -+ } else { -+ value->data[0].v_pointer = NULL; -+ } -+ return NULL; -+} -+ -+ -+static gchar* rygel_lms_value_plugin_factory_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) { -+ RygelLMSPluginFactory** object_p; -+ object_p = collect_values[0].v_pointer; -+ if (!object_p) { -+ return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); -+ } -+ if (!value->data[0].v_pointer) { -+ *object_p = NULL; -+ } else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) { -+ *object_p = value->data[0].v_pointer; -+ } else { -+ *object_p = rygel_lms_plugin_factory_ref (value->data[0].v_pointer); -+ } -+ return NULL; -+} -+ -+ -+GParamSpec* rygel_lms_param_spec_plugin_factory (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) { -+ RygelLMSParamSpecPluginFactory* spec; -+ g_return_val_if_fail (g_type_is_a (object_type, RYGEL_LMS_TYPE_PLUGIN_FACTORY), NULL); -+ spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags); -+ G_PARAM_SPEC (spec)->value_type = object_type; -+ return G_PARAM_SPEC (spec); -+} -+ -+ -+gpointer rygel_lms_value_get_plugin_factory (const GValue* value) { -+ g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_PLUGIN_FACTORY), NULL); -+ return value->data[0].v_pointer; -+} -+ -+ -+void rygel_lms_value_set_plugin_factory (GValue* value, gpointer v_object) { -+ RygelLMSPluginFactory* old; -+ g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_PLUGIN_FACTORY)); -+ old = value->data[0].v_pointer; -+ if (v_object) { -+ g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RYGEL_LMS_TYPE_PLUGIN_FACTORY)); -+ g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); -+ value->data[0].v_pointer = v_object; -+ rygel_lms_plugin_factory_ref (value->data[0].v_pointer); -+ } else { -+ value->data[0].v_pointer = NULL; -+ } -+ if (old) { -+ rygel_lms_plugin_factory_unref (old); -+ } -+} -+ -+ -+void rygel_lms_value_take_plugin_factory (GValue* value, gpointer v_object) { -+ RygelLMSPluginFactory* old; -+ g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_PLUGIN_FACTORY)); -+ old = value->data[0].v_pointer; -+ if (v_object) { -+ g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RYGEL_LMS_TYPE_PLUGIN_FACTORY)); -+ g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); -+ value->data[0].v_pointer = v_object; -+ } else { -+ value->data[0].v_pointer = NULL; -+ } -+ if (old) { -+ rygel_lms_plugin_factory_unref (old); -+ } -+} -+ -+ -+static void rygel_lms_plugin_factory_class_init (RygelLMSPluginFactoryClass * klass) { -+ rygel_lms_plugin_factory_parent_class = g_type_class_peek_parent (klass); -+ ((RygelLMSPluginFactoryClass *) klass)->finalize = rygel_lms_plugin_factory_finalize; -+ g_type_class_add_private (klass, sizeof (RygelLMSPluginFactoryPrivate)); -+} -+ -+ -+static void rygel_lms_plugin_factory_instance_init (RygelLMSPluginFactory * self) { -+ self->priv = RYGEL_LMS_PLUGIN_FACTORY_GET_PRIVATE (self); -+ self->ref_count = 1; -+} -+ -+ -+static void rygel_lms_plugin_factory_finalize (RygelLMSPluginFactory* obj) { -+ RygelLMSPluginFactory * self; -+ self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactory); -+ g_signal_handlers_destroy (self); -+ _g_object_unref0 (self->priv->loader); -+} -+ -+ -+GType rygel_lms_plugin_factory_get_type (void) { -+ static volatile gsize rygel_lms_plugin_factory_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_plugin_factory_type_id__volatile)) { -+ static const GTypeValueTable g_define_type_value_table = { rygel_lms_value_plugin_factory_init, rygel_lms_value_plugin_factory_free_value, rygel_lms_value_plugin_factory_copy_value, rygel_lms_value_plugin_factory_peek_pointer, "p", rygel_lms_value_plugin_factory_collect_value, "p", rygel_lms_value_plugin_factory_lcopy_value }; -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSPluginFactoryClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_plugin_factory_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSPluginFactory), 0, (GInstanceInitFunc) rygel_lms_plugin_factory_instance_init, &g_define_type_value_table }; -+ static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }; -+ GType rygel_lms_plugin_factory_type_id; -+ rygel_lms_plugin_factory_type_id = g_type_register_fundamental (g_type_fundamental_next (), "RygelLMSPluginFactory", &g_define_type_info, &g_define_type_fundamental_info, 0); -+ g_once_init_leave (&rygel_lms_plugin_factory_type_id__volatile, rygel_lms_plugin_factory_type_id); -+ } -+ return rygel_lms_plugin_factory_type_id__volatile; -+} -+ -+ -+gpointer rygel_lms_plugin_factory_ref (gpointer instance) { -+ RygelLMSPluginFactory* self; -+ self = instance; -+ g_atomic_int_inc (&self->ref_count); -+ return instance; -+} -+ -+ -+void rygel_lms_plugin_factory_unref (gpointer instance) { -+ RygelLMSPluginFactory* self; -+ self = instance; -+ if (g_atomic_int_dec_and_test (&self->ref_count)) { -+ RYGEL_LMS_PLUGIN_FACTORY_GET_CLASS (self)->finalize (self); -+ g_type_free_instance ((GTypeInstance *) self); -+ } -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-plugin.c b/src/plugins/lms/rygel-lms-plugin.c -new file mode 100644 -index 0000000..980de64 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-plugin.c -@@ -0,0 +1,134 @@ -+/* rygel-lms-plugin.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-plugin.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-server.h> -+#include <stdlib.h> -+#include <string.h> -+#include <rygel-core.h> -+ -+ -+#define RYGEL_LMS_TYPE_PLUGIN (rygel_lms_plugin_get_type ()) -+#define RYGEL_LMS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPlugin)) -+#define RYGEL_LMS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPluginClass)) -+#define RYGEL_LMS_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_PLUGIN)) -+#define RYGEL_LMS_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_PLUGIN)) -+#define RYGEL_LMS_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPluginClass)) -+ -+typedef struct _RygelLMSPlugin RygelLMSPlugin; -+typedef struct _RygelLMSPluginClass RygelLMSPluginClass; -+typedef struct _RygelLMSPluginPrivate RygelLMSPluginPrivate; -+ -+#define RYGEL_LMS_TYPE_ROOT_CONTAINER (rygel_lms_root_container_get_type ()) -+#define RYGEL_LMS_ROOT_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainer)) -+#define RYGEL_LMS_ROOT_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerClass)) -+#define RYGEL_LMS_IS_ROOT_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER)) -+#define RYGEL_LMS_IS_ROOT_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ROOT_CONTAINER)) -+#define RYGEL_LMS_ROOT_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerClass)) -+ -+typedef struct _RygelLMSRootContainer RygelLMSRootContainer; -+typedef struct _RygelLMSRootContainerClass RygelLMSRootContainerClass; -+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) -+ -+struct _RygelLMSPlugin { -+ RygelMediaServerPlugin parent_instance; -+ RygelLMSPluginPrivate * priv; -+}; -+ -+struct _RygelLMSPluginClass { -+ RygelMediaServerPluginClass parent_class; -+}; -+ -+ -+static gpointer rygel_lms_plugin_parent_class = NULL; -+static RygelLMSRootContainer* rygel_lms_plugin_root; -+static RygelLMSRootContainer* rygel_lms_plugin_root = NULL; -+ -+GType rygel_lms_plugin_get_type (void) G_GNUC_CONST; -+enum { -+ RYGEL_LMS_PLUGIN_DUMMY_PROPERTY -+}; -+GType rygel_lms_root_container_get_type (void) G_GNUC_CONST; -+#define RYGEL_LMS_PLUGIN_NAME "LMS" -+RygelLMSPlugin* rygel_lms_plugin_new (void); -+RygelLMSPlugin* rygel_lms_plugin_construct (GType object_type); -+RygelLMSRootContainer* rygel_lms_root_container_new (void); -+RygelLMSRootContainer* rygel_lms_root_container_construct (GType object_type); -+static void rygel_lms_plugin_finalize (GObject* obj); -+ -+ -+RygelLMSPlugin* rygel_lms_plugin_construct (GType object_type) { -+ RygelLMSPlugin * self = NULL; -+ RygelLMSRootContainer* _tmp0_ = NULL; -+ RygelLMSRootContainer* _tmp2_ = NULL; -+ _tmp0_ = rygel_lms_plugin_root; -+ if (_tmp0_ == NULL) { -+ RygelLMSRootContainer* _tmp1_ = NULL; -+ _tmp1_ = rygel_lms_root_container_new (); -+ _g_object_unref0 (rygel_lms_plugin_root); -+ rygel_lms_plugin_root = _tmp1_; -+ } -+ _tmp2_ = rygel_lms_plugin_root; -+ self = (RygelLMSPlugin*) rygel_media_server_plugin_construct (object_type, (RygelMediaContainer*) _tmp2_, RYGEL_LMS_PLUGIN_NAME, NULL, RYGEL_PLUGIN_CAPABILITIES_TRACK_CHANGES); -+ return self; -+} -+ -+ -+RygelLMSPlugin* rygel_lms_plugin_new (void) { -+ return rygel_lms_plugin_construct (RYGEL_LMS_TYPE_PLUGIN); -+} -+ -+ -+static void rygel_lms_plugin_class_init (RygelLMSPluginClass * klass) { -+ rygel_lms_plugin_parent_class = g_type_class_peek_parent (klass); -+ G_OBJECT_CLASS (klass)->finalize = rygel_lms_plugin_finalize; -+} -+ -+ -+static void rygel_lms_plugin_instance_init (RygelLMSPlugin * self) { -+} -+ -+ -+static void rygel_lms_plugin_finalize (GObject* obj) { -+ RygelLMSPlugin * self; -+ self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_PLUGIN, RygelLMSPlugin); -+ G_OBJECT_CLASS (rygel_lms_plugin_parent_class)->finalize (obj); -+} -+ -+ -+GType rygel_lms_plugin_get_type (void) { -+ static volatile gsize rygel_lms_plugin_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_plugin_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSPluginClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_plugin_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSPlugin), 0, (GInstanceInitFunc) rygel_lms_plugin_instance_init, NULL }; -+ GType rygel_lms_plugin_type_id; -+ rygel_lms_plugin_type_id = g_type_register_static (RYGEL_TYPE_MEDIA_SERVER_PLUGIN, "RygelLMSPlugin", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_plugin_type_id__volatile, rygel_lms_plugin_type_id); -+ } -+ return rygel_lms_plugin_type_id__volatile; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-root-container.c b/src/plugins/lms/rygel-lms-root-container.c -new file mode 100644 -index 0000000..625ed2f ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-root-container.c -@@ -0,0 +1,318 @@ -+/* rygel-lms-root-container.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-root-container.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2013 Intel Corporation. -+ * -+ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <rygel-server.h> -+#include <rygel-core.h> -+#include <stdlib.h> -+#include <string.h> -+#include <glib/gi18n-lib.h> -+ -+ -+#define RYGEL_LMS_TYPE_ROOT_CONTAINER (rygel_lms_root_container_get_type ()) -+#define RYGEL_LMS_ROOT_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainer)) -+#define RYGEL_LMS_ROOT_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerClass)) -+#define RYGEL_LMS_IS_ROOT_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER)) -+#define RYGEL_LMS_IS_ROOT_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ROOT_CONTAINER)) -+#define RYGEL_LMS_ROOT_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerClass)) -+ -+typedef struct _RygelLMSRootContainer RygelLMSRootContainer; -+typedef struct _RygelLMSRootContainerClass RygelLMSRootContainerClass; -+typedef struct _RygelLMSRootContainerPrivate RygelLMSRootContainerPrivate; -+ -+#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) -+#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) -+#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) -+#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) -+ -+typedef struct _RygelLMSDatabase RygelLMSDatabase; -+typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; -+#define _rygel_lms_database_unref0(var) ((var == NULL) ? NULL : (var = (rygel_lms_database_unref (var), NULL))) -+#define _g_free0(var) (var = (g_free (var), NULL)) -+#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) -+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) -+ -+#define RYGEL_LMS_TYPE_MUSIC_ROOT (rygel_lms_music_root_get_type ()) -+#define RYGEL_LMS_MUSIC_ROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRoot)) -+#define RYGEL_LMS_MUSIC_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRootClass)) -+#define RYGEL_LMS_IS_MUSIC_ROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT)) -+#define RYGEL_LMS_IS_MUSIC_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_MUSIC_ROOT)) -+#define RYGEL_LMS_MUSIC_ROOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRootClass)) -+ -+typedef struct _RygelLMSMusicRoot RygelLMSMusicRoot; -+typedef struct _RygelLMSMusicRootClass RygelLMSMusicRootClass; -+ -+#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) -+#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) -+#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) -+ -+typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; -+typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; -+ -+#define RYGEL_LMS_TYPE_ALL_VIDEOS (rygel_lms_all_videos_get_type ()) -+#define RYGEL_LMS_ALL_VIDEOS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideos)) -+#define RYGEL_LMS_ALL_VIDEOS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideosClass)) -+#define RYGEL_LMS_IS_ALL_VIDEOS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS)) -+#define RYGEL_LMS_IS_ALL_VIDEOS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_VIDEOS)) -+#define RYGEL_LMS_ALL_VIDEOS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideosClass)) -+ -+typedef struct _RygelLMSAllVideos RygelLMSAllVideos; -+typedef struct _RygelLMSAllVideosClass RygelLMSAllVideosClass; -+ -+#define RYGEL_LMS_TYPE_IMAGE_ROOT (rygel_lms_image_root_get_type ()) -+#define RYGEL_LMS_IMAGE_ROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRoot)) -+#define RYGEL_LMS_IMAGE_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRootClass)) -+#define RYGEL_LMS_IS_IMAGE_ROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT)) -+#define RYGEL_LMS_IS_IMAGE_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_ROOT)) -+#define RYGEL_LMS_IMAGE_ROOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRootClass)) -+ -+typedef struct _RygelLMSImageRoot RygelLMSImageRoot; -+typedef struct _RygelLMSImageRootClass RygelLMSImageRootClass; -+ -+struct _RygelLMSRootContainer { -+ RygelSimpleContainer parent_instance; -+ RygelLMSRootContainerPrivate * priv; -+}; -+ -+struct _RygelLMSRootContainerClass { -+ RygelSimpleContainerClass parent_class; -+}; -+ -+struct _RygelLMSRootContainerPrivate { -+ RygelLMSDatabase* lms_db; -+}; -+ -+typedef enum { -+ RYGEL_LMS_DATABASE_ERROR_OPEN, -+ RYGEL_LMS_DATABASE_ERROR_PREPARE, -+ RYGEL_LMS_DATABASE_ERROR_BIND, -+ RYGEL_LMS_DATABASE_ERROR_STEP, -+ RYGEL_LMS_DATABASE_ERROR_NOT_FOUND -+} RygelLMSDatabaseError; -+#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark () -+ -+static gpointer rygel_lms_root_container_parent_class = NULL; -+ -+GType rygel_lms_root_container_get_type (void) G_GNUC_CONST; -+gpointer rygel_lms_database_ref (gpointer instance); -+void rygel_lms_database_unref (gpointer instance); -+GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); -+void rygel_lms_value_set_database (GValue* value, gpointer v_object); -+void rygel_lms_value_take_database (GValue* value, gpointer v_object); -+gpointer rygel_lms_value_get_database (const GValue* value); -+GType rygel_lms_database_get_type (void) G_GNUC_CONST; -+#define RYGEL_LMS_ROOT_CONTAINER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerPrivate)) -+enum { -+ RYGEL_LMS_ROOT_CONTAINER_DUMMY_PROPERTY -+}; -+RygelLMSRootContainer* rygel_lms_root_container_new (void); -+RygelLMSRootContainer* rygel_lms_root_container_construct (GType object_type); -+GQuark rygel_lms_database_error_quark (void); -+RygelLMSDatabase* rygel_lms_database_new (GError** error); -+RygelLMSDatabase* rygel_lms_database_construct (GType object_type, GError** error); -+RygelLMSMusicRoot* rygel_lms_music_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSMusicRoot* rygel_lms_music_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+GType rygel_lms_music_root_get_type (void) G_GNUC_CONST; -+RygelLMSAllVideos* rygel_lms_all_videos_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSAllVideos* rygel_lms_all_videos_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; -+GType rygel_lms_all_videos_get_type (void) G_GNUC_CONST; -+RygelLMSImageRoot* rygel_lms_image_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+RygelLMSImageRoot* rygel_lms_image_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); -+GType rygel_lms_image_root_get_type (void) G_GNUC_CONST; -+static void rygel_lms_root_container_finalize (GObject* obj); -+ -+ -+RygelLMSRootContainer* rygel_lms_root_container_construct (GType object_type) { -+ RygelLMSRootContainer * self = NULL; -+ RygelMetaConfig* config = NULL; -+ RygelMetaConfig* _tmp0_ = NULL; -+ gchar* title = NULL; -+ const gchar* _tmp1_ = NULL; -+ gchar* _tmp2_ = NULL; -+ const gchar* _tmp6_ = NULL; -+ GError * _inner_error_ = NULL; -+ _tmp0_ = rygel_meta_config_get_default (); -+ config = _tmp0_; -+ _tmp1_ = _ ("Shared media"); -+ _tmp2_ = g_strdup (_tmp1_); -+ title = _tmp2_; -+ { -+ gchar* _tmp3_ = NULL; -+ gchar* _tmp4_ = NULL; -+ gchar* _tmp5_ = NULL; -+ _tmp4_ = rygel_configuration_get_string ((RygelConfiguration*) config, "LightMediaScanner", "title", &_inner_error_); -+ _tmp3_ = _tmp4_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ goto __catch0_g_error; -+ } -+ _tmp5_ = _tmp3_; -+ _tmp3_ = NULL; -+ _g_free0 (title); -+ title = _tmp5_; -+ _g_free0 (_tmp3_); -+ } -+ goto __finally0; -+ __catch0_g_error: -+ { -+ GError* _error_ = NULL; -+ _error_ = _inner_error_; -+ _inner_error_ = NULL; -+ _g_error_free0 (_error_); -+ } -+ __finally0: -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _g_free0 (title); -+ _g_object_unref0 (config); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ _tmp6_ = title; -+ self = (RygelLMSRootContainer*) rygel_simple_container_construct_root (object_type, _tmp6_); -+ { -+ RygelLMSDatabase* _tmp7_ = NULL; -+ RygelLMSDatabase* _tmp8_ = NULL; -+ RygelLMSDatabase* _tmp9_ = NULL; -+ const gchar* _tmp10_ = NULL; -+ RygelLMSDatabase* _tmp11_ = NULL; -+ RygelLMSMusicRoot* _tmp12_ = NULL; -+ RygelLMSMusicRoot* _tmp13_ = NULL; -+ const gchar* _tmp14_ = NULL; -+ RygelLMSDatabase* _tmp15_ = NULL; -+ RygelLMSAllVideos* _tmp16_ = NULL; -+ RygelLMSAllVideos* _tmp17_ = NULL; -+ const gchar* _tmp18_ = NULL; -+ RygelLMSDatabase* _tmp19_ = NULL; -+ RygelLMSImageRoot* _tmp20_ = NULL; -+ RygelLMSImageRoot* _tmp21_ = NULL; -+ _tmp8_ = rygel_lms_database_new (&_inner_error_); -+ _tmp7_ = _tmp8_; -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { -+ goto __catch1_rygel_lms_database_error; -+ } -+ _g_free0 (title); -+ _g_object_unref0 (config); -+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ _tmp9_ = _tmp7_; -+ _tmp7_ = NULL; -+ _rygel_lms_database_unref0 (self->priv->lms_db); -+ self->priv->lms_db = _tmp9_; -+ _tmp10_ = _ ("Music"); -+ _tmp11_ = self->priv->lms_db; -+ _tmp12_ = rygel_lms_music_root_new ("music", (RygelMediaContainer*) self, _tmp10_, _tmp11_); -+ _tmp13_ = _tmp12_; -+ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp13_); -+ _g_object_unref0 (_tmp13_); -+ _tmp14_ = _ ("Videos"); -+ _tmp15_ = self->priv->lms_db; -+ _tmp16_ = rygel_lms_all_videos_new ("all-videos", (RygelMediaContainer*) self, _tmp14_, _tmp15_); -+ _tmp17_ = _tmp16_; -+ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp17_); -+ _g_object_unref0 (_tmp17_); -+ _tmp18_ = _ ("Pictures"); -+ _tmp19_ = self->priv->lms_db; -+ _tmp20_ = rygel_lms_image_root_new ("images", (RygelMediaContainer*) self, _tmp18_, _tmp19_); -+ _tmp21_ = _tmp20_; -+ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp21_); -+ _g_object_unref0 (_tmp21_); -+ _rygel_lms_database_unref0 (_tmp7_); -+ } -+ goto __finally1; -+ __catch1_rygel_lms_database_error: -+ { -+ GError* e = NULL; -+ GError* _tmp22_ = NULL; -+ const gchar* _tmp23_ = NULL; -+ e = _inner_error_; -+ _inner_error_ = NULL; -+ _tmp22_ = e; -+ _tmp23_ = _tmp22_->message; -+ g_warning ("rygel-lms-root-container.vala:49: %s\n", _tmp23_); -+ _g_error_free0 (e); -+ } -+ __finally1: -+ if (G_UNLIKELY (_inner_error_ != NULL)) { -+ _g_free0 (title); -+ _g_object_unref0 (config); -+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); -+ g_clear_error (&_inner_error_); -+ return NULL; -+ } -+ _g_free0 (title); -+ _g_object_unref0 (config); -+ return self; -+} -+ -+ -+RygelLMSRootContainer* rygel_lms_root_container_new (void) { -+ return rygel_lms_root_container_construct (RYGEL_LMS_TYPE_ROOT_CONTAINER); -+} -+ -+ -+static void rygel_lms_root_container_class_init (RygelLMSRootContainerClass * klass) { -+ rygel_lms_root_container_parent_class = g_type_class_peek_parent (klass); -+ g_type_class_add_private (klass, sizeof (RygelLMSRootContainerPrivate)); -+ G_OBJECT_CLASS (klass)->finalize = rygel_lms_root_container_finalize; -+} -+ -+ -+static void rygel_lms_root_container_instance_init (RygelLMSRootContainer * self) { -+ self->priv = RYGEL_LMS_ROOT_CONTAINER_GET_PRIVATE (self); -+ self->priv->lms_db = NULL; -+} -+ -+ -+static void rygel_lms_root_container_finalize (GObject* obj) { -+ RygelLMSRootContainer * self; -+ self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainer); -+ _rygel_lms_database_unref0 (self->priv->lms_db); -+ G_OBJECT_CLASS (rygel_lms_root_container_parent_class)->finalize (obj); -+} -+ -+ -+GType rygel_lms_root_container_get_type (void) { -+ static volatile gsize rygel_lms_root_container_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_root_container_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSRootContainerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_root_container_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSRootContainer), 0, (GInstanceInitFunc) rygel_lms_root_container_instance_init, NULL }; -+ GType rygel_lms_root_container_type_id; -+ rygel_lms_root_container_type_id = g_type_register_static (RYGEL_TYPE_SIMPLE_CONTAINER, "RygelLMSRootContainer", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_root_container_type_id__volatile, rygel_lms_root_container_type_id); -+ } -+ return rygel_lms_root_container_type_id__volatile; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-sql-function.c b/src/plugins/lms/rygel-lms-sql-function.c -new file mode 100644 -index 0000000..a56c7be ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-sql-function.c -@@ -0,0 +1,146 @@ -+/* rygel-lms-sql-function.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-sql-function.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2010 Jens Georg <mail@jensge.org>. -+ * -+ * Author: Jens Georg <mail@jensge.org> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <stdlib.h> -+#include <string.h> -+ -+ -+#define RYGEL_LMS_TYPE_SQL_OPERATOR (rygel_lms_sql_operator_get_type ()) -+#define RYGEL_LMS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperator)) -+#define RYGEL_LMS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass)) -+#define RYGEL_LMS_IS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR)) -+#define RYGEL_LMS_IS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR)) -+#define RYGEL_LMS_SQL_OPERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass)) -+ -+typedef struct _RygelLMSSqlOperator RygelLMSSqlOperator; -+typedef struct _RygelLMSSqlOperatorClass RygelLMSSqlOperatorClass; -+typedef struct _RygelLMSSqlOperatorPrivate RygelLMSSqlOperatorPrivate; -+ -+#define RYGEL_LMS_TYPE_SQL_FUNCTION (rygel_lms_sql_function_get_type ()) -+#define RYGEL_LMS_SQL_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunction)) -+#define RYGEL_LMS_SQL_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunctionClass)) -+#define RYGEL_LMS_IS_SQL_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION)) -+#define RYGEL_LMS_IS_SQL_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_FUNCTION)) -+#define RYGEL_LMS_SQL_FUNCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunctionClass)) -+ -+typedef struct _RygelLMSSqlFunction RygelLMSSqlFunction; -+typedef struct _RygelLMSSqlFunctionClass RygelLMSSqlFunctionClass; -+typedef struct _RygelLMSSqlFunctionPrivate RygelLMSSqlFunctionPrivate; -+ -+struct _RygelLMSSqlOperator { -+ GObject parent_instance; -+ RygelLMSSqlOperatorPrivate * priv; -+ gchar* name; -+ gchar* arg; -+ gchar* collate; -+}; -+ -+struct _RygelLMSSqlOperatorClass { -+ GObjectClass parent_class; -+ gchar* (*to_string) (RygelLMSSqlOperator* self); -+}; -+ -+struct _RygelLMSSqlFunction { -+ RygelLMSSqlOperator parent_instance; -+ RygelLMSSqlFunctionPrivate * priv; -+}; -+ -+struct _RygelLMSSqlFunctionClass { -+ RygelLMSSqlOperatorClass parent_class; -+}; -+ -+ -+static gpointer rygel_lms_sql_function_parent_class = NULL; -+ -+GType rygel_lms_sql_operator_get_type (void) G_GNUC_CONST; -+GType rygel_lms_sql_function_get_type (void) G_GNUC_CONST; -+enum { -+ RYGEL_LMS_SQL_FUNCTION_DUMMY_PROPERTY -+}; -+RygelLMSSqlFunction* rygel_lms_sql_function_new (const gchar* name, const gchar* arg); -+RygelLMSSqlFunction* rygel_lms_sql_function_construct (GType object_type, const gchar* name, const gchar* arg); -+RygelLMSSqlOperator* rygel_lms_sql_operator_new (const gchar* name, const gchar* arg, const gchar* collate); -+RygelLMSSqlOperator* rygel_lms_sql_operator_construct (GType object_type, const gchar* name, const gchar* arg, const gchar* collate); -+static gchar* rygel_lms_sql_function_real_to_string (RygelLMSSqlOperator* base); -+ -+ -+RygelLMSSqlFunction* rygel_lms_sql_function_construct (GType object_type, const gchar* name, const gchar* arg) { -+ RygelLMSSqlFunction * self = NULL; -+ const gchar* _tmp0_ = NULL; -+ const gchar* _tmp1_ = NULL; -+ g_return_val_if_fail (name != NULL, NULL); -+ g_return_val_if_fail (arg != NULL, NULL); -+ _tmp0_ = name; -+ _tmp1_ = arg; -+ self = (RygelLMSSqlFunction*) rygel_lms_sql_operator_construct (object_type, _tmp0_, _tmp1_, ""); -+ return self; -+} -+ -+ -+RygelLMSSqlFunction* rygel_lms_sql_function_new (const gchar* name, const gchar* arg) { -+ return rygel_lms_sql_function_construct (RYGEL_LMS_TYPE_SQL_FUNCTION, name, arg); -+} -+ -+ -+static gchar* rygel_lms_sql_function_real_to_string (RygelLMSSqlOperator* base) { -+ RygelLMSSqlFunction * self; -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ const gchar* _tmp1_ = NULL; -+ gchar* _tmp2_ = NULL; -+ self = (RygelLMSSqlFunction*) base; -+ _tmp0_ = ((RygelLMSSqlOperator*) self)->name; -+ _tmp1_ = ((RygelLMSSqlOperator*) self)->arg; -+ _tmp2_ = g_strdup_printf ("%s(%s,?)", _tmp0_, _tmp1_); -+ result = _tmp2_; -+ return result; -+} -+ -+ -+static void rygel_lms_sql_function_class_init (RygelLMSSqlFunctionClass * klass) { -+ rygel_lms_sql_function_parent_class = g_type_class_peek_parent (klass); -+ ((RygelLMSSqlOperatorClass *) klass)->to_string = rygel_lms_sql_function_real_to_string; -+} -+ -+ -+static void rygel_lms_sql_function_instance_init (RygelLMSSqlFunction * self) { -+} -+ -+ -+GType rygel_lms_sql_function_get_type (void) { -+ static volatile gsize rygel_lms_sql_function_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_sql_function_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSSqlFunctionClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_sql_function_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSSqlFunction), 0, (GInstanceInitFunc) rygel_lms_sql_function_instance_init, NULL }; -+ GType rygel_lms_sql_function_type_id; -+ rygel_lms_sql_function_type_id = g_type_register_static (RYGEL_LMS_TYPE_SQL_OPERATOR, "RygelLMSSqlFunction", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_sql_function_type_id__volatile, rygel_lms_sql_function_type_id); -+ } -+ return rygel_lms_sql_function_type_id__volatile; -+} -+ -+ -+ -diff --git a/src/plugins/lms/rygel-lms-sql-operator.c b/src/plugins/lms/rygel-lms-sql-operator.c -new file mode 100644 -index 0000000..90db1a9 ---- /dev/null -+++ b/src/plugins/lms/rygel-lms-sql-operator.c -@@ -0,0 +1,240 @@ -+/* rygel-lms-sql-operator.c generated by valac 0.28.0, the Vala compiler -+ * generated from rygel-lms-sql-operator.vala, do not modify */ -+ -+/* -+ * Copyright (C) 2010 Jens Georg <mail@jensge.org>. -+ * -+ * Author: Jens Georg <mail@jensge.org> -+ * -+ * This file is part of Rygel. -+ * -+ * Rygel 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 of the License, or -+ * (at your option) any later version. -+ * -+ * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <stdlib.h> -+#include <string.h> -+#include <libgupnp-av/gupnp-av.h> -+ -+ -+#define RYGEL_LMS_TYPE_SQL_OPERATOR (rygel_lms_sql_operator_get_type ()) -+#define RYGEL_LMS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperator)) -+#define RYGEL_LMS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass)) -+#define RYGEL_LMS_IS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR)) -+#define RYGEL_LMS_IS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR)) -+#define RYGEL_LMS_SQL_OPERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass)) -+ -+typedef struct _RygelLMSSqlOperator RygelLMSSqlOperator; -+typedef struct _RygelLMSSqlOperatorClass RygelLMSSqlOperatorClass; -+typedef struct _RygelLMSSqlOperatorPrivate RygelLMSSqlOperatorPrivate; -+#define _g_free0(var) (var = (g_free (var), NULL)) -+ -+struct _RygelLMSSqlOperator { -+ GObject parent_instance; -+ RygelLMSSqlOperatorPrivate * priv; -+ gchar* name; -+ gchar* arg; -+ gchar* collate; -+}; -+ -+struct _RygelLMSSqlOperatorClass { -+ GObjectClass parent_class; -+ gchar* (*to_string) (RygelLMSSqlOperator* self); -+}; -+ -+ -+static gpointer rygel_lms_sql_operator_parent_class = NULL; -+ -+GType rygel_lms_sql_operator_get_type (void) G_GNUC_CONST; -+enum { -+ RYGEL_LMS_SQL_OPERATOR_DUMMY_PROPERTY -+}; -+RygelLMSSqlOperator* rygel_lms_sql_operator_new (const gchar* name, const gchar* arg, const gchar* collate); -+RygelLMSSqlOperator* rygel_lms_sql_operator_construct (GType object_type, const gchar* name, const gchar* arg, const gchar* collate); -+RygelLMSSqlOperator* rygel_lms_sql_operator_new_from_search_criteria_op (GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate); -+RygelLMSSqlOperator* rygel_lms_sql_operator_construct_from_search_criteria_op (GType object_type, GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate); -+gchar* rygel_lms_sql_operator_to_string (RygelLMSSqlOperator* self); -+static gchar* rygel_lms_sql_operator_real_to_string (RygelLMSSqlOperator* self); -+static void rygel_lms_sql_operator_finalize (GObject* obj); -+ -+ -+RygelLMSSqlOperator* rygel_lms_sql_operator_construct (GType object_type, const gchar* name, const gchar* arg, const gchar* collate) { -+ RygelLMSSqlOperator * self = NULL; -+ const gchar* _tmp0_ = NULL; -+ gchar* _tmp1_ = NULL; -+ const gchar* _tmp2_ = NULL; -+ gchar* _tmp3_ = NULL; -+ const gchar* _tmp4_ = NULL; -+ gchar* _tmp5_ = NULL; -+ g_return_val_if_fail (name != NULL, NULL); -+ g_return_val_if_fail (arg != NULL, NULL); -+ g_return_val_if_fail (collate != NULL, NULL); -+ self = (RygelLMSSqlOperator*) g_object_new (object_type, NULL); -+ _tmp0_ = name; -+ _tmp1_ = g_strdup (_tmp0_); -+ _g_free0 (self->name); -+ self->name = _tmp1_; -+ _tmp2_ = arg; -+ _tmp3_ = g_strdup (_tmp2_); -+ _g_free0 (self->arg); -+ self->arg = _tmp3_; -+ _tmp4_ = collate; -+ _tmp5_ = g_strdup (_tmp4_); -+ _g_free0 (self->collate); -+ self->collate = _tmp5_; -+ return self; -+} -+ -+ -+RygelLMSSqlOperator* rygel_lms_sql_operator_new (const gchar* name, const gchar* arg, const gchar* collate) { -+ return rygel_lms_sql_operator_construct (RYGEL_LMS_TYPE_SQL_OPERATOR, name, arg, collate); -+} -+ -+ -+RygelLMSSqlOperator* rygel_lms_sql_operator_construct_from_search_criteria_op (GType object_type, GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate) { -+ RygelLMSSqlOperator * self = NULL; -+ gchar* sql = NULL; -+ GUPnPSearchCriteriaOp _tmp0_ = 0; -+ const gchar* _tmp7_ = NULL; -+ const gchar* _tmp8_ = NULL; -+ const gchar* _tmp9_ = NULL; -+ g_return_val_if_fail (arg != NULL, NULL); -+ g_return_val_if_fail (collate != NULL, NULL); -+ sql = NULL; -+ _tmp0_ = op; -+ switch (_tmp0_) { -+ case GUPNP_SEARCH_CRITERIA_OP_EQ: -+ { -+ gchar* _tmp1_ = NULL; -+ _tmp1_ = g_strdup ("="); -+ _g_free0 (sql); -+ sql = _tmp1_; -+ break; -+ } -+ case GUPNP_SEARCH_CRITERIA_OP_NEQ: -+ { -+ gchar* _tmp2_ = NULL; -+ _tmp2_ = g_strdup ("!="); -+ _g_free0 (sql); -+ sql = _tmp2_; -+ break; -+ } -+ case GUPNP_SEARCH_CRITERIA_OP_LESS: -+ { -+ gchar* _tmp3_ = NULL; -+ _tmp3_ = g_strdup ("<"); -+ _g_free0 (sql); -+ sql = _tmp3_; -+ break; -+ } -+ case GUPNP_SEARCH_CRITERIA_OP_LEQ: -+ { -+ gchar* _tmp4_ = NULL; -+ _tmp4_ = g_strdup ("<="); -+ _g_free0 (sql); -+ sql = _tmp4_; -+ break; -+ } -+ case GUPNP_SEARCH_CRITERIA_OP_GREATER: -+ { -+ gchar* _tmp5_ = NULL; -+ _tmp5_ = g_strdup (">"); -+ _g_free0 (sql); -+ sql = _tmp5_; -+ break; -+ } -+ case GUPNP_SEARCH_CRITERIA_OP_GEQ: -+ { -+ gchar* _tmp6_ = NULL; -+ _tmp6_ = g_strdup (">="); -+ _g_free0 (sql); -+ sql = _tmp6_; -+ break; -+ } -+ default: -+ { -+ g_assert_not_reached (); -+ } -+ } -+ _tmp7_ = sql; -+ _tmp8_ = arg; -+ _tmp9_ = collate; -+ self = (RygelLMSSqlOperator*) rygel_lms_sql_operator_construct (object_type, _tmp7_, _tmp8_, _tmp9_); -+ _g_free0 (sql); -+ return self; -+} -+ -+ -+RygelLMSSqlOperator* rygel_lms_sql_operator_new_from_search_criteria_op (GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate) { -+ return rygel_lms_sql_operator_construct_from_search_criteria_op (RYGEL_LMS_TYPE_SQL_OPERATOR, op, arg, collate); -+} -+ -+ -+static gchar* rygel_lms_sql_operator_real_to_string (RygelLMSSqlOperator* self) { -+ gchar* result = NULL; -+ const gchar* _tmp0_ = NULL; -+ const gchar* _tmp1_ = NULL; -+ const gchar* _tmp2_ = NULL; -+ gchar* _tmp3_ = NULL; -+ _tmp0_ = self->arg; -+ _tmp1_ = self->name; -+ _tmp2_ = self->collate; -+ _tmp3_ = g_strdup_printf ("(%s %s ? %s)", _tmp0_, _tmp1_, _tmp2_); -+ result = _tmp3_; -+ return result; -+} -+ -+ -+gchar* rygel_lms_sql_operator_to_string (RygelLMSSqlOperator* self) { -+ g_return_val_if_fail (self != NULL, NULL); -+ return RYGEL_LMS_SQL_OPERATOR_GET_CLASS (self)->to_string (self); -+} -+ -+ -+static void rygel_lms_sql_operator_class_init (RygelLMSSqlOperatorClass * klass) { -+ rygel_lms_sql_operator_parent_class = g_type_class_peek_parent (klass); -+ ((RygelLMSSqlOperatorClass *) klass)->to_string = rygel_lms_sql_operator_real_to_string; -+ G_OBJECT_CLASS (klass)->finalize = rygel_lms_sql_operator_finalize; -+} -+ -+ -+static void rygel_lms_sql_operator_instance_init (RygelLMSSqlOperator * self) { -+} -+ -+ -+static void rygel_lms_sql_operator_finalize (GObject* obj) { -+ RygelLMSSqlOperator * self; -+ self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperator); -+ _g_free0 (self->name); -+ _g_free0 (self->arg); -+ _g_free0 (self->collate); -+ G_OBJECT_CLASS (rygel_lms_sql_operator_parent_class)->finalize (obj); -+} -+ -+ -+GType rygel_lms_sql_operator_get_type (void) { -+ static volatile gsize rygel_lms_sql_operator_type_id__volatile = 0; -+ if (g_once_init_enter (&rygel_lms_sql_operator_type_id__volatile)) { -+ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSSqlOperatorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_sql_operator_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSSqlOperator), 0, (GInstanceInitFunc) rygel_lms_sql_operator_instance_init, NULL }; -+ GType rygel_lms_sql_operator_type_id; -+ rygel_lms_sql_operator_type_id = g_type_register_static (G_TYPE_OBJECT, "RygelLMSSqlOperator", &g_define_type_info, 0); -+ g_once_init_leave (&rygel_lms_sql_operator_type_id__volatile, rygel_lms_sql_operator_type_id); -+ } -+ return rygel_lms_sql_operator_type_id__volatile; -+} -+ -+ -+ --- -1.8.3.1 - diff --git a/meta-agl/recipes-connectivity/rygel/rygel_%.bbappend b/meta-agl/recipes-connectivity/rygel/rygel_%.bbappend index bfee4f569..4ae59259f 100644 --- a/meta-agl/recipes-connectivity/rygel/rygel_%.bbappend +++ b/meta-agl/recipes-connectivity/rygel/rygel_%.bbappend @@ -5,28 +5,21 @@ PACKAGECONFIG = "media-export lms" PACKAGECONFIG[lms] = "--enable-lms-plugin,--disable-lms-plugin,sqlite3" # LightMediaScanner plugin patches -SRC_URI += "file://0001-Add-LightMediaScanner-plugin.patch \ - file://0002-lms-add-C-source-files.patch \ - file://0001-Fix-missing-link-to-unistring-for-lms-plugin.patch \ - file://rygel.service \ - " +SRC_URI += "\ + file://0001-Fix-missing-link-to-unistring-for-lms-plugin.patch \ + file://rygel.service \ +" -inherit systemd +do_install_prepend() { + # Install rygel systemd service + if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then + install -m 644 -p -D ${WORKDIR}/rygel.service ${D}${systemd_user_unitdir}/rygel.service -do_install_append() { - # Install rygel systemd service - if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then - install -m 644 -p -D ${WORKDIR}/rygel.service ${D}${systemd_user_unitdir}/rygel.service - - # Execute these manually on behalf of systemctl script (from systemd-systemctl-native.bb) - # because it does not support systemd's user mode. - # However, systemctl --global should be checked - #mkdir -p ${D}/etc/systemd/user/default.target.wants/ - #ln -sf ${systemd_user_unitdir}/rygel.service ${D}/etc/systemd/user/dbus-org.gnome.Rygel1.service - #ln -sf ${systemd_user_unitdir}/rygel.service ${D}/etc/systemd/user/default.target.wants/rygel.service - fi + # Execute these manually on behalf of systemctl script (from systemd-systemctl-native.bb) + # because it does not support systemd's user mode. + # However, systemctl --global should be checked + #mkdir -p ${D}/etc/systemd/user/default.target.wants/ + #ln -sf ${systemd_user_unitdir}/rygel.service ${D}/etc/systemd/user/dbus-org.gnome.Rygel1.service + #ln -sf ${systemd_user_unitdir}/rygel.service ${D}/etc/systemd/user/default.target.wants/rygel.service + fi } - -FILES_${PN} += " \ - ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_user_unitdir}/rygel.service', '', d)} \ - " diff --git a/meta-agl/recipes-core/glibc/glibc/arm/local-arm-futex.diff b/meta-agl/recipes-core/glibc/glibc/arm/local-arm-futex.diff index c6b9d53a1..27d1144d0 100644 --- a/meta-agl/recipes-core/glibc/glibc/arm/local-arm-futex.diff +++ b/meta-agl/recipes-core/glibc/glibc/arm/local-arm-futex.diff @@ -18,6 +18,5 @@ Last-Update: 2015-03-25 configuration. */ -#if __LINUX_KERNEL_VERSION < 0x030E03 +#if __LINUX_KERNEL_VERSION < 0x020620 - # undef __ASSUME_REQUEUE_PI # undef __ASSUME_SET_ROBUST_LIST #endif diff --git a/meta-agl/recipes-core/systemd/systemd/backport-v234-e266c06.patch b/meta-agl/recipes-core/systemd/systemd/backport-v234-e266c06.patch deleted file mode 100644 index 1f4a23ea7..000000000 --- a/meta-agl/recipes-core/systemd/systemd/backport-v234-e266c06.patch +++ /dev/null @@ -1,315 +0,0 @@ -commit e266c068b5597e18b2299f9c9d3ee6cf04198c41 -Author: Michal Sekletar <msekleta@redhat.com> -Date: Mon Jan 23 17:12:35 2017 +0100 - - service: serialize information about currently executing command - - Stored information will help us to resume execution after the - daemon-reload. - - This commit implements following scheme, - - * On serialization: - - we count rank of the currently executing command - - we store command type, its rank and command line arguments - - * On deserialization: - - configuration is parsed and loaded - - we deserialize stored data, command type, rank and arguments - - we look at the given rank in the list and if command there has same - arguments then we restore execution at that point - - otherwise we search respective command list and we look for command - that has the same arguments - - if both methods fail we do not do not resume execution at all - - To better illustrate how does above scheme works, please consider - following cases (<<< denotes position where we resume execution after reload) - - ; Original unit file - [Service] - ExecStart=/bin/true <<< - ExecStart=/bin/false - - ; Swapped commands - ; Second command is not going to be executed - [Service] - ExecStart=/bin/false - ExecStart=/bin/true <<< - - ; Commands added before - ; Same commands are problematic and execution could be restarted at wrong place - [Service] - ExecStart=/bin/foo - ExecStart=/bin/bar - ExecStart=/bin/true <<< - ExecStart=/bin/false - - ; Commands added after - ; Same commands are not an issue in this case - [Service] - ExecStart=/bin/true <<< - ExecStart=/bin/false - ExecStart=/bin/foo - ExecStart=/bin/bar - - ; New commands interleaved with old commands - ; Some new commands will be executed while others won't - ExecStart=/bin/foo - ExecStart=/bin/true <<< - ExecStart=/bin/bar - ExecStart=/bin/false - - As you can see, above scheme has some drawbacks. However, in most - cases (we assume that in most common case unit file command list is not - changed while some other command is running for the same unit) it - should cause that systemd does the right thing, which is restoring - execution exactly at the point we were before daemon-reload. - - Fixes #518 - -Signed-off-by: Scott Murray <scott.murray@konsulko.com> - -Upstream-Status: backport - -diff --git a/src/core/service.c b/src/core/service.c -index 74054887b..5e681fb71 100644 ---- a/src/core/service.c -+++ b/src/core/service.c -@@ -45,6 +45,7 @@ - #include "service.h" - #include "signal-util.h" - #include "special.h" -+#include "stdio-util.h" - #include "string-table.h" - #include "string-util.h" - #include "strv.h" -@@ -2140,6 +2141,80 @@ _pure_ static bool service_can_reload(Unit *u) { - return !!s->exec_command[SERVICE_EXEC_RELOAD]; - } - -+static unsigned service_exec_command_index(Unit *u, ServiceExecCommand id, ExecCommand *current) { -+ Service *s = SERVICE(u); -+ unsigned idx = 0; -+ ExecCommand *first, *c; -+ -+ assert(s); -+ -+ first = s->exec_command[id]; -+ -+ /* Figure out where we are in the list by walking back to the beginning */ -+ for (c = current; c != first; c = c->command_prev) -+ idx++; -+ -+ return idx; -+} -+ -+static int service_serialize_exec_command(Unit *u, FILE *f, ExecCommand *command) { -+ Service *s = SERVICE(u); -+ ServiceExecCommand id; -+ unsigned idx; -+ const char *type; -+ char **arg; -+ _cleanup_strv_free_ char **escaped_args = NULL; -+ _cleanup_free_ char *args = NULL, *p = NULL; -+ size_t allocated = 0, length = 0; -+ -+ assert(s); -+ assert(f); -+ -+ if (!command) -+ return 0; -+ -+ if (command == s->control_command) { -+ type = "control"; -+ id = s->control_command_id; -+ } else { -+ type = "main"; -+ id = SERVICE_EXEC_START; -+ } -+ -+ idx = service_exec_command_index(u, id, command); -+ -+ STRV_FOREACH(arg, command->argv) { -+ size_t n; -+ _cleanup_free_ char *e = NULL; -+ -+ e = xescape(*arg, WHITESPACE); -+ if (!e) -+ return -ENOMEM; -+ -+ n = strlen(e); -+ if (!GREEDY_REALLOC(args, allocated, length + 1 + n + 1)) -+ return -ENOMEM; -+ -+ if (length > 0) -+ args[length++] = ' '; -+ -+ memcpy(args + length, e, n); -+ length += n; -+ } -+ -+ if (!GREEDY_REALLOC(args, allocated, length + 1)) -+ return -ENOMEM; -+ args[length++] = 0; -+ -+ p = xescape(command->path, WHITESPACE); -+ if (!p) -+ return -ENOMEM; -+ -+ fprintf(f, "%s-command=%s %u %s %s\n", type, service_exec_command_to_string(id), idx, p, args); -+ -+ return 0; -+} -+ - static int service_serialize(Unit *u, FILE *f, FDSet *fds) { - Service *s = SERVICE(u); - ServiceFDStore *fs; -@@ -2167,11 +2242,8 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) { - if (r < 0) - return r; - -- /* FIXME: There's a minor uncleanliness here: if there are -- * multiple commands attached here, we will start from the -- * first one again */ -- if (s->control_command_id >= 0) -- unit_serialize_item(u, f, "control-command", service_exec_command_to_string(s->control_command_id)); -+ service_serialize_exec_command(u, f, s->control_command); -+ service_serialize_exec_command(u, f, s->main_command); - - r = unit_serialize_item_fd(u, f, fds, "stdin-fd", s->stdin_fd); - if (r < 0) -@@ -2227,6 +2299,106 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) { - return 0; - } - -+static int service_deserialize_exec_command(Unit *u, const char *key, const char *value) { -+ Service *s = SERVICE(u); -+ int r; -+ unsigned idx = 0, i; -+ bool control, found = false; -+ ServiceExecCommand id = _SERVICE_EXEC_COMMAND_INVALID; -+ ExecCommand *command = NULL; -+ _cleanup_free_ char *args = NULL, *path = NULL; -+ _cleanup_strv_free_ char **argv = NULL; -+ -+ enum ExecCommandState { -+ STATE_EXEC_COMMAND_TYPE, -+ STATE_EXEC_COMMAND_INDEX, -+ STATE_EXEC_COMMAND_PATH, -+ STATE_EXEC_COMMAND_ARGS, -+ _STATE_EXEC_COMMAND_MAX, -+ _STATE_EXEC_COMMAND_INVALID = -1, -+ } state; -+ -+ assert(s); -+ assert(key); -+ assert(value); -+ -+ control = streq(key, "control-command"); -+ -+ state = STATE_EXEC_COMMAND_TYPE; -+ -+ for (;;) { -+ _cleanup_free_ char *arg = NULL; -+ -+ r = extract_first_word(&value, &arg, NULL, EXTRACT_CUNESCAPE); -+ if (r == 0) -+ break; -+ else if (r < 0) -+ return r; -+ -+ switch (state) { -+ case STATE_EXEC_COMMAND_TYPE: -+ id = service_exec_command_from_string(arg); -+ if (id < 0) -+ return -EINVAL; -+ -+ state = STATE_EXEC_COMMAND_INDEX; -+ break; -+ case STATE_EXEC_COMMAND_INDEX: -+ r = safe_atou(arg, &idx); -+ if (r < 0) -+ return -EINVAL; -+ -+ state = STATE_EXEC_COMMAND_PATH; -+ break; -+ case STATE_EXEC_COMMAND_PATH: -+ path = arg; -+ arg = NULL; -+ state = STATE_EXEC_COMMAND_ARGS; -+ -+ if (!path_is_absolute(path)) -+ return -EINVAL; -+ break; -+ case STATE_EXEC_COMMAND_ARGS: -+ r = strv_extend(&argv, arg); -+ if (r < 0) -+ return -ENOMEM; -+ break; -+ default: -+ assert_not_reached("Unknown error at deserialization of exec command"); -+ break; -+ } -+ } -+ -+ if (state != STATE_EXEC_COMMAND_ARGS) -+ return -EINVAL; -+ -+ /* Let's check whether exec command on given offset matches data that we just deserialized */ -+ for (command = s->exec_command[id], i = 0; command; command = command->command_next, i++) { -+ if (i != idx) -+ continue; -+ -+ found = strv_equal(argv, command->argv) && streq(command->path, path); -+ break; -+ } -+ -+ if (!found) { -+ /* Command at the index we serialized is different, let's look for command that exactly -+ * matches but is on different index. If there is no such command we will not resume execution. */ -+ for (command = s->exec_command[id]; command; command = command->command_next) -+ if (strv_equal(command->argv, argv) && streq(command->path, path)) -+ break; -+ } -+ -+ if (command && control) -+ s->control_command = command; -+ else if (command) -+ s->main_command = command; -+ else -+ log_unit_warning(u, "Current command vanished from the unit file, execution of the command list won't be resumed."); -+ -+ return 0; -+} -+ - static int service_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { - Service *s = SERVICE(u); - int r; -@@ -2309,16 +2481,6 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value, - s->status_text = t; - } - -- } else if (streq(key, "control-command")) { -- ServiceExecCommand id; -- -- id = service_exec_command_from_string(value); -- if (id < 0) -- log_unit_debug(u, "Failed to parse exec-command value: %s", value); -- else { -- s->control_command_id = id; -- s->control_command = s->exec_command[id]; -- } - } else if (streq(key, "accept-socket")) { - Unit *socket; - -@@ -2437,6 +2599,10 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value, - s->watchdog_override_enable = true; - s->watchdog_override_usec = watchdog_override_usec; - } -+ } else if (STR_IN_SET(key, "main-command", "control-command")) { -+ r = service_deserialize_exec_command(u, key, value); -+ if (r < 0) -+ log_unit_debug_errno(u, r, "Failed to parse serialized command \"%s\": %m", value); - } else - log_unit_debug(u, "Unknown serialization key: %s", key); - diff --git a/meta-agl/recipes-core/systemd/systemd_%.bbappend b/meta-agl/recipes-core/systemd/systemd_%.bbappend index 354464c12..f64ca8c8a 100644 --- a/meta-agl/recipes-core/systemd/systemd_%.bbappend +++ b/meta-agl/recipes-core/systemd/systemd_%.bbappend @@ -1,9 +1,9 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" -SRC_URI += "file://backport-v234-e266c06.patch \ - file://e2fsck.conf \ - ${@bb.utils.contains('VIRTUAL-RUNTIME_net_manager','systemd','file://wired.network','',d)} \ - " +SRC_URI += "\ + file://e2fsck.conf \ + ${@bb.utils.contains('VIRTUAL-RUNTIME_net_manager','systemd','file://wired.network','',d)} \ +" # enable networkd/resolved support PACKAGECONFIG_append_pn-systemd = " \ diff --git a/meta-agl/recipes-devtools/autogen/autogen-native_5.18.12.bbappend b/meta-agl/recipes-devtools/autogen/autogen-native_5.18.12.bbappend deleted file mode 100644 index a6f697cdb..000000000 --- a/meta-agl/recipes-devtools/autogen/autogen-native_5.18.12.bbappend +++ /dev/null @@ -1,2 +0,0 @@ -FILESEXTRAPATHS_prepend := "${THISDIR}/files:" -SRC_URI_append = "file://0003-autoopts-mk-tpl-config.sh-fix-shell-path.patch" diff --git a/meta-agl/recipes-devtools/autogen/files/0003-autoopts-mk-tpl-config.sh-fix-shell-path.patch b/meta-agl/recipes-devtools/autogen/files/0003-autoopts-mk-tpl-config.sh-fix-shell-path.patch deleted file mode 100644 index db6b0cdf8..000000000 --- a/meta-agl/recipes-devtools/autogen/files/0003-autoopts-mk-tpl-config.sh-fix-shell-path.patch +++ /dev/null @@ -1,29 +0,0 @@ -From df4f5ccc376a630b1a587a8ca3b1f35a305867dd Mon Sep 17 00:00:00 2001 -From: Robert Berger <robert.berger@ReliableEmbeddedSystems.com> -Date: Wed, 23 Aug 2017 07:19:03 +0000 -Subject: [PATCH] autoopts/mk-tpl-config.sh: fix shell path - -POSIX_SHELL as shebang doesn't work when it is longer than -BINPRM_BUF_SIZE which is 128 usually. So use "/bin/sh". - -Signed-off-by: Robert Berger <robert.berger@ReliableEmbeddedSystems.com> ---- - autoopts/mk-tpl-config.sh | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/autoopts/mk-tpl-config.sh b/autoopts/mk-tpl-config.sh -index c4708a2..550870e 100755 ---- a/autoopts/mk-tpl-config.sh -+++ b/autoopts/mk-tpl-config.sh -@@ -102,7 +102,7 @@ fix_scripts() { - sed 1d $f - ;; - -- */sh ) echo '#!' ${POSIX_SHELL} -+ */sh ) echo '#!/bin/sh' - sed 1d $f - ;; - --- -2.7.4 - diff --git a/meta-agl/recipes-multimedia/lightmediascanner/files/0001-Define-comparison_fn_t-for-non-glibc-systems.patch b/meta-agl/recipes-multimedia/lightmediascanner/files/0001-Define-comparison_fn_t-for-non-glibc-systems.patch new file mode 100644 index 000000000..15d4b3f0e --- /dev/null +++ b/meta-agl/recipes-multimedia/lightmediascanner/files/0001-Define-comparison_fn_t-for-non-glibc-systems.patch @@ -0,0 +1,33 @@ +From 5bc5b8c5dad3edec6736fd7e7ce61250c4ce3725 Mon Sep 17 00:00:00 2001 +From: Khem Raj <raj.khem@gmail.com> +Date: Wed, 12 Jul 2017 17:13:19 -0700 +Subject: [PATCH] Define comparison_fn_t for non-glibc systems + +lightmediascanner.c:324:12: error: 'comparison_fn_t' undeclared (first use in this function) + (comparison_fn_t)_plugin_sort); + ^~~~~~~~~~~~~~~ + +Signed-off-by: Khem Raj <raj.khem@gmail.com> +--- + src/lib/lightmediascanner.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/lib/lightmediascanner.c b/src/lib/lightmediascanner.c +index 344b247..b866883 100644 +--- a/src/lib/lightmediascanner.c ++++ b/src/lib/lightmediascanner.c +@@ -37,6 +37,11 @@ + #define DEFAULT_SLAVE_TIMEOUT 1000 + #define DEFAULT_COMMIT_INTERVAL 100 + ++#if !defined(__GLIBC__) ++typedef int (*__compar_fn_t) (const void*, const void*); ++typedef __compar_fn_t comparison_fn_t; ++#endif ++ + #ifdef HAVE_MAGIC_H + static magic_t _magic_handle; + +-- +2.13.2 + diff --git a/meta-agl/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch b/meta-agl/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch new file mode 100644 index 000000000..9528bec79 --- /dev/null +++ b/meta-agl/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch @@ -0,0 +1,11 @@ +--- a/src/plugins/Makefile.am 2015-10-25 16:12:29.331415823 +0000 ++++ b/src/plugins/Makefile.am 2015-10-25 16:14:37.593415808 +0000 +@@ -93,7 +93,7 @@ + id3_id3_la_SOURCES = id3/id3.c id3/id3v1_genres.c + id3_id3_la_LIBADD = $(PLUGINS_LIBADD) + +-id3/id3v1_genres.c: $(srcdir)/id3/id3v1_genres.def $(srcdir)/id3/id3v1_genres_gen.awk ++$(srcdir)/id3/id3v1_genres.c: $(srcdir)/id3/id3v1_genres.def $(srcdir)/id3/id3v1_genres_gen.awk + $(AWK) -f $(srcdir)/id3/id3v1_genres_gen.awk $(srcdir)/id3/id3v1_genres.def > $@ + + EXTRA_DIST += id3/id3v1_genres.def id3/id3v1_genres_gen.awk diff --git a/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb b/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb new file mode 100644 index 000000000..f2158760f --- /dev/null +++ b/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb @@ -0,0 +1,63 @@ +SUMMARY = "Lightweight media scanner" +DESCRIPTION = "Lightweight media scanner meant to be used in not-so-powerful devices, like embedded systems or old machines." +SECTION = "libs/multimedia" + +LICENSE = "LGPLv2.1+" +LIC_FILES_CHKSUM = "file://COPYING;md5=a6f89e2100d9b6cdffcea4f398e37343 \ + file://src/lib/lightmediascanner.c;endline=21;md5=6d8889bccb4c6c27e8b786342a3eb267" + +DEPENDS = "file gawk glib-2.0 sqlite3" + +PV = "0.5.1+git${SRCPV}" +SRCREV = "adfddb3486276a5ed2f5008c9e43a811e1271cc9" +SRC_URI = "git://github.com/profusion/lightmediascanner.git \ + file://id3-plugin-support-out-of-tree-build.patch \ + file://0001-Define-comparison_fn_t-for-non-glibc-systems.patch \ + " + +S = "${WORKDIR}/git" + +inherit autotools pkgconfig + +EXTRA_OECONF = "--enable-static --disable-mp4" + +PACKAGECONFIG ??= "ogg flac wave id3 m3u pls asf rm jpeg png" +PACKAGECONFIG[generic] = "--enable-generic,--disable-generic,libav" +PACKAGECONFIG[ogg] = "--enable-ogg,--disable-ogg,libogg libvorbis libtheora" +PACKAGECONFIG[flac] = "--enable-flac,--disable-flac,flac" +PACKAGECONFIG[wave] = "--enable-wave,--disable-wave" +PACKAGECONFIG[id3] = "--enable-id3,--disable-id3" +PACKAGECONFIG[m3u] = "--enable-m3u,--disable-m3u" +PACKAGECONFIG[pls] = "--enable-pls,--disable-pls" +PACKAGECONFIG[asf] = "--enable-asf,--disable-asf" +PACKAGECONFIG[rm] = "--enable-rm,--disable-rm" +PACKAGECONFIG[jpeg] = "--enable-jpeg,--disable-jpeg" +PACKAGECONFIG[png] = "--enable-png,--disable-png" + +do_install_append() { + # Install "test" binary for corresponding package + install -d ${D}/${bindir} + install -m 755 ${B}/src/bin/.libs/test ${D}/${bindir}/test-lms + # Remove .la files for loadable modules + rm -f ${D}/${libdir}/${PN}/plugins/*.la +} + +FILES_${PN} += "${datadir}/dbus-1" +FILES_${PN}-dbg += "${libdir}/${PN}/plugins/.debug" + +PACKAGES_prepend = "${PN}-test " +FILES_${PN}-test_prepend = "${bindir}/test-lms " + +PACKAGES += "${PN}-meta" +ALLOW_EMPTY_${PN}-meta = "1" + +PACKAGES_DYNAMIC = "${PN}-plugin-*" + +python populate_packages_prepend () { + lms_libdir = d.expand('${libdir}/${PN}') + pkgs = [] + + pkgs += do_split_packages(d, oe.path.join(lms_libdir, "plugins"), '^(.*)\.so$', d.expand('${PN}-plugin-%s'), 'LightMediaScanner plugin for %s', prepend=True, extra_depends=d.expand('${PN}')) + metapkg = d.getVar('PN') + '-meta' + d.setVar('RDEPENDS_' + metapkg, ' '.join(pkgs)) +} diff --git a/meta-agl/recipes-navigation/geoclue/geoclue_%.bbappend b/meta-agl/recipes-navigation/geoclue/geoclue_%.bbappend index 1025e0e79..9d61a9f61 100644 --- a/meta-agl/recipes-navigation/geoclue/geoclue_%.bbappend +++ b/meta-agl/recipes-navigation/geoclue/geoclue_%.bbappend @@ -1,4 +1,3 @@ -DEPENDS += "gobject-introspection-native" inherit gobject-introspection FILESEXTRAPATHS_prepend := "${THISDIR}/files:" diff --git a/meta-app-framework/conf/include/agl-appfw-smack.inc b/meta-app-framework/conf/include/agl-appfw-smack.inc index 1d8ab0a77..b77a5d17c 100644 --- a/meta-app-framework/conf/include/agl-appfw-smack.inc +++ b/meta-app-framework/conf/include/agl-appfw-smack.inc @@ -4,7 +4,7 @@ DISTRO_FEATURES_append = " smack dbus-cynara xattr" # use tar-native to support SMACK extended attributes independently of host config IMAGE_CMD_TAR = "tar --xattrs --xattrs-include='*'" -IMAGE_DEPENDS_tar_append = " tar-replacement-native" +do_image_tar[depends] += "tar-replacement-native:do_populate_sysroot" EXTRANATIVEPATH += "tar-native" # security: enable ssh server in place of dropbear to support PAM on user sessions diff --git a/meta-app-framework/recipes-core/security-manager/security-manager/0001-gcc-7-requires-include-functional-for-std-function.patch b/meta-app-framework/recipes-core/security-manager/security-manager/0001-gcc-7-requires-include-functional-for-std-function.patch new file mode 100644 index 000000000..7b6845abc --- /dev/null +++ b/meta-app-framework/recipes-core/security-manager/security-manager/0001-gcc-7-requires-include-functional-for-std-function.patch @@ -0,0 +1,51 @@ +From ed1c105db9d7b1ceb52ec16f35b0a2c959c19c6d Mon Sep 17 00:00:00 2001 +From: Changhyeok Bae <changhyeok.bae@gmail.com> +Date: Sun, 17 Dec 2017 15:40:58 +0000 +Subject: [PATCH] gcc-7 requires include <functional> for std::function + +Signed-off-by: Changhyeok Bae <changhyeok.bae@gmail.com> +--- + src/client/client-common.cpp | 1 + + src/common/smack-labels.cpp | 1 + + src/dpl/core/src/binary_queue.cpp | 1 + + 3 files changed, 3 insertions(+) + +diff --git a/src/client/client-common.cpp b/src/client/client-common.cpp +index 883ab8d..1babdf7 100644 +--- a/src/client/client-common.cpp ++++ b/src/client/client-common.cpp +@@ -31,6 +31,7 @@ + #include <sys/xattr.h> + #include <linux/xattr.h> + #include <unistd.h> ++#include <functional> + + #include <dpl/log/log.h> + #include <dpl/serialization.h> +diff --git a/src/common/smack-labels.cpp b/src/common/smack-labels.cpp +index 0294a42..1598099 100644 +--- a/src/common/smack-labels.cpp ++++ b/src/common/smack-labels.cpp +@@ -29,6 +29,7 @@ + #include <sys/xattr.h> + #include <linux/xattr.h> + #include <memory> ++#include <functional> + #include <fts.h> + #include <cstring> + #include <string> +diff --git a/src/dpl/core/src/binary_queue.cpp b/src/dpl/core/src/binary_queue.cpp +index 72817a6..838409f 100644 +--- a/src/dpl/core/src/binary_queue.cpp ++++ b/src/dpl/core/src/binary_queue.cpp +@@ -26,6 +26,7 @@ + #include <malloc.h> + #include <cstring> + #include <new> ++#include <functional> + + namespace SecurityManager { + BinaryQueue::BinaryQueue() : +-- +2.7.4 + diff --git a/meta-app-framework/recipes-core/security-manager/security-manager_%.bbappend b/meta-app-framework/recipes-core/security-manager/security-manager_%.bbappend index bd1a43ea3..92b79572f 100644 --- a/meta-app-framework/recipes-core/security-manager/security-manager_%.bbappend +++ b/meta-app-framework/recipes-core/security-manager/security-manager_%.bbappend @@ -7,6 +7,7 @@ SRC_URI += " file://0001-Adapt-rules-to-AGL.patch \ file://init-security-manager-db.sh \ file://0001-Fix-gcc6-build.patch \ file://0001-Fix-Cmake-conf-for-gcc6-build.patch \ + file://0001-gcc-7-requires-include-functional-for-std-function.patch \ " FILES_${PN}_append = "${bindir}/init-security-manager-db.sh \ diff --git a/meta-app-framework/recipes-kernel/linux/linux-yocto_4.1.bbappend b/meta-app-framework/recipes-kernel/linux/linux-yocto_4.1.bbappend deleted file mode 100644 index c1c657201..000000000 --- a/meta-app-framework/recipes-kernel/linux/linux-yocto_4.1.bbappend +++ /dev/null @@ -1,12 +0,0 @@ -FILESEXTRAPATHS_prepend := "${THISDIR}/linux/linux-yocto-4.1:" - -#------------------------------------------------------------------------- -# smack patches for handling bluetooth - -SRC_URI_append_smack = "\ - file://0001-Smack-File-receive-for-sockets.patch \ - file://0002-smack-fix-cache-of-access-labels.patch \ - file://0003-Smack-ignore-null-signal-in-smack_task_kill.patch \ - file://0004-Smack-Assign-smack_known_web-label-for-kernel-thread.patch \ -" - diff --git a/meta-app-framework/recipes-kernel/linux/linux-yocto_4.4.bbappend b/meta-app-framework/recipes-kernel/linux/linux-yocto_4.12.bbappend index 51df08719..b1eadaffa 100644 --- a/meta-app-framework/recipes-kernel/linux/linux-yocto_4.4.bbappend +++ b/meta-app-framework/recipes-kernel/linux/linux-yocto_4.12.bbappend @@ -1,4 +1,4 @@ -FILESEXTRAPATHS_prepend := "${THISDIR}/linux/linux-yocto-4.4:" +FILESEXTRAPATHS_prepend := "${THISDIR}/linux/linux-yocto-4.12:" #------------------------------------------------------------------------- # smack patches for handling bluetooth diff --git a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0001-Smack-File-receive-for-sockets.patch b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0001-Smack-File-receive-for-sockets.patch deleted file mode 100644 index b0c5ee8f4..000000000 --- a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0001-Smack-File-receive-for-sockets.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 2e65b888820ea372984d412cee3bd7dcba05d7d2 Mon Sep 17 00:00:00 2001 -From: Casey Schaufler <casey@schaufler-ca.com> -Date: Mon, 7 Dec 2015 14:34:32 -0800 -Subject: [PATCH 1/4] Smack: File receive for sockets - -The existing file receive hook checks for access on -the file inode even for UDS. This is not right, as -the inode is not used by Smack to make access checks -for sockets. This change checks for an appropriate -access relationship between the receiving (current) -process and the socket. If the process can't write -to the socket's send label or the socket's receive -label can't write to the process fail. - -This will allow the legitimate cases, where the -socket sender and socket receiver can freely communicate. -Only strangly set socket labels should cause a problem. - -Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> ---- - security/smack/smack_lsm.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - -diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c -index b644757..487b2f3 100644 ---- a/security/smack/smack_lsm.c -+++ b/security/smack/smack_lsm.c -@@ -1672,9 +1672,31 @@ static int smack_file_receive(struct file *file) - int may = 0; - struct smk_audit_info ad; - struct inode *inode = file_inode(file); -+ struct socket *sock; -+ struct task_smack *tsp; -+ struct socket_smack *ssp; - - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); - smk_ad_setfield_u_fs_path(&ad, file->f_path); -+ -+ if (S_ISSOCK(inode->i_mode)) { -+ sock = SOCKET_I(inode); -+ ssp = sock->sk->sk_security; -+ tsp = current_security(); -+ /* -+ * If the receiving process can't write to the -+ * passed socket or if the passed socket can't -+ * write to the receiving process don't accept -+ * the passed socket. -+ */ -+ rc = smk_access(tsp->smk_task, ssp->smk_out, MAY_WRITE, &ad); -+ rc = smk_bu_file(file, may, rc); -+ if (rc < 0) -+ return rc; -+ rc = smk_access(ssp->smk_in, tsp->smk_task, MAY_WRITE, &ad); -+ rc = smk_bu_file(file, may, rc); -+ return rc; -+ } - /* - * This code relies on bitmasks. - */ --- -2.7.4 - diff --git a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0002-smack-fix-cache-of-access-labels.patch b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0002-smack-fix-cache-of-access-labels.patch deleted file mode 100644 index 51c3b31ec..000000000 --- a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0002-smack-fix-cache-of-access-labels.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 5bcea0fc4e5360deca133e211fdc76717a1693a4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jos=C3=A9=20Bollo?= <jobol@nonadev.net> -Date: Tue, 12 Jan 2016 21:23:40 +0100 -Subject: [PATCH 2/4] smack: fix cache of access labels -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Before this commit, removing the access property of -a file, aka, the extended attribute security.SMACK64 -was not effictive until the cache had been cleaned. - -This patch fixes that problem. - -Signed-off-by: José Bollo <jobol@nonadev.net> -Acked-by: Casey Schaufler <casey@schaufler-ca.com> ---- - security/smack/smack_lsm.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c -index 487b2f3..b9393e3 100644 ---- a/security/smack/smack_lsm.c -+++ b/security/smack/smack_lsm.c -@@ -1256,9 +1256,13 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) - * Don't do anything special for these. - * XATTR_NAME_SMACKIPIN - * XATTR_NAME_SMACKIPOUT -- * XATTR_NAME_SMACKEXEC - */ -- if (strcmp(name, XATTR_NAME_SMACK) == 0) -+ if (strcmp(name, XATTR_NAME_SMACK) == 0) { -+ struct super_block *sbp = d_backing_inode(dentry)->i_sb; -+ struct superblock_smack *sbsp = sbp->s_security; -+ -+ isp->smk_inode = sbsp->smk_default; -+ } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) - isp->smk_task = NULL; - else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) - isp->smk_mmap = NULL; --- -2.7.4 - diff --git a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0003-Smack-ignore-null-signal-in-smack_task_kill.patch b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0003-Smack-ignore-null-signal-in-smack_task_kill.patch deleted file mode 100644 index 67761ae46..000000000 --- a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0003-Smack-ignore-null-signal-in-smack_task_kill.patch +++ /dev/null @@ -1,39 +0,0 @@ -From aa63c4f8ece0c54a9be735ac38667f11fcd6f44a Mon Sep 17 00:00:00 2001 -From: Rafal Krypa <r.krypa@samsung.com> -Date: Mon, 4 Apr 2016 11:14:53 +0200 -Subject: [PATCH 3/4] Smack: ignore null signal in smack_task_kill - -Kill with signal number 0 is commonly used for checking PID existence. -Smack treated such cases like any other kills, although no signal is -actually delivered when sig == 0. - -Checking permissions when sig == 0 didn't prevent an unprivileged caller -from learning whether PID exists or not. When it existed, kernel returned -EPERM, when it didn't - ESRCH. The only effect of policy check in such -case is noise in audit logs. - -This change lets Smack silently ignore kill() invocations with sig == 0. - -Signed-off-by: Rafal Krypa <r.krypa@samsung.com> -Acked-by: Casey Schaufler <casey@schaufler-ca.com> ---- - security/smack/smack_lsm.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c -index b9393e3..c916f58 100644 ---- a/security/smack/smack_lsm.c -+++ b/security/smack/smack_lsm.c -@@ -2056,6 +2056,9 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, - struct smack_known *tkp = smk_of_task_struct(p); - int rc; - -+ if (!sig) -+ return 0; /* null signal; existence test */ -+ - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); - smk_ad_setfield_u_tsk(&ad, p); - /* --- -2.7.4 - diff --git a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0004-Smack-Assign-smack_known_web-label-for-kernel-thread.patch b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0004-Smack-Assign-smack_known_web-label-for-kernel-thread.patch deleted file mode 100644 index 4281c201c..000000000 --- a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0004-Smack-Assign-smack_known_web-label-for-kernel-thread.patch +++ /dev/null @@ -1,49 +0,0 @@ -From b2b9e7ec8e79ede841104f76464f4b77c057b011 Mon Sep 17 00:00:00 2001 -From: jooseong lee <jooseong.lee@samsung.com> -Date: Thu, 3 Nov 2016 10:55:43 +0100 -Subject: [PATCH 4/4] Smack: Assign smack_known_web label for kernel thread's -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Assign smack_known_web label for kernel thread's socket in the sk_alloc_security hook - -Creating struct sock by sk_alloc function in various kernel subsystems -like bluetooth dosen't call smack_socket_post_create(). In such case, -received sock label is the floor('_') label and makes access deny. - -Refers-to: https://review.tizen.org/gerrit/#/c/80717/4 - -Change-Id: I2e5c9359bfede84a988fd4d4d74cdb9dfdfc52d8 -Signed-off-by: jooseong lee <jooseong.lee@samsung.com> -Signed-off-by: José Bollo <jose.bollo@iot.bzh> ---- - security/smack/smack_lsm.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c -index c916f58..cc6769b 100644 ---- a/security/smack/smack_lsm.c -+++ b/security/smack/smack_lsm.c -@@ -2138,8 +2138,16 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) - if (ssp == NULL) - return -ENOMEM; - -- ssp->smk_in = skp; -- ssp->smk_out = skp; -+ /* -+ * Sockets created by kernel threads receive web label. -+ */ -+ if (unlikely(current->flags & PF_KTHREAD)) { -+ ssp->smk_in = &smack_known_web; -+ ssp->smk_out = &smack_known_web; -+ } else { -+ ssp->smk_in = skp; -+ ssp->smk_out = skp; -+ } - ssp->smk_packet = NULL; - - sk->sk_security = ssp; --- -2.7.4 - diff --git a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.4/0001-Smack-File-receive-for-sockets.patch b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.12/0001-Smack-File-receive-for-sockets.patch index 4021e5d38..4021e5d38 100644 --- a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.4/0001-Smack-File-receive-for-sockets.patch +++ b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.12/0001-Smack-File-receive-for-sockets.patch diff --git a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.4/0002-smack-fix-cache-of-access-labels.patch b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.12/0002-smack-fix-cache-of-access-labels.patch index c516f3aa5..c516f3aa5 100644 --- a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.4/0002-smack-fix-cache-of-access-labels.patch +++ b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.12/0002-smack-fix-cache-of-access-labels.patch diff --git a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.4/0003-Smack-ignore-null-signal-in-smack_task_kill.patch b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.12/0003-Smack-ignore-null-signal-in-smack_task_kill.patch index c9180bb9f..c9180bb9f 100644 --- a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.4/0003-Smack-ignore-null-signal-in-smack_task_kill.patch +++ b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.12/0003-Smack-ignore-null-signal-in-smack_task_kill.patch diff --git a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.4/0004-Smack-Assign-smack_known_web-label-for-kernel-thread.patch b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.12/0004-Smack-Assign-smack_known_web-label-for-kernel-thread.patch index a1eeac3d7..a1eeac3d7 100644 --- a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.4/0004-Smack-Assign-smack_known_web-label-for-kernel-thread.patch +++ b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.12/0004-Smack-Assign-smack_known_web-label-for-kernel-thread.patch diff --git a/meta-app-framework/recipes-security/cynara/cynara/0001-gcc-7-requires-include-functional-for-std-function.patch b/meta-app-framework/recipes-security/cynara/cynara/0001-gcc-7-requires-include-functional-for-std-function.patch new file mode 100644 index 000000000..bd060b26d --- /dev/null +++ b/meta-app-framework/recipes-security/cynara/cynara/0001-gcc-7-requires-include-functional-for-std-function.patch @@ -0,0 +1,38 @@ +From 2169344adbb42ff580856204e2b290e3b04fd447 Mon Sep 17 00:00:00 2001 +From: Changhyeok Bae <changhyeok.bae@gmail.com> +Date: Sun, 17 Dec 2017 15:28:28 +0000 +Subject: [PATCH] gcc-7 requires include <functional> for std::function + +Signed-off-by: Changhyeok Bae <changhyeok.bae@gmail.com> +--- + src/common/types/PolicyBucket.h | 1 + + src/cyad/AdminPolicyParser.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/src/common/types/PolicyBucket.h b/src/common/types/PolicyBucket.h +index 029d3dd..1bceeca 100644 +--- a/src/common/types/PolicyBucket.h ++++ b/src/common/types/PolicyBucket.h +@@ -30,6 +30,7 @@ + #include <set> + #include <string> + #include <vector> ++#include <functional> + + #include <exceptions/NotImplementedException.h> + #include <types/pointers.h> +diff --git a/src/cyad/AdminPolicyParser.h b/src/cyad/AdminPolicyParser.h +index 53dde23..f38c194 100644 +--- a/src/cyad/AdminPolicyParser.h ++++ b/src/cyad/AdminPolicyParser.h +@@ -25,6 +25,7 @@ + + #include <istream> + #include <memory> ++#include <functional> + + #include <cyad/CynaraAdminPolicies.h> + +-- +2.7.4 + diff --git a/meta-app-framework/recipes-security/cynara/cynara_git.bbappend b/meta-app-framework/recipes-security/cynara/cynara_git.bbappend index 9a61e7044..4c38da1cc 100644 --- a/meta-app-framework/recipes-security/cynara/cynara_git.bbappend +++ b/meta-app-framework/recipes-security/cynara/cynara_git.bbappend @@ -1,3 +1,8 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:" +SRC_URI_append = " file://0001-gcc-7-requires-include-functional-for-std-function.patch" + +CXXFLAGS_append = " -Wimplicit-fallthrough=0" + pkg_postinst_${PN} () { # Fail on error. set -e diff --git a/meta-app-framework/recipes-support/libcap/libcap_%.bbappend b/meta-app-framework/recipes-support/libcap/libcap_%.bbappend index fbe893501..c4561db22 100644 --- a/meta-app-framework/recipes-support/libcap/libcap_%.bbappend +++ b/meta-app-framework/recipes-support/libcap/libcap_%.bbappend @@ -1,5 +1,2 @@ FILESEXTRAPATHS_append_class-native := ":${THISDIR}/${PN}" SRC_URI_append_class-native = " file://removing-capability-enforcement.patch" -PACKAGECONFIG_class-native ?= "attr" -DEPENDS_append_class-native = " attr-native" - diff --git a/meta-app-framework/recipes-support/libmicrohttpd/libmicrohttpd_0.9.55.bb b/meta-app-framework/recipes-support/libmicrohttpd/libmicrohttpd_0.9.55.bb deleted file mode 100644 index bb650ce23..000000000 --- a/meta-app-framework/recipes-support/libmicrohttpd/libmicrohttpd_0.9.55.bb +++ /dev/null @@ -1,25 +0,0 @@ -DESCRIPTION = "A small C library that is supposed to make it easy to run an HTTP server as part of another application" -HOMEPAGE = "http://www.gnu.org/software/libmicrohttpd/" -LICENSE = "LGPL-2.1+" -LIC_FILES_CHKSUM = "file://COPYING;md5=9331186f4f80db7da0e724bdd6554ee5" -SECTION = "net" -DEPENDS = "libgcrypt gnutls file" - -SRC_URI = "http://ftp.gnu.org/gnu/libmicrohttpd/${BPN}-${PV}.tar.gz" -SRC_URI[md5sum] = "1c20f84a8b9cf692dd50b558b3571a3a" -SRC_URI[sha256sum] = "0c1cab8dc9f2588bd3076a28f77a7f8de9560cbf2d80e53f9a8696ada80ed0f8" - -inherit autotools lib_package pkgconfig gettext - -EXTRA_OECONF += "--disable-static --with-gnutls=${STAGING_LIBDIR}/../" - -PACKAGECONFIG ?= "curl" -PACKAGECONFIG_append_class-target = "\ - ${@bb.utils.contains('DISTRO_FEATURES', 'largefile', 'largefile', '', d)} \ -" -PACKAGECONFIG[largefile] = "--enable-largefile,--disable-largefile,," -PACKAGECONFIG[curl] = "--enable-curl,--disable-curl,curl," - -do_compile_append() { - sed -i s:-L${STAGING_LIBDIR}::g libmicrohttpd.pc -} diff --git a/meta-ivi-common/recipes-test/freetype/freetype_2.7.1.bbappend b/meta-ivi-common/recipes-test/freetype/freetype_2.8.bbappend index 0593cf573..282ce784a 100644 --- a/meta-ivi-common/recipes-test/freetype/freetype_2.7.1.bbappend +++ b/meta-ivi-common/recipes-test/freetype/freetype_2.8.bbappend @@ -4,8 +4,8 @@ SRC_URI =+ "${SOURCEFORGE_MIRROR}/freetype/ft2demos-${PV}.tar.bz2;name=ft2demos file://0001-Makefile-dont-build-gfx-demos.patch;patchdir=../ft2demos-${PV} \ file://0001-ft2demos-Makefile-Do-not-hardcode-libtool-path.patch;patchdir=../ft2demos-${PV} \ " -SRC_URI[ft2demos.md5sum] = "5c10cb35bec755dbd3f7999e0f97aee3" -SRC_URI[ft2demos.sha256sum] = "d3f8a0d5a3f0d58701133458a8c1d3f97f658869f3c904b1fda447ed3b290ecd" +SRC_URI[ft2demos.md5sum] = "61db5831e213acb843f0fc6d10186054" +SRC_URI[ft2demos.sha256sum] = "2b6ce0d36bcb43fcc8aac07a0287982d855571ee271c3803c768e501f9c1a233" PACKAGES =+ "${PN}-demos" diff --git a/meta-ivi-common/recipes-test/packagegroups/packagegroup-ivi-common-test.bb b/meta-ivi-common/recipes-test/packagegroups/packagegroup-ivi-common-test.bb index bd42820fc..44fabae06 100644 --- a/meta-ivi-common/recipes-test/packagegroups/packagegroup-ivi-common-test.bb +++ b/meta-ivi-common/recipes-test/packagegroups/packagegroup-ivi-common-test.bb @@ -34,9 +34,6 @@ RDEPENDS_${PN} += "\ " # to be added, but needs LICENSE_FLAGS_WHITELIST="non-commercial" # netperf -# wayland-fits is broken in jethro, https://www.mail-archive.com/openembedded-devel@lists.openembedded.org/msg46505.html -# http://errors.yoctoproject.org/Errors/Details/35141/ -# wayland-fits # FTBS, SPEC-316 # himeno diff --git a/meta-ivi-common/recipes-test/wayland/wayland-fits_%.bbappend b/meta-ivi-common/recipes-test/wayland/wayland-fits_%.bbappend deleted file mode 100644 index 772f81b0f..000000000 --- a/meta-ivi-common/recipes-test/wayland/wayland-fits_%.bbappend +++ /dev/null @@ -1,5 +0,0 @@ -# Disable GTK+ and EFL tests -PACKAGECONFIG = "" - -# UInput driver is necessary on QEMU -RDEPENDS_${PN}_append_qemux86-64 = " kernel-module-uinput" diff --git a/meta-ivi-common/recipes-test/wayland/wayland-fits_git.bbappend b/meta-ivi-common/recipes-test/wayland/wayland-fits_git.bbappend deleted file mode 100644 index 84c7cfdbe..000000000 --- a/meta-ivi-common/recipes-test/wayland/wayland-fits_git.bbappend +++ /dev/null @@ -1,2 +0,0 @@ -# Updating to latest version is necessary for Weston >= 1.9.0 -SRCREV = "f108335e374772ae2818a30ae37fe6fcda81980f" diff --git a/meta-netboot/classes/netboot.bbclass b/meta-netboot/classes/netboot.bbclass index 65ca4a15d..363e6bcc9 100644 --- a/meta-netboot/classes/netboot.bbclass +++ b/meta-netboot/classes/netboot.bbclass @@ -1,10 +1,7 @@ # Enable network bootable image and initrd/initramfs -# add image classes for uboot -IMAGE_CLASSES += "${@'image_types_uboot' if (d.getVar("KERNEL_IMAGETYPE", True) == "uImage") else ''}" - python () { - if (bb.utils.contains_any("IMAGE_FSTYPES",["live","vmdk","vmdk.xz"],True,False,d)): + if (bb.utils.contains_any("IMAGE_FSTYPES",["live","wic.vmdk"],True,False,d)): # typical case for Minnowboard Max d.setVar("INITRD_IMAGE","initramfs-netboot-image") d.setVar("INITRD_IMAGE_LIVE",d.getVar("INITRD_IMAGE",True)) diff --git a/templates/base/00_local.conf.agl.inc b/templates/base/00_local.conf.agl.inc index 1cfd90557..1128b323b 100644 --- a/templates/base/00_local.conf.agl.inc +++ b/templates/base/00_local.conf.agl.inc @@ -6,3 +6,6 @@ DISTRO = "poky-agl" #see meta-agl/meta-agl/conf/include/base-agl.inc require conf/include/base-agl.inc + +# Temporarily disable GObject Introspection Data +GI_DATA_ENABLED = "False" diff --git a/templates/base/bblayers.conf.sample b/templates/base/bblayers.conf.sample index 6bccb7932..d86954698 100644 --- a/templates/base/bblayers.conf.sample +++ b/templates/base/bblayers.conf.sample @@ -35,7 +35,6 @@ AGL_CORE_LAYERS = " \ AGL_CORE_DEPENDENCY_LAYERS = " \ ${METADIR}/meta-openembedded/meta-oe \ ${METADIR}/meta-openembedded/meta-multimedia \ - ${METADIR}/meta-openembedded/meta-efl \ ${METADIR}/meta-openembedded/meta-networking \ ${METADIR}/meta-openembedded/meta-python \ ${METADIR}/meta-openembedded/meta-filesystems \ diff --git a/templates/feature/agl-sota/50_bblayers.conf.inc b/templates/feature/agl-sota/50_bblayers.conf.inc index bdcf07605..22a718f43 100644 --- a/templates/feature/agl-sota/50_bblayers.conf.inc +++ b/templates/feature/agl-sota/50_bblayers.conf.inc @@ -2,7 +2,6 @@ BBLAYERS =+ " \ ${METADIR}/meta-updater \ ${METADIR}/meta-openembedded/meta-filesystems \ ${METADIR}/meta-openembedded/meta-python \ - ${METADIR}/meta-openembedded/meta-ruby \ ${METADIR}/meta-rust \ " diff --git a/templates/machine/dragonboard-410c/50_setup.sh b/templates/machine/dragonboard-410c/50_setup.sh deleted file mode 100644 index 7be1dad32..000000000 --- a/templates/machine/dragonboard-410c/50_setup.sh +++ /dev/null @@ -1 +0,0 @@ -find_and_ack_eula $METADIR/meta-qcom |