File gupnp-av-0.14.4.obscpio of Package gupnp-av
07070100000000000081A40000000000000000000000016860451500000F5A000000000000000000000000000000000000001E00000000gupnp-av-0.14.4/.clang-format---
Language: Cpp
# BasedOnStyle: Mozilla
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: TopLevel
AlwaysBreakAfterReturnType: TopLevel
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterEnum: true
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: true
AfterExternBlock: true
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: false
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeComma
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 8
Cpp11BracedListStyle: false
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
- Regex: '.*'
Priority: 1
SortPriority: 0
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: false
IndentGotoLabels: false
IndentPPDirectives: None
IndentWidth: 8
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: false
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: Always
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Latest
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
...
07070100000001000081A400000000000000000000000168604515000000AB000000000000000000000000000000000000001E00000000gupnp-av-0.14.4/.editorconfig# https://editorconfig.org
[*]
end_of_line = lf
insert_final_newline = true
[*.{c,h}]
indent_style = space
indent_size = 8
[*.xml]
indent_style = space
indent_size = 2
07070100000002000081A40000000000000000000000016860451500000092000000000000000000000000000000000000001B00000000gupnp-av-0.14.4/.gitignorebuild-aux
*~
gupnp-av-marshal*
*.swp
/tests/test-search-criteria-parser
/vala/gupnp-av-1.0.stamp
/vala/gupnp-av-1.0.vapi
build
meson.build.user
07070100000003000041ED0000000000000000000000026860451500000000000000000000000000000000000000000000001B00000000gupnp-av-0.14.4/.gitlab-ci07070100000004000081A400000000000000000000000168604515000019B9000000000000000000000000000000000000001F00000000gupnp-av-0.14.4/.gitlab-ci.yml## This file is generated. Do not modify
include:
- '/.gitlab-ci/tags.yml'
- project: "Infrastructure/freedesktop-ci-templates"
file: "templates/fedora.yml"
ref: "32afe5644697e503af18a736587c8619fa036a72"
- project: "Infrastructure/freedesktop-ci-templates"
file: "templates/ci-fairy.yml"
ref: "32afe5644697e503af18a736587c8619fa036a72"
- component: "gitlab.gnome.org/GNOME/citemplates/release-service@master"
inputs:
dist-job-name: build-fedora:42@x86_64
# gupnp tags are always of the format {PROJECT_NAME}-{version}
tarball-artifact-path: "build/meson-dist/${CI_COMMIT_TAG}.tar.xz"
- project: "GNOME/citemplates"
file: "templates/default-rules.yml"
variables:
MESON_TEST_TIMEOUT_MULTIPLIER: 3
stages:
- review
- prepare
- build
- test
- website
- analysis
- deploy
.check-template: &check
extends:
- .fdo.ci-fairy
artifacts:
expire_in: 1 week
paths:
- check-junit-report.xml
reports:
junit: check-junit-report.xml
check-commit-log:
variables:
GIT_DEPTH: "100"
stage: review
script:
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
then
ci-fairy check-commits --junit-xml=check-junit-report.xml ;
else
echo "Not a merge request" ;
fi
<<: *check
check-merge-request:
variables:
GIT_STRATEGY: none
stage: review
script:
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
then
ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-junit-report.xml ;
else
echo "Not a merge request" ;
fi
<<: *check
.build-template: &build
stage: build
script:
- meson . build --prefix=/usr -Db_coverage=true -Dgtk_doc=true
- ninja -C build
- meson dist -C build --no-tests
artifacts:
expire_in: 1 day
paths:
- build
.test-template: &test
stage: test
variables:
G_SLICE: "always-malloc"
MALLOC_CHECK_: "3"
script:
- cd build
- |
# Remove the many "CI_" variables from the environment. Meson dumps the
# whole environment for every failed test, and that gives a whole
# screenful of junk each time unless we strip these.
unset $(env|grep -o '^CI_[^=]*')
env LANG=C.UTF-8 LC_ALL=C.UTF-8 meson test --timeout-multiplier ${MESON_TEST_TIMEOUT_MULTIPLIER} --print-errorlogs ${MESON_TEST_EXTRA_ARGS} --suite gupnp-av
after_script:
- |
echo "Distribution: "
echo
egrep '^NAME=|^VERSION=' /etc/os-release
echo
echo "Test suite settings:"
echo
echo "G_MESSAGES_DEBUG: ${G_MESSAGES_DEBUG}"
echo "MESON_TEST_EXTRA_ARGS: ${MESON_TEST_EXTRA_ARGS}"
echo
echo "These values can be set at https://gitlab.gnome.org/GNOME/gupnp-av/pipelines/new"
artifacts:
expire_in: 1 day
when: always
paths:
- build
reports:
junit: "build/meson-logs/testlog.junit.xml"
.gupnp-av.fedora@common:
variables:
BASE_TAG: '${FEDORA_BASE_TAG}'
FDO_UPSTREAM_REPO: GNOME/gupnp-av
FDO_DISTRIBUTION_PACKAGES: "clang clang-analyzer gcovr git libasan libubsan python3-gobject meson python3-pip xmlto gobject-introspection-devel libxml2-devel vala ninja-build libnghttp2-devel libpsl-devel sqlite-devel python3-setuptools"
FDO_DISTRIBUTION_EXEC: .gitlab-ci/setup-image-fedora.sh
.gupnp-av.fedora:42@x86_64:
extends: .gupnp-av.fedora@common
variables:
FDO_DISTRIBUTION_VERSION: "42"
FDO_DISTRIBUTION_TAG: "x86_64-${BASE_TAG}"
build-container-fedora:42@x86_64:
extends:
- .fdo.container-build@fedora
- .gupnp-av.fedora:42@x86_64
stage: prepare
variables:
GIT_STRATEGY: none
build-fedora:42@x86_64:
extends:
- .fdo.distribution-image@fedora
- .gupnp-av.fedora:42@x86_64
needs:
- build-container-fedora:42@x86_64
<<: *build
test-fedora:42@x86_64:
tags:
- ipv6
extends:
- .fdo.distribution-image@fedora
- .gupnp-av.fedora:42@x86_64
needs:
- build-fedora:42@x86_64
<<: *test
coverage-analysis:
extends:
- .fdo.distribution-image@fedora
- .gupnp-av.fedora:42@x86_64
stage: analysis
allow_failure: true
script:
- cd build
- mkdir -p coveragereport
- gcovr --html-details --print-summary --root=.. --exclude=../build --exclude=../subprojects --exclude=../docs/reference --exclude=../tests --exclude=../tools --exclude=../examples --output coveragereport/index.html
coverage: '/^lines: (\d+\.\d+\%)/'
artifacts:
when: always
paths:
- build/coveragereport
needs:
- test-fedora:42@x86_64
static-scan:
extends:
- .fdo.distribution-image@fedora
- .gupnp-av.fedora:42@x86_64
stage: analysis
needs:
- build-container-fedora:42@x86_64
script:
- meson --buildtype=debug _scan_build -Dintrospection=false
- export SCANBUILD="$PWD/.gitlab-ci/scanbuild-wrapper.sh"
- ninja -C _scan_build scan-build
artifacts:
paths:
- _scan_build/meson-logs
after_script:
- .gitlab-ci/scanbuild-plist-to-junit.py _scan_build/meson-logs/scanbuild/ > _scan_build/junit-scan-build.xml
artifacts:
reports:
junit: "_scan_build/junit-scan-build.xml"
coverity:
extends:
- .fdo.distribution-image@fedora
- .gupnp-av.fedora:42@x86_64
stage: analysis
allow_failure: true
script:
- curl https://scan.coverity.com/download/linux64 --data "token=$COVERITY_TOKEN&project=gupnp-av" --output /tmp/coverity_tool.tgz
- tar zxf /tmp/coverity_tool.tgz
- mkdir coverity-build
- cd coverity-build
- env CC=clang meson ..
- ../cov-analysis-linux64-*/bin/cov-build --dir cov-int ninja
- tar czf cov-int.tar.gz cov-int
- curl https://scan.coverity.com/builds?project=gupnp-av
--form token=$COVERITY_TOKEN --form email=mail@jensge.org
--form file=@cov-int.tar.gz --form version="`git describe --tags`"
--form description="gitlab CI build"
needs:
- build-container-fedora:42@x86_64
only:
- master
except:
changes:
- po/*.po
pages:
extends:
- .fdo.distribution-image@fedora
- .gupnp-av.fedora:42@x86_64
stage: website
script:
- mkdir -p public
- mv build/doc/gupnp-av-1.0 public/docs
artifacts:
paths:
- public
needs:
- build-fedora:42@x86_64
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH == /^wip\/.*\/ci.*$/
- if: $CI_COMMIT_BRANCH == /^wip\/.*\/.*doc.*$/
07070100000005000081A40000000000000000000000016860451500001C1C000000000000000000000000000000000000002700000000gupnp-av-0.14.4/.gitlab-ci/ci.template## This file is generated. Do not modify
include:
- '/.gitlab-ci/tags.yml'
- project: "Infrastructure/freedesktop-ci-templates"
file: "templates/fedora.yml"
ref: "32afe5644697e503af18a736587c8619fa036a72"
- project: "Infrastructure/freedesktop-ci-templates"
file: "templates/ci-fairy.yml"
ref: "32afe5644697e503af18a736587c8619fa036a72"
- component: "gitlab.gnome.org/GNOME/citemplates/release-service@master"
inputs:
dist-job-name: build-{{targets["dist"]}}
# gupnp tags are always of the format {PROJECT_NAME}-{version}
tarball-artifact-path: "build/meson-dist/${CI_COMMIT_TAG}.tar.xz"
- project: "GNOME/citemplates"
file: "templates/default-rules.yml"
variables:
MESON_TEST_TIMEOUT_MULTIPLIER: 3
stages:
- review
- prepare
- build
- test
- website
- analysis
- deploy
.check-template: &check
extends:
- .fdo.ci-fairy
artifacts:
expire_in: 1 week
paths:
- check-junit-report.xml
reports:
junit: check-junit-report.xml
check-commit-log:
variables:
GIT_DEPTH: "100"
stage: review
script:
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
then
ci-fairy check-commits --junit-xml=check-junit-report.xml ;
else
echo "Not a merge request" ;
fi
<<: *check
check-merge-request:
variables:
GIT_STRATEGY: none
stage: review
script:
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
then
ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-junit-report.xml ;
else
echo "Not a merge request" ;
fi
<<: *check
.build-template: &build
stage: build
script:
- meson . build --prefix=/usr -Db_coverage=true -Dgtk_doc=true
- ninja -C build
- meson dist -C build --no-tests
artifacts:
expire_in: 1 day
paths:
- build
.test-template: &test
stage: test
variables:
G_SLICE: "always-malloc"
MALLOC_CHECK_: "3"
script:
- cd build
- |
# Remove the many "CI_" variables from the environment. Meson dumps the
# whole environment for every failed test, and that gives a whole
# screenful of junk each time unless we strip these.
unset $(env|grep -o '^CI_[^=]*')
env LANG=C.UTF-8 LC_ALL=C.UTF-8 meson test --timeout-multiplier ${MESON_TEST_TIMEOUT_MULTIPLIER} --print-errorlogs ${MESON_TEST_EXTRA_ARGS} --suite {{project}}
after_script:
- |
echo "Distribution: "
echo
egrep '^NAME=|^VERSION=' /etc/os-release
echo
echo "Test suite settings:"
echo
echo "G_MESSAGES_DEBUG: ${G_MESSAGES_DEBUG}"
echo "MESON_TEST_EXTRA_ARGS: ${MESON_TEST_EXTRA_ARGS}"
echo
echo "These values can be set at https://gitlab.gnome.org/GNOME/{{project}}/pipelines/new"
artifacts:
expire_in: 1 day
when: always
paths:
- build
reports:
junit: "build/meson-logs/testlog.junit.xml"
{% for distro in distributions %}
{% for version in distributions[distro] %}
.{{project}}.{{distro}}@common:
variables:
BASE_TAG: '${{"{"}}{{distro|upper}}_BASE_TAG}'
FDO_UPSTREAM_REPO: GNOME/{{project}}
FDO_DISTRIBUTION_PACKAGES: "{{" ".join(packages[distro].needed)}}"
FDO_DISTRIBUTION_EXEC: .gitlab-ci/setup-image-{{distro}}.sh
.{{project}}.{{distro}}:{{version}}@{{arch}}:
extends: .{{project}}.{{distro}}@common
variables:
FDO_DISTRIBUTION_VERSION: "{{version}}"
FDO_DISTRIBUTION_TAG: "{{arch}}-${BASE_TAG}"
build-container-{{distro}}:{{version}}@{{arch}}:
extends:
- .fdo.container-build@{{distro}}
- .{{project}}.{{distro}}:{{version}}@{{arch}}
stage: prepare
variables:
GIT_STRATEGY: none
build-{{distro}}:{{version}}@{{arch}}:
extends:
- .fdo.distribution-image@{{distro}}
- .{{project}}.{{distro}}:{{version}}@{{arch}}
needs:
- build-container-{{distro}}:{{version}}@{{arch}}
<<: *build
test-{{distro}}:{{version}}@{{arch}}:
tags:
- ipv6
extends:
- .fdo.distribution-image@{{distro}}
- .{{project}}.{{distro}}:{{version}}@{{arch}}
needs:
- build-{{distro}}:{{version}}@{{arch}}
<<: *test
{% endfor %}
{% endfor %}
{% if triggers is not none %}
{% for downstream in triggers %}
trigger-{{downstream}}:
stage: analysis
needs:
- test-{{targets["downstream"]}}
trigger: {{triggers[downstream]}}
only:
- master
{% endfor %}
{% endif %}
coverage-analysis:
extends:
- .fdo.distribution-image@{{targets["coverage"].split(":")[0]}}
- .{{project}}.{{targets["coverage"]}}
stage: analysis
allow_failure: true
script:
- cd build
- mkdir -p coveragereport
- gcovr --html-details --print-summary --root=.. --exclude=../build --exclude=../subprojects --exclude=../docs/reference --exclude=../tests --exclude=../tools --exclude=../examples --output coveragereport/index.html
coverage: '/^lines: (\d+\.\d+\%)/'
artifacts:
when: always
paths:
- build/coveragereport
needs:
- test-{{targets["coverage"]}}
static-scan:
extends:
- .fdo.distribution-image@{{targets["static-scan"].split(":")[0]}}
- .{{project}}.{{targets["static-scan"]}}
stage: analysis
needs:
- build-container-{{targets["static-scan"]}}
script:
- meson --buildtype=debug _scan_build -Dintrospection=false
- export SCANBUILD="$PWD/.gitlab-ci/scanbuild-wrapper.sh"
- ninja -C _scan_build scan-build
artifacts:
paths:
- _scan_build/meson-logs
after_script:
- .gitlab-ci/scanbuild-plist-to-junit.py _scan_build/meson-logs/scanbuild/ > _scan_build/junit-scan-build.xml
artifacts:
reports:
junit: "_scan_build/junit-scan-build.xml"
coverity:
extends:
- .fdo.distribution-image@{{targets["coverity"].split(":")[0]}}
- .{{project}}.{{targets["coverity"]}}
stage: analysis
allow_failure: true
script:
- curl https://scan.coverity.com/download/linux64 --data "token=$COVERITY_TOKEN&project={{project}}" --output /tmp/coverity_tool.tgz
- tar zxf /tmp/coverity_tool.tgz
- mkdir coverity-build
- cd coverity-build
- env CC=clang meson ..
- ../cov-analysis-linux64-*/bin/cov-build --dir cov-int ninja
- tar czf cov-int.tar.gz cov-int
- curl https://scan.coverity.com/builds?project={{project}}
--form token=$COVERITY_TOKEN --form email=mail@jensge.org
--form file=@cov-int.tar.gz --form version="`git describe --tags`"
--form description="gitlab CI build"
needs:
- build-container-{{targets["coverity"]}}
only:
- master
except:
changes:
- po/*.po
pages:
extends:
- .fdo.distribution-image@{{targets["pages"].split(":")[0]}}
- .{{project}}.{{targets["pages"]}}
stage: website
script:
- mkdir -p public
- mv build/doc/{{project}}-{{api_version}} public/docs
artifacts:
paths:
- public
needs:
- build-{{targets["pages"]}}
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH == /^wip\/.*\/ci.*$/
- if: $CI_COMMIT_BRANCH == /^wip\/.*\/.*doc.*$/
07070100000006000081A4000000000000000000000001686045150000035D000000000000000000000000000000000000002600000000gupnp-av-0.14.4/.gitlab-ci/config.ymlproject: gupnp-av
api_version: 1.0
# TODO: Hardcode architecture for now
arch: x86_64
# Those are all jobs that are just run once, not on all distributions and versions
# format has to be distribution:version@arch
targets:
coverage: fedora:42@x86_64
coverity: fedora:42@x86_64
static-scan: fedora:42@x86_64
pages: fedora:42@x86_64
downstream: fedora:42@x86_64
dist: fedora:42@x86_64
# Projects to trigger after a successful build
# Format is name: gitlab project on this server
triggers:
# Distribution configurations
distributions:
fedora: [42]
packages:
fedora:
needed: ['clang', 'clang-analyzer', 'gcovr', 'git', 'libasan', 'libubsan', 'python3-gobject', 'meson', 'python3-pip', 'xmlto', 'gobject-introspection-devel', 'libxml2-devel', 'vala', 'ninja-build', 'libnghttp2-devel', 'libpsl-devel', 'sqlite-devel', 'python3-setuptools']
07070100000007000081ED00000000000000000000000168604515000010BB000000000000000000000000000000000000003700000000gupnp-av-0.14.4/.gitlab-ci/scanbuild-plist-to-junit.py#!/usr/bin/env python3
#
# SPDX-License-Identifier: MIT
#
# Usage:
# $ scanbuild-plist-to-junit.py /path/to/meson-logs/scanbuild/ > junit-report.xml
#
# Converts the plist output from scan-build into a JUnit-compatible XML.
#
# For use with meson, use a wrapper script with this content:
# scan-build -v --status-bugs -plist-html "$@"
# then build with
# SCANBUILD="/abs/path/to/wrapper.sh" ninja -C builddir scan-build
#
# For file context, $PWD has to be the root source directory.
#
# Note that the XML format is tailored towards being useful in the gitlab
# CI, the JUnit format supports more features.
#
# This file is formatted with Python Black
import argparse
import plistlib
import re
import sys
from pathlib import Path
errors = []
class Error(object):
pass
parser = argparse.ArgumentParser(
description="This tool convers scan-build's plist format to JUnit XML"
)
parser.add_argument(
"directory", help="Path to a scan-build output directory", type=Path
)
args = parser.parse_args()
if not args.directory.exists():
print(f"Invalid directory: {args.directory}", file=sys.stderr)
sys.exit(1)
# Meson places scan-build runs into a timestamped directory. To make it
# easier to invoke this script, we just glob everything on the assumption
# that there's only one scanbuild/$timestamp/ directory anyway.
for file in Path(args.directory).glob("**/*.plist"):
with open(file, "rb") as fd:
plist = plistlib.load(fd, fmt=plistlib.FMT_XML)
try:
sources = plist["files"]
for elem in plist["diagnostics"]:
e = Error()
e.type = elem["type"] # Human-readable error type
e.description = elem["description"] # Longer description
e.func = elem["issue_context"] # function name
e.lineno = elem["location"]["line"]
filename = sources[elem["location"]["file"]]
# Remove the ../../../ prefix from the file
e.file = re.sub(r"^(\.\./)*", "", filename)
errors.append(e)
except KeyError:
print(
"Failed to access plist content, incompatible format?", file=sys.stderr
)
sys.exit(1)
# Add a few lines of context for each error that we can print in the xml
# output. Note that e.lineno is 1-indexed.
#
# If one of the files fail, we stop doing this, we're probably in the wrong
# directory.
try:
current_file = None
lines = []
for e in sorted(errors, key=lambda x: x.file):
if current_file != e.file:
current_file = e.file
lines = open(current_file).readlines()
# e.lineno is 1-indexed, lineno is our 0-indexed line number
lineno = e.lineno - 1
start = max(0, lineno - 4)
end = min(len(lines), lineno + 5) # end is exclusive
e.context = [
f"{'>' if line == e.lineno else ' '} {line}: {content}"
for line, content in zip(range(start + 1, end), lines[start:end])
]
except FileNotFoundError:
pass
print('<?xml version="1.0" encoding="utf-8"?>')
print("<testsuites>")
if errors:
suites = sorted(set([s.type for s in errors]))
# Use a counter to ensure test names are unique, otherwise the CI
# display ignores duplicates.
counter = 0
for suite in suites:
errs = [e for e in errors if e.type == suite]
# Note: the grouping by suites doesn't actually do anything in gitlab. Oh well
print(f'<testsuite name="{suite}" failures="{len(errs)}" tests="{len(errs)}">')
for error in errs:
print(
f"""\
<testcase name="{counter}. {error.type} - {error.file}:{error.lineno}" classname="{error.file}">
<failure message="{error.description}">
<![CDATA[
In function {error.func}(),
{error.description}
{error.file}:{error.lineno}
---
{"".join(error.context)}
]]>
</failure>
</testcase>"""
)
counter += 1
print("</testsuite>")
else:
# In case of success, add one test case so that registers in the UI
# properly
print('<testsuite name="scanbuild" failures="0" tests="1">')
print('<testcase name="scanbuild" classname="scanbuild"/>')
print("</testsuite>")
print("</testsuites>")
07070100000008000081ED0000000000000000000000016860451500000037000000000000000000000000000000000000003000000000gupnp-av-0.14.4/.gitlab-ci/scanbuild-wrapper.sh#!/bin/sh
scan-build -v --status-bugs -plist-html "$@"
07070100000009000081ED0000000000000000000000016860451500000072000000000000000000000000000000000000003100000000gupnp-av-0.14.4/.gitlab-ci/setup-image-fedora.sh#!/usr/bin/bash
dnf clean all
pip3 install markdown gi-docgen jinja2 Markdown markupsafe pygments toml typogrify
0707010000000A000081A4000000000000000000000001686045150000002D000000000000000000000000000000000000002400000000gupnp-av-0.14.4/.gitlab-ci/tags.ymlvariables:
FEDORA_BASE_TAG: "2025-05-12.1"
0707010000000B000081A4000000000000000000000001686045150000004D000000000000000000000000000000000000001800000000gupnp-av-0.14.4/AUTHORSZeeshan Ali Khattak <zeenix@gstreamer.net>
Jorn Baayen <jorn@openedhand.com>
0707010000000C000081A400000000000000000000000168604515000067A2000000000000000000000000000000000000001800000000gupnp-av-0.14.4/COPYING GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
0707010000000D000081A4000000000000000000000001686045150000574A000000000000000000000000000000000000001500000000gupnp-av-0.14.4/NEWS0.14.4 (stable)
- Move documentation to gi-docgen
Merge requests included in this release:
- https://gitlab.gnome.org/GNOME/gupnp-av/merge_requests/9
- https://gitlab.gnome.org/GNOME/gupnp-av/merge_requests/8
All contributors to this release:
- Jens Georg <mail@jensge.org>
0.14.3 (stable)
===============
- CI fixes
0.14.2 (stable)
===============
- xml: Fix compatibility with libxml2 2.12.x
- Add missing array annotation
- build: Fix Requires: line of pkg-config file
- Loosen restriction on dc:date verification
All contributors to this release:
- Jens Georg <mail@jensge.org>
- Bastien Nocera <hadess@hadess.net>
- Bartłomiej Piotrowski <b@bpiotrowski.pl>
- Jordan Petridis <jpetridis@gnome.org>
0.14.1 (stable)
===============
- Add utility function to format GDateTime to the iso variant
DIDL expects
All contributors to this release:
- Jens Georg <mail@jensge.org>
0.14.0 (stable)
======
- Re-tag of 0.13.1 as stable version, no other changes
0.13.1 (development)
======
- Make Feature derivable again
- Fix unsetting subtitleFileType
All contributors to this release:
- Jens Georg <mail@jensge.org>
0.13.0
======
Changes since 0.12.11:
- Fix stripping @refID
- Port to modern GObject
- Drop autotools
- Allow to be used as a subproject
- Remove hand-written ref-counting, use RcBox/AtomicRcBox instead
- Obsolete code removal
All contributors to this release:
- Jens Georg <mail@jensge.org>
- Andre Klapper <a9016009@gmx.de>
0.12.11
=======
Changes since 0.12.10:
- Fix memory leak in GUPnPAVXMLDoc
- Fix parsing of storageUsed
- Fix name clash of internal XML utility functions
- Fix multiple compiler warnings with recent GCC
- Remove deprecated g_type_class_add_private
- Bump GLib requirement to 2.38
Bugs fixed in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=770174
- https://bugzilla.gnome.org/show_bug.cgi?id=778396
- https://bugzilla.gnome.org/show_bug.cgi?id=784511
All contributors to this release:
- Jens Georg <mail@jensge.org>
- Thomas Martinez <thomas.martinez@parrot.com>
0.12.10
=======
Changes since 0.12.9:
- Remove unneeded dependency on GSSDP-1.0.gir
All contributors to this release:
- Jens Georg <mail@jensge.org>
0.12.9
======
Changes since 0.12.8:
- Drop dependency on GUPnP
All contributors to this release:
- Jens Georg <mail@jensge.org>
0.12.8
======
Changes since 0.12.7:
- Remove gnome-common.
- Use -Wno-unused-parameter
- Make DIDL-Lite check less restrictive
- Distribute VAPI file
Bugs fixed in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=740266
- https://bugzilla.gnome.org/show_bug.cgi?id=751102
- https://bugzilla.gnome.org/show_bug.cgi?id=753382
All contributors to this release:
- Jens Georg <mail@jensge.org>
- Ting-Wei Lan <lantw@src.gnome.org>
0.12.7
======
Changes since 0.12.6:
- Remove use of deprecated INCLUDES.
- Fix GUPnPDIDLLiteObject namespace getters.
- Avoid warnings on missing protocol info.
- Require vapigen 0.22 to avoid endless loop on VAPI generation.
Bugs fixed in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=740265
- https://bugzilla.gnome.org/show_bug.cgi?id=741103
- https://bugzilla.gnome.org/show_bug.cgi?id=741555
- https://bugzilla.gnome.org/show_bug.cgi?id=740365
All contributors to this release:
- Sven Neumann <neumann@teufel.de>
- Jens Georg <mail@jensge.org>
- Philip Withnall <philip.withnall@collabora.co.uk>
0.12.6
======
Changes since 0.12.5:
- Fix some coverity issues.
- lazy-create XML namespaces so only used-ones are declared.
Bugs fixed in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=705564
- https://bugzilla.gnome.org/show_bug.cgi?id=730590
- https://bugzilla.gnome.org/show_bug.cgi?id=730591
- https://bugzilla.gnome.org/show_bug.cgi?id=731033
All contributors to this release:
- Jens Georg <mail@jensge.org>
0.12.5
======
Changes since 0.12.4:
- Fix name of cleartext-size property.
- Fix creation of pv namespace in DIDLLite parser.
- Check for empty mandatory tags in UpdateObject.
Bugs fixed in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=705522
- https://bugzilla.gnome.org/show_bug.cgi?id=719377
All contributors to this release:
- Parthiban Balasubramanian <p.balasubramanian@cablelabs.com>
- Jens Georg <mail@jensge.org>
0.12.4
======
Changes since 0.12.3:
- Add support for pv:subtitleFileUri and pv:subtitleFileType
Bugs fixed in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=695990
All contributors to this release:
- Jens Georg <mail@jensge.org>
0.12.3
======
Changes since 0.12.2:
- Add support for link protection DLNA flags.
- Fix DLNA.ORG_PS generation.
- Add res@dlna:cleartextSize attribute.
- Only use DLNA XML namespace when it's actually used.
- Add res@dlna:trackTotal attribute.
Bugs fixed in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=705564
- https://bugzilla.gnome.org/show_bug.cgi?id=707495
- https://bugzilla.gnome.org/show_bug.cgi?id=702557
- https://bugzilla.gnome.org/show_bug.cgi?id=706926
- https://bugzilla.gnome.org/show_bug.cgi?id=706928
All contributors to this release:
- Parthiban Balasubramanian <p.balasubramanian@cablelabs.com>
- Jens Georg <mail@jensge.org>
- Craig Pratt <craig@ecaspia.com>
0.12.2
======
Changes since 0.12.1:
- Fix VAPI generation if GObject-introspection version is >= 1.36.
- Fix vala bindings for LastChangeParser.parse_last_change.
- Small improvement to resource matching.
- Fix DIDLLiteContainer.get_total_deleted_child_count return value.
- Fix compiling with -Wall -Werror.
- Fix gtk-doc warnings.
All contributors to this release:
Jens Georg <mail@jensge.org>
Ludovic Ferrandis <ludovic.ferrandis@intel.com>
0.12.1
======
Changes since 0.12.0:
- Fix compiler warnings.
- Update .gitignore.
All contributors to this release:
Andreas Henriksson <andreas@fatal.se>
Krzesimir Nowak <qdlacz@gmail.com>
0.12.0
======
Changes since 0.11.6:
- Fix implicit dependency on glib 2.32.
- Explicitly call AM_MAINTAINER_MODE([enable]).
All contributors to this release:
Jens Georg <mail@jensge.org>
Krzesimir Nowak <qdlacz@gmail.com>
0.11.6
======
Changes since 0.11.5:
- Fix an unitialized variable.
- Fix a wrong use of BAD_CAST.
- Fix handling of updateID in the CDS LastChange parser.
- Fix CDS LastChange test.
All contributors to this release:
Jens Georg <jensg@openismus.com>
Mark Ryan <mark.d.ryan@intel.com>
Bugs fixed in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=689701
- https://bugzilla.gnome.org/show_bug.cgi?id=689808
0.11.5
======
Changes since 0.11.4:
- Fix API definition in gupnp-cds-last-change-parser.h
- Set items in a media collection to "restricted" by default.
All contributors to this release:
Jens Georg <jensg@openismus.com>
Ludovic Ferrandis <ludovic.ferrandis@intel.com>
Bugs fixed in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=689517
0.11.4
======
Changes since 0.11.3:
- Fix DIDL_S parsing issues in GUPnPMediaCollection.
- Fix reference count issues in GUPnPMediaCollection.
- Add more tests for GUPnPMediaCollection.
- Add test for LastChange parser.
- Fix LD_LIBRARAY_PATH handling on make check.
- Silence XSD validation errors on make check.
- Silence makefile portability warnings.
- Some gtk-doc fixes.
- Add LastChange parser for LastChange in ContentDirectory:3 including tests.
All contributors to this release:
Jens Georg <jensg@openismus.com>
Krzesimir Nowak <krnowak@openismus.com>
Regis Merlino <regis.merlino@intel.com>
Bugs fixed in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=689094
- https://bugzilla.gnome.org/show_bug.cgi?id=689141
- https://bugzilla.gnome.org/show_bug.cgi?id=689276
0.11.3
======
Changes since 0.11.2:
- Fix documentation generation for recently added functionality.
- Tweak XSD files to make the validation shut up completely.
- Fix an issue in the DIDL-Lite filtering.
- Add new class GUPnPMediaCollection for parsing and creation of DIDL_S
playlists.
All contributors to this release:
Jens Georg <jensg@openismus.com>
Bugs fixed in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=687462
0.11.2
======
Changes since 0.11.1:
- Implement fragment handling and verification in DIDLLiteObject.
- Don't error out if vapigen cannot be found.
All contributors to this release:
Krzesimir Nowak <krnowak@openismus.com>
Jens Georg <mail@jensge.org>
0.11.1
======
Changes since 0.11.0:
- Add m4 vapigen detection macro.
- Fix introspection install dirs.
- Fix objectUpdateID setter.
- Add a FeatureList parser.
- Add some XML fragment getters for DIDLLiteObject.
- Lower G-I requirements.
- Enable introspection during distcheck.
- Undeprecate single-value _{get|set}_creator methods.
Bugs fixed in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=685963
- https://bugzilla.gnome.org/show_bug.cgi?id=686464
All contributors to this release:
Jens Georg <mail@jensge.org>
Regis Merlino <regis.merlino@intel.com>
Christophe Guiraud <christophe.guiraud@intel.com>
0.11.0
======
Changes since 0.10.3:
- Add support for properties needed to implement MediaServer:3 "Track changes"
functionality.
- Add proper upnp:createClass support.
- Clean-up pkg-config files and link to the correct libraries instead of
relying on gupnp leaking the right ones.
- Generate vapi from GIR files.
All contributors to this release:
Krzesimir Nowak <krnowak@openismus.com>
Jens Georg <mail@jensge.org>
Andreas Henriksson <andreas@fatal.se>
Christophe Guiraud <christophe.guiraud@intel.com>
Bug fixed in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=684297
- https://bugzilla.gnome.org/show_bug.cgi?id=685477
Changes in dependencies:
- gupnp >= 0.19.0 for proper cleaned pkg-config file consistency.
0.10.3
======
Changes since 0.10.2:
- Ignore case when parsing DIDLLite and LastChange.
- Fix gupnp_didl_lite_container_get_{create|search}_classes.
- Fix a potential memory corruption in parse_additional_info.
All contributors to this release:
Jens Georg <mail@jensge.org>
Mark Ryan <mark.d.ryan@intel.com>
Bugs fixes in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=674322
- https://bugzilla.gnome.org/show_bug.cgi?id=676372
- https://bugzilla.gnome.org/show_bug.cgi?id=678784
0.10.2
======
Changes since 0.10.1:
- Update Autotools integration.
- Create xz tarballs by default.
- Several fixes from static code analysis.
- Fix an endless loop on really largs {Source,Sink}ProtocolInfo strings.
- Fix a crash in gupnp_didl_lite_contributor_get_name.
- Fix documentation for gupnp_didl_lite_object_get_parent_id.
- Fix a memory leak in resolution parsing.
- Allow OP, CI and PS params without DLNA profile.
All contributors to this release:
Jens Georg <mail@jensge.org>
Javier Jardón <jjardon@gnome.org>
Mark Ryan <mark.d.ryan@intel.com>
Bugs fixed in this release:
- https://bugzilla.gnome.org/show_bug.cgi?id=671246
- https://bugzilla.gnome.org/show_bug.cgi?id=674319
- https://bugzilla.gnome.org/show_bug.cgi?id=674324
- https://bugzilla.gnome.org/show_bug.cgi?id=674325
- https://bugzilla.gnome.org/show_bug.cgi?id=653894
0.10.1
======
Changes since 0.10.0:
- Bump minimum dependency of GUPnP to 0.17.0.
All contributors to this release:
Jens Georg <mail@jensge.org>
0.10.0
======
Changes since 0.9.1:
- Verify passed date in DIDL. Not a full verification but a small sanity
check.
All contributors to this release:
Topi Santakivi <topi.santakivi@digia.com>
Jens Georg <mail@jensge.org>
0.9.1
=====
Changes since 0.9.0:
- Wrong validation of boolean arguments led to DIDL parsing regressions in
control points
All contributors to this release:
Jens Georg <mail@jensge.org>
0.9.0
=====
Changes since 0.8.0:
- Wrong XML namespace for dlna attributes.
- Add a sanity check for @restricted.
- Updated gobject-introspection annotations.
- add upnp:searchClass to containers.
- make upnp:createClass@includeDerived mandatory.
- add unpn:storageUsed property and make it mandatory for
object.container.storageFolder.
All contributors to this release:
Jens Georg <mail@jensge.org>
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
Topi Santakivi <topi.santakivi@digia.com>
0.8.0
=====
Changes since 0.7.1:
- Fix XML node names for 'artist' and 'author'.
- Explicitly link test programs. This should fix the DSO build issue on Fedora.
- Use LDADD rather than LDFLAGS in Makefile.am.
Bug fixed in this release:
2222 - DIDLLiteObject get_artists()/get_authors() broken
All contributors to this release:
Jussi Kukkonen <jku@linux.intel.com>
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
Luis de Bethencourt <luis@debethencourt.com>
0.7.1
=====
Another micro release in the unstable 0.7.x branch that brings in all new
fixes from the stable 0.6.3 release.
All contributors to this release:
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
0.7.0
=====
The first release in the new unstable 0.7.x branch.
- Add API to set/get dlna:dlnaManaged attribute.
- Add API to add/list createClass elements to/of DIDL-Lite containers.
- Declare/create the DLNA namespace only once at the start of the DIDL-Lite
document (just like upnp and dc namespaces) and pass that to each object
in that document.
- Correct minor typo/c&p mistakes in docs.
- Use correct function to set XML attributes.
- Minor coding-style fixes to doc comments.
All contributors to this release:
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
0.6.2
=====
Another micro release that bumps the g-i requirement to 0.9.5.
We either have the option of staying with the older gobject-introspection and
keeping disto packagers happy or fix our .gir build against latest (and
unstable) gobject-introspection that happens to be part of GNOME 2.32. After
looking at possible alternatives, talking to a few people and keeping in mind
that we mainly stabalized for GNOME 2.32, we've decided to go for the latter
choice.
All contributors to this release:
Vincent Untz <vuntz@gnome.org>
0.6.1
=====
A micro release that corrects the GIR generation rule and make it work against
the latest gobject-intrsopection.
All contributors to this release:
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
0.6.0
=====
Changes since 0.5.9:
- Add mising symbols to docs.
- Remove redundant entries from doc sections.
- Doc system should ignore all private headers.
- Don't use deprecated gobject API.
- "genre" is in the upnp namespace, not dc.
Bug fixed in this release:
2191 - gupnp-av uses dc:genre instead of upnp:genre
All contributors to this release:
Sven Neumann <s.neumann@raumfeld.com>
Jens Georg <mail@jensge.org>
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
0.5.9
=====
Changes since 0.5.8:
- Add 64bit size property to allow resources to be bigger than 2-GB.
- Mircoseconds part of duration in resources needs to be a 3-digit number
as per DLNA requirement (7.3.22.1).
- Don't set the operation parameter if no operations are supported as per DLNA
requirement (7.3.33.3).
Bug fixed in this release:
2183 - size property of DIDL resource should be 64bit unsigned according to UPnP
spec
All contributors to this release:
Jens Georg <mail@jensge.org>
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
0.5.8
=====
Changes since 0.5.7:
- Fix crashes in DIDLLiteContributor API.
- Remove incomplete and broken DLNA guessing code. Applications should use
gupnp-dlna now for all their DLNA needs.
- Do set the 'dlna:profileID' property of 'albumArtURI' node and treat it as
mandatory as per DLNA guidelines (7.3.61.3).
- Prefer non-transcoded resources over transcoded ones when choosing compatible
resources for a particular MediaRenderer.
- Minor correction to DIDL filtering code.
- Some other minor improvements/fixes.
Bug fixed in this release:
2187 - GUPnPDIDLLiteContributor class doesn't work
All contributors to this release:
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
0.5.7
=====
Changes since 0.5.6:
- Make namespace properties on GUPnPDIDLLiteObject readable and provide
getter functions for them.
- Improve performance of DIDL-Lite parsing by moving namespace lookups to
GUPnPDIDLLiteParser.
All contributors to this release:
Sven Neumann <s.neumann@raumfeld.com>
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
0.5.6
=====
Changes since 0.5.5:
- Optimize namespace handling in DIDL-Lite handling code.
- Hide internal function gupnp_didl_lite_object_new_from_xml().
- Remove new redundant gupnp_didl_lite_container_new_from_xml().
- Free the array allocated by xmlGetNsList().
All contributors to this release:
Sven Neumann <s.neumann@raumfeld.com>
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
0.5.5
=====
Changes since 0.5.4:
- Provide gobject-introspection GIR and typelib.
- Provide microseconds in 'duration' to satisfy XBox.
- Fix data type of GUPnPDIDLLiteContainer:child-count
- Fix build issues in jhbuild environment.
- Enable silent build rules if they are available.
All contributors to this release:
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
Zach Goldberg <zach@zachgoldberg.com>
Neil Roberts <neil@linux.intel.com>
Ross Burton <ross@linux.intel.com>
0.5.4
=====
Changes since 0.5.2:
- Gracefully handle empty or no 'res' node.
- Function to get the list of descriptors from DIDL-Lite objects.
- More complete comparison for LPCM mime types.
- Fix incorrect type conversion of DLNA flags.
- DLNA flags should not default to a specific DLNA version.
- New APIs to deal with contributor-related properties in DIDL-Lite objects.
- Remove redundant construction methods.
- Add forgotten header to the meta-header file.
- Add and fix gobject-introspection annotations.
- Lots of documentation fixes.
- Many minor non-functional fixes/improvements.
Bug fixes in this release:
1935 - Incorrect conversion while parsing primary DLNA Flags
1934 - DLNA Flags should not default to a specific DLNA version.
1933 - Content type matching fails when additional parameters exist in LPCM
mime-type
1814 - Add "artists" property to GUPnPDIDLLiteObject
All contributors to this release:
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
Yakup Akbay <yakbay@ubicom.com>
Zachary Goldberg <zach@zachgoldberg.com>
0.5.2
=====
Changes since 0.5.1:
- Add a missing NULL check.
- Fix a potential leak of xmlDoc.
- Register a (g)type for GUPnPSearchCriteriaOp for better gtk-doc and
vala-gen-introspect support.
- Fix docs for GUPnPSearchCriteriaParser::expression.
- Fix parsing of SearchCriteria strings: Closing parenthesis doesn't imply end
of SearchCriteria expression.
All contributors to this release:
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
0.5.1
=====
A micro release to fix a regression in DLNA profile guessing code in the
previous (0.5) release.
0.5
===
Changes in this release:
- New completely object-oriented, much simpler and consistent API:
* GUPnPDIDLLiteResource & GUPnPDIDLLiteObject are now first-class GObjects.
* Convert the helper methods to read props and their attributes from DIDL-Lite
xml node into new first-class objects with writable properties:
- GUPnPDIDLLiteObject
- GUPnPDIDLLiteItem
- GUPnPDIDLLiteContainer
* GUPnPDIDLLiteObject provides a convenient method to get the compatible
resource given a SinkProtocolInfo string.
* A new class for dealing with protocolInfo fields: GUPnPProtocolInfo.
* A new class for dealing with DIDL-Lite descriptors: GUPnPDIDLLiteDescriptor.
* GUPnPDIDLLiteWriter now provides a much simpler API that is consistent with
rest of the GUPnP AV API.
* GUPnPDIDLLiteWriter now handles filtering of DIDL-Lite XML.
* Correct possible values of GUPnPDLNAFlags.
* Replace GUPnPDIDLLiteParserObjectCallback by following signals:
- object-available
- container-available
- item-available
- New Error domain for protocol related errors.
- Workaround for broken printf() implementations.
- Bitrate is in bytes/second and not bits/second.
- Enable DLL on windows.
Dependencies changed:
- gupnp >= 0.13
Bug fixes in this release:
1729 - bitrate checks in gupnp-dlna.c look wrong.
1579 - Minor fixes to enable dynamic library on windows
All contributors to this release:
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
Sven Neumann <s.neumann@raumfeld.com>
Jens Georg <mail@jensge.org>
Ross Burton <ross@openedhand.com>
WARNING: This release is API and ABI incompatible with previous releases.
0.4.1
=====
Changes in this release:
- Fix typos in allowed frequencies.
- Fix allowed frequencies in AC-3 and LPCM profiles.
- Fix pkg-config paths.
- Don't set the variable if it's value is not provided in the LastChange event.
Bug fixes in this release:
1563 - typos in allowed frequencies for DLNA profiles
1570 - gupnp doesn't set the pkgconfig lib dir correctly in 64 bit env
All contributors to this release:
Sven Neumann
Zeeshan Ali (Khattak)
Ross Burton
0.4
===
- Watch for empty DIDL-Lite nodes.
- Escape the URIs before putting them into DIDL-Lite XML.
- The '.' must be omitted from duration if fraction part is not included.
- Be more lenient when parsing DIDL-Lite XML fragments.
- Don't require the DLNA profile string.
- Try to guess the DLNA Profile if not provided and put "*" in the whole 4th
field of protocolInfo if our guess work fails.
- Make sure 4th field of protocolInfo is completely in compliance with DLNA
guidelines. This only implies one change in the API: enum dlna_play_speed is
replaced by play_speeds, a GList of allowed play speeds as strings.
- Use '1' and '0' to express boolean properties in DIDL-Lite XML.
- Other minor fixes.
All contributors to this release:
Henrique Ferreiro García
Peter Christensen
Sven Neumann
Zeeshan Ali (Khattak)
0.3.1
=====
- DIDLLiteResource is now an independent GBoxed-derving type.
0.3
===
- Better error handling. [Jorn Baayen, Sven Neumann]
- Fixes to documentation and build. [Ross Burton, Zeeshan Ali]
- Fixes and additions to DIDLLiteResource to ease impelementation of
higher-level language bindings. [Zeeshan Ali]
- DIDLLiteParser should only report container and item nodes. Fixes bug#1155.
[Zeeshan Ali]
0.2.1
=====
- Correct function prototype. Fixes #940. [Jorn Baayen]
- Include the glib header to satisfy vala-gen-introspect. [Zeeshan Ali Khattak]
0.2
===
- Use libsoup 2.4. [Jorn Baayen]
- Add DLNA support to DIDL writer. [Jorn Baayen]
- Some small fixes. [Jorn Baayen]
0.1
===
Initial release.
0707010000000E000081A40000000000000000000000016860451500000181000000000000000000000000000000000000001A00000000gupnp-av-0.14.4/README.md# GUPnP A/V
GUPnP is an object-oriented open source framework for creating UPnP devices and
control points, written in C using GObject and libsoup. The GUPnP API is
intended to be easy to use, efficient and flexible.
GUPnP A/V is a small utility library that aims to ease the handling and
implementation of UPnP A/V profiles.
GUPnP A/V is free software released under the GNU LGPL.
0707010000000F000041ED0000000000000000000000026860451500000000000000000000000000000000000000000000001A00000000gupnp-av-0.14.4/build-aux07070100000010000081A400000000000000000000000168604515000001BA000000000000000000000000000000000000002700000000gupnp-av-0.14.4/build-aux/dist-docs.py#!/usr/bin/env python3
import os
import shutil
references = [
'doc/gupnp-av-1.0',
]
sourceroot = os.environ.get('MESON_SOURCE_ROOT')
buildroot = os.environ.get('MESON_BUILD_ROOT')
distroot = os.environ.get('MESON_DIST_ROOT')
for reference in references:
src_path = os.path.join(buildroot, reference)
if os.path.isdir(src_path):
dst_path = os.path.join(distroot, reference)
shutil.copytree(src_path, dst_path)
07070100000011000041ED0000000000000000000000026860451500000000000000000000000000000000000000000000001500000000gupnp-av-0.14.4/data07070100000012000081A40000000000000000000000016860451500007673000000000000000000000000000000000000001C00000000gupnp-av-0.14.4/data/av.xsd<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:av="urn:schemas-upnp-org:av:av" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:schemas-upnp-org:av:av" version="3-20101231">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Note that all schema supplied by the UPnP Forum AV WC committee are for informational use only and that the
standardized DCPs describe the normative requirements for these schema. Some schema provided do not necessarily
embody requirements regarding number of element occurrances allowed or their ordering.
Schema for UPnP A/V AV
</xsd:documentation>
</xsd:annotation>
<!--=============================-=============================-->
<!-- String Types -->
<!--=============================-=============================-->
<xsd:simpleType name="_pName.attributeOnly">
<xsd:annotation>
<xsd:documentation>
Dependent property name that has no associated independent property.
MAY include namespace prefix
MUST NOT include independent property name
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:pattern value="([\i-[:]][\c-[:]]*:)?@[\i-[:]][\c-[:]]*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="_pName.elementIncluded">
<xsd:annotation>
<xsd:documentation>
General property name type
MUST include independent property name
MAY include namespace prefix
MAY include dependent property name
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:pattern value="([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*(@[\i-[:]][\c-[:]]*)?"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="pName">
<xsd:union memberTypes="av:_pName.attributeOnly av:_pName.elementIncluded"/>
</xsd:simpleType>
<xsd:simpleType name="pName.csv.1-n">
<xsd:restriction base="xsd:string">
<xsd:pattern value="(([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*(@[\i-[:]][\c-[:]])?)|(@[\i-[:]][\c-[:]])(,(([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*(@[\i-[:]][\c-[:]])?)|(@[\i-[:]][\c-[:]]))*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="pName.csv.0-n">
<xsd:union memberTypes="av:pName.csv.1-n av:string.len.0"/>
</xsd:simpleType>
<!--
Use the following names in type names that represent individual
strings or delimited sequences of strings to distinguish the cases
where individual string components MUST be empty vs. MAY be empty vs.
MUST NOT be empty:
string.len.0
string.len.1_
string.len.0_
-->
<!--4,294,967,295-->
<xsd:simpleType name="_unsignedInt0">
<xsd:restriction base="xsd:token">
<xsd:pattern value="0*[0-9]{1,9}"/>
<xsd:pattern value="0*[1-3][0-9]{9}"/>
<xsd:pattern value="0*4[0-1][0-9]{8}"/>
<xsd:pattern value="0*42[0-8][0-9]{7}"/>
<xsd:pattern value="0*429[0-3][0-9]{6}"/>
<xsd:pattern value="0*4294[0-8][0-9]{5}"/>
<xsd:pattern value="0*42949[0-5][0-9]{4}"/>
<xsd:pattern value="0*429496[0-6][0-9]{3}"/>
<xsd:pattern value="0*4294967[0-1][0-9]{2}"/>
<xsd:pattern value="0*42949672[0-8][0-9]"/>
<xsd:pattern value="0*429496729[0-5]"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="_unsignedInt">
<xsd:restriction base="xsd:token">
<xsd:pattern value="0*(([0-9]{1,9})|([1-3][0-9]{9})|(4[0-1][0-9]{8})|(42[0-8][0-9]{7})|(429[0-3][0-9]{6})|(4294[0-8][0-9]{5})|(42949[0-5][0-9]{4})|(429496[0-6][0-9]{3})|(4294967[0-1][0-9]{2})|(42949672[0-8][0-9])|(429496729[0-5]))"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.len.0">
<xsd:restriction base="xsd:string">
<xsd:length value="0"/>
<xsd:whiteSpace value="collapse"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.len.1_">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\s*\S+\s*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.len.0_">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="string.len.0_256">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="256"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="NCName.len.1_31">
<xsd:restriction base="xsd:NCName">
<xsd:maxLength value="31"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="csv.0_.string.len.1_">
<xsd:restriction base="xsd:string">
<xsd:pattern value="([^,]|\\,)+(,([^,]|\\,)+)*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="csv.0_.string.len.0_">
<xsd:restriction base="xsd:string">
<xsd:pattern value="([^,]|\\,)*(,([^,]|\\,)*)*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="csv.1_.string.len.1_">
<xsd:restriction base="av:csv.0_.string.len.1_">
<xsd:minLength value="1"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="csv.1_.string.len.0_">
<xsd:restriction base="av:csv.0_.string.len.0_">
<xsd:minLength value="1"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="csv.4.string.len.1_">
<xsd:restriction base="av:csv.0_.string.len.1_">
<xsd:pattern value="([^,]|\\,)+(,([^,]|\\,)+){3}"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="csv.4.string.len.0_">
<xsd:restriction base="av:csv.0_.string.len.0_">
<xsd:pattern value="([^,]|\\,)*(,([^,]|\\,)*){3}"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="csv.0_.unsignedInteger">
<xsd:union memberTypes="av:csv.1_.unsignedInteger av:string.len.0"/>
</xsd:simpleType>
<xsd:simpleType name="csv.1_.unsignedInteger">
<xsd:restriction base="xsd:string">
<xsd:pattern value="([0-9]+)(,[0-9]+)*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="csv.1_Name">
<xsd:restriction base="xsd:string">
<xsd:pattern value="(\i\c*)(,(\i\c*))*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="csv.1_.QName">
<xsd:restriction base="xsd:string">
<xsd:pattern value="([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*(,([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*)*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="csv.1_.NCName">
<xsd:restriction base="av:csv.1_.QName">
<xsd:pattern value="[^:]+"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="csv.1_.colonDelimPairs">
<xsd:restriction base="xsd:token">
<xsd:pattern value="[^:]+:[^:]+(,[^:]+:[^:]+)*"/>
</xsd:restriction>
</xsd:simpleType>
<!--=============================-=============================-->
<!-- Named Constants -->
<!--=============================-=============================-->
<xsd:simpleType name="string.const.ALL">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ALL"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.const.ANY">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ANY"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.const.AUTO">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="AUTO"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.const.DEFAULT">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="DEFAULT"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.const.FIRST-RUN">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="FIRST-RUN"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.const.HIGHEST">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="HIGHEST"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.const.INFINITY">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="INFINITY"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.const.LOWEST">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="LOWEST"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.const.NOT_IMPLEMENTED">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="NOT_IMPLEMENTED"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.const.NOW">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="NOW"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.const.OBJECTID">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="OBJECTID"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.const.PREDEF">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="PREDEF"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.const.REPEAT">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="REPEAT"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.const.UNBOUNDED">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="UNBOUNDED"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string.const.UNKNOWN">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="UNKNOWN"/>
</xsd:restriction>
</xsd:simpleType>
<!--=============================-=============================-->
<!-- Numeric Datatypes -->
<!--=============================-=============================-->
<xsd:simpleType name="unsignedInt.or.UNKNOWN">
<xsd:union memberTypes="xsd:unsignedInt av:string.const.UNKNOWN"/>
</xsd:simpleType>
<xsd:simpleType name="unsignedInt.or.UNBOUNDED">
<xsd:union memberTypes="xsd:unsignedInt av:string.const.UNBOUNDED"/>
</xsd:simpleType>
<xsd:simpleType name="positiveInt">
<xsd:restriction base="xsd:unsignedInt">
<xsd:minInclusive value="1"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="rational">
<xsd:restriction base="xsd:string">
<xsd:pattern value="-?[0-9]+(/0*[1-9][0-9]*)?"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="nonZeroRational">
<xsd:restriction base="av:rational">
<xsd:pattern value="[^/]*[1-9].*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="long.-1_">
<xsd:restriction base="xsd:long">
<xsd:minInclusive value="-1"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="int.-1_">
<xsd:restriction base="xsd:int">
<xsd:minInclusive value="-1"/>
</xsd:restriction>
</xsd:simpleType>
<!--=============================-=============================-->
<!-- Time Datatypes -->
<!--=============================-=============================-->
<!--
EBNF from ScheduledRecording:1 1.00
sched-start ::= date-time |
day-of-yr-time |
named-day-time |
T-labeled-time |
'NOW'
start-range ::= (date-time|'NOW') '/' (date-time|'INFINITY')
duration ::= 'P' [n 'D'] time
duration-long ::= duration|'INFINITY'
duration-any ::= duration|'INFINITY'|'ANY'
duration-adj ::= ('+'|'-') duration
duration-range ::= duration '/' duration-long
date-time ::= yyyy '-' mm '-' dd T-labeled-time
day-of-yr-time ::= mm '-' dd T-labeled-time
named-day-time ::= named-day T-labeled-time
T-labeled-time ::= 'T' time [zone]
time ::= HH ':' MM ':' SS
zone ::= 'Z'|(('+'|'-') HH ':' MM)
month-day ::= mm '-' dd
named-day ::= 'MON'|'TUE'|'WED'|'THU'|'FRI'|'SAT'|'SUN'|
'MON-FRI'|'MON-SAT'
n ::= 1*DIGIT (* non-negative integer *)
yyyy ::= 4DIGIT (* 0001-9999 *)
mm ::= 2DIGIT (* 01-12 *)
-->
<xsd:simpleType name="dateTime">
<xsd:annotation>
<xsd:documentation> Disallows fractional seconds </xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:dateTime">
<xsd:pattern value="[^\.]*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="signedDuration">
<xsd:restriction base="xsd:token">
<xsd:pattern value="[-+]P([0-9]*D)?(2[0-3]|[0-1][0-9])(:[0-5][0-9]){2}"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="unsignedDuration">
<xsd:restriction base="xsd:string">
<xsd:pattern value="P([0-9]*D)?(2[0-3]|[0-1][0-9])(:[0-5][0-9]){2}"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="unsignedDuration.or.INFINITY">
<xsd:union memberTypes="av:unsignedDuration av:string.const.INFINITY"/>
</xsd:simpleType>
<xsd:simpleType name="unsignedDuration.or.INFINITY.or.ANY">
<xsd:union memberTypes="av:unsignedDuration.or.INFINITY av:string.const.ANY"/>
</xsd:simpleType>
<xsd:simpleType name="dayOfWeek.en.len.3">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="SUN"/>
<xsd:enumeration value="MON"/>
<xsd:enumeration value="TUE"/>
<xsd:enumeration value="WED"/>
<xsd:enumeration value="THU"/>
<xsd:enumeration value="FRI"/>
<xsd:enumeration value="SAT"/>
</xsd:restriction>
</xsd:simpleType>
<!-- Original duration definition in CDS:1 -->
<xsd:simpleType name="duration.cds1.decFrac">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[-+]?[0-9]+(:[0-5][0-9]){2}(\.[0-9]+)?"/>
</xsd:restriction>
<!-- Decimal fraction version -->
</xsd:simpleType>
<xsd:simpleType name="duration.cds1.numDenomFrac">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[-+]?[0-9]+(:[0-5][0-9]){2}(\.[0-9]+/[0-9]+)?"/>
</xsd:restriction>
<!-- Numerator/denominator fraction version -->
</xsd:simpleType>
<xsd:simpleType name="duration.cds1">
<xsd:union memberTypes="av:duration.cds1.decFrac av:duration.cds1.numDenomFrac"/>
</xsd:simpleType>
<xsd:simpleType name="duration.cds1.or.NOT_IMPLEMENTED">
<xsd:union memberTypes="av:duration.cds1 av:string.const.NOT_IMPLEMENTED"/>
</xsd:simpleType>
<xsd:simpleType name="daylightSaving.type">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="startTimeUsage">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<!--=============================-=============================-->
<!-- Internet-related datatypes -->
<!--=============================-=============================-->
<xsd:simpleType name="domainName">
<xsd:restriction base="xsd:string">
<xsd:pattern value="([^\.]+\.)+[^\.]+\.?"/>
</xsd:restriction>
</xsd:simpleType>
<!--===========================================================-->
<!-- -->
<!-- UPnP Specific Datatypes -->
<!-- -->
<!--===========================================================-->
<xsd:simpleType name="UDN">
<xsd:restriction base="xsd:anyURI">
<xsd:pattern value="uuid:.+"/>
</xsd:restriction>
</xsd:simpleType>
<!--===========================================================-->
<!-- -->
<!-- AV Specific Datatypes -->
<!-- -->
<!--===========================================================-->
<xsd:simpleType name="sched-start">
<xsd:union memberTypes="av:dateTime xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="dateTime-range">
<xsd:restriction base="xsd:token">
<xsd:pattern value=".+/.+"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="duration-range">
<xsd:restriction base="xsd:token">
<xsd:pattern value=".+/.+"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="radioBand.wc.values">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="AM"/>
<xsd:enumeration value="FM"/>
<xsd:enumeration value="Shortwave"/>
<xsd:enumeration value="Internet"/>
<xsd:enumeration value="Satellite"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="radioBand.type">
<xsd:union memberTypes="av:radioBand.wc.values av:radioBand.vx.values"/>
</xsd:simpleType>
<!--=============================-=============================-->
<!-- Simple Common Types -->
<!--=============================-=============================-->
<xsd:simpleType name="_id.type">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="_classNameBase.type">
<xsd:restriction base="xsd:NCName"/>
</xsd:simpleType>
<xsd:simpleType name="_title.type">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="stateUpdateID.type">
<xsd:restriction base="xsd:unsignedInt"/>
</xsd:simpleType>
<xsd:simpleType name="string.domainNamePrefixed">
<xsd:annotation>
<xsd:documentation>
string.domainNamePrefixed == Domain Name Prefix type
This type is defined in ContentDirectory:2 and ScheduledRecording:1 as
string.domainNamePrefixed ::= domain-name '_' string
Therefore, the only requirement imposed here is the occurrence of at
least one underscore that has at least one character before and after it.
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:pattern value=".+_.+"/>
</xsd:restriction>
</xsd:simpleType>
<!--=============================-=============================-->
<!-- Storage Related Types -->
<!--=============================-=============================-->
<xsd:complexType name="storageMedium.type">
<xsd:attribute name="val" type="av:storageMedium.values" use="required"/>
</xsd:complexType>
<xsd:simpleType name="storageMedium.wc.values">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="UNKNOWN"/>
<xsd:enumeration value="DV"/>
<xsd:enumeration value="MINI-DV"/>
<xsd:enumeration value="VHS"/>
<xsd:enumeration value="W-VHS"/>
<xsd:enumeration value="S-VHS"/>
<xsd:enumeration value="D-VHS"/>
<xsd:enumeration value="VHSC"/>
<xsd:enumeration value="VIDEO8"/>
<xsd:enumeration value="HI8"/>
<xsd:enumeration value="CD-ROM"/>
<xsd:enumeration value="CD-DA"/>
<xsd:enumeration value="CD-R"/>
<xsd:enumeration value="CD-RW"/>
<xsd:enumeration value="VIDEO-CD"/>
<xsd:enumeration value="SACD"/>
<xsd:enumeration value="MD-AUDIO"/>
<xsd:enumeration value="MD-PICTURE"/>
<xsd:enumeration value="DVD-ROM"/>
<xsd:enumeration value="DVD-VIDEO"/>
<xsd:enumeration value="DVD+R"/>
<xsd:enumeration value="DVD-R"/>
<xsd:enumeration value="DVD+RW"/>
<xsd:enumeration value="DVD-RW"/>
<xsd:enumeration value="DVD-RAM"/>
<xsd:enumeration value="DVD-AUDIO"/>
<xsd:enumeration value="DAT"/>
<xsd:enumeration value="LD"/>
<xsd:enumeration value="HDD"/>
<xsd:enumeration value="MICRO-MV"/>
<xsd:enumeration value="NETWORK"/>
<xsd:enumeration value="NONE"/>
<xsd:enumeration value="NOT_IMPLEMENTED"/>
<xsd:enumeration value="SD"/>
<xsd:enumeration value="PC-CARD"/>
<xsd:enumeration value="MMC"/>
<xsd:enumeration value="CF"/>
<xsd:enumeration value="BD"/>
<xsd:enumeration value="MS"/>
<xsd:enumeration value="HD_DVD"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="storageMedium.values">
<xsd:union memberTypes="av:storageMedium.wc.values av:storageMedium.vx.values"/>
</xsd:simpleType>
<!--=============================-=============================-->
<!-- Program Related Types -->
<!--=============================-=============================-->
<xsd:simpleType name="SIprogramID.type">
<xsd:restriction base="av:csv.4.string.len.1_"/>
</xsd:simpleType>
<xsd:simpleType name="SIseriesID.type">
<xsd:restriction base="av:csv.4.string.len.1_"/>
</xsd:simpleType>
<xsd:simpleType name="programID_at_type.wc.values">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="SI_PROGRAMID"/>
<xsd:enumeration value="SI_SERIESID"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="programID_at_type.values">
<xsd:union memberTypes="av:programID_at_type.wc.values av:programID_at_type.vx.values"/>
</xsd:simpleType>
<xsd:complexType name="programID.type">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="type" type="av:programID_at_type.values"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:simpleType name="channelID_at_type.wc.values">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="ANALOG"/>
<xsd:enumeration value="DIGITAL"/>
<xsd:enumeration value="FREQUENCY"/>
<xsd:enumeration value="SI"/>
<xsd:enumeration value="LINE"/>
<xsd:enumeration value="NETWORK"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="channelID_at_type.values">
<xsd:union memberTypes="av:channelID_at_type.wc.values av:channelID_at_type.vx.values"/>
</xsd:simpleType>
<xsd:complexType name="channelID.type">
<xsd:simpleContent>
<xsd:extension base="xsd:token">
<xsd:attribute name="type" type="av:channelID_at_type.values" use="required"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:simpleType name="csv.1_.allowedUse">
<xsd:restriction base="xsd:token">
<xsd:pattern value="(PLAY|COPY|MOVE|UNKNOWN):(-1|[0-9]+)(,(PLAY|COPY|MOVE|UNKNOWN):(-1|[0-9]+))*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="programCode.type">
<xsd:simpleContent>
<xsd:extension base="xsd:token">
<xsd:attribute name="type" type="av:programCode_at_type.vd.values"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:simpleType name="rating_at_type.wc.values">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="MPAA.ORG"/>
<xsd:enumeration value="RIAA.ORG"/>
<xsd:enumeration value="ESRB.ORG"/>
<xsd:enumeration value="TVGUIDELINES.ORG"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="rating_at_type.values">
<xsd:union memberTypes="av:rating_at_type.wc.values av:rating_at_type.vx.values"/>
</xsd:simpleType>
<xsd:simpleType name="rating.MPAA.ORG.values">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="G"/>
<xsd:enumeration value="PG"/>
<xsd:enumeration value="R"/>
<xsd:enumeration value="PG-13"/>
<xsd:enumeration value="R"/>
<xsd:enumeration value="NC-17"/>
<xsd:enumeration value="NR"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="rating.RIIA.ORG.values">
<xsd:restriction base="xsd:token">
<xsd:enumeration value=""/>
<xsd:enumeration value="PA-EC"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="rating.ESRB.ORG.values">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="EC"/>
<xsd:enumeration value="E"/>
<xsd:enumeration value="E10+"/>
<xsd:enumeration value="T"/>
<xsd:enumeration value="M"/>
<xsd:enumeration value="AO"/>
<xsd:enumeration value="RP"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="rating.TVGUIDELINES.ORG.values">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="TV-Y"/>
<xsd:enumeration value="TV-Y7"/>
<xsd:enumeration value="TV-Y7FV"/>
<xsd:enumeration value="TV-G"/>
<xsd:enumeration value="TV-PG"/>
<xsd:enumeration value="TV-14"/>
<xsd:enumeration value="TV-MA"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="rating.wc.values">
<xsd:union memberTypes="av:rating.MPAA.ORG.values av:rating.RIIA.ORG.values av:rating.ESRB.ORG.values av:rating.TVGUIDELINES.ORG.values"/>
</xsd:simpleType>
<xsd:simpleType name="rating.values">
<xsd:union memberTypes="av:rating.wc.values av:rating.vx.values"/>
</xsd:simpleType>
<xsd:complexType name="rating.type">
<xsd:simpleContent>
<xsd:extension base="av:rating.values">
<xsd:attribute name="type" type="av:rating_at_type.values"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:simpleType name="FIRST-RUN.or.REPEAT">
<xsd:union memberTypes="av:string.const.FIRST-RUN av:string.const.REPEAT"/>
</xsd:simpleType>
<xsd:simpleType name="ALL.or.FIRST-RUN.or.REPEAT">
<xsd:union memberTypes="av:string.const.ALL av:string.const.FIRST-RUN av:string.const.REPEAT"/>
</xsd:simpleType>
<!--=============================-=============================-->
<!-- User Channel and EPG Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="channelGroupName.type">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="id" type="av:string.domainNamePrefixed"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:simpleType name="stationCallSign.type">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="signalStrength.wc.type">
<xsd:restriction base="xsd:int">
<xsd:minInclusive value="-1"/>
<xsd:maxInclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="signalStrength.type">
<xsd:union memberTypes="av:signalStrength.wc.type av:signalStrength.vx.type"/>
</xsd:simpleType>
<!--=============================-=============================-->
<!-- Bookmark Related Properties -->
<!--=============================-=============================-->
<xsd:simpleType name="serviceType">
<xsd:restriction base="xsd:token">
<xsd:pattern value="[^#:]{1,64}:[1-9][0-9]*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="serviceId">
<xsd:restriction base="xsd:token">
<xsd:pattern value="[^:]{1,64}"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="deviceUDN.type">
<xsd:simpleContent>
<xsd:extension base="av:UDN">
<xsd:attribute name="serviceType" type="av:serviceType" use="required"/>
<xsd:attribute name="serviceId" type="av:serviceId" use="required"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<!--=================================-=================================-->
<!-- -->
<!-- Extension Master Datatypes -->
<!-- -->
<!--=================================-=================================-->
<xsd:simpleType name="extensions.simpleType.none">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Use this type wherever extensions to a simpleType are allowed by the specification,
but they are disallowed for testing validation purposes.
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:NCName">
<xsd:pattern value="[:]+"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:group name="extensions.elementType.none">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Use this group wherever element extensions are allowed by the specification,
but they are disallowed for testing validation purposes.
</xsd:documentation>
</xsd:annotation>
<xsd:choice>
<xsd:any minOccurs="0" maxOccurs="0"/>
</xsd:choice>
</xsd:group>
<xsd:attributeGroup name="extensions.attributes.none">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Use this group wherever attribute extensions are allowed by the specification,
but they are disallowed for testing validation purposes.
</xsd:documentation>
</xsd:annotation>
</xsd:attributeGroup>
<xsd:simpleType name="extensions.simpleType.any">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Use this type wherever extensions to a simpleType are allowed by the specification,
and no constraints are imposed for testing validation purposes.
</xsd:documentation>
</xsd:annotation>
<xsd:union memberTypes="xsd:duration xsd:date xsd:dateTime xsd:time xsd:gDay xsd:gMonth xsd:gMonthDay xsd:gYear xsd:gYearMonth xsd:boolean xsd:float xsd:decimal xsd:double xsd:anyURI xsd:QName xsd:string xsd:base64Binary xsd:hexBinary"/>
</xsd:simpleType>
<xsd:group name="extensions.elementType.any">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Use this group wherever element extensions are allowed by the specification,
and no constraints are imposed for testing validation purposes.
</xsd:documentation>
</xsd:annotation>
<xsd:choice>
<xsd:any minOccurs="0" maxOccurs="unbounded"/>
</xsd:choice>
</xsd:group>
<xsd:attributeGroup name="extensions.attributes.any">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Use this group wherever attribute extensions are allowed by the specification,
and no constraints are imposed for testing validation purposes.
</xsd:documentation>
</xsd:annotation>
<xsd:anyAttribute/>
</xsd:attributeGroup>
<!--===================================================================-->
<!-- -->
<!-- Extension Component Datatypes -->
<!-- -->
<!--===================================================================-->
<xsd:simpleType name="storageMedium.vx.values">
<xsd:restriction base="av:extensions.simpleType.any"/>
</xsd:simpleType>
<xsd:simpleType name="programID_at_type.vx.values">
<xsd:restriction base="av:domainName"/>
</xsd:simpleType>
<xsd:simpleType name="channelID_at_type.vx.values">
<xsd:restriction base="xsd:token"/>
</xsd:simpleType>
<xsd:simpleType name="rating_at_type.vx.values">
<xsd:restriction base="av:string.domainNamePrefixed"/>
</xsd:simpleType>
<xsd:simpleType name="rating.vx.values">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="radioBand.vx.values">
<xsd:restriction base="xsd:token"/>
</xsd:simpleType>
<xsd:simpleType name="signalStrength.vx.type">
<xsd:restriction base="xsd:int"/>
</xsd:simpleType>
<!--===================================================================-->
<!-- -->
<!-- Vendor-Defined Component Datatypes -->
<!-- -->
<!--===================================================================-->
<xsd:simpleType name="didl-lite_COLON_at_id.vd.type">
<xsd:restriction base="av:_id.type"/>
</xsd:simpleType>
<xsd:simpleType name="srs_COLON_at_id.vd.type">
<xsd:restriction base="av:_id.type"/>
</xsd:simpleType>
<xsd:simpleType name="programCode_at_type.vd.values">
<xsd:restriction base="av:string.domainNamePrefixed"/>
</xsd:simpleType>
</xsd:schema>
07070100000013000081A40000000000000000000000016860451500004233000000000000000000000000000000000000002600000000gupnp-av-0.14.4/data/didl-lite-v2.xsd<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:av="urn:schemas-upnp-org:av:av" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:didl-lite="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2-20060531">
<xsd:annotation>
<xsd:documentation xml:lang="en">
DIDL-Lite schema for UPnP A/V ContentDirectory services,
version 2.0.
</xsd:documentation>
</xsd:annotation>
<xsd:import namespace="urn:schemas-upnp-org:metadata-1-0/upnp/" schemaLocation="http://www.upnp.org/schemas/av/upnp.xsd"/>
<xsd:import namespace="urn:schemas-upnp-org:av:av" schemaLocation="http://www.upnp.org/schemas/av/av.xsd"/>
<xsd:import namespace="http://purl.org/dc/elements/1.1/" schemaLocation="http://dublincore.org/schemas/xmls/simpledc20021212.xsd"/>
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/03/xml.xsd"/>
<!--============================================================
This group defines the subset of Dublin Core elements that are
employed in DIDL-Lite.
Included Excluded
___________ ___________
title subject
rights type
description format
date identifier
language source
creator coverage
publisher
contributor
relation
============================================================-->
<xsd:group name="DublinCoreUsedExcluding-title">
<xsd:choice>
<xsd:element ref="dc:contributor"/>
<xsd:element ref="dc:creator"/>
<!-- XXX - JGR
Would like to use an extension of the dc:date element rather than an extension its data type ("dc:elementType").
As it is now, changes to the dc:date element are not propagated to the 'qualifedDate' data type. Also, the
namespace of the <date> element is no longer "dc" but rather "didl-lite" which is not exactly what we want.
<dc:date didl-lite:daylightSaving="STANDARD">datevalue</dc:date>
<xsd:element ref="dc:date"/>
<xsd:element ref="didl-lite:qualifiedDCDate"/>
<xsd:element name="dcDate" type="didl-lite:qualifiedDCDate"/>
-->
<xsd:element ref="dc:date"/>
<xsd:element ref="dc:description"/>
<xsd:element ref="dc:language"/>
<xsd:element ref="dc:publisher"/>
<xsd:element ref="dc:relation"/>
<xsd:element ref="dc:rights"/>
</xsd:choice>
</xsd:group>
<!-- XXX - JGR
<xsd:complexType name="qualifiedDCDate">
<xsd:complexContent>
<xsd:element ref="dc:date">
<xsd:attributeGroup ref="upnp:dateTime.attr.group"/>
</xsd:element>
</xsd:complexContent>
</xsd:complexType>
-->
<xsd:complexType name="qualifiedDCDate">
<xsd:simpleContent>
<xsd:extension base="dc:elementType">
<xsd:attributeGroup ref="upnp:dateTime.attr.group"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<!--============================================================
'DIDL-Lite' is the root element of DIDL-Lite documents.
Attributes:
xml:lang: optional. The 'xml:lang' attribute may optionally be
used to specify the language of text in the DIDL-Lite document.
============================================================-->
<xsd:group name="allowed-under-DIDL-Lite">
<xsd:annotation>
<xsd:documentation>
This group defines the elements allowed under the
DIDL-Lite root
</xsd:documentation>
</xsd:annotation>
<xsd:choice>
<xsd:element name="item" type="didl-lite:item.type"/>
<xsd:element name="container" type="didl-lite:container.type"/>
<xsd:element name="desc" type="didl-lite:desc.type"/>
</xsd:choice>
</xsd:group>
<xsd:element name="DIDL-Lite" type="didl-lite:root.type"/>
<xsd:complexType name="root.type">
<xsd:annotation>
<xsd:documentation>
DIDL-Lite is the root element
</xsd:documentation>
</xsd:annotation>
<xsd:group ref="didl-lite:allowed-under-DIDL-Lite" maxOccurs="unbounded"/>
<xsd:attribute ref="xml:lang"/>
</xsd:complexType>
<!--============================================================
Parts shared by 'container' and 'item' objects.
============================================================-->
<xsd:attributeGroup name="commonAttrs-item-container.group">
<xsd:attribute name="id" type="av:didl-lite_COLON_at_id.vd.type" use="required"/>
<xsd:attribute name="parentID" type="av:didl-lite_COLON_at_id.vd.type" use="required"/>
<xsd:attribute name="restricted" type="xsd:boolean" use="required"/>
<xsd:attribute name="neverPlayable" type="xsd:boolean"/>
</xsd:attributeGroup>
<!--============================================================
A 'container' element may contain any number of
1. Dublin Core,
2. upnp,
3. res,
4. ref,
5. item,
6. container, and
7. desc elements.
In all cases, the first element in container child element sequence
is required to be "dc:title".
The 'upnp:class' must also appear under container.
Each container is required to specify a value for the 'id' and
'parentID' attributes.
Each container is also required to specify a value for the
'restricted' attribute (true, false, 1, 0).
When restricted="true", the ability to change or delete the
Container is restricted.
Other optional container elements are:
'parentID', 'childCount', and 'searchable'.
Other optional attributes are 'childCount' and 'searchable'.
id: type: string use: required
parentID: type: string use: required
restricted: type: string use: required
searchable: type: string use: optional
childCount: type: string use: optional
The equivalent MPEG21 DIDL element is 'CONTAINER'
============================================================-->
<xsd:group name="allowed-under-container">
<xsd:annotation>
<xsd:documentation>
This group defines the elements allowed under the
'container' element
</xsd:documentation>
</xsd:annotation>
<xsd:choice>
<xsd:group ref="upnp:upnpForContainer"/>
<xsd:group ref="didl-lite:DublinCoreUsedExcluding-title"/>
<xsd:element name="desc" type="didl-lite:desc.type"/>
<xsd:element name="item" type="didl-lite:item.type"/>
<xsd:element name="container" type="didl-lite:container.type"/>
<xsd:element name="res" type="didl-lite:res.type"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="container.type">
<xsd:annotation>
<xsd:documentation>
'container' element may contain any number of
1. Dublin Core,
2. upnp,
3. res,
4. ref,
5 item,
6. container and
7. desc elements.
In all cases, the first element in each container child
element sequence is required to be "dc:title".
A 'upnp:class' element must also appear under container.
container is required to specify a value for the 'id' and
'parentID' attributes.
container is also required to specify a value for the
'restricted' attribute (true, false, 1, 0).
When restricted="true", the ability to change or delete the
container is restricted.
Optional container element attributes are 'childCount', and
'searchable'.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element ref="dc:title"/>
<xsd:group ref="didl-lite:allowed-under-container" minOccurs="0" maxOccurs="unbounded"/>
<xsd:group ref="upnp:class.group"/>
<xsd:group ref="didl-lite:allowed-under-container" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attributeGroup ref="didl-lite:commonAttrs-item-container.group"/>
<xsd:attribute name="searchable" type="xsd:boolean"/>
<xsd:attribute name="childCount" type="xsd:unsignedInt"/>
</xsd:complexType>
<!--============================================================
An 'item' element contains any number of
1. Dublin Core,
2. upnp,
3. res, and
4. desc elements.
In all cases, the first element in each item child element
sequence is required to be "dc:title".
The 'upnp:class' element must also appear under item.
Each item is additionally required to specify a value for the 'id'
attribute. If the item is actually a reference to another item, a
value for 'refID' is specified.
Each item is also required to specify a value for the 'parentID'
Attribute and the 'restricted' attribute (true, false, 1, 0).
When restricted="true", the ability to change or delete the item is
restricted.
Attributes:
Id: type: string use: required
parentID: type: string use: required
refID: type: string use: optional
restricted: type: boolean use: required
The equivalent MPEG21 DIDL element is 'ITEM'.
============================================================-->
<xsd:group name="allowed-under-item">
<xsd:annotation>
<xsd:documentation>
This group defines the elements allowed under the 'item'
Element
</xsd:documentation>
</xsd:annotation>
<xsd:choice>
<xsd:group ref="upnp:upnpForItem"/>
<xsd:group ref="didl-lite:DublinCoreUsedExcluding-title"/>
<xsd:element name="desc" type="didl-lite:desc.type"/>
<xsd:element name="res" type="didl-lite:res.type"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="item.type">
<xsd:annotation>
<xsd:documentation>
'item' element contains any number of
1. Dublin Core,
2. upnp,
3. res, and
4. desc elements.
In all cases, the first element in each item child element
sequence is required to be "dc:title".
A 'upnp:class' element must also appear under item.
Item is additionally required to specify a value for the
'id' attribute.
If the item is actually a reference to another item,
a value for 'refID' must be specified.
Item is also required to specify a value for the 'parentID'
attribute, and the 'restricted' attribute
(true, false, 1, 0).
When restricted="true", the ability to change or delete the
item is restricted.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element ref="dc:title"/>
<xsd:group ref="didl-lite:allowed-under-item" minOccurs="0" maxOccurs="unbounded"/>
<xsd:group ref="upnp:class.group"/>
<xsd:group ref="didl-lite:allowed-under-item" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attributeGroup ref="didl-lite:commonAttrs-item-container.group"/>
<xsd:attribute name="refID" type="av:didl-lite_COLON_at_id.vd.type"/>
</xsd:complexType>
<!--============================================================
A 'res' element indentifies a resource. A resource is typically
some type of asset, such as a photo, song, video, etc.
A 'res' element contains a URI that identifies the resource.
Attributes:
'importUri' type: anyURI use: optional
The 'importUri' attribute is the optional uri locator for
resource updates.
'protocolInfo' type: string use: required
The 'protocolInfo' attribute is a string that identifies the
streaming or transport protocol for transmitting the resource.
If not present then the content has not yet been fully imported by
the ContentDirectory service and is not yet accessible for playback.
'size' type: unsignedLong use: optional
size, in bytes, of the resource.
'duration' type: string use: optional
The 'duration' attribute identifies the duration of the playback of
the resource, at normal speed.
The format of the duration string is:
H+:MM:SS[.F+], or H+:MM:SS[.F0/F1]
Where:
+H one or more digits to indicate elapsed hours,
MM exactly 2 digits to indicate minutes (00 to 59),
SS exactly 2 digits to indicate seconds (00 to 59),
F+ any number of digits (including no digits) to indicate fractions of seconds,
F0/F1 a fraction, with F0 and F1 at least one digit long,
and F0 < F1.
The string may be preceded by an optional + or - sign, and the
decimal point itself may be omitted if there are no fractional seconds digits.
'bitrate' type: unsignedInt use: optional
The bitrate in bytes/second of the resource.
'sampleFrequency' type: unsignedInt use: optional
The sample frequency of the resource in Hz
'bitsPerSample' type: unsignedInt use: optional
The bits per sample of the resource.
'nrAudioChannels' type: unsignedInt use: optional
Number of audio channels of the resource, e.g. 1 for mono,
2 for stereo, 6 for Dolby surround, etc.
'resolution' type: string use: optional
X*Y resolution of the resource (image or video).
The string pattern is restricted to strings of the form:
[0-9]+x[0-9]+
(one or more digits,'x', followed by one or more digits).
'colorDepth' type: unsignedInt use: optional
The color depth in bits of the resource (image or video).
'protection' type: string use: optional
Some statement of the protection type of the resource
(not standardized).
The equivalent MPEG21 DIDL element is 'RESOURCE'.
============================================================-->
<!--=============================-=============================-->
<!-- Resource Encoding Characteristics Properties -->
<!--=============================-=============================-->
<xsd:complexType name="res.type" mixed="true">
<xsd:annotation>
<xsd:documentation>
A 'res' element indentifies a resource.
A resource is typically some type of binary asset,
such as a photo, song, video, etc.
A 'res' element contains a URI that identifies the resource
</xsd:documentation>
</xsd:annotation>
<xsd:simpleContent>
<xsd:extension base="xsd:anyURI">
<xsd:attribute name="importUri" type="xsd:anyURI"/>
<xsd:attribute name="protocolInfo" type="xsd:string" use="required"/>
<xsd:attribute name="size" type="xsd:unsignedLong"/>
<xsd:attribute name="duration" type="av:duration.cds1"/>
<xsd:attribute name="bitrate" type="xsd:unsignedInt"/>
<xsd:attribute name="sampleFrequency" type="xsd:unsignedInt"/>
<xsd:attribute name="bitsPerSample" type="xsd:unsignedInt"/>
<xsd:attribute name="nrAudioChannels" type="xsd:unsignedInt"/>
<xsd:attribute name="resolution">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:pattern value="[0-9]+x[0-9]+"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="colorDepth" type="xsd:unsignedInt"/>
<xsd:attribute name="tspec" type="av:string.len.0_256"/>
<xsd:attribute name="allowedUse" type="av:csv.1_.allowedUse"/>
<xsd:attribute name="validityStart" type="av:dateTime"/>
<xsd:attribute name="validityEnd" type="av:dateTime"/>
<xsd:attribute name="remainingTime" type="av:unsignedDuration"/>
<xsd:attribute name="updateCount" type="xsd:unsignedInt"/>
<xsd:attribute name="usageInfo" type="xsd:string"/>
<xsd:attribute name="rightsInfoURI" type="xsd:anyURI"/>
<xsd:attribute name="contentInfoURI" type="xsd:anyURI"/>
<xsd:attribute name="recordQuality" type="av:csv.1_.colonDelimPairs"/>
<xsd:attribute name="protection" type="xsd:string"/>
<xsd:attributeGroup ref="upnp:dateTime.attr.group"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<!--============================================================
A 'desc' element identifies a descriptor.
A descriptor is intended to contain a block of metadata.
The bio of a music artist is an example use of a 'desc' element.
A 'desc' element may possess child elements from any namespace
except the DIDL-Lite namespace.
Values for 'id' and 'nameSpace' are required.
An optional 'type' attribute allows designation of the metadata
type, e.g. 'ratings', 'rights', etc.
Attributes:
'id' type: string use: required
'type' type: string use: optional
'nameSpace' type: uri use: required
The equivalent MPEG21 DIDL element is 'DESCRIPTOR'.
============================================================-->
<xsd:complexType name="desc.type">
<xsd:annotation>
<xsd:documentation>
A'desc' element identifies a descriptor.
A descriptor is intended to contain a block of metadata.
The bio of a music artist is an example use of 'desc'.
A 'desc' element may possess child elements from any
namespace except the DIDL-Lite namespace.
A value for 'id' is required.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:any namespace="##other"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="type" type="xsd:string"/>
<xsd:attribute name="nameSpace" type="xsd:anyURI" use="required"/>
</xsd:complexType>
<!--===================================================================-->
<!-- -->
<!-- Vendor-Defined Component Datatypes -->
<!-- -->
<!--===================================================================-->
</xsd:schema>
07070100000014000081A40000000000000000000000016860451500000090000000000000000000000000000000000000002100000000gupnp-av-0.14.4/data/meson.buildinstall_data(
[
'av.xsd',
'didl-lite-v2.xsd',
'simpledc20021212.xsd',
'upnp.xsd',
'xml.xsd'
]
)
07070100000015000081A40000000000000000000000016860451500000B28000000000000000000000000000000000000002A00000000gupnp-av-0.14.4/data/simpledc20021212.xsd<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://purl.org/dc/elements/1.1/" targetNamespace="http://purl.org/dc/elements/1.1/" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:annotation>
<xs:documentation xml:lang="en">
Simple DC XML Schema, 2002-10-09
by Pete Johnston (p.johnston@ukoln.ac.uk),
Carl Lagoze (lagoze@cs.cornell.edu), Andy Powell (a.powell@ukoln.ac.uk),
Herbert Van de Sompel (hvdsomp@yahoo.com).
This schema defines terms for Simple Dublin Core, i.e. the 15
elements from the http://purl.org/dc/elements/1.1/ namespace, with
no use of encoding schemes or element refinements.
Default content type for all elements is xs:string with xml:lang
attribute available.
Supercedes version of 2002-03-12.
Amended to remove namespace declaration for http://www.w3.org/XML/1998/namespace namespace,
and to reference lang attribute via built-in xml: namespace prefix.
xs:appinfo also removed.
</xs:documentation>
</xs:annotation>
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/03/xml.xsd">
</xs:import>
<xs:element name="title" type="elementType"/>
<xs:element name="creator" type="elementType"/>
<xs:element name="subject" type="elementType"/>
<xs:element name="description" type="elementType"/>
<xs:element name="publisher" type="elementType"/>
<xs:element name="contributor" type="elementType"/>
<xs:element name="date" type="elementType"/>
<xs:element name="type" type="elementType"/>
<xs:element name="format" type="elementType"/>
<xs:element name="identifier" type="elementType"/>
<xs:element name="source" type="elementType"/>
<xs:element name="language" type="elementType"/>
<xs:element name="relation" type="elementType"/>
<xs:element name="coverage" type="elementType"/>
<xs:element name="rights" type="elementType"/>
<xs:group name="elementsGroup">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="title"/>
<xs:element ref="creator"/>
<xs:element ref="subject"/>
<xs:element ref="description"/>
<xs:element ref="publisher"/>
<xs:element ref="contributor"/>
<xs:element ref="date"/>
<xs:element ref="type"/>
<xs:element ref="format"/>
<xs:element ref="identifier"/>
<xs:element ref="source"/>
<xs:element ref="language"/>
<xs:element ref="relation"/>
<xs:element ref="coverage"/>
<xs:element ref="rights"/>
</xs:choice>
</xs:sequence>
</xs:group>
<xs:complexType name="elementType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute ref="xml:lang" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>07070100000016000081A40000000000000000000000016860451500009F25000000000000000000000000000000000000001E00000000gupnp-av-0.14.4/data/upnp.xsd<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:av="urn:schemas-upnp-org:av:av" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:schemas-upnp-org:metadata-1-0/upnp/" elementFormDefault="qualified" attributeFormDefault="unqualified" version="4-20101231">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Note that all schema supplied by the UPnP Forum AV WC committee are for informational use only and that the
standardized DCPs describe the normative requirements for these schema. Some schema provided do not necessarily
embody requirements regarding number of element occurrances allowed or their ordering.
</xsd:documentation>
</xsd:annotation>
<!-- This schema defines the upnp namespace tags that are employed
as descriptors by the DIDL-Lite schema -->
<xsd:import namespace="urn:schemas-upnp-org:av:av" schemaLocation="http://www.upnp.org/schemas/av/av.xsd"/>
<xsd:group name="class.group">
<xsd:sequence>
<xsd:element name="class" type="upnp:class.type"/>
</xsd:sequence>
</xsd:group>
<xsd:group name="upnpForContainer">
<xsd:choice>
<!--=============================-=============================-->
<!-- Base Properties -->
<!--=============================-=============================-->
<xsd:element name="searchClass" type="upnp:searchClass.type"/>
<xsd:element name="createClass" type="upnp:searchClass.type"/>
<xsd:element name="writeStatus" type="upnp:status.type"/>
<!--=============================-=============================-->
<!-- objectLink Properties -->
<!--=============================-=============================-->
<xsd:element name="objectLink" type="upnp:objectLink.type"/>
<xsd:element name="objectLinkRef" type="upnp:objectLinkRef.type"/>
<!--=============================-=============================-->
<!-- resExt Properties -->
<!--=============================-=============================-->
<xsd:element name="resExt" type="upnp:resExt.type"/>
<!--=============================-=============================-->
<!-- Contributor Related Properties -->
<!--=============================-=============================-->
<xsd:element name="artist" type="upnp:personWithRole.type"/>
<xsd:element name="actor" type="upnp:personWithRole.type"/>
<xsd:element name="author" type="upnp:personWithRole.type"/>
<xsd:element name="producer" type="upnp:person.type"/>
<xsd:element name="director" type="upnp:person.type"/>
<!--=============================-=============================-->
<!-- Affiliation Related Properties -->
<!--=============================-=============================-->
<xsd:element name="genre" type="upnp:genre.type"/>
<xsd:element name="album" type="av:_title.type"/>
<xsd:element name="playlist" type="av:_title.type"/>
<!--=============================-=============================-->
<!-- Associated Resources Properties -->
<!--=============================-=============================-->
<xsd:element name="albumArtURI" type="xsd:anyURI"/>
<xsd:element name="artistDiscographyURI" type="xsd:anyURI"/>
<xsd:element name="lyricsURI" type="xsd:anyURI"/>
<!-- Should have something restricting dc:relation to a URI. -->
<!--=============================-=============================-->
<!-- Storage Related Properties -->
<!--=============================-=============================-->
<xsd:element name="storageTotal" type="av:long.-1_"/>
<xsd:element name="storageUsed" type="av:long.-1_"/>
<xsd:element name="storageFree" type="av:long.-1_"/>
<xsd:element name="storageMaxPartition" type="av:long.-1_"/>
<xsd:element name="storageMedium" type="av:storageMedium.values"/>
<!--=============================-=============================-->
<!-- General Description Properties -->
<!-- (mainly for UI purposes) -->
<!--=============================-=============================-->
<xsd:element name="longDescription" type="xsd:string"/>
<xsd:element name="icon" type="xsd:anyURI"/>
<xsd:element name="region" type="xsd:string"/>
<xsd:element name="rights" type="xsd:string"/>
<xsd:element name="playbackCount" type="av:int.-1_"/>
<xsd:element name="lastPlaybackTime" type="upnp:qualifiedDateTime"/>
<xsd:element name="lastPlaybackPosition" type="av:unsignedDuration"/>
<xsd:element name="recordedStartDateTime" type="upnp:qualifiedDateTime"/>
<xsd:element name="recordedDuration" type="av:unsignedDuration"/>
<xsd:element name="recordedDayOfWeek" type="av:dayOfWeek.en.len.3"/>
<xsd:element name="srsRecordSchedule" type="av:srs_COLON_at_id.vd.type"/>
<xsd:element name="srsRecordTaskID" type="av:srs_COLON_at_id.vd.type"/>
<xsd:element name="recordable" type="xsd:boolean"/>
<!--=============================-=============================-->
<!-- Recorded Object Related Properties -->
<!--=============================-=============================-->
<xsd:element name="programTitle" type="xsd:string"/>
<xsd:element name="seriesTitle" type="xsd:string"/>
<xsd:element name="programID" type="av:programID.type"/>
<xsd:element name="seriesID" type="av:programID.type"/>
<xsd:element name="channelID" type="av:channelID.type"/>
<xsd:element name="episodeCount" type="xsd:unsignedInt"/>
<xsd:element name="episodeNumber" type="xsd:unsignedInt"/>
<xsd:element name="programCode" type="av:programCode.type"/>
<xsd:element name="rating" type="av:rating.type"/>
<xsd:element name="episodeType" type="av:FIRST-RUN.or.REPEAT"/>
<xsd:element name="programPreserved" type="upnp:programPreserved.Type"/>
<xsd:element name="preservedTimeRange" type="upnp:preservedTimeRange.Type"/>
<xsd:element name="programList" type="upnp:programList.Type"/>
<!--=============================-=============================-->
<!-- User Channel and EPG Related Properties -->
<!--=============================-=============================-->
<xsd:element name="channelGroupName" type="av:channelGroupName.type"/>
<xsd:element name="callSign" type="av:stationCallSign.type"/>
<xsd:element name="networkAffiliation" type="xsd:string"/>
<xsd:element name="serviceProvider" type="xsd:string"/>
<xsd:element name="price" type="upnp:price.type"/>
<xsd:element name="payPerView" type="xsd:boolean"/>
<xsd:element name="epgProviderName" type="xsd:string"/>
<xsd:element name="dateTimeRange" type="upnp:qualifiedDateTime-range"/>
<!--=============================-=============================-->
<!-- Radio Broadcast Properties -->
<!--=============================-=============================-->
<xsd:element name="radioCallSign" type="av:stationCallSign.type"/>
<xsd:element name="radioStationID" type="xsd:string"/>
<xsd:element name="radioBand" type="av:radioBand.type"/>
<!--=============================-=============================-->
<!-- Video Broadcast Properties -->
<!--=============================-=============================-->
<xsd:element name="channelNr" type="xsd:int"/>
<xsd:element name="channelName" type="xsd:string"/>
<xsd:element name="scheduledStartTime" type="upnp:qualifiedDateTime.ISO8601"/>
<xsd:element name="scheduledEndTime" type="upnp:qualifiedDateTime.ISO8601"/>
<xsd:element name="scheduledDuration" type="av:unsignedDuration"/>
<!--=============================-=============================-->
<!-- Physical Tuner Status-related Properties -->
<!--=============================-=============================-->
<xsd:element name="signalStrength" type="av:signalStrength.type"/>
<xsd:element name="signalLocked" type="xsd:boolean"/>
<xsd:element name="tuned" type="xsd:boolean"/>
<!--=============================-=============================-->
<!-- Bookmark Related Properties -->
<!--=============================-=============================-->
<xsd:element name="bookmarkID" type="av:didl-lite_COLON_at_id.vd.type"/>
<xsd:element name="bookmarkedObjectID" type="av:didl-lite_COLON_at_id.vd.type"/>
<xsd:element name="deviceUDN" type="av:deviceUDN.type"/>
<xsd:element name="stateVariableCollection" type="upnp:stateVariableCollection.type"/>
<!--=============================-=============================-->
<!-- Foreign Metadata Related Properties -->
<!--=============================-=============================-->
<xsd:element name="foreignMetadata" type="upnp:foreignMetadata.type"/>
<!--=============================-=============================-->
<!-- Miscellaneous Properties -->
<!--=============================-=============================-->
<xsd:element name="DVDRegionCode" type="xsd:int"/>
<xsd:element name="originalTrackNumber" type="xsd:int"/>
<xsd:element name="toc" type="xsd:string"/>
<xsd:element name="userAnnotation" type="xsd:string"/>
<!--=============================-=============================-->
<!-- Object Tracking Properties -->
<!--=============================-=============================-->
<xsd:element name="containerUpdateID" type="xsd:unsignedInt"/>
<xsd:element name="objectUpdateID" type="xsd:unsignedInt"/>
<xsd:element name="totalDeletedChildCount" type="xsd:unsignedInt"/>
<xsd:element name="segmentID" type="av:didl-lite_COLON_at_id.vd.type"/>
<!--=============================-=============================-->
<!-- Content Protection Properties -->
<!--=============================-=============================-->
<xsd:element name="objectOwner" type="upnp:owner.Type"/>
<xsd:element name="inclusionControl" type="upnp:inclusion.Type"/>
</xsd:choice>
</xsd:group>
<xsd:group name="upnpForItem">
<xsd:choice>
<xsd:group ref="upnp:upnpForContainer"/>
</xsd:choice>
</xsd:group>
<!--=============================-=============================-->
<!-- Base Properties -->
<!--=============================-=============================-->
<xsd:simpleType name="className.base.type">
<xsd:restriction base="xsd:NCName">
<xsd:minLength value="11"/>
<xsd:pattern value="object\.(item|container)(\.[\i-[:]][\c-[\.:]]*)*">
<xsd:annotation>
<xsd:documentation>
This pattern exactly matches the definition for class name syntax
given in CDS:2 Section C.1.1.
</xsd:documentation>
</xsd:annotation>
</xsd:pattern>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="className.wc.type">
<xsd:restriction base="xsd:NCName">
<xsd:enumeration value="object.item"/>
<xsd:enumeration value="object.item.imageItem"/>
<xsd:enumeration value="object.item.imageItem.photo"/>
<xsd:enumeration value="object.item.audioItem"/>
<xsd:enumeration value="object.item.audioItem.musicTrack"/>
<xsd:enumeration value="object.item.audioItem.audioBroadcast"/>
<xsd:enumeration value="object.item.audioItem.audioBook"/>
<xsd:enumeration value="object.item.videoItem"/>
<xsd:enumeration value="object.item.videoItem.movie"/>
<xsd:enumeration value="object.item.videoItem.videoBroadcast"/>
<xsd:enumeration value="object.item.videoItem.musicVideoClip"/>
<xsd:enumeration value="object.item.playlistItem"/>
<xsd:enumeration value="object.item.textItem"/>
<xsd:enumeration value="object.item.bookmarkItem"/>
<xsd:enumeration value="object.item.epgItem"/>
<xsd:enumeration value="object.item.epgItem.audioProgram"/>
<xsd:enumeration value="object.item.epgItem.videoProgram"/>
<xsd:enumeration value="object.container.person"/>
<xsd:enumeration value="object.container.person.musicArtist"/>
<xsd:enumeration value="object.container.playlistContainer"/>
<xsd:enumeration value="object.container.album"/>
<xsd:enumeration value="object.container.album.musicAlbum"/>
<xsd:enumeration value="object.container.album.photoAlbum"/>
<xsd:enumeration value="object.container.genre"/>
<xsd:enumeration value="object.container.genre.musicGenre"/>
<xsd:enumeration value="object.container.genre.movieGenre"/>
<xsd:enumeration value="object.container.channelGroup"/>
<xsd:enumeration value="object.container.channelGroup.audioChannelGroup"/>
<xsd:enumeration value="object.container.channelGroup.videoChannelGroup"/>
<xsd:enumeration value="object.container.epgContainer"/>
<xsd:enumeration value="object.container.storageSystem"/>
<xsd:enumeration value="object.container.storageVolume"/>
<xsd:enumeration value="object.container.storageFolder"/>
<xsd:enumeration value="object.container.bookmarkFolder"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="_className.type">
<xsd:union memberTypes="upnp:className.wc.type upnp:className.vx.type"/>
</xsd:simpleType>
<xsd:simpleType name="className.type">
<xsd:restriction base="upnp:_className.type">
<!-- xxx - JGR
<xsd:pattern value="object\.(item|container)(\.[\i-[:]][\c-[\.:]]*)*"/>
Somehow including this pattern restriction rejects the <searchClass> element
but not the <class> element from the following snipet taken from the
ForeignMetadata Example #2. Even when the values are identical, the
<class> element validates and the <searchClass> element fails.
<upnp:class>object.container.storageFolder</upnp:class>
<upnp:searchClass includeDerived="false">
object.container.album.musicAlbum
</upnp:searchClass>
This inconsistent behavior needs to be investigated.
-->
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="class.type">
<xsd:simpleContent>
<xsd:extension base="upnp:className.type">
<xsd:attribute name="name" type="xsd:string"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="searchClass.type">
<xsd:simpleContent>
<xsd:extension base="upnp:class.type">
<xsd:attribute name="includeDerived" type="xsd:boolean" use="required"/>
</xsd:extension>
<!-- XXX - JGR: Should className.type be used rather than class.type> </-->
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="qualifiedDateTime">
<xsd:simpleContent>
<xsd:extension base="av:dateTime">
<xsd:attributeGroup ref="upnp:dateTime.attr.group"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="qualifiedDateTime-range">
<xsd:simpleContent>
<xsd:extension base="av:dateTime-range">
<xsd:attributeGroup ref="upnp:dateTime.attr.group"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:attributeGroup name="dateTime.attr.group">
<xsd:attribute name="daylightSaving" type="av:daylightSaving.type" use="optional"/>
</xsd:attributeGroup>
<xsd:simpleType name="status.type">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="WRITABLE"/>
<xsd:enumeration value="PROTECTED"/>
<xsd:enumeration value="NOT_WRITABLE"/>
<xsd:enumeration value="UNKNOWN"/>
<xsd:enumeration value="MIXED"/>
</xsd:restriction>
</xsd:simpleType>
<!--=============================-=============================-->
<!-- Contributor Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="personWithRole.type">
<xsd:simpleContent>
<xsd:extension base="upnp:person.type">
<xsd:attribute name="role" type="xsd:string"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:simpleType name="person.type">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<!--=============================-=============================-->
<!-- Affiliation Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="genre.type">
<xsd:simpleContent>
<xsd:extension base="av:_title.type">
<xsd:attribute name="id" type="av:string.domainNamePrefixed"/>
<xsd:attribute name="extended" type="av:csv.1_.string.len.1_"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<!--=============================-=============================-->
<!-- Associated Resources Properties -->
<!--=============================-=============================-->
<!-- This section intentionally left blank -->
<!--=============================-=============================-->
<!-- Storage Related Properties -->
<!--=============================-=============================-->
<!-- This section intentionally left blank -->
<!--=============================-=============================-->
<!-- General Description Properties -->
<!-- (mainly for UI purposes) -->
<!--=============================-=============================-->
<!-- This section intentionally left blank -->
<!--=============================-=============================-->
<!-- Recorded Object Related Properties -->
<!--=============================-=============================-->
<!-- This section intentionally left blank -->
<!--=============================-=============================-->
<!-- User Channel and EPG Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="price.type">
<xsd:simpleContent>
<xsd:extension base="xsd:float">
<xsd:attribute name="currency" type="xsd:string" use="required"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<!--=============================-=============================-->
<!-- Radio Broadcast Properties -->
<!--=============================-=============================-->
<!--=============================-=============================-->
<!-- Video Broadcast Properties -->
<!--=============================-=============================-->
<xsd:complexType name="qualifiedDateTime.ISO8601">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attributeGroup ref="upnp:dateTime.attr.group"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="qualifiedDateTime.ISO8601andUsage">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attributeGroup ref="upnp:dateTime.attr.group"/>
<xsd:attribute name="usage" type="av:startTimeUsage"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<!--=============================-=============================-->
<!-- Physical Tuner Status-related Properties -->
<!--=============================-=============================-->
<!--=============================-=============================-->
<!-- Bookmark Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="stateVariableCollection.type">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attributeGroup ref="upnp:serviceAttrGrp"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:attributeGroup name="serviceAttrGrp">
<xsd:attribute name="serviceName" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="AVTransport"/>
<xsd:enumeration value="RenderingControl"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="rcsInstanceType">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="pre-mix"/>
<xsd:enumeration value="post-mix"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:attributeGroup>
<xsd:complexType name="stateVariable.type">
<xsd:attribute name="variableName" type="xsd:string" use="required"/>
<xsd:attribute name="channel" type="xsd:string" use="optional"/>
</xsd:complexType>
<!--=============================-=============================-->
<!-- Foreign Metadata Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="foreignMetadata.type">
<xsd:annotation>
<xsd:documentation>
WC-defined structure for the Foreign Metadata property.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:group ref="upnp:fm.elements.group"/>
</xsd:sequence>
<xsd:attributeGroup ref="upnp:fm.attributes.group"/>
</xsd:complexType>
<xsd:attributeGroup name="fm.attributes.group">
<xsd:attribute name="type" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:pattern value="[a-zA-Z0-9_.]+"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attributeGroup ref="upnp:fm.extensions.attributes.any"/>
</xsd:attributeGroup>
<xsd:group name="fm.elements.group">
<xsd:sequence>
<xsd:group ref="upnp:fm.elements.wc.group" minOccurs="0" maxOccurs="unbounded"/>
<xsd:group ref="upnp:fm.elements.vx.group" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:group>
<xsd:group name="fm.elements.vx.group">
<xsd:annotation>
<xsd:documentation>
Allow the Foreign Metadata tag to also hold vendor-defined elements.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:group>
<xsd:group name="fm.elements.wc.group">
<xsd:annotation>
<xsd:documentation>
Foreign Metadata sub-elements defined by the WC.
</xsd:documentation>
</xsd:annotation>
<xsd:choice>
<xsd:element name="fmId" type="xsd:string"/>
<xsd:element name="fmClass" type="xsd:string"/>
<xsd:element name="fmProvider" type="xsd:string"/>
<xsd:element name="fmBody" type="upnp:fm.elements.body.type"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="fm.elements.body.type">
<xsd:annotation>
<xsd:documentation>
Contains the actual foreign metadata.
</xsd:documentation>
</xsd:annotation>
<xsd:choice>
<xsd:element name="fmEmbeddedXML" type="upnp:fm.elements.body.embeddedXML.type"/>
<xsd:element name="fmEmbeddedString" type="upnp:fm.elements.body.embeddedString.type"/>
<xsd:element name="fmURI" type="upnp:fm.elements.body.uri.type"/>
</xsd:choice>
<xsd:attributeGroup ref="upnp:fm.attrs.bodyAttr.group"/>
<xsd:attributeGroup ref="upnp:fm.extensions.attributes.any"/>
</xsd:complexType>
<xsd:attributeGroup name="fm.attrs.bodyAttr.group">
<xsd:attribute name="xmlFlag" type="xsd:boolean" use="required"/>
<xsd:attribute name="mimeType">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:pattern value="[a-zA-Z0-9_./]+"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:attributeGroup>
<xsd:complexType name="fm.elements.body.embeddedXML.type">
<xsd:annotation>
<xsd:documentation>
Tags allowed inside a Foreign Metadata Body URI element.
</xsd:documentation>
</xsd:annotation>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:any namespace="##other" processContents="lax"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="fm.elements.body.embeddedString.type">
<xsd:annotation>
<xsd:documentation>
Tags allowed inside a Foreign Metadata Body URI element.
</xsd:documentation>
</xsd:annotation>
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attributeGroup ref="upnp:fm.extensions.attributes.any"/>
</xsd:extension>
<!-- Placeholder for future WC attributes. -->
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="fm.elements.body.uri.type">
<xsd:simpleContent>
<xsd:extension base="xsd:anyURI">
<xsd:attributeGroup ref="upnp:fm.extensions.attributes.any"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:attributeGroup name="fm.extensions.attributes.any">
<xsd:attributeGroup ref="av:extensions.attributes.any"/>
</xsd:attributeGroup>
<!--===================================================================-->
<!-- -->
<!-- Extension Component Datatypes -->
<!-- -->
<!--===================================================================-->
<xsd:simpleType name="className.vx.type">
<xsd:restriction base="upnp:className.base.type"/>
</xsd:simpleType>
<xsd:simpleType name="foreignMetadata.element.vx.type">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<!--=============================-=============================-->
<!-- ObjectLink Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="objectLink.type">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="title" type="xsd:string" maxOccurs="1"/>
<xsd:element name="startObject" type="xsd:boolean" minOccurs="0"/>
<xsd:element name="mode" maxOccurs="1">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Playback"/>
<xsd:enumeration value="Step"/>
<xsd:enumeration value="Index"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="relatedInfo" minOccurs="0">
<xsd:complexType mixed="true">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="role" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:pattern value="[A-Za-z0-9]+.*"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="roleText" type="xsd:string" use="required"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="startInfo" minOccurs="0">
<xsd:complexType>
<xsd:attribute name="targetGroupID" type="av:didl-lite_COLON_at_id.vd.type" use="required"/>
<xsd:attribute name="targetObjID" type="av:didl-lite_COLON_at_id.vd.type" use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="endAction" minOccurs="0">
<xsd:complexType>
<xsd:attribute name="action" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Return"/>
<xsd:enumeration value="Branch"/>
<xsd:enumeration value="Stop"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="targetGroupID" type="av:didl-lite_COLON_at_id.vd.type" use="optional"/>
<xsd:attribute name="targetObjID" type="av:didl-lite_COLON_at_id.vd.type" use="optional"/>
</xsd:complexType>
</xsd:element>
</xsd:choice>
<xsd:attribute name="groupID" type="av:didl-lite_COLON_at_id.vd.type" use="required"/>
<xsd:attribute name="headObjID" type="av:didl-lite_COLON_at_id.vd.type" use="required"/>
<xsd:attribute name="nextObjID" type="av:didl-lite_COLON_at_id.vd.type" use="required"/>
<xsd:attribute name="prevObjID" type="av:didl-lite_COLON_at_id.vd.type" use="required"/>
</xsd:complexType>
<!--=============================-=============================-->
<!-- ObjectLinkRef Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="objectLinkRef.type">
<xsd:choice minOccurs="0" maxOccurs="1">
<xsd:element name="title" maxOccurs="1"/>
<xsd:element name="startObject" type="xsd:boolean" minOccurs="0"/>
<xsd:element name="relatedInfo" minOccurs="0">
<xsd:complexType>
<xsd:attribute name="role" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:pattern value="[A-Za-z0-9]+.*"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="roleText" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:choice>
<xsd:attribute name="groupID" type="av:didl-lite_COLON_at_id.vd.type" use="required"/>
<xsd:attribute name="targetGroup" type="av:didl-lite_COLON_at_id.vd.type" use="required"/>
<xsd:attribute name="targetObjID" type="av:didl-lite_COLON_at_id.vd.type" use="required"/>
<xsd:attribute name="return" type="xsd:boolean" use="optional"/>
</xsd:complexType>
<!--=============================-=============================-->
<!-- resExt Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="resExt.type">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Defines the permitted child elements of <resExt>. All children are optional and can be listed in any order in an unbounded manner.
</xsd:documentation>
</xsd:annotation>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="segmentInfo" type="upnp:segmentInfo.Type"/>
<xsd:element name="clockSync" type="upnp:clockSync.Type"/>
<xsd:element name="DRMInfo" type="upnp:DRMInfo.Type"/>
<xsd:element name="isSyncAnchor" type="xsd:string"/>
<xsd:element name="componentInfo" type="upnp:componentInfo.Type"/>
</xsd:choice>
<xsd:attribute name="id" type="av:didl-lite_COLON_at_id.vd.type" use="required">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Must be child of <item> or <container>. Value must match the res@id value.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<!--=============================-=============================-->
<!-- segmentInfo Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="segmentInfo.Type">
<xsd:sequence>
<xsd:element name="timeRange">
<xsd:complexType>
<xsd:attribute name="start" type="av:duration.cds1.decFrac" use="required"/>
<xsd:attribute name="end" type="av:duration.cds1.decFrac" use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="byteRange" minOccurs="0">
<xsd:complexType>
<xsd:attribute name="start" type="xsd:unsignedLong" use="required"/>
<xsd:attribute name="end" type="xsd:unsignedLong" use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="frameRange" minOccurs="0">
<xsd:complexType>
<xsd:attribute name="start" type="xsd:unsignedLong" use="required"/>
<xsd:attribute name="end" type="xsd:unsignedLong" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="baseObjectID" type="av:didl-lite_COLON_at_id.vd.type" use="required"/>
<xsd:attribute name="baseResID" type="av:didl-lite_COLON_at_id.vd.type" use="required"/>
</xsd:complexType>
<!--=============================-=============================-->
<!-- clockSync Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="clockSync.Type">
<xsd:attribute name="deviceClockInfoID" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Identifies the timestamp mechanism that will be used when the associated content-binary is streamed to the network by the device. Its value MUST equal the value of the associated deviceClockInfo@id in a <Feature> element.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="supportedTimestampsID" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Identifies the timestamp mechanism that will be used when the associated content-binary is streamed to the network by the device. Its value MUST equal the value of the associated supportedTimestamps@id in a <Features> element.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<!--=============================-=============================-->
<!-- DRMInfo Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="DRMInfoContent.Type">
<xsd:sequence>
<xsd:element name="foreignMetaData" type="upnp:foreignMetadata.type" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="DRMInfo.Type">
<xsd:sequence>
<xsd:element name="DRMInfo" type="upnp:DRMInfoContent.Type" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<!--=============================-=============================-->
<!-- isSynchAnchor Related Properties -->
<!--=============================-=============================-->
<!--=============================-=============================-->
<!-- componentInfo Related Properties -->
<!--=============================-=============================-->
<!--=============================-=============================-->
<!-- Resource Encoding Characteristics Properties -->
<!--=============================-=============================-->
<xsd:complexType name="upnp.res.type" mixed="true">
<xsd:annotation>
<xsd:documentation>
A 'res' element indentifies a resource.
A resource is typically some type of binary asset,
such as a photo, song, video, etc.
A 'res' element contains a URI that identifies the resource
</xsd:documentation>
</xsd:annotation>
<xsd:simpleContent>
<xsd:extension base="xsd:anyURI">
<xsd:attribute name="importUri" type="xsd:anyURI"/>
<xsd:attribute name="protocolInfo" type="xsd:string" use="required"/>
<xsd:attribute name="size" type="xsd:unsignedLong"/>
<xsd:attribute name="duration" type="av:duration.cds1"/>
<xsd:attribute name="bitrate" type="xsd:unsignedInt"/>
<xsd:attribute name="sampleFrequency" type="xsd:unsignedInt"/>
<xsd:attribute name="bitsPerSample" type="xsd:unsignedInt"/>
<xsd:attribute name="nrAudioChannels" type="xsd:unsignedInt"/>
<xsd:attribute name="resolution">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:pattern value="[0-9]+x[0-9]+"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="colorDepth" type="xsd:unsignedInt"/>
<xsd:attribute name="tspec" type="av:string.len.0_256"/>
<xsd:attribute name="allowedUse" type="av:csv.1_.allowedUse"/>
<xsd:attribute name="validityStart" type="av:dateTime"/>
<xsd:attribute name="validityEnd" type="av:dateTime"/>
<xsd:attribute name="remainingTime" type="av:unsignedDuration"/>
<xsd:attribute name="usageInfo" type="xsd:string"/>
<xsd:attribute name="rightsInfoURI" type="xsd:anyURI"/>
<xsd:attribute name="contentInfoURI" type="xsd:anyURI"/>
<xsd:attribute name="recordQuality" type="av:csv.1_.colonDelimPairs"/>
<xsd:attribute name="protection" type="xsd:string"/>
<xsd:attributeGroup ref="upnp:dateTime.attr.group"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<!--transform names with extensions-->
<xsd:simpleType name="componentClass.Type">
<xsd:restriction base="xsd:string">
<xsd:pattern value=".*"/>
<xsd:pattern value="Audio"/>
<xsd:pattern value="Video"/>
<xsd:pattern value="Caption"/>
<xsd:pattern value="Subtitle"/>
<xsd:pattern value="Unknown"/>
</xsd:restriction>
</xsd:simpleType>
<!-- content.type -->
<xsd:complexType name="content.Type">
<xsd:sequence/>
<xsd:attribute name="MIMEType" type="xsd:string" use="required"/>
<xsd:attribute name="extendedType" type="xsd:string" use="required"/>
</xsd:complexType>
<!-- CompRes.type -->
<xsd:complexType name="compRes.Type" mixed="true">
<xsd:sequence>
<!-- we can't reffer directly to didl-lite:res.type since that creates a circular reference -->
<xsd:element name="isSynchAnchor" type="xsd:string" minOccurs="0" maxOccurs="1"/>
<xsd:element name="refUDN" type="xsd:string" minOccurs="0" maxOccurs="1"/>
<xsd:element name="refObjectID" type="xsd:string" minOccurs="0" maxOccurs="1"/>
<xsd:element name="refResID" type="xsd:string" minOccurs="0" maxOccurs="1"/>
<xsd:element name="res" type="upnp:upnp.res.type" minOccurs="0" maxOccurs="unbounded"/>
<!-- <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded"/> -->
</xsd:sequence>
</xsd:complexType>
<!--Component.type -->
<xsd:complexType name="component.Type">
<xsd:all minOccurs="1">
<xsd:element name="componentClass" type="upnp:componentClass.Type" maxOccurs="1" minOccurs="1"/>
<xsd:element name="contentType" type="upnp:content.Type" minOccurs="1" maxOccurs="1"/>
<xsd:element name="language" type="xsd:string" minOccurs="0" maxOccurs="1"/>
<xsd:element name="compRes" type="upnp:compRes.Type" minOccurs="0" maxOccurs="1"/>
</xsd:all>
<xsd:attribute name="componentID" type="xsd:string" use="required"/>
<xsd:attribute name="supportive" type="xsd:boolean" use="optional"/>
<xsd:attribute name="supportID" type="xsd:string" use="optional"/>
</xsd:complexType>
<!-- ComponentGroup.type-->
<xsd:complexType name="componentGroup.Type">
<xsd:sequence>
<xsd:element name="component" type="upnp:component.Type" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="groupID" type="xsd:string" use="required"/>
<xsd:attribute name="required" type="xsd:boolean" use="required"/>
</xsd:complexType>
<!-- ComponentInfo.type -->
<xsd:complexType name="componentInfo.Type">
<xsd:sequence>
<xsd:element name="componentGroup" type="upnp:componentGroup.Type" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="componentID" type="xsd:string" use="optional"/>
</xsd:complexType>
<!--=============================-=============================-->
<!-- programPreserved Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="programPreserved.Type">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="startTime" use="required"/>
<xsd:attribute name="startTimeDaylightSaving"/>
<xsd:attribute name="endTime"/>
<xsd:attribute name="endTimeDaylightSaving"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<!--=============================-=============================-->
<!-- programPreserved Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="preservedTimeRange.Type">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="startTime"/>
<xsd:attribute name="startTimeDaylightSaving"/>
<xsd:attribute name="endTime"/>
<xsd:attribute name="endTimeDaylightSaving"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<!--=============================-=============================-->
<!-- programList Related Properties -->
<!--=============================-=============================-->
<xsd:complexType name="programList.Type">
<xsd:sequence>
<xsd:element name="program" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="preserved"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<!--=============================-=============================-->
<!-- Content Protection Feature Properties -->
<!--=============================-=============================-->
<xsd:complexType name="owner.Type">
<xsd:sequence>
<xsd:element name="role" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="lock" type="xsd:boolean" use="required"/>
</xsd:complexType>
<xsd:complexType name="inclusion.Type">
<xsd:sequence>
<xsd:element name="role" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
07070100000017000081A400000000000000000000000168604515000016D8000000000000000000000000000000000000001D00000000gupnp-av-0.14.4/data/xml.xsd<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en">
<xs:annotation>
<xs:documentation>
See http://www.w3.org/XML/1998/namespace.html and
http://www.w3.org/TR/REC-xml for information about this namespace.
This schema document describes the XML namespace, in a form
suitable for import by other schema documents.
Note that local names in this namespace are intended to be defined
only by the World Wide Web Consortium or its subgroups. The
following names are currently defined in this namespace and should
not be used with conflicting semantics by any Working Group,
specification, or document instance:
base (as an attribute name): denotes an attribute whose value
provides a URI to be used as the base for interpreting any
relative URIs in the scope of the element on which it
appears; its value is inherited. This name is reserved
by virtue of its definition in the XML Base specification.
id (as an attribute name): denotes an attribute whose value
should be interpreted as if declared to be of type ID.
The xml:id specification is not yet a W3C Recommendation,
but this attribute is included here to facilitate experimentation
with the mechanisms it proposes. Note that it is _not_ included
in the specialAttrs attribute group.
lang (as an attribute name): denotes an attribute whose value
is a language code for the natural language of the content of
any element; its value is inherited. This name is reserved
by virtue of its definition in the XML specification.
space (as an attribute name): denotes an attribute whose
value is a keyword indicating what whitespace processing
discipline is intended for the content of the element; its
value is inherited. This name is reserved by virtue of its
definition in the XML specification.
Father (in any context at all): denotes Jon Bosak, the chair of
the original XML Working Group. This name is reserved by
the following decision of the W3C XML Plenary and
XML Coordination groups:
In appreciation for his vision, leadership and dedication
the W3C XML Plenary on this 10th day of February, 2000
reserves for Jon Bosak in perpetuity the XML name
xml:Father
</xs:documentation>
</xs:annotation>
<xs:annotation>
<xs:documentation>This schema defines attributes and an attribute group
suitable for use by
schemas wishing to allow xml:base, xml:lang, xml:space or xml:id
attributes on elements they define.
To enable this, such a schema must import this schema
for the XML namespace, e.g. as follows:
<schema . . .>
. . .
<import namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.w3.org/2005/08/xml.xsd"/>
Subsequently, qualified reference to any of the attributes
or the group defined below will have the desired effect, e.g.
<type . . .>
. . .
<attributeGroup ref="xml:specialAttrs"/>
will define a type which will schema-validate an instance
element with any of those attributes</xs:documentation>
</xs:annotation>
<xs:annotation>
<xs:documentation>In keeping with the XML Schema WG's standard versioning
policy, this schema document will persist at
http://www.w3.org/2005/08/xml.xsd.
At the date of issue it can also be found at
http://www.w3.org/2001/xml.xsd.
The schema document at that URI may however change in the future,
in order to remain compatible with the latest version of XML Schema
itself, or with the XML namespace itself. In other words, if the XML
Schema or XML namespaces change, the version of this document at
http://www.w3.org/2001/xml.xsd will change
accordingly; the version at
http://www.w3.org/2005/08/xml.xsd will not change.
</xs:documentation>
</xs:annotation>
<xs:attribute name="lang">
<xs:annotation>
<xs:documentation>Attempting to install the relevant ISO 2- and 3-letter
codes as the enumerated possible values is probably never
going to be a realistic possibility. See
RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry
at http://www.iana.org/assignments/lang-tag-apps.htm for
further information.
The union allows for the 'un-declaration' of xml:lang with
the empty string.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:union memberTypes="xs:language">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value=""/>
</xs:restriction>
</xs:simpleType>
</xs:union>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="space">
<xs:simpleType>
<xs:restriction base="xs:NCName">
<xs:enumeration value="default"/>
<xs:enumeration value="preserve"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="base" type="xs:anyURI">
<xs:annotation>
<xs:documentation>See http://www.w3.org/TR/xmlbase/ for
information about this attribute.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="id" type="xs:ID">
<xs:annotation>
<xs:documentation>See http://www.w3.org/TR/xml-id/ for
information about this attribute.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attributeGroup name="specialAttrs">
<xs:attribute ref="xml:base"/>
<xs:attribute ref="xml:lang"/>
<xs:attribute ref="xml:space"/>
</xs:attributeGroup>
</xs:schema>
07070100000018000041ED0000000000000000000000026860451500000000000000000000000000000000000000000000001400000000gupnp-av-0.14.4/doc07070100000019000081A400000000000000000000000168604515000003B7000000000000000000000000000000000000002500000000gupnp-av-0.14.4/doc/gupnp-av.toml.in[library]
namespace = "GUPnPAV"
version = "@VERSION@"
browse_url = "https://gitlab.gnome.org/GNOME/gupnp-av/"
repository_url = "https://gitlab.gnome.org/GNOME/gupnp.git"
website_url = "https://gupnp.org"
logo_url = "gupnp-logo-short.svg"
license = "LGPL-2.1-or-later"
description = "Helper objects for dealing with UPnP-AV"
dependencies = [ "GObject-2.0", "libxml2-2.0" ]
devhelp = true
search_index = true
authors = "The GUPnP developers"
[theme]
name="basic"
show_index_summary = true
[source-location]
base_url = "https://gitlab.gnome.org/GNOME/gupnp-av/-/blob/master"
[dependencies."GObject-2.0"]
name = "GObject"
description = "The base type system library"
docs_url = "https://developer.gnome.org/gobject/stable"
[dependencies."libxml2-2.0"]
name = "LibXML2"
description = "A XML handling library"
docs_url = "http://www.xmlsoft.org/html/index.html"
[extra]
content_images = [
"images/gupnp-logo-short.svg"
]
urlmap_file = "urlmap.js"
0707010000001A000041ED0000000000000000000000026860451500000000000000000000000000000000000000000000001B00000000gupnp-av-0.14.4/doc/images0707010000001B000081A40000000000000000000000016860451500001F11000000000000000000000000000000000000003000000000gupnp-av-0.14.4/doc/images/gupnp-logo-short.svg<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
id="svg4194"
version="1.1"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
width="89.339256mm"
height="37.64888mm"
viewBox="0 0 316.55642 133.40154"
sodipodi:docname="gupnp-logo-short.svg"
inkscape:export-filename="/home/jgeorg/gupnp-logo-v1.svg.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata4200">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<cc:license
rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<defs
id="defs4198" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1011"
id="namedview4196"
showgrid="false"
showguides="true"
inkscape:snap-page="false"
inkscape:zoom="1.6897519"
inkscape:cx="106.82042"
inkscape:cy="36.691777"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="svg4194"
inkscape:guide-bbox="true"
inkscape:pagecheckerboard="0"
units="mm"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:document-units="mm">
<inkscape:grid
type="xygrid"
id="grid5354"
originx="-2.7774772"
originy="-2.2013303"
spacingx="1"
spacingy="1" />
<sodipodi:guide
position="311.44403,45.237576"
orientation="0,1"
id="guide4237"
inkscape:locked="false" />
<sodipodi:guide
position="316.24124,64.031713"
orientation="1,0"
id="guide14" />
</sodipodi:namedview>
<path
inkscape:connector-curvature="0"
id="path4222"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:111.914px;line-height:125%;font-family:moderna;-inkscape-font-specification:moderna;letter-spacing:0px;word-spacing:0px;fill:#204a87;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 59.874011,60.321668 q 0,12.7582 -9.176951,21.487495 9.288865,8.841209 9.288865,21.711327 0,16.11562 -13.205856,24.84491 -7.722069,5.03614 -16.675192,5.03614 -16.003708,0 -24.8449171,-13.31778 -5.1480458,-7.61015 -5.1480458,-16.56327 0,-5.819533 2.2382807,-11.191407 L 16.33945,97.92479 q -1.11914,2.68593 -1.11914,5.5957 0,6.15527 4.364647,10.408 4.476562,4.36465 10.51992,4.36465 6.043358,0 10.408006,-4.36465 4.364647,-4.36464 4.364647,-10.408 0,-9.848438 -9.288865,-13.76543 -2.797851,0.55957 -5.595702,0.55957 -12.534373,0 -21.2636682,-8.729295 Q 0,72.85604 0,60.321668 0,47.899209 8.7292948,39.169914 17.570504,30.440619 29.992963,30.440619 l 8.729295,-20.7040974 11.862888,5.0361324 -7.833983,18.57773 q 7.833983,3.805078 12.422459,11.07949 4.700389,7.274413 4.700389,15.891794 z m -15.108395,0 q 0,-6.043358 -4.364647,-10.408006 -4.364648,-4.364647 -10.408006,-4.364647 -6.155272,0 -10.51992,4.364647 -4.364647,4.252734 -4.364647,10.408006 0,6.155272 4.364647,10.519919 4.364648,4.364648 10.51992,4.364648 6.155272,0 10.408006,-4.364648 4.364647,-4.364647 4.364647,-10.519919 z" />
<path
inkscape:connector-curvature="0"
id="path4224"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:111.914px;line-height:125%;font-family:moderna;-inkscape-font-specification:moderna;letter-spacing:0px;word-spacing:0px;fill:#204a87;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 97.753413,73.527524 q -6.15527,0 -10.519918,-4.252733 -4.252733,-4.364648 -4.252733,-10.51992 L 82.868848,0 H 67.760452 v 58.754871 q 0,12.422459 8.729296,21.151754 8.841209,8.729295 21.263665,8.729295 12.422457,0 21.151757,-8.729295 8.8412,-8.729295 8.8412,-21.151754 V 0 h -15.10839 v 58.754871 q 0,6.155272 -4.36465,10.51992 -4.36465,4.252733 -10.519917,4.252733 z" />
<path
inkscape:connector-curvature="0"
id="path4226"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:111.914px;line-height:125%;font-family:moderna;-inkscape-font-specification:moderna;letter-spacing:0px;word-spacing:0px;fill:#204a87;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 190.13495,30.216791 Q 190.24687,17.682419 181.51757,9.0650376 172.78828,0.3357421 160.2539,0.2238281 L 135.5209,0.111914 V 88.63592 h 15.22031 V 59.985926 h 9.40078 q 12.42246,0 21.15175,-8.617381 8.7293,-8.729296 8.84121,-21.151754 z m -15.10839,-0.111914 q -0.11192,6.267186 -4.36465,10.51992 -4.25273,4.252733 -10.51992,4.252733 H 150.6293 V 15.22031 l 9.6246,0.111914 q 6.26719,0.111914 10.51992,4.364647 4.36465,4.252734 4.25274,10.408006 z" />
<path
inkscape:connector-curvature="0"
id="path4228"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:111.914px;line-height:125%;font-family:moderna;-inkscape-font-specification:moderna;letter-spacing:0px;word-spacing:0px;fill:#204a87;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 221.80976,45.549015 q 6.04336,0 10.40801,4.364647 4.36465,4.364648 4.36465,10.408006 l 0.11191,28.314252 h 15.1084 V 60.321668 q 0,-12.422459 -8.84121,-21.151754 -8.7293,-8.729295 -21.15176,-8.729295 -12.42246,0 -21.26366,8.729295 -8.7293,8.729295 -8.7293,21.151754 V 88.63592 h 15.1084 V 60.321668 q 0,-6.155272 4.36464,-10.408006 4.36465,-4.364647 10.51992,-4.364647 z" />
<path
inkscape:connector-curvature="0"
id="path4230"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:111.914px;line-height:125%;font-family:moderna;-inkscape-font-specification:moderna;letter-spacing:0px;word-spacing:0px;fill:#204a87;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 314.19132,30.216791 Q 314.30323,17.682419 305.57394,9.0650376 296.84464,0.3357421 284.31027,0.2238281 L 259.57727,0.111914 V 88.63592 h 15.22031 V 59.985926 h 9.40078 q 12.42245,0 21.15175,-8.617381 8.7293,-8.729296 8.84121,-21.151754 z m -15.1084,-0.111914 q -0.11191,6.267186 -4.36464,10.51992 -4.25274,4.252733 -10.51992,4.252733 h -9.5127 V 15.22031 l 9.62461,0.111914 q 6.26719,0.111914 10.51992,4.364647 4.36465,4.252734 4.25273,10.408006 z" />
<rect
style="fill:#204a87;fill-opacity:1;stroke:#204a87;stroke-width:0.630386;stroke-linejoin:miter;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="rect5352"
width="248.92432"
height="15.959336"
x="67.316925"
y="104.33861"
ry="0" />
</svg>
0707010000001C000081A400000000000000000000000168604515000003EB000000000000000000000000000000000000002000000000gupnp-av-0.14.4/doc/meson.buildconf = configuration_data()
conf.set('VERSION', meson.project_version())
if get_option('gtk_doc')
gidocgen = find_program('gi-docgen', required: true)
gupnp_av_toml = configure_file (
input: 'gupnp-av.toml.in',
output: 'gupnp-av.toml',
configuration: conf
)
docs_dir = join_paths(get_option('prefix'), get_option('datadir')) / 'doc'
custom_target(
'gupnp-av-doc',
input: [ gupnp_av_toml, gupnp_av_gir[0] ],
output: GUPNP_AV_API_NAME,
command : [
gidocgen,
'generate',
'--quiet',
'--add-include-path=@0@'.format(meson.current_build_dir() / '../libgupnp-av'),
'--config', gupnp_av_toml,
'--output-dir=@OUTPUT@',
'--no-namespace-dir',
'--content-dir=@0@'.format(meson.current_source_dir()),
'@INPUT1@',
],
depend_files : [
gupnp_av_toml,
],
build_by_default: true,
install: true,
install_dir : docs_dir,
)
endif
0707010000001D000081A40000000000000000000000016860451500000187000000000000000000000000000000000000001E00000000gupnp-av-0.14.4/doc/urlmap.js// A map between namespaces and base URLs for their online documentation
baseURLs = [
[ 'GLib', 'https://docs.gtk.org/glib/' ],
[ 'GObject', 'https://docs.gtk.org/gobject/' ],
[ 'Gio', 'https://docs.gtk.org/gio/' ],
[ 'GSSDP', 'https://gnome.pages.gitlab.gnome.org/gssdp/docs/' ],
[ 'libxml2', 'https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#']
]
0707010000001E000081A40000000000000000000000016860451500000514000000000000000000000000000000000000001E00000000gupnp-av-0.14.4/gupnp-av.doap<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:gnome="http://api.gnome.org/doap-extensions#"
xmlns="http://usefulinc.com/ns/doap#">
<name xml:lang="en">GUPnP A/V</name>
<shortdesc xml:lang="en">Utility library that eases the handling and implementation of UPnP A/V profiles.</shortdesc>
<description>GUPnP is an object-oriented open source framework for creating UPnP devices and
control points, written in C using GObject and libsoup. The GUPnP API is
intended to be easy to use, efficient and flexible.
GUPnP A/V is a small utility library that aims to ease the handling and
implementation of UPnP A/V profiles.</description>
<homepage
rdf:resource="http://gupnp.org" />
<support-forum
rdf:resource="https://discourse.gnome.org/tag/gupnp" />
<download-page
rdf:resource="https://download.gnome.org/sources/gupnp-av/"/>
<bug-database
rdf:resource="https://gitlab.gnome.org/GNOME/gupnp-av/issues/" />
<maintainer>
<foaf:Person>
<foaf:name>Jens Georg</foaf:name>
<foaf:mbox rdf:resource="mailto:mail@jensge.org" />
<gnome:userid>jensgeorg</gnome:userid>
</foaf:Person>
</maintainer>
</Project>
0707010000001F000041ED0000000000000000000000026860451500000000000000000000000000000000000000000000001900000000gupnp-av-0.14.4/internal07070100000020000081A4000000000000000000000001686045150000006E000000000000000000000000000000000000002500000000gupnp-av-0.14.4/internal/meson.buildconfig_h = configure_file(output : 'config.h', configuration : conf)
config_h_inc = include_directories('.')
07070100000021000041ED0000000000000000000000026860451500000000000000000000000000000000000000000000001C00000000gupnp-av-0.14.4/libgupnp-av07070100000022000081A40000000000000000000000016860451500007C4F000000000000000000000000000000000000002C00000000gupnp-av-0.14.4/libgupnp-av/fragment-util.c/*
* Copyright (C) 2012 Intel Corporation
*
* Authors: Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include <stdarg.h>
#include <libxml/parserInternals.h>
#include "fragment-util.h"
#include "xml-util.h"
typedef struct {
gchar *node_name;
gchar *attribute_name;
} NodeDiff;
static NodeDiff *
node_diff_new (const xmlChar *node_name,
const xmlChar *attribute_name)
{
NodeDiff *diff = g_slice_new (NodeDiff);
diff->node_name = g_strdup ((gchar *) node_name);
diff->attribute_name = g_strdup ((gchar *) attribute_name);
return diff;
}
static void
node_diff_free (NodeDiff *diff)
{
if (diff != NULL) {
g_free (diff->node_name);
g_free (diff->attribute_name);
g_slice_free (NodeDiff, diff);
}
}
static GList *
get_toplevel_changes (xmlNodePtr current_node,
xmlNodePtr new_node)
{
xmlAttrPtr attribute;
GHashTable *current_attributes = av_xml_util_get_attributes_map
(current_node);
GList *changes = NULL;
const xmlChar *name = new_node->name;
/* compare attributes */
for (attribute = new_node->properties;
attribute != NULL;
attribute = attribute->next) {
const xmlChar *value = NULL;
const xmlChar *key = attribute->name;
gboolean differs = FALSE;
if (g_hash_table_lookup_extended (current_attributes,
key,
NULL,
(gpointer *) &value)) {
if (xmlStrcmp (value, attribute->children->content))
differs = TRUE;
g_hash_table_remove (current_attributes, key);
} else
differs = TRUE;
if (differs)
changes = g_list_prepend (changes,
node_diff_new (name,
key));
}
if (g_hash_table_size (current_attributes) > 0) {
GHashTableIter iter;
xmlChar *key = NULL;
g_hash_table_iter_init (&iter, current_attributes);
while (g_hash_table_iter_next (&iter,
(gpointer *) &key,
NULL))
changes = g_list_prepend (changes, node_diff_new (name,
key));
}
g_hash_table_unref (current_attributes);
return changes;
}
static gboolean
is_read_only (const gchar *changed_element,
const gchar *changed_attribute)
{
static GHashTable *readonly_props = NULL;
static gsize readonly_props_loaded = 0;
if (g_once_init_enter (&readonly_props_loaded)) {
readonly_props = g_hash_table_new (g_str_hash,
g_str_equal);
g_hash_table_add (readonly_props, (gpointer) "@id");
g_hash_table_add (readonly_props, (gpointer) "@parentID");
g_hash_table_add (readonly_props, (gpointer) "@refID");
g_hash_table_add (readonly_props, (gpointer) "@restricted");
g_hash_table_add (readonly_props, (gpointer) "@searchable");
g_hash_table_add (readonly_props, (gpointer) "@childCount");
g_hash_table_add (readonly_props, (gpointer) "searchClass");
g_hash_table_add (readonly_props, (gpointer) "searchClass@name");
g_hash_table_add (readonly_props, (gpointer) "searchClass@includeDerived");
g_hash_table_add (readonly_props, (gpointer) "createClass");
g_hash_table_add (readonly_props, (gpointer) "createClass@name");
g_hash_table_add (readonly_props, (gpointer) "createClass@includeDerived");
g_hash_table_add (readonly_props, (gpointer) "writeStatus");
g_hash_table_add (readonly_props, (gpointer) "res@importUri");
g_hash_table_add (readonly_props, (gpointer) "storageTotal");
g_hash_table_add (readonly_props, (gpointer) "storageUsed");
g_hash_table_add (readonly_props, (gpointer) "storageFree");
g_hash_table_add (readonly_props, (gpointer) "storageMaxPartition");
g_hash_table_add (readonly_props, (gpointer) "storageMedium");
g_hash_table_add (readonly_props, (gpointer) "playbackCount");
g_hash_table_add (readonly_props, (gpointer) "srsRecordScheduleID");
g_hash_table_add (readonly_props, (gpointer) "srsRecordTaskID");
g_hash_table_add (readonly_props, (gpointer) "price");
g_hash_table_add (readonly_props, (gpointer) "price@currency");
g_hash_table_add (readonly_props, (gpointer) "payPerView");
g_hash_table_add (readonly_props, (gpointer) "dateTimeRange");
g_hash_table_add (readonly_props, (gpointer)
"dateTimeRange@daylightSaving");
g_hash_table_add (readonly_props, (gpointer) "signalStrength");
g_hash_table_add (readonly_props, (gpointer) "signalLocked");
g_hash_table_add (readonly_props, (gpointer) "tuned");
g_hash_table_add (readonly_props, (gpointer) "containerUpdateID");
g_hash_table_add (readonly_props, (gpointer) "objectUpdateID");
g_hash_table_add (readonly_props, (gpointer) "totalDeletedChildCount");
g_hash_table_add (readonly_props, (gpointer) "res@updateCount");
g_once_init_leave (&readonly_props_loaded, 1);
}
if (changed_element != NULL) {
if (changed_attribute != NULL) {
gchar *test_prop = g_strdup_printf ("%s@%s",
changed_element,
changed_attribute);
gboolean result = g_hash_table_contains (readonly_props,
test_prop);
g_free (test_prop);
if (result)
return TRUE;
test_prop = g_strdup_printf ("@%s", changed_attribute);
result = g_hash_table_contains (readonly_props,
test_prop);
g_free (test_prop);
if (result)
return TRUE;
}
return g_hash_table_contains (readonly_props, changed_element);
}
return FALSE;
}
static gboolean
is_any_change_read_only (xmlNodePtr current_node,
xmlNodePtr new_node)
{
GList *changes = get_toplevel_changes (current_node, new_node);
GList *iter;
gboolean read_only = FALSE;
for (iter = changes; iter != NULL; iter = iter->next) {
NodeDiff *diff = (NodeDiff *) iter->data;
if (is_read_only (diff->node_name,
diff->attribute_name)) {
read_only = TRUE;
break;
}
}
if (changes != NULL)
g_list_free_full (changes, (GDestroyNotify) node_diff_free);
return read_only;
}
static GUPnPDIDLLiteFragmentResult
apply_temporary_modification (DocNode *modified,
xmlNodePtr current_node,
xmlNodePtr new_node,
XSDData *xsd_data)
{
xmlNodePtr mod_cur_node = av_xml_util_find_node (modified->node,
current_node);
xmlNodePtr new_node_copy = av_xml_util_copy_node (new_node);
if (mod_cur_node == NULL) {
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR;
}
xmlUnlinkNode (new_node_copy);
mod_cur_node = xmlReplaceNode (mod_cur_node, new_node_copy);
xmlUnlinkNode (mod_cur_node);
xmlFreeNode (mod_cur_node);
if (!xsd_data_validate_doc (xsd_data, modified->doc))
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_INVALID;
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK;
}
static GUPnPDIDLLiteFragmentResult
apply_temporary_addition (DocNode *modified,
xmlNodePtr sibling,
xmlNodePtr new_node,
XSDData *xsd_data)
{
xmlNodePtr mod_sibling;
xmlNodePtr new_node_copy = av_xml_util_copy_node (new_node);
if (sibling->doc == modified->doc)
mod_sibling = sibling;
else
mod_sibling = av_xml_util_find_node (modified->node, sibling);
if (mod_sibling == NULL)
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR;
xmlUnlinkNode (new_node_copy);
if (xmlAddNextSibling (mod_sibling, new_node_copy) == NULL) {
xmlFreeNode (new_node_copy);
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR;
}
if (!xsd_data_validate_doc (xsd_data, modified->doc))
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_INVALID;
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK;
}
static GUPnPDIDLLiteFragmentResult
apply_temporary_removal (DocNode *modified,
xmlNodePtr current_node,
XSDData *xsd_data)
{
xmlNodePtr mod_cur_node = av_xml_util_find_node (modified->node,
current_node);
if (mod_cur_node == NULL)
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR;
xmlUnlinkNode (mod_cur_node);
xmlFreeNode (mod_cur_node);
if (!xsd_data_validate_doc (xsd_data, modified->doc))
/* not sure if this is correct */
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_REQUIRED_TAG;
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK;
}
typedef struct {
gboolean required;
GHashTable* required_dep_props; /* string set */
GHashTable* required_indep_props; /* string to indep prop */
} IndependentProperty;
static void
independent_property_free (IndependentProperty *indep)
{
if (indep != NULL) {
g_hash_table_unref (indep->required_dep_props);
g_hash_table_unref (indep->required_indep_props);
g_slice_free (IndependentProperty, indep);
}
}
static IndependentProperty *
independent_property_new (gboolean required)
{
IndependentProperty *indep = g_slice_new (IndependentProperty);
indep->required = required;
indep->required_dep_props = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
NULL);
indep->required_indep_props = g_hash_table_new_full
(g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify) independent_property_free);
return indep;
}
static void
insert_indep_prop (GHashTable *props,
const gchar *name,
IndependentProperty *prop)
{
g_hash_table_insert (props, g_strdup (name), prop);
}
static void
insert_indep_prop_to_indep (IndependentProperty *prop,
const gchar *name,
IndependentProperty *req_prop)
{
insert_indep_prop (prop->required_indep_props, name, req_prop);
}
static void
add_dep_prop (IndependentProperty *indep,
const gchar *name)
{
g_hash_table_add (indep->required_dep_props, g_strdup (name));
}
static IndependentProperty *
create_prop_with_required_dep_props (gboolean required,
const gchar *dep_prop,
...)
{
IndependentProperty *indep = independent_property_new (required);
if (dep_prop != NULL) {
va_list var_args;
const gchar *name = dep_prop;
va_start (var_args, dep_prop);
do {
add_dep_prop (indep, name);
name = va_arg (var_args, gchar *);
} while (name != NULL);
va_end (var_args);
}
return indep;
}
static IndependentProperty *
create_foreign_metadata_props (void)
{
IndependentProperty *fm = independent_property_new (FALSE);
IndependentProperty *other;
add_dep_prop (fm, "type");
other = independent_property_new (TRUE);
insert_indep_prop_to_indep (fm, "fmId", other);
other = independent_property_new (TRUE);
insert_indep_prop_to_indep (fm, "fmClass", other);
other = independent_property_new (TRUE);
insert_indep_prop_to_indep (fm, "fmProvider", other);
other = independent_property_new (TRUE);
add_dep_prop (other, "xmlFlag");
insert_indep_prop_to_indep (fm, "fmBody", other);
return fm;
}
static GHashTable *
get_required_properties (void)
{
static GHashTable *required_props = NULL;
static gsize required_props_loaded = 0;
if (g_once_init_enter (&required_props_loaded)) {
required_props = g_hash_table_new_full
(g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify) independent_property_free);
insert_indep_prop (required_props,
"",
create_prop_with_required_dep_props
(FALSE,
"id",
"parentID",
"restricted",
NULL));
insert_indep_prop (required_props,
"title",
independent_property_new (TRUE));
insert_indep_prop (required_props,
"class",
independent_property_new (TRUE));
insert_indep_prop (required_props,
"res",
create_prop_with_required_dep_props
(FALSE,
"protocolInfo",
NULL));
insert_indep_prop (required_props,
"programID",
create_prop_with_required_dep_props
(FALSE,
"type",
NULL));
insert_indep_prop (required_props,
"seriesID",
create_prop_with_required_dep_props
(FALSE,
"type",
NULL));
insert_indep_prop (required_props,
"channelID",
create_prop_with_required_dep_props
(FALSE,
"type",
NULL));
insert_indep_prop (required_props,
"programCode",
create_prop_with_required_dep_props
(FALSE,
"type",
NULL));
insert_indep_prop (required_props,
"channelGroupName",
create_prop_with_required_dep_props
(FALSE,
"id",
NULL));
insert_indep_prop (required_props,
"price",
create_prop_with_required_dep_props
(FALSE,
"currency",
NULL));
insert_indep_prop (required_props,
"desc",
create_prop_with_required_dep_props
(FALSE,
"nameSpace",
NULL));
insert_indep_prop (required_props,
"deviceUDN",
create_prop_with_required_dep_props
(FALSE,
"serviceType",
"serviceId",
NULL));
insert_indep_prop (required_props,
"stateVariableCollection",
create_prop_with_required_dep_props
(FALSE,
"serviceName",
"rcsInstanceType",
NULL));
insert_indep_prop (required_props,
"foreignMetadata",
create_foreign_metadata_props ());
g_once_init_leave (&required_props_loaded, 1);
}
return required_props;
}
static gboolean
is_required (const xmlChar *changed_element,
const xmlChar *changed_attribute)
{
GHashTable *required_props = get_required_properties ();
if (changed_element != NULL) {
IndependentProperty *toplevel_prop = g_hash_table_lookup
(required_props,
"");
IndependentProperty *this_prop = g_hash_table_lookup
(required_props,
(gpointer) changed_element);
if (changed_attribute != NULL) {
if (g_hash_table_contains
(toplevel_prop->required_dep_props,
changed_attribute))
return TRUE;
if (g_hash_table_contains (this_prop->required_dep_props,
changed_attribute))
return TRUE;
}
if (g_hash_table_contains (toplevel_prop->required_indep_props,
changed_element))
return TRUE;
/* TODO: check if changed element is not a required
* property of its parent element. That needs some
* additions in IndepependentProperty.
*/
}
return FALSE;
}
static GUPnPDIDLLiteFragmentResult
new_doc_is_valid_modification (DocNode *modified,
xmlDocPtr current_doc,
xmlDocPtr new_doc,
XSDData *xsd_data)
{
xmlNodePtr current_node = current_doc->children->children;
xmlNodePtr new_node = new_doc->children->children;
xmlNodePtr last_sibling = NULL;
while (current_node != NULL && new_node != NULL) {
GUPnPDIDLLiteFragmentResult result;
xmlNodePtr temp_current_node = current_node;
xmlNodePtr temp_new_node = new_node;
last_sibling = new_node;
/* We can't put this line into for instruction,
* because new_node could be unlinked from its
* document and put into another one in
* apply_temporary_modification. We have to get its
* sibling before that could happen.
*/
new_node = new_node->next;
current_node = current_node->next;
if (av_xml_util_node_deep_equal (temp_current_node,
temp_new_node))
/* This is just a context, skip the checks. */
continue;
if (xmlStrcmp (temp_current_node->name, temp_new_node->name))
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_INVALID;
if (is_any_change_read_only (temp_current_node, temp_new_node))
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_READONLY_TAG;
result = apply_temporary_modification (modified,
temp_current_node,
temp_new_node,
xsd_data);
if (result != GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK)
return result;
}
if (last_sibling == NULL) {
if (modified->node->children != NULL)
last_sibling = modified->node->last;
else
/* We expect that modified object has some
* required tags like <upnp:class> or
* <dc:title>.
*/
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR;
}
/* If there are some more nodes in current fragment then it
* means they are going to be removed. Check against required
* or read-only tag removal.
*/
while (current_node != NULL) {
GUPnPDIDLLiteFragmentResult result;
xmlNodePtr temp_node = current_node;
current_node = current_node->next;
/* TODO: should we check if there are some readonly
* attributes when we remove whole element?
*/
if (is_read_only ((gchar *) temp_node->name, NULL))
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_READONLY_TAG;
/* We don't check for required attributes or
* subelements, because most of them are required only
* when the element exists. And we are removing this
* one.
*/
if (is_required (temp_node->name, NULL))
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_REQUIRED_TAG;
result = apply_temporary_removal (modified,
temp_node,
xsd_data);
if (result != GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK)
return result;
}
/* If there are some more nodes in new fragment then it means
* they are going to be added. Check against read-only tags
* addition and general sanity check.
*/
while (new_node != NULL) {
GUPnPDIDLLiteFragmentResult result;
xmlNodePtr temp_node;
if (is_read_only ((gchar *) new_node->name, NULL))
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_READONLY_TAG;
/* TODO: We probably should check if newly added node
* has all required properties. Maybe XSD check could
* do that for us.
*/
temp_node = new_node;
new_node = new_node->next;
result = apply_temporary_addition (modified,
last_sibling,
temp_node,
xsd_data);
if (result != GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK)
return result;
}
return GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK;
}
static gchar *
fix_fragment (const gchar *fragment)
{
return g_strdup_printf
("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<DIDLLiteFragment\n"
"xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n"
"xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\"\n"
"xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\"\n"
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
">%s</DIDLLiteFragment>\n",
fragment);
}
static gboolean
is_current_doc_part_of_original_doc (DocNode *original,
xmlDocPtr current_doc)
{
xmlNodePtr current_node = current_doc->children->children;
xmlNodePtr this_node;
/* No current node means that we want to add new elements to
the document. */
if (current_node == NULL)
return TRUE;
this_node = av_xml_util_find_node (original->node, current_node);
if (this_node == NULL)
return FALSE;
for (current_node = current_node->next, this_node = this_node->next;
current_node != NULL && this_node != NULL;
current_node = current_node->next, this_node = this_node->next)
if (!av_xml_util_node_deep_equal (current_node, this_node))
return FALSE;
return TRUE;
}
GUPnPDIDLLiteFragmentResult
fragment_util_check_fragments (DocNode *original,
DocNode *modified,
const gchar *current_fragment,
const gchar *new_fragment,
XSDData *xsd_data)
{
gchar *fixed_current_fragment = fix_fragment (current_fragment);
gchar *fixed_new_fragment = fix_fragment (new_fragment);
xmlDocPtr current_doc = xmlReadDoc (BAD_CAST (fixed_current_fragment),
NULL,
NULL,
XML_PARSE_NONET);
xmlDocPtr new_doc = xmlReadDoc (BAD_CAST (fixed_new_fragment),
NULL,
NULL,
XML_PARSE_NONET);
GUPnPDIDLLiteFragmentResult result;
if (current_doc == NULL || current_doc->children == NULL) {
result = GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_BAD_XML;
goto out;
}
if (new_doc == NULL || new_doc->children == NULL) {
result = GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_BAD_XML;
goto out;
}
/* Assuming current_doc->children is non-NULL. */
if (current_doc->children->children != NULL) {
/* If the child element is title or class,
* it must not be set to empty or removed.
*/
if (g_strrstr ((const char *) current_doc->children->children->name,
"title") != NULL ||
g_strrstr ((const char *) current_doc->children->children->name,
"class") != NULL) {
/* If the new tag has no corresponding title or class element */
if (new_doc->children->children == NULL) {
result = GUPNP_DIDL_LITE_FRAGMENT_RESULT_REQUIRED_TAG;
goto out;
}
/* If the new tag has an empty value for title or class */
if (new_doc->children->children->children == NULL) {
result = GUPNP_DIDL_LITE_FRAGMENT_RESULT_REQUIRED_TAG;
goto out;
}
}
}
if (!is_current_doc_part_of_original_doc (original, current_doc)) {
result = GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_INVALID;
goto out;
}
result = new_doc_is_valid_modification (modified,
current_doc,
new_doc,
xsd_data);
out:
if (new_doc != NULL)
xmlFreeDoc (new_doc);
if (current_doc != NULL)
xmlFreeDoc (current_doc);
g_free (fixed_new_fragment);
g_free (fixed_current_fragment);
return result;
}
static const gchar *
get_data_dir (void)
{
const gchar *datadir = g_getenv ("GUPNP_AV_DATADIR");
if (datadir == NULL)
/* that's a macro defined by -DDATADIR=foo */
datadir = DATADIR;
return datadir;
}
static gchar *
get_xsd_path (const gchar *path)
{
return g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s",
get_data_dir (),
path);
}
static xmlParserInputPtr
our_own_loader (const char *url,
const char *id,
xmlParserCtxtPtr context)
{
gchar *basename;
gchar *path;
xmlParserInputPtr input;
g_debug ("URL: %s, ID: %s.", url, id);
basename = g_path_get_basename (url);
path = get_xsd_path (basename);
g_debug ("BASENAME: %s, PATH: %s", basename, path);
input = xmlNewInputFromFile (context, path);
g_free (basename);
g_free (path);
return input;
}
XSDData *
fragment_util_get_didl_lite_xsd_data (void)
{
gchar *path = get_xsd_path ("didl-lite-v2.xsd");
xmlExternalEntityLoader original_loader = xmlGetExternalEntityLoader ();
XSDData *xsd_data;
xmlSetExternalEntityLoader (our_own_loader);
xsd_data = xsd_data_new (path);
xmlSetExternalEntityLoader (original_loader);
g_free (path);
return xsd_data;
}
gboolean
fragment_util_apply_modification (xmlNodePtr *node_ptr,
DocNode *modified)
{
xmlNodePtr node_copy;
xmlNodePtr old;
if (node_ptr == NULL || *node_ptr == NULL)
return FALSE;
node_copy = av_xml_util_copy_node (modified->node);
if (node_copy == NULL)
return FALSE;
old = xmlReplaceNode (*node_ptr, node_copy);
if (old == NULL)
return FALSE;
*node_ptr = node_copy;
xmlFreeNode (old);
return TRUE;
}
07070100000023000081A40000000000000000000000016860451500000425000000000000000000000000000000000000002C00000000gupnp-av-0.14.4/libgupnp-av/fragment-util.h/*
* Copyright (C) 2012 Intel Corporation
*
* Authors: Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_AV_FRAGMENT_UTIL_H
#define GUPNP_AV_FRAGMENT_UTIL_H
#include <glib.h>
#include <libxml/tree.h>
#include "xsd-data.h"
#include "gupnp-av-enums.h"
G_BEGIN_DECLS
typedef struct {
xmlDocPtr doc;
xmlNodePtr node;
} DocNode;
G_GNUC_INTERNAL XSDData *
fragment_util_get_didl_lite_xsd_data (void);
G_GNUC_INTERNAL GUPnPDIDLLiteFragmentResult
fragment_util_check_fragments (DocNode *original,
DocNode *modified,
const gchar *current_fragment,
const gchar *new_fragment,
XSDData *xsd_data);
G_GNUC_INTERNAL gboolean
fragment_util_apply_modification (xmlNodePtr *node_ptr,
DocNode *modified);
G_END_DECLS
#endif /* __FRAGMENT_UTIL_H__ */
07070100000024000081A400000000000000000000000168604515000006AE000000000000000000000000000000000000002D00000000gupnp-av-0.14.4/libgupnp-av/gupnp-av-enums.h/*
* Copyright (C) 2012 Intel Corporation
*
* Authors: Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_AV_ENUMS_H
#define GUPNP_AV_ENUMS_H
#include <glib.h>
G_BEGIN_DECLS
/**
* GUPnPDIDLLiteFragmentResult:
* @GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK: Operation succeeded.
* @GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_BAD_XML: Current set of fragments
* is bad XML
* @GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_BAD_XML: New set of fragments is bad
* XML
* @GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_INVALID: Current set of fragments
* is invalid
* @GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_INVALID: New set of fragments is
* invalid
* @GUPNP_DIDL_LITE_FRAGMENT_RESULT_REQUIRED_TAG: Trying to remove a required
* tag
* @GUPNP_DIDL_LITE_FRAGMENT_RESULT_READONLY_TAG: Trying to modify or remove a
* read-only tag
* @GUPNP_DIDL_LITE_FRAGMENT_RESULT_MISMATCH: Length of the two fragment sets
* does not match
* @GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR: General error sink if none
* of the others applies.
*
* Possible return values of the gupnp_didl_lite_object_apply_fragments() call.
**/
typedef enum {
GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK,
GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_BAD_XML,
GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_BAD_XML,
GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_INVALID,
GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_INVALID,
GUPNP_DIDL_LITE_FRAGMENT_RESULT_REQUIRED_TAG,
GUPNP_DIDL_LITE_FRAGMENT_RESULT_READONLY_TAG,
GUPNP_DIDL_LITE_FRAGMENT_RESULT_MISMATCH,
GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR
} GUPnPDIDLLiteFragmentResult;
G_END_DECLS
#endif /* __GUPNP_AV_ENUMS_H__ */
07070100000025000081A400000000000000000000000168604515000002E1000000000000000000000000000000000000002D00000000gupnp-av-0.14.4/libgupnp-av/gupnp-av-error.c/*
* Copyright (C) 2009, Nokia Corporation.
* Copyright (C) 2006, 2007 OpenedHand Ltd.
*
* Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
* <zeeshan.ali@nokia.com>
* Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include "gupnp-av-error.h"
/**
* GUPNP_PROTOCOL_ERROR:
*
* The #GQuark uniquely used by GUPnP AV protocol related errors.
*
* Returns: a #GQuark uniquely used by GUPnP AV protocol related errors.
**/
GQuark
gupnp_protocol_error_quark (void)
{
static GQuark quark = 0;
if (!quark)
quark = g_quark_from_static_string ("gupnp-protocol-error");
return quark;
}
07070100000026000081A400000000000000000000000168604515000003B6000000000000000000000000000000000000002D00000000gupnp-av-0.14.4/libgupnp-av/gupnp-av-error.h/*
* Copyright (C) 2009, Nokia Corporation.
* Copyright (C) 2006, 2007 OpenedHand Ltd.
*
* Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
* <zeeshan.ali@nokia.com>
* Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_AV_ERROR_H
#define GUPNP_AV_ERROR_H
#include <glib.h>
G_BEGIN_DECLS
GQuark
gupnp_protocol_error_quark (void) G_GNUC_CONST;
#define GUPNP_PROTOCOL_ERROR (gupnp_protocol_error_quark ())
/**
* GUPnPProtocolError:
* @GUPNP_PROTOCOL_ERROR_INVALID_SYNTAX: Invalid syntax.
* @GUPNP_PROTOCOL_ERROR_OTHER: Unknown/unhandled protocol related errors.
*
* #GError codes used for errors in the #GUPNP_PROTOCOL_ERROR domain, upon any
* protocol related errors.
*/
typedef enum {
GUPNP_PROTOCOL_ERROR_INVALID_SYNTAX,
GUPNP_PROTOCOL_ERROR_OTHER
} GUPnPProtocolError;
G_END_DECLS
#endif /* __GUPNP_AV_ERROR_H__ */
07070100000027000081A40000000000000000000000016860451500000023000000000000000000000000000000000000003200000000gupnp-av-0.14.4/libgupnp-av/gupnp-av-marshal.listBOOLEAN:STRING,UINT,STRING,POINTER
07070100000028000081A40000000000000000000000016860451500000377000000000000000000000000000000000000002700000000gupnp-av-0.14.4/libgupnp-av/gupnp-av.h/*
* Copyright (C) 2007 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
* Copyright (C) 2006, 2007, 2008 OpenedHand Ltd.
*
* Author: Zeeshan Ali Khattak <zeenix@gstreamer.net>
* Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include "gupnp-av-enums.h"
#include "gupnp-didl-lite-object.h"
#include "gupnp-didl-lite-container.h"
#include "gupnp-didl-lite-createclass.h"
#include "gupnp-didl-lite-item.h"
#include "gupnp-didl-lite-parser.h"
#include "gupnp-didl-lite-resource.h"
#include "gupnp-didl-lite-descriptor.h"
#include "gupnp-didl-lite-writer.h"
#include "gupnp-protocol-info.h"
#include "gupnp-search-criteria-parser.h"
#include "gupnp-last-change-parser.h"
#include "gupnp-cds-last-change-parser.h"
#include "gupnp-feature.h"
#include "gupnp-feature-list-parser.h"
#include "gupnp-dlna.h"
#include "gupnp-media-collection.h"
07070100000029000081A40000000000000000000000016860451500002E80000000000000000000000000000000000000003B00000000gupnp-av-0.14.4/libgupnp-av/gupnp-cds-last-change-parser.c/*
* Copyright (C) 2012 Intel Corporation.
*
* Authors: Jens Georg <jensg@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPCDSLastChangeParser:
*
* LastChange parser for the format used in ContentDirectory:3
*
* [class@GUPnPAV.CDSLastChangeParser] parses XML strings from
* ContentDirectory's LastChange state variable.
*
* Unfortunately this is different enough from the renderer's
* LastChange syntax that it warrants a different parser.
*/
#include <config.h>
#include "xml-util.h"
#include "gupnp-cds-last-change-parser.h"
/**
* GUPnPCDSLastChangeEntry:
*
* Opaque struct which contains information about the event.
**/
struct _GUPnPCDSLastChangeEntry {
GUPnPCDSLastChangeEvent event;
char *object_id;
char *parent_id;
char *class;
guint32 update_id;
gboolean is_subtree_update;
};
G_DEFINE_TYPE (GUPnPCDSLastChangeParser,
gupnp_cds_last_change_parser,
G_TYPE_OBJECT)
G_DEFINE_BOXED_TYPE (GUPnPCDSLastChangeEntry,
gupnp_cds_last_change_entry,
gupnp_cds_last_change_entry_ref,
gupnp_cds_last_change_entry_unref)
static void
gupnp_cds_last_change_parser_init (G_GNUC_UNUSED GUPnPCDSLastChangeParser *parser)
{
}
static void
gupnp_cds_last_change_parser_class_init (G_GNUC_UNUSED GUPnPCDSLastChangeParserClass *klass)
{
}
/**
* gupnp_cds_last_change_parser_new:
*
* Create a new [class@GUPnPAV.CDSLastChangeParser].
*
* This parser is able to parse LastChange as defined in the
* ContentDirectory:3 specification.
*
* Returns:(transfer full): A new instance of
*[class@GUPnPAV.CDSLastChangeParser].
**/
GUPnPCDSLastChangeParser *
gupnp_cds_last_change_parser_new (void)
{
return g_object_new (GUPNP_TYPE_CDS_LAST_CHANGE_PARSER,
NULL);
}
/**
* gupnp_cds_last_change_parser_parse:
* @parser: [class@GUPnPAV.CDSLastChangeParser]
* @last_change: XML string to parse
* @error: Return value for parser error or %NULL to ignore
*
* Parse a LastChange XML document in the flavor defined by the
* ContentDirectory:3 specification.
*
* Returns: (element-type GUPnPCDSLastChangeEntry)(transfer full):
* List of [struct@GUPnPAV.CDSLastChangeEntry]
**/
GList *
gupnp_cds_last_change_parser_parse (GUPnPCDSLastChangeParser *parser,
const char *last_change,
GError **error)
{
xmlDoc *doc;
xmlNode *state_event, *it;
GList *result = NULL;
GUPnPCDSLastChangeEntry *entry;
g_return_val_if_fail (GUPNP_IS_CDS_LAST_CHANGE_PARSER (parser),
NULL);
doc = xmlParseDoc ((const xmlChar *) last_change);
if (doc == NULL) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_PARSE,
"Could not parse LastChange XML");
goto out;
}
state_event = av_xml_util_get_element ((xmlNode *) doc,
"StateEvent",
NULL);
if (state_event == NULL) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_PARSE,
"Missing StateEvent node");
goto out;
}
for (it = state_event->children; it != NULL; it = it->next) {
if (it->type == XML_TEXT_NODE)
continue;
if (g_ascii_strcasecmp ((const char *) it->name,
"objAdd") == 0) {
const char *tmp;
entry = g_atomic_rc_box_alloc0(sizeof(GUPnPCDSLastChangeEntry));
entry->event = GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED;
tmp = av_xml_util_get_attribute_content (it, "objID");
entry->object_id = g_strdup (tmp);
tmp = av_xml_util_get_attribute_content (it,
"objParentID");
entry->parent_id = g_strdup (tmp);
tmp = av_xml_util_get_attribute_content (it, "objClass");
entry->class = g_strdup (tmp);
entry->update_id = (guint32) av_xml_util_get_uint_attribute
(it,
"updateID",
0);
entry->is_subtree_update =
av_xml_util_get_boolean_attribute
(it,
"stUpdate");
} else if (g_ascii_strcasecmp ((const char *) it->name,
"objMod") == 0) {
const char *tmp;
entry = g_atomic_rc_box_alloc0(sizeof(GUPnPCDSLastChangeEntry));
entry->event = GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED;
tmp = av_xml_util_get_attribute_content (it, "objID");
entry->object_id = g_strdup (tmp);
entry->update_id = (guint32) av_xml_util_get_uint_attribute
(it,
"updateID",
0);
entry->is_subtree_update =
av_xml_util_get_boolean_attribute
(it,
"stUpdate");
} else if (g_ascii_strcasecmp ((const char *) it->name,
"objDel") == 0) {
const char *tmp;
entry = g_atomic_rc_box_alloc0 (sizeof(GUPnPCDSLastChangeEntry));
entry->event = GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED;
tmp = av_xml_util_get_attribute_content (it, "objID");
entry->object_id = g_strdup (tmp);
entry->update_id = (guint32) av_xml_util_get_uint_attribute
(it,
"updateID",
0);
entry->is_subtree_update =
av_xml_util_get_boolean_attribute
(it,
"stUpdate");
} else if (g_ascii_strcasecmp ((const char *) it->name,
"stDone") == 0) {
const char *tmp;
entry = g_atomic_rc_box_alloc0(sizeof(GUPnPCDSLastChangeEntry));
entry->event = GUPNP_CDS_LAST_CHANGE_EVENT_ST_DONE;
tmp = av_xml_util_get_attribute_content (it, "objID");
entry->object_id = g_strdup (tmp);
entry->update_id = (guint32) av_xml_util_get_uint_attribute
(it,
"updateID",
0);
} else {
g_warning ("Skipping invalid LastChange entry: %s",
(const char *) it->name);
continue;
}
result = g_list_prepend (result, entry);
}
result = g_list_reverse (result);
out:
if (doc != NULL) {
xmlFreeDoc (doc);
}
return result;
}
/**
* gupnp_cds_last_change_entry_ref:
* @entry: A #GUPnPCDSLastChangeEntry
*
* Increase reference count of a [struct@GUPnPAV.CDSLastChangeEntry].
*
* Returns:(transfer full): The object passed in @entry.
**/
GUPnPCDSLastChangeEntry *
gupnp_cds_last_change_entry_ref (GUPnPCDSLastChangeEntry *entry)
{
g_return_val_if_fail (entry != NULL, NULL);
return g_atomic_rc_box_acquire(entry);
}
static void
last_change_entry_free (GUPnPCDSLastChangeEntry *entry)
{
g_free (entry->class);
g_free (entry->object_id);
g_free (entry->parent_id);
}
/**
* gupnp_cds_last_change_entry_unref:
* @entry: A [struct@GUPnPAV.CDSLastChangeEntry]
*
* Decrease reference count of a [struct@GUPnPAV.CDSLastChangeEntry]. If the
* reference count drops to 0, @entry is freed.
**/
void
gupnp_cds_last_change_entry_unref (GUPnPCDSLastChangeEntry *entry)
{
g_return_if_fail (entry != NULL);
g_atomic_rc_box_release_full(entry, (GDestroyNotify) last_change_entry_free);
}
/**
* gupnp_cds_last_change_entry_get_event:
* @entry: A [struct@GUPnPAV.CDSLastChangeEntry]
*
* Get the type of the last change entry as defined in
* [enum@GUPnPAV.CDSLastChangeEvent].
*
* Returns: An event from the [enum@GUPnPAV.CDSLastChangeEvent] or
* %GUPNP_CDS_LAST_CHANGE_EVENT_INVALID if the entry is not valid.
**/
GUPnPCDSLastChangeEvent
gupnp_cds_last_change_entry_get_event (GUPnPCDSLastChangeEntry *entry)
{
g_return_val_if_fail (entry != NULL,
GUPNP_CDS_LAST_CHANGE_EVENT_INVALID);
return entry->event;
}
/**
* gupnp_cds_last_change_entry_get_object_id:
* @entry: A [struct@GUPnPAV.CDSLastChangeEntry]
*
* Get the ID of the object in this change entry.
*
* Returns: (transfer none): The id of the object of this entry.
**/
const char *
gupnp_cds_last_change_entry_get_object_id (GUPnPCDSLastChangeEntry *entry)
{
g_return_val_if_fail (entry != NULL, NULL);
return entry->object_id;
}
/**
* gupnp_cds_last_change_entry_get_parent_id:
* @entry: A [struct@GUPnPAV.CDSLastChangeEntry]
*
* Get the parent object id of the object in this change entry. This is only
* valid if [method@GUPnPAV.CDSLastChangeEntry.get_event] returns
* %GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED.
*
* Returns: (transfer none): The id of the object's parent of this entry.
**/
const char *
gupnp_cds_last_change_entry_get_parent_id (GUPnPCDSLastChangeEntry *entry)
{
g_return_val_if_fail (entry != NULL, NULL);
return entry->parent_id;
}
/**
* gupnp_cds_last_change_entry_get_class:
* @entry: A [struct@GUPnPAV.CDSLastChangeEntry]
*
* Get the UPnP class of the object in this change entry. This is only
* valid if [method@GUPnPAV.CDSLastChangeEntry.get_event] returns
* [enum@GUPnPAV.CDSLastChangeEvent.OBJECT_ADDED].
*
* Returns: (transfer none): The upnp class of the object of this entry.
**/
const char *
gupnp_cds_last_change_entry_get_class (GUPnPCDSLastChangeEntry *entry)
{
g_return_val_if_fail (entry != NULL, NULL);
return entry->class;
}
/**
* gupnp_cds_last_change_entry_is_subtree_update:
* @entry: A [struct@GUPnPAV.CDSLastChangeEntry]
*
* Returns whether this entry is part of a subtree update.
*
* Returns: %TRUE, if the entry is part of a subtree update, %FALSE otherwise.
**/
gboolean
gupnp_cds_last_change_entry_is_subtree_update (GUPnPCDSLastChangeEntry *entry)
{
g_return_val_if_fail (entry != NULL, FALSE);
return entry->is_subtree_update;
}
/**
* gupnp_cds_last_change_entry_get_update_id:
* @entry: A [struct@GUPnPAV.CDSLastChangeEntry]
*
* Get the update id of the last change entry.
*
* Returns: update id of the entry or 0 if the entry is not valid.
**/
guint32
gupnp_cds_last_change_entry_get_update_id (GUPnPCDSLastChangeEntry *entry)
{
g_return_val_if_fail (entry != NULL, 0);
return entry->update_id;
}
0707010000002A000081A40000000000000000000000016860451500000BA4000000000000000000000000000000000000003B00000000gupnp-av-0.14.4/libgupnp-av/gupnp-cds-last-change-parser.h/*
* Copyright (C) 2012 Intel Corporation.
*
* Authors: Jens Georg <jensg@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_CDS_LAST_CHANGE_PARSER_H
#define GUPNP_CDS_LAST_CHANGE_PARSER_H
#include <glib-object.h>
G_BEGIN_DECLS
GType
gupnp_cds_last_change_entry_get_type (void) G_GNUC_CONST;
G_DECLARE_DERIVABLE_TYPE(GUPnPCDSLastChangeParser,
gupnp_cds_last_change_parser,
GUPNP,
CDS_LAST_CHANGE_PARSER,
GObject)
#define GUPNP_TYPE_CDS_LAST_CHANGE_PARSER gupnp_cds_last_change_parser_get_type()
struct _GUPnPCDSLastChangeParserClass
{
GObjectClass parent_class;
};
typedef struct _GUPnPCDSLastChangeEntry GUPnPCDSLastChangeEntry;
/**
* GUPnPCDSLastChangeEvent:
* @GUPNP_CDS_LAST_CHANGE_EVENT_INVALID: Invalid [struct@GUPnPAV.CDSLastChangeEntry]
* @GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED: The [struct@GUPnPAV.CDSLastChangeEntry] is
* an object added event.
* @GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED: The [struct@GUPnPAV.CDSLastChangeEntry]
* is an object removal event.
* @GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED: The [struct@GUPnPAV.CDSLastChangeEntry]
* is an object modification event.
* @GUPNP_CDS_LAST_CHANGE_EVENT_ST_DONE: The [struct@GUPnPAV.CDSLastChangeEntry] is a
* subtree update done event.
*
* The type of event a [struct@GUPnPAV.CDSLastChangeEntry] is representing
*
*/
typedef enum GUPnPCDSLastChangeEvent {
GUPNP_CDS_LAST_CHANGE_EVENT_INVALID,
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED,
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
GUPNP_CDS_LAST_CHANGE_EVENT_ST_DONE
} GUPnPCDSLastChangeEvent;
GUPnPCDSLastChangeParser *
gupnp_cds_last_change_parser_new (void);
GList *
gupnp_cds_last_change_parser_parse (GUPnPCDSLastChangeParser *parser,
const char *last_change,
GError **error);
GUPnPCDSLastChangeEntry *
gupnp_cds_last_change_entry_ref (GUPnPCDSLastChangeEntry *entry);
void
gupnp_cds_last_change_entry_unref (GUPnPCDSLastChangeEntry *entry);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GUPnPCDSLastChangeEntry,
gupnp_cds_last_change_entry_unref)
GUPnPCDSLastChangeEvent
gupnp_cds_last_change_entry_get_event (GUPnPCDSLastChangeEntry *entry);
const char *
gupnp_cds_last_change_entry_get_object_id (GUPnPCDSLastChangeEntry *entry);
const char *
gupnp_cds_last_change_entry_get_parent_id (GUPnPCDSLastChangeEntry *entry);
const char *
gupnp_cds_last_change_entry_get_class (GUPnPCDSLastChangeEntry *entry);
gboolean
gupnp_cds_last_change_entry_is_subtree_update (GUPnPCDSLastChangeEntry *entry);
guint32
gupnp_cds_last_change_entry_get_update_id (GUPnPCDSLastChangeEntry *entry);
G_END_DECLS
#endif /* __GUPNP_CDS_LAST_CHANGE_PARSER_H__ */
0707010000002B000081A40000000000000000000000016860451500007C63000000000000000000000000000000000000003800000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-container.c/*
* Copyright (C) 2009 Nokia Corporation.
* Copyright (C) 2012 Intel Corporation
*
* Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
* <zeeshan.ali@nokia.com>
* Krzesimir Nowak <krnowak@openismus.com>
* Christophe Guiraud <christophe.guiraud@intel.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPDIDLLiteContainer:
*
* Representation of a DIDL-Lite container element.
*/
#include <config.h>
#include <string.h>
#include "gupnp-didl-lite-container.h"
#include "gupnp-didl-lite-object-private.h"
#include "gupnp-didl-lite-createclass.h"
#include "gupnp-didl-lite-createclass-private.h"
#include "xml-util.h"
G_DEFINE_TYPE (GUPnPDIDLLiteContainer,
gupnp_didl_lite_container,
GUPNP_TYPE_DIDL_LITE_OBJECT)
enum {
PROP_0,
PROP_SEARCHABLE,
PROP_CHILD_COUNT,
PROP_STORAGE_USED,
PROP_CONTAINER_UPDATE_ID,
PROP_TOTAL_DELETED_CHILD_COUNT
};
static void
gupnp_didl_lite_container_init (G_GNUC_UNUSED GUPnPDIDLLiteContainer *container)
{
/* Nothing to initialize, yay! */
}
static void
gupnp_didl_lite_container_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteContainer *container;
container = GUPNP_DIDL_LITE_CONTAINER (object);
switch (property_id) {
case PROP_SEARCHABLE:
g_value_set_boolean
(value,
gupnp_didl_lite_container_get_searchable (container));
break;
case PROP_CHILD_COUNT:
g_value_set_int
(value,
gupnp_didl_lite_container_get_child_count (container));
break;
case PROP_STORAGE_USED:
g_value_set_long
(value,
gupnp_didl_lite_container_get_storage_used (container));
break;
case PROP_CONTAINER_UPDATE_ID:
g_value_set_uint
(value,
gupnp_didl_lite_container_get_container_update_id
(container));
break;
case PROP_TOTAL_DELETED_CHILD_COUNT:
g_value_set_uint
(value,
gupnp_didl_lite_container_get_total_deleted_child_count
(container));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_container_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteContainer *container;
container = GUPNP_DIDL_LITE_CONTAINER (object);
switch (property_id) {
case PROP_SEARCHABLE:
gupnp_didl_lite_container_set_searchable
(container,
g_value_get_boolean (value));
break;
case PROP_CHILD_COUNT:
gupnp_didl_lite_container_set_child_count
(container,
g_value_get_int (value));
break;
case PROP_STORAGE_USED:
gupnp_didl_lite_container_set_storage_used
(container,
g_value_get_int64 (value));
break;
case PROP_CONTAINER_UPDATE_ID:
gupnp_didl_lite_container_set_container_update_id
(container,
g_value_get_uint (value));
break;
case PROP_TOTAL_DELETED_CHILD_COUNT:
gupnp_didl_lite_container_set_total_deleted_child_count
(container,
g_value_get_uint (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_container_class_init (GUPnPDIDLLiteContainerClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gupnp_didl_lite_container_get_property;
object_class->set_property = gupnp_didl_lite_container_set_property;
/**
* GUPnPDIDLLiteContainer:searchable:(attributes org.gtk.Property.get=gupnp_didl_lite_container_get_searchable org.gtk.Property.set=gupnp_didl_lite_container_set_searchable):
*
* Whether this container is searchable.
**/
g_object_class_install_property
(object_class,
PROP_SEARCHABLE,
g_param_spec_boolean ("searchable",
"Searchable",
"Whether this container is searchable.",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteContainer:child-count:(attributes org.gtk.Property.get=gupnp_didl_lite_container_get_child_count org.gtk.Property.set=gupnp_didl_lite_container_set_child_count):
*
* The child count of this container.
**/
g_object_class_install_property
(object_class,
PROP_CHILD_COUNT,
g_param_spec_int ("child-count",
"ChildCount",
"The child count of this container.",
0,
G_MAXINT,
0,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteContainer:storage-used:(attributes org.gtk.Property.get=gupnp_didl_lite_container_get_storage_used org.gtk.Property.set=gupnp_didl_lite_container_set_storage_used):
*
* The number of bytes used by all child items of this container.
**/
g_object_class_install_property
(object_class,
PROP_STORAGE_USED,
g_param_spec_int64 ("storage-used",
"Storage Used",
"The Number of bytes used by all child "
"items of this container.",
-1,
G_MAXINT64,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteContainer:container-update-id:(attributes org.gtk.Property.get=gupnp_didl_lite_container_get_container_update_id org.gtk.Property.set=gupnp_didl_lite_container_set_container_update_id):
*
* Update ID of this container.
**/
g_object_class_install_property
(object_class,
PROP_CONTAINER_UPDATE_ID,
g_param_spec_uint ("container-update-id",
"ContainerUpdateID",
"Update ID of this container.",
0,
G_MAXUINT,
0,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteContainer:total-deleted-child-count:(attributes org.gtk.Property.get=gupnp_didl_lite_container_get_total_deleted_child_count org.gtk.Property.set=gupnp_didl_lite_container_set_total_deleted_child_count):
*
* Total deleted child count of this container.
**/
g_object_class_install_property
(object_class,
PROP_TOTAL_DELETED_CHILD_COUNT,
g_param_spec_uint ("total-deleted-child-count",
"TotalDeletedChildCOunt",
"Total deleted child count of this container.",
0,
G_MAXUINT,
0,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
}
/**
* gupnp_didl_lite_container_get_searchable:(attributes org.gtk.Method.get_property=searchable):
* @container: #GUPnPDIDLLiteContainer
*
* Checks whether @container is searchable.
*
* Return value: #TRUE if @container is searchable.
**/
gboolean
gupnp_didl_lite_container_get_searchable (GUPnPDIDLLiteContainer *container)
{
xmlNode *xml_node;
g_return_val_if_fail (container != NULL, FALSE);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), FALSE);
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (container));
return av_xml_util_get_boolean_attribute (xml_node, "searchable");
}
/**
* gupnp_didl_lite_container_get_child_count:(attributes org.gtk.Method.get_property=child-count):
* @container: #GUPnPDIDLLiteContainer
*
* Get the child count of the @container.
*
* If the child count is unknown, -1 is returned.
*
* Return value: The child count of the @container, or -1 if it is unknown.
**/
gint
gupnp_didl_lite_container_get_child_count (GUPnPDIDLLiteContainer *container)
{
xmlNode *xml_node;
g_return_val_if_fail (container != NULL, 0);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), 0);
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (container));
return av_xml_util_get_int_attribute (xml_node, "childCount", -1);
}
/**
* gupnp_didl_lite_container_get_container_update_id:(attributes org.gtk.Method.get_property=container-update-id):
* @container: #GUPnPDIDLLiteContainer
*
* Get the container update ID of the @container.
*
* Return value: The container update ID of the @container.
**/
guint
gupnp_didl_lite_container_get_container_update_id
(GUPnPDIDLLiteContainer *container)
{
xmlNode *xml_node;
g_return_val_if_fail (container != NULL, 0);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), 0);
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (container));
return av_xml_util_get_uint_child_element (xml_node,
"containerUpdateID",
0);
}
/**
* gupnp_didl_lite_container_container_update_id_is_set:
* @container: #GUPnPDIDLLiteContainer
*
* Get whether the container update ID of the @container is set.
*
* Return value: %TRUE if update ID is set, otherwise %FALSE
**/
gboolean
gupnp_didl_lite_container_container_update_id_is_set
(GUPnPDIDLLiteContainer *container)
{
const char *content;
xmlNode *xml_node;
g_return_val_if_fail (container != NULL, FALSE);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), FALSE);
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (container));
content = av_xml_util_get_child_element_content (xml_node,
"containerUpdateID");
return content != NULL;
}
/**
* gupnp_didl_lite_container_get_total_deleted_child_count:(attributes org.gtk.Method.get_property=total-deleted-child-count):
* @container: #GUPnPDIDLLiteContainer
*
* Get the total deleted child count of the @container.
*
* Return value: The total deleted child count of the @container.
**/
guint
gupnp_didl_lite_container_get_total_deleted_child_count
(GUPnPDIDLLiteContainer *container)
{
xmlNode *xml_node;
g_return_val_if_fail (container != NULL, 0);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), 0);
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (container));
return av_xml_util_get_uint_child_element (xml_node,
"totalDeletedChildCount",
-1);
}
/**
* gupnp_didl_lite_container_total_deleted_child_count_is_set:
* @container: #GUPnPDIDLLiteContainer
*
* Get whether the total deleted child count of the @container is set.
*
* Return value: %TRUE if property is set, otherwise %FALSE
**/
gboolean
gupnp_didl_lite_container_total_deleted_child_count_is_set
(GUPnPDIDLLiteContainer *container)
{
const char *content;
xmlNode *xml_node;
g_return_val_if_fail (container != NULL, FALSE);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), FALSE);
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (container));
content = av_xml_util_get_child_element_content (xml_node,
"totalDeletedChildCount");
return content != NULL;
}
/**
* gupnp_didl_lite_container_get_create_classes:
* @container: #GUPnPDIDLLiteContainer
*
* Gets the list of create classes of the @container.
*
* Returns: (element-type utf8) (transfer full): The list of create classes
* belonging to @container, or %NULL.
**/
GList *
gupnp_didl_lite_container_get_create_classes (GUPnPDIDLLiteContainer *container)
{
GList *classes = NULL;
GList *ret = NULL;
GList *l;
g_return_val_if_fail (container != NULL, NULL);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), NULL);
classes = gupnp_didl_lite_object_get_properties (
GUPNP_DIDL_LITE_OBJECT (container),
"createClass");
for (l = classes; l; l = l->next) {
char *create_class;
xmlNode *node;
node = (xmlNode *) l->data;
if (node->children != NULL) {
create_class = g_strdup ((const char *) node->children->content);
ret = g_list_append (ret, create_class);
}
}
g_list_free (classes);
return ret;
}
/**
* gupnp_didl_lite_container_get_create_classes_full:
* @container: #GUPnPDIDLLiteContainer
*
* Gets the list of create classes of the @container.
*
* Returns: (element-type GUPnPDIDLLiteCreateClass) (transfer full): The list
* of create classes belonging to @container, or %NULL.
**/
GList *
gupnp_didl_lite_container_get_create_classes_full (
GUPnPDIDLLiteContainer *container)
{
GList *cc_list = NULL;
GList *ret = NULL;
GList *l;
g_return_val_if_fail (container != NULL, NULL);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), NULL);
cc_list = gupnp_didl_lite_object_get_properties (
GUPNP_DIDL_LITE_OBJECT (container),
"createClass");
for (l = cc_list; l; l = l->next) {
GUPnPDIDLLiteCreateClass *cc;
xmlNode *cc_node;
GUPnPAVXMLDoc *cc_doc;
cc_node = (xmlNode *) l->data;
if (!cc_node->children)
continue;
cc_doc = gupnp_didl_lite_object_get_gupnp_xml_doc (
GUPNP_DIDL_LITE_OBJECT (container));
cc = gupnp_didl_lite_create_class_new_from_xml (cc_node, cc_doc);
ret = g_list_append (ret, cc);
}
g_list_free (cc_list);
return ret;
}
/**
* gupnp_didl_lite_container_get_search_classes:
* @container: #GUPnPDIDLLiteContainer
*
* Gets the list of search classes of the @container.
*
* Return value: (element-type utf8) (transfer full): The list of search classes
* belonging to @container, or %NULL. #g_list_free the returned list after usage
* and #g_free each string in it.
**/
GList *
gupnp_didl_lite_container_get_search_classes (GUPnPDIDLLiteContainer *container)
{
GList *classes = NULL;
GList *ret = NULL;
GList *l;
g_return_val_if_fail (container != NULL, NULL);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), NULL);
classes = gupnp_didl_lite_object_get_properties (
GUPNP_DIDL_LITE_OBJECT (container),
"searchClass");
for (l = classes; l; l = l->next) {
char *search_class;
xmlNode *node;
node = (xmlNode *) l->data;
if (node->children != NULL) {
search_class = g_strdup ((const char *) node->children->content);
ret = g_list_append (ret, search_class);
}
}
g_list_free (classes);
return ret;
}
/**
* gupnp_didl_lite_container_get_storage_used:(attributes org.gtk.Method.get_property=storage-used):
* @container: #GUPnPDIDLLiteContainer
*
* Get the number of bytes used by all child items of the @container.
*
* If storage used is unknown, -1 is returned.
*
* Return value: The number of bytes used by all children of the @container,
* or -1 if it is unknown.
**/
gint64
gupnp_didl_lite_container_get_storage_used (GUPnPDIDLLiteContainer *container)
{
xmlNode *xml_node;
const char *str;
g_return_val_if_fail (container != NULL, 0);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), 0);
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (container));
str = av_xml_util_get_child_element_content (xml_node, "storageUsed");
if (str == NULL)
return -1;
return g_ascii_strtoll (str, NULL, 10);
}
/**
* gupnp_didl_lite_container_set_searchable:(attributes org.gtk.Method.set_property=searchable):
* @container: #GUPnPDIDLLiteContainer
* @searchable: The search-ability
*
* (Un)set the search-ability of @container.
**/
void
gupnp_didl_lite_container_set_searchable (GUPnPDIDLLiteContainer *container,
gboolean searchable)
{
xmlNode *xml_node;
const char *str;
g_return_if_fail (container != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container));
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (container));
if (searchable)
str = "1";
else
str = "0";
xmlSetProp (xml_node,
(unsigned char *) "searchable",
(unsigned char *) str);
g_object_notify (G_OBJECT (container), "searchable");
}
/**
* gupnp_didl_lite_container_set_child_count:(attributes org.gtk.Method.set_property=child-count):
* @container: #GUPnPDIDLLiteContainer
* @child_count: The child count
*
* Set the child count of the @container.
**/
void
gupnp_didl_lite_container_set_child_count (GUPnPDIDLLiteContainer *container,
gint child_count)
{
xmlNode *xml_node;
char *str;
g_return_if_fail (container != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container));
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (container));
str = g_strdup_printf ("%d", child_count);
xmlSetProp (xml_node,
(unsigned char *) "childCount",
(unsigned char *) str);
g_free (str);
g_object_notify (G_OBJECT (container), "child-count");
}
/**
* gupnp_didl_lite_container_set_container_update_id:(attributes org.gtk.Method.set_property=container-update-id):
* @container: #GUPnPDIDLLiteContainer
* @update_id: The container update ID
*
* Set the container update ID of the @container.
**/
void
gupnp_didl_lite_container_set_container_update_id
(GUPnPDIDLLiteContainer *container,
guint update_id)
{
xmlNode *xml_node;
xmlNsPtr upnp_ns;
GUPnPAVXMLDoc *xml_doc;
char *str;
GUPnPDIDLLiteObject *self_as_object;
g_return_if_fail (container != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container));
self_as_object = GUPNP_DIDL_LITE_OBJECT (container);
xml_node = gupnp_didl_lite_object_get_xml_node (self_as_object);
xml_doc = gupnp_didl_lite_object_get_gupnp_xml_doc (self_as_object);
upnp_ns = gupnp_didl_lite_object_get_upnp_namespace (self_as_object);
str = g_strdup_printf ("%u", update_id);
av_xml_util_set_child (xml_node,
GUPNP_XML_NAMESPACE_UPNP,
&upnp_ns,
xml_doc->doc,
"containerUpdateID",
str);
g_free (str);
g_object_notify (G_OBJECT (container), "container-update-id");
}
/**
* gupnp_didl_lite_container_unset_container_update_id:
* @container: #GUPnPDIDLLiteContainer
*
* Unset the container update ID property of the @container.
**/
void
gupnp_didl_lite_container_unset_container_update_id
(GUPnPDIDLLiteContainer *container)
{
xmlNode *xml_node;
g_return_if_fail (container != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container));
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (container));
av_xml_util_unset_child (xml_node, "containerUpdateID");
g_object_notify (G_OBJECT (container), "container-update-id");
}
/**
* gupnp_didl_lite_container_set_total_deleted_child_count:(attributes org.gtk.Method.set_property=total-deleted-child-count):
* @container: #GUPnPDIDLLiteContainer
* @count: The container update ID
*
* Set the container update ID of the @container.
**/
void
gupnp_didl_lite_container_set_total_deleted_child_count
(GUPnPDIDLLiteContainer *container,
guint count)
{
xmlNode *xml_node;
xmlNsPtr upnp_ns;
GUPnPAVXMLDoc *xml_doc;
char *str;
GUPnPDIDLLiteObject *self_as_object;
g_return_if_fail (container != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container));
self_as_object = GUPNP_DIDL_LITE_OBJECT (container);
xml_node = gupnp_didl_lite_object_get_xml_node (self_as_object);
xml_doc = gupnp_didl_lite_object_get_gupnp_xml_doc (self_as_object);
upnp_ns = gupnp_didl_lite_object_get_upnp_namespace (self_as_object);
str = g_strdup_printf ("%u", count);
av_xml_util_set_child (xml_node,
GUPNP_XML_NAMESPACE_UPNP,
&upnp_ns,
xml_doc->doc,
"totalDeletedChildCount",
str);
g_free (str);
g_object_notify (G_OBJECT (container), "total-deleted-child-count");
}
/**
* gupnp_didl_lite_container_unset_total_deleted_child_count:
* @container: #GUPnPDIDLLiteContainer
*
* Unset the total deleted child count property of the @container.
**/
void
gupnp_didl_lite_container_unset_total_deleted_child_count
(GUPnPDIDLLiteContainer *container)
{
xmlNode *xml_node;
g_return_if_fail (container != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container));
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (container));
av_xml_util_unset_child (xml_node, "totalDeletedChildCount");
g_object_notify (G_OBJECT (container), "total-deleted-child-count");
}
/**
* gupnp_didl_lite_container_add_create_class:
* @container: #GUPnPDIDLLiteContainer
* @create_class: The createClass to add.
*
* Add a new create class to the @container. includeDerived defaults to "0".
* If setting the includeDerived is required, see
* [method@GUPnPAV.DIDLLiteContainer.add_create_class_full]
**/
void
gupnp_didl_lite_container_add_create_class (
GUPnPDIDLLiteContainer *container,
const char *create_class)
{
gupnp_didl_lite_container_add_create_class_full (container,
create_class,
FALSE);
}
/**
* gupnp_didl_lite_container_add_create_class_full:
* @container: #GUPnPDIDLLiteContainer
* @create_class: The createClass to add.
* @include_derived: Whether object with derived classes, such as
* object.item.imageItem.Photo for a create class of object.item.imageItem are allowed.
*
* Add a new create class to the @container.
**/
void
gupnp_didl_lite_container_add_create_class_full (
GUPnPDIDLLiteContainer *container,
const char *create_class,
gboolean include_derived)
{
xmlNode *container_node, *new_node;
xmlNs *namespace;
const char *str;
g_return_if_fail (container != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container));
container_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (container));
namespace = gupnp_didl_lite_object_get_upnp_namespace
(GUPNP_DIDL_LITE_OBJECT (container));
new_node = xmlNewChild (container_node,
namespace,
(unsigned char *) "createClass",
(unsigned char *) create_class);
if (include_derived)
str = "1";
else
str = "0";
xmlSetProp (new_node,
(unsigned char *) "includeDerived",
(unsigned char *) str);
}
/**
* gupnp_didl_lite_container_add_search_class:
* @container: #GUPnPDIDLLiteContainer
* @search_class: The searchClass to add.
*
* Add a new search class to the @container.
*
* `includDerived` will default to "1". See
* [method@GUPnPAV.DIDLLiteContainer.add_search_class_full] if
* you need to set the property to "0".
**/
void
gupnp_didl_lite_container_add_search_class (
GUPnPDIDLLiteContainer *container,
const char *search_class)
{
gupnp_didl_lite_container_add_search_class_full (container,
search_class,
TRUE);
}
/**
* gupnp_didl_lite_container_add_search_class_full:
* @container: #GUPnPDIDLLiteContainer
* @search_class: The searchClass to add.
* @include_derived: includeDerived attribute of the DIDL
*
* Add a new search class to the @container.
**/
void
gupnp_didl_lite_container_add_search_class_full (
GUPnPDIDLLiteContainer *container,
const char *search_class,
gboolean include_derived)
{
xmlNode *xml_node;
xmlNode *new_xml_node;
xmlNs *namespace;
const char *str;
g_return_if_fail (container != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container));
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (container));
namespace = gupnp_didl_lite_object_get_upnp_namespace
(GUPNP_DIDL_LITE_OBJECT (container));
new_xml_node = xmlNewChild (xml_node,
namespace,
(unsigned char *) "searchClass",
(unsigned char *) search_class);
if (include_derived)
str = "1";
else
str = "0";
xmlSetProp (new_xml_node,
(unsigned char*) "includeDerived",
(unsigned char*) str);
}
/**
* gupnp_didl_lite_container_set_storage_used:
* @container: #GUPnPDIDLLiteContainer
* @storage_used: The number of bytes used by all child items of the
* @container or -1 if unknown.
*
* Set the number of bytes used by all child items of the @container.
**/
void
gupnp_didl_lite_container_set_storage_used (
GUPnPDIDLLiteContainer *container,
gint64 storage_used)
{
GList *storage = NULL;
xmlNode *xml_node;
xmlNs *namespace;
char *str;
g_return_if_fail (container != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container));
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (container));
namespace = gupnp_didl_lite_object_get_upnp_namespace
(GUPNP_DIDL_LITE_OBJECT (container));
str = g_strdup_printf ("%"G_GINT64_FORMAT, storage_used);
storage = gupnp_didl_lite_object_get_properties (
GUPNP_DIDL_LITE_OBJECT (container),
"storageUsed");
if (storage == NULL)
xmlNewChild (xml_node,
namespace,
(unsigned char *) "storageUsed",
(unsigned char *) str);
else
xmlNodeSetContent ((xmlNode *) storage->data,
(unsigned char *) str);
g_free (str);
g_object_notify (G_OBJECT (container), "storage-used");
}
0707010000002C000081A400000000000000000000000168604515000012C6000000000000000000000000000000000000003800000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-container.h/*
* Copyright (C) 2009 Nokia Corporation.
* Copyright (C) 2012 Intel Corporation
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
* Christophe Guiraud <christophe.guiraud@intel.com>
* Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_CONTAINER_H
#define GUPNP_DIDL_LITE_CONTAINER_H
#include <glib-object.h>
#include "gupnp-didl-lite-object.h"
G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE(GUPnPDIDLLiteContainer,
gupnp_didl_lite_container,
GUPNP,
DIDL_LITE_CONTAINER,
GUPnPDIDLLiteObject)
#define GUPNP_TYPE_DIDL_LITE_CONTAINER (gupnp_didl_lite_container_get_type ())
struct _GUPnPDIDLLiteContainerClass {
GUPnPDIDLLiteObjectClass parent_class;
/* future padding */
void (* _gupnp_reserved1) (void);
void (* _gupnp_reserved2) (void);
void (* _gupnp_reserved3) (void);
void (* _gupnp_reserved4) (void);
};
gboolean
gupnp_didl_lite_container_get_searchable
(GUPnPDIDLLiteContainer *container);
gint
gupnp_didl_lite_container_get_child_count
(GUPnPDIDLLiteContainer *container);
guint
gupnp_didl_lite_container_get_container_update_id
(GUPnPDIDLLiteContainer *container);
gboolean
gupnp_didl_lite_container_container_update_id_is_set
(GUPnPDIDLLiteContainer *container);
guint
gupnp_didl_lite_container_get_total_deleted_child_count
(GUPnPDIDLLiteContainer *container);
gboolean
gupnp_didl_lite_container_total_deleted_child_count_is_set
(GUPnPDIDLLiteContainer *container);
GList *
gupnp_didl_lite_container_get_create_classes
(GUPnPDIDLLiteContainer *container);
GList *
gupnp_didl_lite_container_get_create_classes_full
(GUPnPDIDLLiteContainer *container);
GList *
gupnp_didl_lite_container_get_search_classes
(GUPnPDIDLLiteContainer *container);
void
gupnp_didl_lite_container_set_searchable
(GUPnPDIDLLiteContainer *container,
gboolean searchable);
void
gupnp_didl_lite_container_set_child_count
(GUPnPDIDLLiteContainer *container,
gint child_count);
void
gupnp_didl_lite_container_set_container_update_id
(GUPnPDIDLLiteContainer *container,
guint update_id);
void
gupnp_didl_lite_container_unset_container_update_id
(GUPnPDIDLLiteContainer *container);
void
gupnp_didl_lite_container_set_total_deleted_child_count
(GUPnPDIDLLiteContainer *container,
guint count);
void
gupnp_didl_lite_container_unset_total_deleted_child_count
(GUPnPDIDLLiteContainer *container);
void
gupnp_didl_lite_container_add_create_class
(GUPnPDIDLLiteContainer *container,
const char *create_class);
void
gupnp_didl_lite_container_add_create_class_full
(GUPnPDIDLLiteContainer *container,
const char *create_class,
gboolean include_derived);
void
gupnp_didl_lite_container_add_search_class
(GUPnPDIDLLiteContainer *container,
const char *search_class);
void
gupnp_didl_lite_container_add_search_class_full
(GUPnPDIDLLiteContainer *container,
const char *search_class,
gboolean include_derived);
gint64
gupnp_didl_lite_container_get_storage_used
(GUPnPDIDLLiteContainer *container);
void
gupnp_didl_lite_container_set_storage_used
(GUPnPDIDLLiteContainer *container,
gint64 storage_used);
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_CONTAINER_H__ */
0707010000002D000081A400000000000000000000000168604515000002AE000000000000000000000000000000000000004200000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-contributor-private.h/*
* Copyright (C) 2009 Nokia Corporation.
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_CONTRIBUTOR_PRIVATE_H
#define GUPNP_DIDL_LITE_CONTRIBUTOR_PRIVATE_H
#include "xml-util.h"
#include <glib-object.h>
#include <libxml/tree.h>
#include "gupnp-didl-lite-contributor.h"
G_BEGIN_DECLS
G_GNUC_INTERNAL GUPnPDIDLLiteContributor *
gupnp_didl_lite_contributor_new_from_xml (xmlNode *xml_node,
GUPnPAVXMLDoc *xml_doc);
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_CONTRIBUTOR_PRIVATE_H__ */
0707010000002E000081A4000000000000000000000001686045150000300D000000000000000000000000000000000000003A00000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-contributor.c/*
* Copyright (C) 2009 Nokia Corporation.
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPDIDLLiteContributor:
*
* Contributor attached to a DIDL-Lite object
*
* This represents a contributor (artist, author, actor,
* producer, director, producer and contributor) property in a DIDL-Lite object.
*/
#include <config.h>
#include "gupnp-didl-lite-contributor.h"
#include "gupnp-didl-lite-contributor-private.h"
#include "xml-util.h"
typedef struct _GUPnPDIDLLiteContributorPrivate {
xmlNode *xml_node;
GUPnPAVXMLDoc *xml_doc;
} GUPnPDIDLLiteContributorPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GUPnPDIDLLiteContributor,
gupnp_didl_lite_contributor,
G_TYPE_OBJECT)
enum {
PROP_0,
PROP_XML_NODE,
PROP_XML_DOC,
PROP_ROLE,
PROP_NAME
};
static void
gupnp_didl_lite_contributor_init (GUPnPDIDLLiteContributor *contributor)
{
}
static void
gupnp_didl_lite_contributor_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteContributor *contributor;
contributor = GUPNP_DIDL_LITE_CONTRIBUTOR (object);
switch (property_id) {
case PROP_XML_NODE:
g_value_set_pointer
(value,
gupnp_didl_lite_contributor_get_xml_node
(contributor));
break;
case PROP_ROLE:
g_value_set_string
(value,
gupnp_didl_lite_contributor_get_role (contributor));
break;
case PROP_NAME:
g_value_set_string
(value,
gupnp_didl_lite_contributor_get_name (contributor));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_contributor_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteContributor *contributor =
GUPNP_DIDL_LITE_CONTRIBUTOR (object);
GUPnPDIDLLiteContributorPrivate *priv =
gupnp_didl_lite_contributor_get_instance_private (contributor);
switch (property_id) {
case PROP_XML_NODE:
priv->xml_node = g_value_get_pointer (value);
break;
case PROP_XML_DOC:
priv->xml_doc = g_value_dup_boxed (value);
break;
case PROP_ROLE:
gupnp_didl_lite_contributor_set_role
(contributor,
g_value_get_string (value));
break;
case PROP_NAME:
gupnp_didl_lite_contributor_set_name
(contributor,
g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_contributor_dispose (GObject *object)
{
GObjectClass *object_class;
GUPnPDIDLLiteContributor *contributor =
GUPNP_DIDL_LITE_CONTRIBUTOR (object);
GUPnPDIDLLiteContributorPrivate *priv =
gupnp_didl_lite_contributor_get_instance_private (contributor);
g_clear_pointer (&priv->xml_doc, av_xml_doc_unref);
object_class = G_OBJECT_CLASS
(gupnp_didl_lite_contributor_parent_class);
object_class->dispose (object);
}
static void
gupnp_didl_lite_contributor_class_init (GUPnPDIDLLiteContributorClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gupnp_didl_lite_contributor_get_property;
object_class->set_property = gupnp_didl_lite_contributor_set_property;
object_class->dispose = gupnp_didl_lite_contributor_dispose;
/**
* GUPnPDIDLLiteContributor:xml-node:(attributes org.gtk.Property.get=gupnp_didl_lite_contributor_get_xml_node):
*
* The pointer to object node in XML document.
**/
g_object_class_install_property
(object_class,
PROP_XML_NODE,
g_param_spec_pointer ("xml-node",
"XMLNode",
"The pointer to contributor node in XML"
" document.",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteContributor:xml-doc:
*
* The reference to XML document containing this object.
*
* Internal property.
*
* Stability: Private
**/
g_object_class_install_property
(object_class,
PROP_XML_DOC,
g_param_spec_boxed ("xml-doc",
"XMLDoc",
"The reference to XML document"
" containing this contributor.",
av_xml_doc_get_type (),
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteContributor:role:(attributes org.gtk.Property.get=gupnp_didl_lite_contributor_get_role org.gtk.Property.set=gupnp_didl_lite_contributor_set_role):
*
* The role of this contributor.
**/
g_object_class_install_property
(object_class,
PROP_ROLE,
g_param_spec_string ("role",
"Role",
"The role of this contributor.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteContributor:name:(attributes org.gtk.Property.get=gupnp_didl_lite_contributor_get_role org.gtk.Property.set=gupnp_didl_lite_contributor_set_role):
*
* The name of this contributor.
**/
g_object_class_install_property
(object_class,
PROP_NAME,
g_param_spec_string ("name",
"Name",
"The name of this contributor.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
}
/**
* gupnp_didl_lite_contributor_get_role:(attributes org.gtk.Method.get_property=role):
* @contributor: #GUPnPDIDLLiteContributor
*
* Get the role of the @contributor.
*
* Return value: The role of the @contributor, or %NULL.
**/
const char *
gupnp_didl_lite_contributor_get_role (GUPnPDIDLLiteContributor *contributor)
{
g_return_val_if_fail (contributor != NULL, NULL);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTRIBUTOR (contributor),
NULL);
GUPnPDIDLLiteContributorPrivate *priv =
gupnp_didl_lite_contributor_get_instance_private (contributor);
return av_xml_util_get_attribute_content (priv->xml_node, "role");
}
/**
* gupnp_didl_lite_contributor_get_name:(attributes org.gtk.Method.get_property=name):
* @contributor: A #GUPnPDIDLLiteContributor
*
* Get the name of the @contributor.
*
* Return value: The name of the @contributor or %NULL.
**/
const char *
gupnp_didl_lite_contributor_get_name (GUPnPDIDLLiteContributor *contributor)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTRIBUTOR (contributor),
NULL);
GUPnPDIDLLiteContributorPrivate *priv =
gupnp_didl_lite_contributor_get_instance_private (contributor);
return (const char *) priv->xml_node->children->content;
}
/**
* gupnp_didl_lite_contributor_set_role:(attributes org.gtk.Method.set_property=role):
* @contributor: #GUPnPDIDLLiteContributor
* @role: The role of the @contributor
*
* Set the role of the @contributor to @role.
**/
void
gupnp_didl_lite_contributor_set_role (GUPnPDIDLLiteContributor *contributor,
const char *role)
{
g_return_if_fail (contributor != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTRIBUTOR (contributor));
GUPnPDIDLLiteContributorPrivate *priv =
gupnp_didl_lite_contributor_get_instance_private (contributor);
xmlSetProp (priv->xml_node,
(unsigned char *) "role",
(unsigned char *) role);
g_object_notify (G_OBJECT (contributor), "role");
}
/**
* gupnp_didl_lite_contributor_set_name:(attributes org.gtk.Method.set_property=name):
* @contributor: A #GUPnPDIDLLiteContributor
* @name: The name of the contributor
*
* Set the name of the @contributor to @name.
**/
void
gupnp_didl_lite_contributor_set_name (GUPnPDIDLLiteContributor *contributor,
const char *name)
{
xmlChar *escaped;
g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTRIBUTOR (contributor));
g_return_if_fail (name != NULL);
GUPnPDIDLLiteContributorPrivate *priv =
gupnp_didl_lite_contributor_get_instance_private (contributor);
escaped = xmlEncodeSpecialChars (priv->xml_doc->doc,
(const unsigned char *) name);
xmlNodeSetContent (priv->xml_node, escaped);
xmlFree (escaped);
g_object_notify (G_OBJECT (contributor), "name");
}
/**
* gupnp_didl_lite_contributor_new_from_xml:
* @xml_node: The pointer to relevant node in XML document
* @xml_doc: The reference to containing XML document
*
* Creates a new #GUPnPDIDLLiteContributor for the @xml_node.
*
* Return value: A new #GUPnPDIDLLiteContributor object. Unref after usage.
**/
GUPnPDIDLLiteContributor *
gupnp_didl_lite_contributor_new_from_xml (xmlNode *xml_node,
GUPnPAVXMLDoc *xml_doc)
{
return g_object_new (GUPNP_TYPE_DIDL_LITE_CONTRIBUTOR,
"xml-node", xml_node,
"xml-doc", xml_doc,
NULL);
}
/**
* gupnp_didl_lite_contributor_get_xml_node:(attributes org.gtk.Method.get_property=xml-node):
* @contributor: The #GUPnPDIDLLiteContributor
*
* Get the pointer to relevant node in XML document.
*
* Returns: (transfer none): The pointer to relevant node in XML document.
**/
xmlNode *
gupnp_didl_lite_contributor_get_xml_node (GUPnPDIDLLiteContributor *contributor)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTRIBUTOR (contributor),
NULL);
GUPnPDIDLLiteContributorPrivate *priv =
gupnp_didl_lite_contributor_get_instance_private (contributor);
return priv->xml_node;
}
0707010000002F000081A4000000000000000000000001686045150000067E000000000000000000000000000000000000003A00000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-contributor.h/*
* Copyright (C) 2009 Nokia Corporation.
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_CONTRIBUTOR_H
#define GUPNP_DIDL_LITE_CONTRIBUTOR_H
#include <glib-object.h>
#include <libxml/tree.h>
G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE(GUPnPDIDLLiteContributor,
gupnp_didl_lite_contributor,
GUPNP,
DIDL_LITE_CONTRIBUTOR,
GObject)
#define GUPNP_TYPE_DIDL_LITE_CONTRIBUTOR \
(gupnp_didl_lite_contributor_get_type ())
struct _GUPnPDIDLLiteContributorClass{
GObjectClass parent_class;
/* future padding */
void (* _gupnp_reserved1) (void);
void (* _gupnp_reserved2) (void);
void (* _gupnp_reserved3) (void);
void (* _gupnp_reserved4) (void);
};
const char *
gupnp_didl_lite_contributor_get_role (GUPnPDIDLLiteContributor *contributor);
const char *
gupnp_didl_lite_contributor_get_name (GUPnPDIDLLiteContributor *contributor);
void
gupnp_didl_lite_contributor_set_role (GUPnPDIDLLiteContributor *contributor,
const char *role);
void
gupnp_didl_lite_contributor_set_name (GUPnPDIDLLiteContributor *contributor,
const char *name);
xmlNode *
gupnp_didl_lite_contributor_get_xml_node
(GUPnPDIDLLiteContributor *contributor);
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_CONTRIBUTOR_H__ */
07070100000030000081A40000000000000000000000016860451500000316000000000000000000000000000000000000004200000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-createclass-private.h/*
* Copyright (C) 2012 Intel Corporation.
* Copyright (C) 2009 Nokia Corporation.
*
* Author: Christophe Guiraud <christophe.guiraud@intel.com>
* Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
* <zeeshan.ali@nokia.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_CREATE_CLASS_PRIVATE_H
#define GUPNP_DIDL_LITE_CREATE_CLASS_PRIVATE_H
#include "xml-util.h"
#include "gupnp-didl-lite-createclass.h"
#include <glib-object.h>
#include <libxml/tree.h>
G_BEGIN_DECLS
G_GNUC_INTERNAL GUPnPDIDLLiteCreateClass *
gupnp_didl_lite_create_class_new_from_xml (xmlNode *xml_node,
GUPnPAVXMLDoc *xml_doc);
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_CREATE_CLASS_PRIVATE_H__ */
07070100000031000081A40000000000000000000000016860451500003E4B000000000000000000000000000000000000003A00000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-createclass.c/*
* Copyright (C) 2012 Intel Corporation.
* Copyright (C) 2009 Nokia Corporation.
*
* Author: Christophe Guiraud <christophe.guiraud@intel.com>
* Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
* <zeeshan.ali@nokia.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPDIDLLiteCreateClass:
*
* DIDL-Lite CreateClass
*
* [class@GUPnPAV.DIDLLiteCreateClass] respresents a DIDL-Lite create class
* element.
*/
#include <config.h>
#include <string.h>
#include "gupnp-didl-lite-createclass.h"
#include "gupnp-didl-lite-createclass-private.h"
#include "xml-util.h"
struct _GUPnPDIDLLiteCreateClassPrivate {
xmlNode *xml_node;
GUPnPAVXMLDoc *xml_doc;
};
typedef struct _GUPnPDIDLLiteCreateClassPrivate GUPnPDIDLLiteCreateClassPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GUPnPDIDLLiteCreateClass,
gupnp_didl_lite_create_class,
G_TYPE_OBJECT)
enum {
PROP_0,
PROP_XML_NODE,
PROP_XML_DOC,
PROP_CONTENT,
PROP_INCLUDE_DERIVED,
PROP_FRIENDLY_NAME,
};
static void
gupnp_didl_lite_create_class_init (GUPnPDIDLLiteCreateClass *create_class)
{
}
static void
gupnp_didl_lite_create_class_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteCreateClass *create_class;
create_class = GUPNP_DIDL_LITE_CREATE_CLASS (object);
switch (property_id) {
case PROP_XML_NODE:
g_value_set_pointer
(value,
gupnp_didl_lite_create_class_get_xml_node
(create_class));
break;
case PROP_CONTENT:
g_value_set_string
(value,
gupnp_didl_lite_create_class_get_content
(create_class));
break;
case PROP_INCLUDE_DERIVED:
g_value_set_boolean
(value,
gupnp_didl_lite_create_class_get_include_derived
(create_class));
break;
case PROP_FRIENDLY_NAME:
g_value_set_string
(value,
gupnp_didl_lite_create_class_get_friendly_name
(create_class));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_create_class_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteCreateClass *create_class;
create_class = GUPNP_DIDL_LITE_CREATE_CLASS (object);
GUPnPDIDLLiteCreateClassPrivate *priv =
gupnp_didl_lite_create_class_get_instance_private (
create_class);
switch (property_id) {
case PROP_XML_NODE:
priv->xml_node = g_value_get_pointer (value);
break;
case PROP_XML_DOC:
priv->xml_doc = g_value_dup_boxed (value);
break;
case PROP_CONTENT:
gupnp_didl_lite_create_class_set_content
(create_class,
g_value_get_string (value));
break;
case PROP_INCLUDE_DERIVED:
gupnp_didl_lite_create_class_set_include_derived
(create_class,
g_value_get_boolean (value));
break;
case PROP_FRIENDLY_NAME:
gupnp_didl_lite_create_class_set_friendly_name
(create_class,
g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_create_class_dispose (GObject *object)
{
GObjectClass *object_class;
GUPnPDIDLLiteCreateClassPrivate *priv =
gupnp_didl_lite_create_class_get_instance_private (
GUPNP_DIDL_LITE_CREATE_CLASS (object));
g_clear_pointer (&priv->xml_doc, av_xml_doc_unref);
object_class = G_OBJECT_CLASS
(gupnp_didl_lite_create_class_parent_class);
object_class->dispose (object);
}
static void
gupnp_didl_lite_create_class_class_init (GUPnPDIDLLiteCreateClassClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gupnp_didl_lite_create_class_get_property;
object_class->set_property = gupnp_didl_lite_create_class_set_property;
object_class->dispose = gupnp_didl_lite_create_class_dispose;
/**
* GUPnPDIDLLiteCreateClass:xml-node:
*
* The pointer to desc node in XML document.
**/
g_object_class_install_property
(object_class,
PROP_XML_NODE,
g_param_spec_pointer
("xml-node",
"XMLNode",
"The pointer to desc node in XML"
" document.",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteCreateClass:xml-doc:
*
* The reference to XML document containing this object.
*
* Internal property.
*
* Stability: Private
**/
g_object_class_install_property
(object_class,
PROP_XML_DOC,
g_param_spec_boxed
("xml-doc",
"XMLDoc",
"The reference to XML document"
" containing this object.",
av_xml_doc_get_type (),
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteCreateClass:content:
*
* The content of this create Class.
**/
g_object_class_install_property
(object_class,
PROP_CONTENT,
g_param_spec_string
("content",
"Content",
"The content of this create Class.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteCreateClass:include-derived:
*
* Whether this create Class can be derived.
**/
g_object_class_install_property
(object_class,
PROP_INCLUDE_DERIVED,
g_param_spec_boolean
("include-derived",
"IncludeDerived",
"Wether this create Class can be derived.",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteCreateClass:friendly-name:
*
* The friendly name of this create Class.
**/
g_object_class_install_property
(object_class,
PROP_FRIENDLY_NAME,
g_param_spec_string
("friendly-name",
"FriendlyName",
"The friendly name of this create Class.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
}
/**
* gupnp_didl_lite_create_class_get_content:
* @create_class: [class@GUPnPAV.DIDLLiteCreateClass]
*
* Get the content of the @create_class.
*
* Return value: The Content of the @create_class, or %NULL.
**/
const char *
gupnp_didl_lite_create_class_get_content
(GUPnPDIDLLiteCreateClass *create_class)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CREATE_CLASS (create_class),
NULL);
GUPnPDIDLLiteCreateClassPrivate *priv =
gupnp_didl_lite_create_class_get_instance_private (
create_class);
if (G_UNLIKELY (priv->xml_node->children == NULL))
return NULL;
return (const char *) priv->xml_node->children->content;
}
/**
* gupnp_didl_lite_create_class_set_content:
* @create_class: [class@GUPnPAV.DIDLLiteCreateClass]
* @content: The content
*
* Set the content of the @create_class.
**/
void
gupnp_didl_lite_create_class_set_content
(GUPnPDIDLLiteCreateClass *create_class,
const char *content)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_CREATE_CLASS (create_class));
g_return_if_fail (create_class != NULL);
GUPnPDIDLLiteCreateClassPrivate *priv =
gupnp_didl_lite_create_class_get_instance_private (
create_class);
xmlChar *escaped =
xmlEncodeSpecialChars (priv->xml_doc->doc,
(const unsigned char *) content);
xmlNodeSetContent (priv->xml_node, escaped);
xmlFree (escaped);
g_object_notify (G_OBJECT (create_class), "content");
}
/**
* gupnp_didl_lite_create_class_get_include_derived:
* @create_class: [class@GUPnPAV.DIDLLiteCreateClass]
*
* Checks whether @create_class can be derived.
*
* Return value: #TRUE if @create_class can be derived.
**/
gboolean
gupnp_didl_lite_create_class_get_include_derived
(GUPnPDIDLLiteCreateClass *create_class)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CREATE_CLASS (create_class),
FALSE);
GUPnPDIDLLiteCreateClassPrivate *priv =
gupnp_didl_lite_create_class_get_instance_private (
create_class);
return av_xml_util_get_boolean_attribute (priv->xml_node,
"includeDerived");
}
/**
* gupnp_didl_lite_create_class_set_include_derived:
* @create_class: [class@GUPnPAV.DIDLLiteCreateClass]
* @include_derived: the derivability
*
* (Un)set the derivability of create_class.
**/
void
gupnp_didl_lite_create_class_set_include_derived
(GUPnPDIDLLiteCreateClass *create_class,
gboolean include_derived)
{
const char *str;
g_return_if_fail (create_class != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_CREATE_CLASS (create_class));
GUPnPDIDLLiteCreateClassPrivate *priv =
gupnp_didl_lite_create_class_get_instance_private (
create_class);
if (include_derived)
str = "1";
else
str = "0";
xmlSetProp (priv->xml_node,
(unsigned char *) "includeDerived",
(unsigned char *) str);
g_object_notify (G_OBJECT (create_class), "include-derived");
}
/**
* gupnp_didl_lite_create_class_get_friendly_name:
* @create_class: [class@GUPnPAV.DIDLLiteCreateClass]
*
* Get the friendly name of the @create_class.
*
* Return value: The FriendlyName of the @create_class, or %NULL.
**/
const char *
gupnp_didl_lite_create_class_get_friendly_name
(GUPnPDIDLLiteCreateClass *create_class)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CREATE_CLASS (create_class),
NULL);
GUPnPDIDLLiteCreateClassPrivate *priv =
gupnp_didl_lite_create_class_get_instance_private (
create_class);
return av_xml_util_get_attribute_content (priv->xml_node, "name");
}
/**
* gupnp_didl_lite_create_class_set_friendly_name:
* @create_class: [class@GUPnPAV.DIDLLiteCreateClass]
* @friendly_name: The friendly name
*
* Set the friendly name of the @create_class.
**/
void
gupnp_didl_lite_create_class_set_friendly_name
(GUPnPDIDLLiteCreateClass *create_class,
const char *friendly_name)
{
g_return_if_fail (create_class != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_CREATE_CLASS (create_class));
GUPnPDIDLLiteCreateClassPrivate *priv =
gupnp_didl_lite_create_class_get_instance_private (
create_class);
xmlSetProp (priv->xml_node,
(unsigned char *) "name",
(const unsigned char *) friendly_name);
g_object_notify (G_OBJECT (create_class), "friendly-name");
}
/**
* gupnp_didl_lite_create_class_new_from_xml:
* @xml_node: The pointer to relevant node in XML document
* @xml_doc: The reference to containing XML document
*
* Creates a new [class@GUPnPAV.DIDLLiteCreateClass] for the @xml_node.
*
* Returns: (transfer full): A new [class@GUPnPAV.DIDLLiteCreateClass] object.
*Unref after usage.
**/
GUPnPDIDLLiteCreateClass *
gupnp_didl_lite_create_class_new_from_xml (xmlNode *xml_node,
GUPnPAVXMLDoc *xml_doc)
{
return g_object_new (GUPNP_TYPE_DIDL_LITE_CREATE_CLASS,
"xml-node", xml_node,
"xml-doc", xml_doc,
NULL);
}
/**
* gupnp_didl_lite_create_class_get_xml_node:
* @create_class: The [class@GUPnPAV.DIDLLiteCreateClass]
*
* Get the pointer to relevant node in XML document.
*
* Returns: (transfer none): The pointer to relevant node in XML document.
**/
xmlNode *
gupnp_didl_lite_create_class_get_xml_node
(GUPnPDIDLLiteCreateClass *create_class)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CREATE_CLASS (create_class),
NULL);
GUPnPDIDLLiteCreateClassPrivate *priv =
gupnp_didl_lite_create_class_get_instance_private (
create_class);
return priv->xml_node;
}
07070100000032000081A40000000000000000000000016860451500000918000000000000000000000000000000000000003A00000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-createclass.h/*
* Copyright (C) 2012 Intel Corporation.
* Copyright (C) 2009 Nokia Corporation.
*
* Author: Christophe Guiraud <christophe.guiraud@intel.com>
* Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
* <zeeshan.ali@nokia.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_CREATE_CLASS_H
#define GUPNP_DIDL_LITE_CREATE_CLASS_H
#include <glib-object.h>
#include <libxml/tree.h>
#include "gupnp-didl-lite-container.h"
G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE(GUPnPDIDLLiteCreateClass,
gupnp_didl_lite_create_class,
GUPNP,
DIDL_LITE_CREATE_CLASS,
GObject)
#define GUPNP_TYPE_DIDL_LITE_CREATE_CLASS \
(gupnp_didl_lite_create_class_get_type ())
struct _GUPnPDIDLLiteCreateClassClass {
GObjectClass parent_class;
/* future padding */
void (* _gupnp_reserved1) (void);
void (* _gupnp_reserved2) (void);
void (* _gupnp_reserved3) (void);
void (* _gupnp_reserved4) (void);
};
const char *
gupnp_didl_lite_create_class_get_content
(GUPnPDIDLLiteCreateClass *create_class);
void
gupnp_didl_lite_create_class_set_content
(GUPnPDIDLLiteCreateClass *create_class,
const char *content);
gboolean
gupnp_didl_lite_create_class_get_include_derived
(GUPnPDIDLLiteCreateClass *create_class);
void
gupnp_didl_lite_create_class_set_include_derived
(GUPnPDIDLLiteCreateClass *create_class,
gboolean include_derived);
const char *
gupnp_didl_lite_create_class_get_friendly_name
(GUPnPDIDLLiteCreateClass *create_class);
void
gupnp_didl_lite_create_class_set_friendly_name
(GUPnPDIDLLiteCreateClass *create_class,
const char *friendly_name);
xmlNode *
gupnp_didl_lite_create_class_get_xml_node
(GUPnPDIDLLiteCreateClass *create_class);
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_CREATE_CLASS_H__ */
07070100000033000081A400000000000000000000000168604515000002BA000000000000000000000000000000000000004100000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-descriptor-private.h/*
* Copyright (C) 2009 Nokia Corporation.
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_DESCRIPTOR_PRIVATE_H
#define GUPNP_DIDL_LITE_DESCRIPTOR_PRIVATE_H
#include "xml-util.h"
#include "gupnp-didl-lite-descriptor.h"
#include <stdarg.h>
#include <glib-object.h>
#include <libxml/tree.h>
G_BEGIN_DECLS
G_GNUC_INTERNAL GUPnPDIDLLiteDescriptor *
gupnp_didl_lite_descriptor_new_from_xml (xmlNode *xml_node,
GUPnPAVXMLDoc *xml_doc);
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_DESCRIPTOR_PRIVATE_H__ */
07070100000034000081A400000000000000000000000168604515000042B6000000000000000000000000000000000000003900000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-descriptor.c/*
* Copyright (C) 2009 Nokia Corporation.
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPDIDLLiteDescriptor:
*
* DIDL-Lite Descriptor
*
* #GUPnPDIDLLiteDescriptor respresents a DIDL-Lite descriptor (desc) element.
*/
#include <config.h>
#include <string.h>
#include "gupnp-didl-lite-descriptor.h"
#include "gupnp-didl-lite-descriptor-private.h"
#include "xml-util.h"
struct _GUPnPDIDLLiteDescriptorPrivate {
xmlNode *xml_node;
GUPnPAVXMLDoc *xml_doc;
};
typedef struct _GUPnPDIDLLiteDescriptorPrivate GUPnPDIDLLiteDescriptorPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GUPnPDIDLLiteDescriptor,
gupnp_didl_lite_descriptor,
G_TYPE_OBJECT)
enum {
PROP_0,
PROP_XML_NODE,
PROP_XML_DOC,
PROP_ID,
PROP_METADATA_TYPE,
PROP_NAME_SPACE,
PROP_CONTENT
};
static void
gupnp_didl_lite_descriptor_init (GUPnPDIDLLiteDescriptor *descriptor)
{
}
static void
gupnp_didl_lite_descriptor_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteDescriptor *descriptor;
descriptor = GUPNP_DIDL_LITE_DESCRIPTOR (object);
GUPnPDIDLLiteDescriptorPrivate *priv =
gupnp_didl_lite_descriptor_get_instance_private (descriptor);
switch (property_id) {
case PROP_XML_NODE:
priv->xml_node = g_value_get_pointer (value);
break;
case PROP_XML_DOC:
priv->xml_doc = g_value_dup_boxed (value);
break;
case PROP_ID:
gupnp_didl_lite_descriptor_set_id
(descriptor,
g_value_get_string (value));
break;
case PROP_METADATA_TYPE:
gupnp_didl_lite_descriptor_set_metadata_type
(descriptor,
g_value_get_string (value));
break;
case PROP_NAME_SPACE:
gupnp_didl_lite_descriptor_set_name_space
(descriptor,
g_value_get_string (value));
break;
case PROP_CONTENT:
gupnp_didl_lite_descriptor_set_content
(descriptor,
g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_descriptor_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteDescriptor *descriptor;
descriptor = GUPNP_DIDL_LITE_DESCRIPTOR (object);
switch (property_id) {
case PROP_XML_NODE:
g_value_set_pointer
(value,
gupnp_didl_lite_descriptor_get_xml_node (descriptor));
break;
case PROP_ID:
g_value_set_string
(value,
gupnp_didl_lite_descriptor_get_id (descriptor));
break;
case PROP_METADATA_TYPE:
g_value_set_string
(value,
gupnp_didl_lite_descriptor_get_metadata_type
(descriptor));
break;
case PROP_NAME_SPACE:
g_value_set_string
(value,
gupnp_didl_lite_descriptor_get_name_space
(descriptor));
break;
case PROP_CONTENT:
g_value_set_string
(value,
gupnp_didl_lite_descriptor_get_content (descriptor));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_descriptor_dispose (GObject *object)
{
GObjectClass *object_class;
GUPnPDIDLLiteDescriptorPrivate *priv =
gupnp_didl_lite_descriptor_get_instance_private (
GUPNP_DIDL_LITE_DESCRIPTOR (object));
g_clear_pointer (&priv->xml_doc, av_xml_doc_unref);
object_class = G_OBJECT_CLASS (gupnp_didl_lite_descriptor_parent_class);
object_class->dispose (object);
}
static void
gupnp_didl_lite_descriptor_class_init (GUPnPDIDLLiteDescriptorClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->set_property = gupnp_didl_lite_descriptor_set_property;
object_class->get_property = gupnp_didl_lite_descriptor_get_property;
object_class->dispose = gupnp_didl_lite_descriptor_dispose;
/**
* GUPnPDIDLLiteDescriptor:xml-node:
*
* The pointer to desc node in XML document.
**/
g_object_class_install_property
(object_class,
PROP_XML_NODE,
g_param_spec_pointer ("xml-node",
"XMLNode",
"The pointer to desc node in XML"
" document.",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteDescriptor:xml-doc:
*
* The reference to XML document containing this object.
*
* Internal property.
*
* Stability: Private
**/
g_object_class_install_property
(object_class,
PROP_XML_DOC,
g_param_spec_boxed ("xml-doc",
"XMLDoc",
"The reference to XML document"
" containing this object.",
av_xml_doc_get_type (),
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteDescriptor:name-space:
*
* The name space associated with this descriptor.
**/
g_object_class_install_property
(object_class,
PROP_NAME_SPACE,
g_param_spec_string ("name-space",
"NameSpace",
"The name space associated with this"
" descriptor",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteDescriptor:id:
*
* The ID of this descriptor.
**/
g_object_class_install_property
(object_class,
PROP_ID,
g_param_spec_string ("id",
"ID",
"The ID of this descriptor",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteDescriptor:metadata-type:
*
* The type of this descriptor.
**/
g_object_class_install_property
(object_class,
PROP_METADATA_TYPE,
g_param_spec_string ("metadata-type",
"MetadataType",
"The metadata type of this descriptor",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteDescriptor:content:
*
* The content of this descriptor.
**/
g_object_class_install_property
(object_class,
PROP_CONTENT,
g_param_spec_string ("content",
"Content",
"The content of this descriptor",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
}
/**
* gupnp_didl_lite_descriptor_new:
*
* Create a new GUPnPDIDLLiteDescriptor oobject.
*
* Return value: A new #GUPnPDIDLLiteDescriptor object. Unref after usage.
**/
GUPnPDIDLLiteDescriptor *
gupnp_didl_lite_descriptor_new (void)
{
return g_object_new (GUPNP_TYPE_DIDL_LITE_DESCRIPTOR,
NULL);
}
/**
* gupnp_didl_lite_descriptor_new_from_xml:
* @xml_node: The pointer to 'desc' node in XML document
* @xml_doc: The reference to XML document containing this descriptor
*
* Creates a new #GUPnPDIDLLiteDescriptor for the @xml_node.
*
* Return value: A new #GUPnPDIDLLiteDescriptor object. Unref after usage.
**/
GUPnPDIDLLiteDescriptor *
gupnp_didl_lite_descriptor_new_from_xml (xmlNode *xml_node,
GUPnPAVXMLDoc *xml_doc)
{
return g_object_new (GUPNP_TYPE_DIDL_LITE_DESCRIPTOR,
"xml-node", xml_node,
"xml-doc", xml_doc,
NULL);
}
/**
* gupnp_didl_lite_descriptor_get_xml_node:
* @descriptor: The #GUPnPDIDLLiteDescriptor
*
* Get the pointer to desc node in XML document.
*
* Returns: (transfer none): The pointer to desc node in XML document.
**/
xmlNode *
gupnp_didl_lite_descriptor_get_xml_node (GUPnPDIDLLiteDescriptor *descriptor)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor), NULL);
GUPnPDIDLLiteDescriptorPrivate *priv =
gupnp_didl_lite_descriptor_get_instance_private (descriptor);
return priv->xml_node;
}
/**
* gupnp_didl_lite_descriptor_get_content:
* @descriptor: A #GUPnPDIDLLiteDescriptor
*
* Get the content of the @descriptor.
*
* Return value: The content of the @descriptor or %NULL.
**/
const char *
gupnp_didl_lite_descriptor_get_content (GUPnPDIDLLiteDescriptor *descriptor)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor), NULL);
GUPnPDIDLLiteDescriptorPrivate *priv =
gupnp_didl_lite_descriptor_get_instance_private (descriptor);
return (const char *) priv->xml_node->children;
}
/**
* gupnp_didl_lite_descriptor_get_id:
* @descriptor: A #GUPnPDIDLLiteDescriptor
*
* Get the ID of the @descriptor.
*
* Return value: The ID string or %NULL.
**/
const char *
gupnp_didl_lite_descriptor_get_id (GUPnPDIDLLiteDescriptor *descriptor)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor), NULL);
GUPnPDIDLLiteDescriptorPrivate *priv =
gupnp_didl_lite_descriptor_get_instance_private (descriptor);
return av_xml_util_get_attribute_content (priv->xml_node, "id");
}
/**
* gupnp_didl_lite_descriptor_get_metadata_type:
* @descriptor: A #GUPnPDIDLLiteDescriptor
*
* Get the metadata type of the @descriptor.
*
* Return value: The type as string or %NULL.
**/
const char *
gupnp_didl_lite_descriptor_get_metadata_type
(GUPnPDIDLLiteDescriptor *descriptor)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor), NULL);
GUPnPDIDLLiteDescriptorPrivate *priv =
gupnp_didl_lite_descriptor_get_instance_private (descriptor);
return av_xml_util_get_attribute_content (priv->xml_node, "type");
}
/**
* gupnp_didl_lite_descriptor_get_name_space:
* @descriptor: A #GUPnPDIDLLiteDescriptor
*
* Get the name space associated with the @descriptor.
*
* Return value: The name space or %NULL.
**/
const char *
gupnp_didl_lite_descriptor_get_name_space (GUPnPDIDLLiteDescriptor *descriptor)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor), NULL);
GUPnPDIDLLiteDescriptorPrivate *priv =
gupnp_didl_lite_descriptor_get_instance_private (descriptor);
return av_xml_util_get_attribute_content (priv->xml_node, "nameSpace");
}
/**
* gupnp_didl_lite_descriptor_set_content:
* @descriptor: A #GUPnPDIDLLiteDescriptor
* @content: The content as string
*
* Set the content of the @descriptor.
**/
void
gupnp_didl_lite_descriptor_set_content (GUPnPDIDLLiteDescriptor *descriptor,
const char *content)
{
xmlChar *escaped;
g_return_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor));
g_return_if_fail (content != NULL);
GUPnPDIDLLiteDescriptorPrivate *priv =
gupnp_didl_lite_descriptor_get_instance_private (descriptor);
escaped = xmlEncodeSpecialChars (priv->xml_doc->doc,
(const unsigned char *) content);
xmlNodeSetContent (priv->xml_node, escaped);
xmlFree (escaped);
g_object_notify (G_OBJECT (descriptor), "content");
}
/**
* gupnp_didl_lite_descriptor_set_id:
* @descriptor: A #GUPnPDIDLLiteDescriptor
* @id: The ID as string
*
* Set the ID of the @descriptor.
**/
void
gupnp_didl_lite_descriptor_set_id (GUPnPDIDLLiteDescriptor *descriptor,
const char *id)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor));
g_return_if_fail (id != NULL);
GUPnPDIDLLiteDescriptorPrivate *priv =
gupnp_didl_lite_descriptor_get_instance_private (descriptor);
xmlSetProp (priv->xml_node,
(unsigned char *) "id",
(const unsigned char *) id);
g_object_notify (G_OBJECT (descriptor), "id");
}
/**
* gupnp_didl_lite_descriptor_set_metadata_type:
* @descriptor: A #GUPnPDIDLLiteDescriptor
* @type: The metadata type as string
*
* Set the metadata type of the @descriptor.
**/
void
gupnp_didl_lite_descriptor_set_metadata_type
(GUPnPDIDLLiteDescriptor *descriptor,
const char *type)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor));
g_return_if_fail (type != NULL);
GUPnPDIDLLiteDescriptorPrivate *priv =
gupnp_didl_lite_descriptor_get_instance_private (descriptor);
xmlSetProp (priv->xml_node,
(unsigned char *) "type",
(const unsigned char *) type);
g_object_notify (G_OBJECT (descriptor), "metadata-type");
}
/**
* gupnp_didl_lite_descriptor_set_name_space:
* @descriptor: A #GUPnPDIDLLiteDescriptor
* @name_space: The name space URI as string
*
* Set the name space associated with the @descriptor.
**/
void
gupnp_didl_lite_descriptor_set_name_space (GUPnPDIDLLiteDescriptor *descriptor,
const char *name_space)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor));
g_return_if_fail (name_space != NULL);
GUPnPDIDLLiteDescriptorPrivate *priv =
gupnp_didl_lite_descriptor_get_instance_private (descriptor);
xmlSetProp (priv->xml_node,
(unsigned char *) "nameSpace",
(const unsigned char *) name_space);
g_object_notify (G_OBJECT (descriptor), "name-space");
}
07070100000035000081A40000000000000000000000016860451500000931000000000000000000000000000000000000003900000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-descriptor.h/*
* Copyright (C) 2009 Nokia Corporation.
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_DESCRIPTOR_H
#define GUPNP_DIDL_LITE_DESCRIPTOR_H
#include <stdarg.h>
#include <glib-object.h>
#include <libxml/tree.h>
G_BEGIN_DECLS
#define GUPNP_TYPE_DIDL_LITE_DESCRIPTOR gupnp_didl_lite_descriptor_get_type ()
G_DECLARE_DERIVABLE_TYPE (GUPnPDIDLLiteDescriptor,
gupnp_didl_lite_descriptor,
GUPNP,
DIDL_LITE_DESCRIPTOR,
GObject)
struct _GUPnPDIDLLiteDescriptorClass {
GObjectClass parent_class;
/* future padding */
void (* _gupnp_reserved1) (void);
void (* _gupnp_reserved2) (void);
void (* _gupnp_reserved3) (void);
void (* _gupnp_reserved4) (void);
};
GUPnPDIDLLiteDescriptor *
gupnp_didl_lite_descriptor_new (void);
xmlNode *
gupnp_didl_lite_descriptor_get_xml_node (GUPnPDIDLLiteDescriptor *descriptor);
const char *
gupnp_didl_lite_descriptor_get_content (GUPnPDIDLLiteDescriptor *descriptor);
const char *
gupnp_didl_lite_descriptor_get_id (GUPnPDIDLLiteDescriptor *descriptor);
const char *
gupnp_didl_lite_descriptor_get_metadata_type
(GUPnPDIDLLiteDescriptor *descriptor);
const char *
gupnp_didl_lite_descriptor_get_name_space
(GUPnPDIDLLiteDescriptor *descriptor);
void
gupnp_didl_lite_descriptor_set_content (GUPnPDIDLLiteDescriptor *descriptor,
const char *content);
void
gupnp_didl_lite_descriptor_set_id (GUPnPDIDLLiteDescriptor *descriptor,
const char *id);
void
gupnp_didl_lite_descriptor_set_metadata_type
(GUPnPDIDLLiteDescriptor *descriptor,
const char *type);
void
gupnp_didl_lite_descriptor_set_name_space
(GUPnPDIDLLiteDescriptor *descriptor,
const char *name_space);
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_DESCRIPTOR_H__ */
07070100000036000081A40000000000000000000000016860451500001D82000000000000000000000000000000000000003300000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-item.c/*
* Copyright (C) 2009 Nokia Corporation.
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPDIDLLiteItem:
*
* DIDL-Lite Item
*
* #GUPnPDIDLLiteItem respresents a DIDL-Lite item element.
*/
#include <config.h>
#include <string.h>
#include "gupnp-didl-lite-item.h"
#include "xml-util.h"
#include "time-utils.h"
G_DEFINE_TYPE (GUPnPDIDLLiteItem,
gupnp_didl_lite_item,
GUPNP_TYPE_DIDL_LITE_OBJECT)
enum {
PROP_0,
PROP_REF_ID,
PROP_LIFETIME
};
static void
gupnp_didl_lite_item_init (G_GNUC_UNUSED GUPnPDIDLLiteItem *item)
{
/* Nothing to initialize, yay! */
}
static void
gupnp_didl_lite_item_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteItem *item;
item = GUPNP_DIDL_LITE_ITEM (object);
switch (property_id) {
case PROP_REF_ID:
g_value_set_string
(value,
gupnp_didl_lite_item_get_ref_id (item));
break;
case PROP_LIFETIME:
g_value_set_long
(value,
gupnp_didl_lite_item_get_lifetime (item));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_item_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteItem *item;
item = GUPNP_DIDL_LITE_ITEM (object);
switch (property_id) {
case PROP_REF_ID:
gupnp_didl_lite_item_set_ref_id (item,
g_value_get_string (value));
break;
case PROP_LIFETIME:
gupnp_didl_lite_item_set_lifetime (item,
g_value_get_long (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_item_class_init (GUPnPDIDLLiteItemClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gupnp_didl_lite_item_get_property;
object_class->set_property = gupnp_didl_lite_item_set_property;
/**
* GUPnPDIDLLiteItem:ref-id:
*
* The ref ID of this item.
**/
g_object_class_install_property
(object_class,
PROP_REF_ID,
g_param_spec_string ("ref-id",
"RefID",
"The ref ID of this item.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteItem:lifetime:
*
* The lifetime in seconds of this DIDLLite item in a media collection.
**/
g_object_class_install_property
(object_class,
PROP_LIFETIME,
g_param_spec_long ("lifetime",
"Lifetime",
"The lifetime (in seconds) of this"
" item.",
-1,
G_MAXLONG,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}
/**
* gupnp_didl_lite_item_get_ref_id:
* @item: #GUPnPDIDLLiteItem
*
* Get the ref ID of the @item.
*
* Return value: The ref ID of the @item, or %NULL.
**/
const char *
gupnp_didl_lite_item_get_ref_id (GUPnPDIDLLiteItem *item)
{
xmlNode *xml_node;
g_return_val_if_fail (item != NULL, 0);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_ITEM (item), NULL);
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (item));
return av_xml_util_get_attribute_content (xml_node, "refID");
}
/**
* gupnp_didl_lite_item_set_ref_id:
* @item: #GUPnPDIDLLiteItem
* @ref_id: The ref ID
*
* Set the ref ID of the @item.
**/
void
gupnp_didl_lite_item_set_ref_id (GUPnPDIDLLiteItem *item,
const char *ref_id)
{
xmlNode *xml_node;
g_return_if_fail (item != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_ITEM (item));
xml_node = gupnp_didl_lite_object_get_xml_node
(GUPNP_DIDL_LITE_OBJECT (item));
xmlSetProp (xml_node,
(unsigned char *) "refID",
(unsigned char *) ref_id);
g_object_notify (G_OBJECT (item), "ref-id");
}
/**
* gupnp_didl_lite_item_set_lifetime:
* @item: #GUPnPDIDLLiteItem
* @lifetime: The lifetime (in seconds) of this item in a media collection.
*
* Sets the lifetime in seconds of this item in a media collection.
**/
void
gupnp_didl_lite_item_set_lifetime (GUPnPDIDLLiteItem *item,
glong lifetime)
{
xmlNode *node = NULL;
xmlNs *ns = NULL;
GUPnPAVXMLDoc *doc = NULL;
GUPnPDIDLLiteObject *object = NULL;
g_return_if_fail (GUPNP_IS_DIDL_LITE_ITEM (item));
object = GUPNP_DIDL_LITE_OBJECT (item);
node = gupnp_didl_lite_object_get_xml_node (object);
ns = gupnp_didl_lite_object_get_dlna_namespace (object);
g_object_get (G_OBJECT (object), "xml-doc", &doc, NULL);
if (lifetime < 0)
av_xml_util_unset_child (node, "lifetime");
else {
char *str;
str = seconds_to_time (lifetime);
av_xml_util_set_child (node,
GUPNP_XML_NAMESPACE_DLNA,
&ns,
doc->doc,
"lifetime",
str);
g_free (str);
}
g_object_notify (G_OBJECT (object), "lifetime");
}
/**
* gupnp_didl_lite_item_get_lifetime:
* @item: #GUPnPDIDLLiteItem
*
* Returns: -1 if unset or the lifetime (in seconds) of the current item.
**/
glong
gupnp_didl_lite_item_get_lifetime (GUPnPDIDLLiteItem *item)
{
xmlNode *node = NULL;
const char *lifetime_str;
long lifetime;
GUPnPDIDLLiteObject *object = NULL;
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_ITEM (item), -1);
object = GUPNP_DIDL_LITE_OBJECT (item);
node = gupnp_didl_lite_object_get_xml_node (object);
lifetime_str = av_xml_util_get_child_element_content (node,
"lifetime");
lifetime = seconds_from_time (lifetime_str);
return lifetime;
}
07070100000037000081A400000000000000000000000168604515000005ED000000000000000000000000000000000000003300000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-item.h/*
* Copyright (C) 2009 Nokia Corporation.
* Copyright (C) 2012 Intel Corporation.
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
* Jens Georg <jensg@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_ITEM_H
#define GUPNP_DIDL_LITE_ITEM_H
#include <glib-object.h>
#include "gupnp-didl-lite-object.h"
G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE(GUPnPDIDLLiteItem,
gupnp_didl_lite_item,
GUPNP,
DIDL_LITE_ITEM,
GUPnPDIDLLiteObject)
#define GUPNP_TYPE_DIDL_LITE_ITEM \
(gupnp_didl_lite_item_get_type ())
struct _GUPnPDIDLLiteItemClass {
GUPnPDIDLLiteObjectClass parent_class;
/* future padding */
void (* _gupnp_reserved1) (void);
void (* _gupnp_reserved2) (void);
void (* _gupnp_reserved3) (void);
void (* _gupnp_reserved4) (void);
};
const char *
gupnp_didl_lite_item_get_ref_id (GUPnPDIDLLiteItem *item);
void
gupnp_didl_lite_item_set_ref_id (GUPnPDIDLLiteItem *item,
const char *ref_id);
void
gupnp_didl_lite_item_set_lifetime (GUPnPDIDLLiteItem *item,
glong lifetime);
glong
gupnp_didl_lite_item_get_lifetime (GUPnPDIDLLiteItem *item);
G_END_DECLS
#endif /* GUPNP_DIDL_LITE_ITEM_H */
07070100000038000081A40000000000000000000000016860451500000477000000000000000000000000000000000000003D00000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-object-private.h/*
* Copyright (C) 2009 Nokia Corporation.
* Copyright (C) 2012 Intel Corporation
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
* Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_OBJECT_PRIVATE_H
#define GUPNP_DIDL_LITE_OBJECT_PRIVATE_H
#include "xml-util.h"
#include "gupnp-didl-lite-object.h"
#include <glib-object.h>
#include <libxml/tree.h>
G_BEGIN_DECLS
G_GNUC_INTERNAL GUPnPDIDLLiteObject *
gupnp_didl_lite_object_new_from_xml (xmlNode *xml_node,
GUPnPAVXMLDoc *xml_doc,
xmlNs *upnp_ns,
xmlNs *dc_ns,
xmlNs *dlna_ns,
xmlNs *pv_ns);
G_GNUC_INTERNAL GUPnPAVXMLDoc *
gupnp_didl_lite_object_get_gupnp_xml_doc
(GUPnPDIDLLiteObject *object);
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_OBJECT_PRIVATE_H__ */
07070100000039000081A400000000000000000000000168604515000170B5000000000000000000000000000000000000003500000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-object.c/*
* Copyright (C) 2009 Nokia Corporation.
* Copyright (C) 2012 Intel Corporation
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
* Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPDIDLLiteObject:
*
* DIDL-Lite Object
*
* #GUPnPDIDLLiteObject respresent a DIDL-Lite object element.
*/
#include <config.h>
#include <string.h>
#include "gupnp-didl-lite-object.h"
#include "gupnp-didl-lite-object-private.h"
#include "gupnp-didl-lite-resource-private.h"
#include "gupnp-didl-lite-descriptor-private.h"
#include "gupnp-didl-lite-container.h"
#include "gupnp-didl-lite-item.h"
#include "gupnp-didl-lite-contributor-private.h"
#include "xml-util.h"
#include "fragment-util.h"
#include "xsd-data.h"
struct _GUPnPDIDLLiteObjectPrivate {
xmlNode *xml_node;
GUPnPAVXMLDoc *xml_doc;
xmlNs *upnp_ns;
xmlNs *dc_ns;
xmlNs *dlna_ns;
xmlNs *pv_ns;
};
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GUPnPDIDLLiteObject,
gupnp_didl_lite_object,
G_TYPE_OBJECT)
static XSDData *didl_lite_xsd;
enum {
PROP_0,
PROP_XML_NODE,
PROP_XML_DOC,
PROP_UPNP_NAMESPACE,
PROP_DC_NAMESPACE,
PROP_DLNA_NAMESPACE,
PROP_PV_NAMESPACE,
PROP_ID,
PROP_PARENT_ID,
PROP_RESTRICTED,
PROP_TITLE,
PROP_UPNP_CLASS,
PROP_CREATOR,
PROP_ARTIST,
PROP_AUTHOR,
PROP_GENRE,
PROP_WRITE_STATUS,
PROP_ALBUM,
PROP_ALBUM_ART,
PROP_DESCRIPTION,
PROP_DATE,
PROP_TRACK_NUMBER,
PROP_DLNA_MANAGED,
PROP_UPDATE_ID
};
static int
is_non_transcoded_resource (GUPnPDIDLLiteResource *resource, gpointer data)
{
GUPnPProtocolInfo *info;
info = gupnp_didl_lite_resource_get_protocol_info (resource);
if (G_UNLIKELY (info == NULL))
return -1;
return gupnp_protocol_info_get_dlna_conversion (info) &
GUPNP_DLNA_CONVERSION_TRANSCODED;
}
static void
gupnp_didl_lite_object_init (GUPnPDIDLLiteObject *object)
{
}
static void
gupnp_didl_lite_object_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteObject *didl_object;
GUPnPDIDLLiteObjectPrivate *priv;
didl_object = GUPNP_DIDL_LITE_OBJECT(object);
priv = gupnp_didl_lite_object_get_instance_private(didl_object);
switch (property_id) {
case PROP_XML_NODE:
priv->xml_node = g_value_get_pointer (value);
break;
case PROP_XML_DOC:
priv->xml_doc = g_value_dup_boxed (value);
break;
case PROP_UPNP_NAMESPACE:
priv->upnp_ns = g_value_get_pointer (value);
break;
case PROP_DC_NAMESPACE:
priv->dc_ns = g_value_get_pointer (value);
break;
case PROP_DLNA_NAMESPACE:
priv->dlna_ns = g_value_get_pointer (value);
break;
case PROP_PV_NAMESPACE:
priv->pv_ns = g_value_get_pointer (value);
break;
case PROP_ID:
gupnp_didl_lite_object_set_id (didl_object,
g_value_get_string (value));
break;
case PROP_PARENT_ID:
gupnp_didl_lite_object_set_parent_id
(didl_object,
g_value_get_string (value));
break;
case PROP_RESTRICTED:
gupnp_didl_lite_object_set_restricted
(didl_object,
g_value_get_boolean (value));
break;
case PROP_TITLE:
gupnp_didl_lite_object_set_title
(didl_object,
g_value_get_string (value));
break;
case PROP_UPNP_CLASS:
gupnp_didl_lite_object_set_upnp_class
(didl_object,
g_value_get_string (value));
break;
case PROP_CREATOR:
gupnp_didl_lite_object_set_creator
(didl_object,
g_value_get_string (value));
break;
case PROP_ARTIST:
gupnp_didl_lite_object_set_artist
(didl_object,
g_value_get_string (value));
break;
case PROP_AUTHOR:
gupnp_didl_lite_object_set_author
(didl_object,
g_value_get_string (value));
break;
case PROP_GENRE:
gupnp_didl_lite_object_set_genre
(didl_object,
g_value_get_string (value));
break;
case PROP_WRITE_STATUS:
gupnp_didl_lite_object_set_write_status
(didl_object,
g_value_get_string (value));
break;
case PROP_ALBUM:
gupnp_didl_lite_object_set_album
(didl_object,
g_value_get_string (value));
break;
case PROP_ALBUM_ART:
gupnp_didl_lite_object_set_album_art
(didl_object,
g_value_get_string (value));
break;
case PROP_DESCRIPTION:
gupnp_didl_lite_object_set_description
(didl_object,
g_value_get_string (value));
break;
case PROP_DATE:
gupnp_didl_lite_object_set_date
(didl_object,
g_value_get_string (value));
break;
case PROP_TRACK_NUMBER:
gupnp_didl_lite_object_set_track_number
(didl_object,
g_value_get_int (value));
break;
case PROP_DLNA_MANAGED:
gupnp_didl_lite_object_set_dlna_managed
(didl_object,
g_value_get_flags (value));
break;
case PROP_UPDATE_ID:
gupnp_didl_lite_object_set_update_id
(didl_object,
g_value_get_uint (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_object_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteObject *didl_object;
didl_object = GUPNP_DIDL_LITE_OBJECT (object);
switch (property_id) {
case PROP_XML_NODE:
g_value_set_pointer
(value,
gupnp_didl_lite_object_get_xml_node (didl_object));
break;
case PROP_UPNP_NAMESPACE:
g_value_set_pointer
(value,
gupnp_didl_lite_object_get_upnp_namespace
(didl_object));
break;
case PROP_DC_NAMESPACE:
g_value_set_pointer
(value,
gupnp_didl_lite_object_get_dc_namespace
(didl_object));
break;
case PROP_DLNA_NAMESPACE:
g_value_set_pointer
(value,
gupnp_didl_lite_object_get_dlna_namespace
(didl_object));
break;
case PROP_PV_NAMESPACE:
g_value_set_pointer
(value,
gupnp_didl_lite_object_get_pv_namespace
(didl_object));
break;
case PROP_ID:
g_value_set_string
(value,
gupnp_didl_lite_object_get_id (didl_object));
break;
case PROP_PARENT_ID:
g_value_set_string
(value,
gupnp_didl_lite_object_get_parent_id (didl_object));
break;
case PROP_RESTRICTED:
g_value_set_boolean
(value,
gupnp_didl_lite_object_get_restricted (didl_object));
break;
case PROP_TITLE:
g_value_set_string
(value,
gupnp_didl_lite_object_get_title (didl_object));
break;
case PROP_UPNP_CLASS:
g_value_set_string
(value,
gupnp_didl_lite_object_get_upnp_class (didl_object));
break;
case PROP_CREATOR:
g_value_set_string
(value,
gupnp_didl_lite_object_get_creator (didl_object));
break;
case PROP_ARTIST:
g_value_set_string
(value,
gupnp_didl_lite_object_get_artist (didl_object));
break;
case PROP_AUTHOR:
g_value_set_string
(value,
gupnp_didl_lite_object_get_author (didl_object));
break;
case PROP_GENRE:
g_value_set_string
(value,
gupnp_didl_lite_object_get_genre (didl_object));
break;
case PROP_WRITE_STATUS:
g_value_set_string
(value,
gupnp_didl_lite_object_get_write_status (didl_object));
break;
case PROP_ALBUM:
g_value_set_string
(value,
gupnp_didl_lite_object_get_album (didl_object));
break;
case PROP_ALBUM_ART:
g_value_set_string
(value,
gupnp_didl_lite_object_get_album_art (didl_object));
break;
case PROP_DESCRIPTION:
g_value_set_string
(value,
gupnp_didl_lite_object_get_description (didl_object));
break;
case PROP_DATE:
g_value_set_string
(value,
gupnp_didl_lite_object_get_date (didl_object));
break;
case PROP_TRACK_NUMBER:
g_value_set_int
(value,
gupnp_didl_lite_object_get_track_number (didl_object));
break;
case PROP_DLNA_MANAGED:
g_value_set_flags
(value,
gupnp_didl_lite_object_get_dlna_managed (didl_object));
break;
case PROP_UPDATE_ID:
g_value_set_uint
(value,
gupnp_didl_lite_object_get_update_id (didl_object));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_object_dispose (GObject *object)
{
GObjectClass *object_class;
GUPnPDIDLLiteObjectPrivate *priv;
GUPnPDIDLLiteObject *self = GUPNP_DIDL_LITE_OBJECT (object);
priv = gupnp_didl_lite_object_get_instance_private (self);
g_clear_pointer (&priv->xml_doc, av_xml_doc_unref);
object_class = G_OBJECT_CLASS (gupnp_didl_lite_object_parent_class);
object_class->dispose (object);
}
static void
gupnp_didl_lite_object_class_init (GUPnPDIDLLiteObjectClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->set_property = gupnp_didl_lite_object_set_property;
object_class->get_property = gupnp_didl_lite_object_get_property;
object_class->dispose = gupnp_didl_lite_object_dispose;
/**
* GUPnPDIDLLiteObject:xml-node:
*
* The pointer to object node in XML document.
**/
g_object_class_install_property
(object_class,
PROP_XML_NODE,
g_param_spec_pointer ("xml-node",
"XMLNode",
"The pointer to object node in XML"
" document.",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:xml-doc:
*
* The reference to XML document containing this object.
*
* Internal property.
*
* Stability: Private
**/
g_object_class_install_property
(object_class,
PROP_XML_DOC,
g_param_spec_boxed ("xml-doc",
"XMLDoc",
"The reference to XML document"
" containing this object.",
av_xml_doc_get_type (),
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:upnp-namespace:
*
* Pointer to the UPnP namespace registered with the XML document
* containing this object.
*
**/
g_object_class_install_property
(object_class,
PROP_UPNP_NAMESPACE,
g_param_spec_pointer ("upnp-namespace",
"XML namespace",
"Pointer to the UPnP XML namespace "
"registered with the XML document "
"containing this object.",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:dc-namespace:
*
* Pointer to the DublinCore namespace registered with the XML document
* containing this object.
*
**/
g_object_class_install_property
(object_class,
PROP_DC_NAMESPACE,
g_param_spec_pointer ("dc-namespace",
"XML namespace",
"Pointer to the Dublin Core XML "
"namespace registered with the XML "
"document containing this object.",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:dlna-namespace:
*
* Pointer to the DLNA metadata namespace registered with the XML
* document containing this object.
*
**/
g_object_class_install_property
(object_class,
PROP_DLNA_NAMESPACE,
g_param_spec_pointer ("dlna-namespace",
"XML namespace",
"Pointer to the DLNA metadata namespace "
"registered with the XML document "
"containing this object.",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:pv-namespace:
*
* Pointer to the PV metadata namespace registered with the XML
* document containing this object.
*
**/
g_object_class_install_property
(object_class,
PROP_PV_NAMESPACE,
g_param_spec_pointer ("pv-namespace",
"XML namespace",
"Pointer to the PV metadata namespace "
"registered with the XML document "
"containing this object.",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* GUPnPDIDLLiteObject:id:
*
* The ID of this object.
**/
g_object_class_install_property
(object_class,
PROP_ID,
g_param_spec_string ("id",
"ID",
"The ID of this object.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:parent-id:
*
* The ID of the parent container of this object.
**/
g_object_class_install_property
(object_class,
PROP_PARENT_ID,
g_param_spec_string ("parent-id",
"ParentID",
"The ID of the parent container of"
" this object.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:restricted:
*
* Whether this object is restricted.
**/
g_object_class_install_property
(object_class,
PROP_RESTRICTED,
g_param_spec_boolean ("restricted",
"Restricted",
"Whether this object is restricted.",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:title:
*
* The title of this object.
**/
g_object_class_install_property
(object_class,
PROP_TITLE,
g_param_spec_string ("title",
"Title",
"The title of this object.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:upnp-class:
*
* The UPnP class of this object.
**/
g_object_class_install_property
(object_class,
PROP_UPNP_CLASS,
g_param_spec_string ("upnp-class",
"UPnPClassName",
"The UPnP class of this object.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:creator:
*
* The creator of this object.
*
**/
g_object_class_install_property
(object_class,
PROP_CREATOR,
g_param_spec_string ("creator",
"Creator",
"The creator of this object.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:artist:
*
* The artist of this object.
*
* Deprecated: 0.5.3: Use #gupnp_didl_lite_object_get_artists and
* #gupnp_didl_lite_object_add_artist instead since unlike this
* property, they are capable of dealing with multiple artist nodes.
**/
g_object_class_install_property
(object_class,
PROP_ARTIST,
g_param_spec_string ("artist",
"Artist",
"The artist of this object.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:author:
*
* The author of this object.
*
* Deprecated: 0.5.3: Use #gupnp_didl_lite_object_get_authors and
* #gupnp_didl_lite_object_add_author instead since unlike this
* property, they are capable of dealing with multiple author nodes.
**/
g_object_class_install_property
(object_class,
PROP_AUTHOR,
g_param_spec_string ("author",
"Author",
"The author of this object.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:genre:
*
* The genre of this object.
**/
g_object_class_install_property
(object_class,
PROP_GENRE,
g_param_spec_string ("genre",
"Genre",
"The genre of this object.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:write-status:
*
* The write status of this object.
**/
g_object_class_install_property
(object_class,
PROP_WRITE_STATUS,
g_param_spec_string ("write-status",
"WriteStatus",
"The write status of this object.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:album:
*
* The album of this object.
**/
g_object_class_install_property
(object_class,
PROP_ALBUM,
g_param_spec_string ("album",
"Album",
"The album of this object.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:album-art:
*
* The URI to album art of this object.
**/
g_object_class_install_property
(object_class,
PROP_ALBUM_ART,
g_param_spec_string ("album-art",
"AlbumArt",
"The URI to album art of this object.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:description:
*
* The description of this object.
**/
g_object_class_install_property
(object_class,
PROP_DESCRIPTION,
g_param_spec_string ("description",
"Description",
"The description of this object.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:date:
*
* The date of this object.
**/
g_object_class_install_property
(object_class,
PROP_DATE,
g_param_spec_string ("date",
"Date",
"The date of this object.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:track-number:
*
* The original track number of this object.
**/
g_object_class_install_property
(object_class,
PROP_TRACK_NUMBER,
g_param_spec_int ("track-number",
"TrackNumber",
"The original track number of this object.",
-1, G_MAXINT, -1,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:dlna-managed:
*
* The 'dlna:dlnaManaged' attribute.
**/
g_object_class_install_property
(object_class,
PROP_DLNA_MANAGED,
g_param_spec_flags ("dlna-managed",
"DLNAManaged",
"The 'dlna:dlnaManaged' attribute",
GUPNP_TYPE_OCM_FLAGS,
GUPNP_OCM_FLAGS_NONE,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteObject:update-id:
*
* Update ID of this object.
**/
g_object_class_install_property
(object_class,
PROP_UPDATE_ID,
g_param_spec_uint ("update-id",
"UpdateID",
"Update ID of this object.",
0,
G_MAXUINT,
0,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
if (didl_lite_xsd == NULL)
didl_lite_xsd = fragment_util_get_didl_lite_xsd_data ();
}
static gboolean
is_resource_compatible (GUPnPDIDLLiteResource *resource,
char **protocols)
{
gboolean ret = FALSE;
char **it;
for (it = protocols; *it != NULL && !ret; it++) {
GUPnPProtocolInfo *info;
GUPnPProtocolInfo *res_info;
info = gupnp_protocol_info_new_from_string (*it, NULL);
if (info == NULL)
continue;
res_info = gupnp_didl_lite_resource_get_protocol_info
(resource);
if (res_info == NULL)
continue;
ret = gupnp_protocol_info_is_compatible (info, res_info);
g_object_unref (info);
}
return ret;
}
static GList *
get_contributor_list_by_name (GUPnPDIDLLiteObject *object,
const char *name)
{
GList *contributors = NULL;
GList *ret = NULL;
GList *l;
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
contributors = gupnp_didl_lite_object_get_properties (object, name);
for (l = contributors; l; l = l->next) {
GUPnPDIDLLiteContributor *contributor;
xmlNode *contributor_node;
contributor_node = (xmlNode *) l->data;
if (!contributor_node->children)
continue;
contributor = gupnp_didl_lite_contributor_new_from_xml
(contributor_node,
priv->xml_doc);
ret = g_list_append (ret, contributor);
}
g_list_free (contributors);
return ret;
}
static char *
get_contributors_xml_string_by_name (GUPnPDIDLLiteObject *object,
const char *name)
{
GList *contributors = NULL;
char *ret = NULL;
GList *l;
xmlBuffer *buffer;
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
contributors = gupnp_didl_lite_object_get_properties (object, name);
if (contributors == NULL)
return NULL;
buffer = xmlBufferCreate ();
for (l = contributors; l; l = l->next) {
xmlNode *node;
node = (xmlNode *) l->data;
if (!node->children)
continue;
xmlNodeDump (buffer,
priv->xml_doc->doc,
node,
0,
0);
}
ret = g_strndup ((char *) xmlBufferContent (buffer),
xmlBufferLength (buffer));
xmlBufferFree (buffer);
g_list_free (contributors);
return ret;
}
static void
unset_contributors_by_name (GUPnPDIDLLiteObject *object, const char *name)
{
GList *contributors = NULL;
GList *l;
contributors = gupnp_didl_lite_object_get_properties (object, name);
if (contributors == NULL)
return;
for (l = contributors; l; l = l->next) {
xmlNode *node;
node = (xmlNode *) l->data;
if (!node->children)
continue;
xmlUnlinkNode (node);
xmlFreeNode (node);
}
g_list_free (contributors);
return;
}
/**
* gupnp_didl_lite_object_new_from_xml:
* @xml_node: The pointer to 'res' node in XML document
* @xml_doc: The reference to XML document containing this object
* @upnp_ns: The pointer to 'upnp' namespace in XML document
* @dc_ns: The pointer to 'dc' namespace in XML document
* @dlna_ns: The pointer to 'dlna' namespace in XML document
* @pv_ns: The pointer to 'pv' namespace in XML document
*
* Creates a new #GUPnPDIDLLiteObject for the @xml_node.
*
* Return value: A new #GUPnPDIDLLiteObject object. Unref after usage.
**/
GUPnPDIDLLiteObject *
gupnp_didl_lite_object_new_from_xml (xmlNode *xml_node,
GUPnPAVXMLDoc *xml_doc,
xmlNs *upnp_ns,
xmlNs *dc_ns,
xmlNs *dlna_ns,
xmlNs *pv_ns)
{
g_return_val_if_fail (xml_node != NULL, NULL);
g_return_val_if_fail (xml_node->name != NULL, NULL);
if (g_ascii_strcasecmp ((char *) xml_node->name, "container") == 0)
return g_object_new (GUPNP_TYPE_DIDL_LITE_CONTAINER,
"xml-node", xml_node,
"xml-doc", xml_doc,
"upnp-namespace", upnp_ns,
"dc-namespace", dc_ns,
"dlna-namespace", dlna_ns,
"pv-namespace", pv_ns,
NULL);
else if (g_ascii_strcasecmp ((char *) xml_node->name, "item") == 0)
return g_object_new (GUPNP_TYPE_DIDL_LITE_ITEM,
"xml-node", xml_node,
"xml-doc", xml_doc,
"upnp-namespace", upnp_ns,
"dc-namespace", dc_ns,
"dlna-namespace", dlna_ns,
"pv-namespace", pv_ns,
NULL);
else
return NULL;
}
/**
* gupnp_didl_lite_object_get_gupnp_xml_doc:
* @object: The #GUPnPDIDLLiteObject
*
* Get the pointer to the XML document containing this object.
*
* Returns: (transfer none): The pointer to the XML document containing this
* object.
**/
GUPnPAVXMLDoc *
gupnp_didl_lite_object_get_gupnp_xml_doc (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return priv->xml_doc;
}
/**
* gupnp_didl_lite_object_get_xml_node:
* @object: The #GUPnPDIDLLiteObject
*
* Get the pointer to object node in XML document.
*
* Returns: (transfer none): The pointer to object node in XML document.
**/
xmlNode *
gupnp_didl_lite_object_get_xml_node (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return priv->xml_node;
}
/**
* gupnp_didl_lite_object_get_upnp_namespace:
* @object: The #GUPnPDIDLLiteObject
*
* Get the pointer to the UPnP namespace registered with the XML document.
*
* Returns: (transfer none): The pointer to UPnP namespace in XML document.
**/
xmlNsPtr
gupnp_didl_lite_object_get_upnp_namespace (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_ns (priv->xml_doc->doc,
GUPNP_XML_NAMESPACE_UPNP,
&(priv->upnp_ns));
}
/**
* gupnp_didl_lite_object_get_dc_namespace:
* @object: The #GUPnPDIDLLiteObject
*
* Get the pointer to the DublinCore namespace registered with the XML document
* containing this object.
*
* Returns: (transfer none): The pointer to DublinCore namespace in XML document.
**/
xmlNsPtr
gupnp_didl_lite_object_get_dc_namespace (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_ns (priv->xml_doc->doc,
GUPNP_XML_NAMESPACE_DC,
&(priv->dc_ns));
}
/**
* gupnp_didl_lite_object_get_upnp_class:
* @object: The #GUPnPDIDLLiteObject
*
* Get the UPnP class of the @object.
*
* Return value: The class of @object, or %NULL.
**/
const char *
gupnp_didl_lite_object_get_upnp_class (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_element_content (priv->xml_node,
"class");
}
/**
* gupnp_didl_lite_object_get_dlna_namespace:
* @object: The #GUPnPDIDLLiteObject
*
* Get the pointer to the DLNA metadata namespace registered with the XML
* document containing this object.
*
* Returns: (transfer none): The pointer to DLNA namespace in XML document.
**/
xmlNsPtr
gupnp_didl_lite_object_get_dlna_namespace (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_ns (priv->xml_doc->doc,
GUPNP_XML_NAMESPACE_DLNA,
&(priv->dlna_ns));
}
/**
* gupnp_didl_lite_object_get_pv_namespace:
* @object: The #GUPnPDIDLLiteObject
*
* Get the pointer to the PV metadata namespace registered with the XML
* document containing this object.
*
* Returns: (transfer none): The pointer to PV namespace in XML document.
**/
xmlNsPtr
gupnp_didl_lite_object_get_pv_namespace (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_ns (priv->xml_doc->doc,
GUPNP_XML_NAMESPACE_PV,
&(priv->pv_ns));
}
/**
* gupnp_didl_lite_object_get_id:
* @object: #GUPnPDIDLLiteObject
*
* Get the ID of the @object.
*
* Return value: The ID of the @object, or %NULL.
**/
const char *
gupnp_didl_lite_object_get_id (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_attribute_content (priv->xml_node, "id");
}
/**
* gupnp_didl_lite_object_get_parent_id:
* @object: #GUPnPDIDLLiteObject
*
* Get the ID of the parent of the @object.
*
* Return value: The ID of parent of the @object, or %NULL.
**/
const char *
gupnp_didl_lite_object_get_parent_id (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_attribute_content (priv->xml_node, "parentID");
}
/**
* gupnp_didl_lite_object_get_properties:
* @object: #GUPnPDIDLLiteObject
* @name: name of the properties
*
* Use this function to retreive property nodes by name.
*
* Return value: (element-type xmlNode*) (transfer container): The list of
* property nodes by the name @property_name belonging to @object, or %NULL.
* #g_list_free the returned list after usage but do not modify the contents.
**/
GList *
gupnp_didl_lite_object_get_properties (GUPnPDIDLLiteObject *object,
const char *name)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
g_return_val_if_fail (name != NULL, NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_elements_by_name (priv->xml_node, name);
}
/**
* gupnp_didl_lite_object_is_restricted_set:
* @object: #GUPnPDIDLLiteObject
*
* Whehter the restricted attribute exists on @object
*
* Return value: #TRUE if restricted exists, #FALSE otherwise.
**/
gboolean
gupnp_didl_lite_object_is_restricted_set (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (object != NULL, FALSE);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), FALSE);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_attribute_content (priv->xml_node,
"restricted") != NULL;
}
/**
* gupnp_didl_lite_object_get_restricted:
* @object: #GUPnPDIDLLiteObject
*
* Whether the @object is restricted or not.
*
* Return value: #TRUE if @object is restricted.
**/
gboolean
gupnp_didl_lite_object_get_restricted (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), FALSE);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_boolean_attribute (priv->xml_node, "restricted");
}
/**
* gupnp_didl_lite_object_get_title:
* @object: #GUPnPDIDLLiteObject
*
* Get the title of the @object.
*
* Return value: The title of the @object, or %NULL.
**/
const char *
gupnp_didl_lite_object_get_title (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_element_content (priv->xml_node, "title");
}
/**
* gupnp_didl_lite_object_get_creator:
* @object: #GUPnPDIDLLiteObject
*
* Get the creator of the @object.
*
* Return value: The creator of the @object, or %NULL.
**/
const char *
gupnp_didl_lite_object_get_creator (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_element_content (priv->xml_node,
"creator");
}
/**
* gupnp_didl_lite_object_get_creators:
* @object: #GUPnPDIDLLiteObject
*
* Get the creators of the @object.
*
* Returns: (element-type GUPnPDIDLLiteContributor*) (transfer full): The list
* of creators belonging to @object, or %NULL.
* #g_list_free the returned list after usage and unref each object in it.
**/
GList *
gupnp_didl_lite_object_get_creators (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
return get_contributor_list_by_name (object, "creator");
}
/**
* gupnp_didl_lite_object_get_artist:
* @object: #GUPnPDIDLLiteObject
*
* Get the artist of the @object. If role is not %NULL, it is set to the role
* of the artist if available.
*
* Return value: The artist of the @object, or %NULL.
*
* Deprecated: 0.5.3: Use #gupnp_didl_lite_object_get_artists instead.
**/
const char *
gupnp_didl_lite_object_get_artist (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_element_content (priv->xml_node, "artist");
}
/**
* gupnp_didl_lite_object_get_artists:
* @object: #GUPnPDIDLLiteObject
*
* Get the artists of the @object.
*
* Returns: (element-type GUPnPDIDLLiteContributor*) (transfer full): The list
* of artists belonging to @object, or %NULL.
* #g_list_free the returned list after usage and unref each object in it.
**/
GList *
gupnp_didl_lite_object_get_artists (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
return get_contributor_list_by_name (object, "artist");
}
/**
* gupnp_didl_lite_object_get_author:
* @object: #GUPnPDIDLLiteObject
*
* Get the author of the @object.
*
* Return value: The author of the @object, or %NULL.
*
* Deprecated: 0.5.3: Use #gupnp_didl_lite_object_get_authors instead.
**/
const char *
gupnp_didl_lite_object_get_author (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_element_content (priv->xml_node, "author");
}
/**
* gupnp_didl_lite_object_get_authors:
* @object: #GUPnPDIDLLiteObject
*
* Get the authors of the @object.
*
* Returns: (element-type GUPnPDIDLLiteContributor*) (transfer full): The list
* of authors belonging to @object, or %NULL.
* #g_list_free the returned list after usage and unref each object in it.
**/
GList *
gupnp_didl_lite_object_get_authors (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
return get_contributor_list_by_name (object, "author");
}
/**
* gupnp_didl_lite_object_get_descriptors:
* @object: #GUPnPDIDLLiteObject
*
* Get the descriptors of the @object.
*
* Returns: (element-type GUPnPDIDLLiteDescriptor*) (transfer full): The list of
* descriptors belonging to @object, or %NULL.
* #g_list_free the returned list after usage and unref each object in it.
**/
GList *
gupnp_didl_lite_object_get_descriptors (GUPnPDIDLLiteObject *object)
{
GList *descriptors = NULL;
GList *ret = NULL;
GList *l;
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
descriptors = gupnp_didl_lite_object_get_properties (object, "desc");
for (l = descriptors; l; l = l->next) {
GUPnPDIDLLiteDescriptor *descriptor;
xmlNode *descriptor_node;
descriptor_node = (xmlNode *) l->data;
descriptor = gupnp_didl_lite_descriptor_new_from_xml (
descriptor_node,
priv->xml_doc);
ret = g_list_append (ret, descriptor);
}
g_list_free (descriptors);
return ret;
}
/**
* gupnp_didl_lite_object_get_genre:
* @object: #GUPnPDIDLLiteObject
*
* Get the genre of the @object.
*
* Return value: The genre of the @object, or %NULL.
**/
const char *
gupnp_didl_lite_object_get_genre (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_element_content (priv->xml_node, "genre");
}
/**
* gupnp_didl_lite_object_get_write_status:
* @object: #GUPnPDIDLLiteObject
*
* Get the write status of the @object.
*
* Return value: The write status of the @object, or %NULL.
**/
const char *
gupnp_didl_lite_object_get_write_status (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_element_content (priv->xml_node,
"writeStatus");
}
/**
* gupnp_didl_lite_object_get_album:
* @object: #GUPnPDIDLLiteObject
*
* Get the album of the @object.
*
* Return value: The album of the @object, or %NULL.
**/
const char *
gupnp_didl_lite_object_get_album (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_element_content (priv->xml_node, "album");
}
/**
* gupnp_didl_lite_object_get_album_art:
* @object: #GUPnPDIDLLiteObject
*
* Get the URI to album art of the @object.
*
* Return value: The URI to album art of the @object, or %NULL.
**/
const char *
gupnp_didl_lite_object_get_album_art (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_element_content (priv->xml_node,
"albumArtURI");
}
/**
* gupnp_didl_lite_object_get_description:
* @object: #GUPnPDIDLLiteObject
*
* Get the description of the @object.
*
* Return value: The description of the @object, or %NULL.
**/
const char *
gupnp_didl_lite_object_get_description (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_element_content (priv->xml_node,
"description");
}
/**
* gupnp_didl_lite_object_get_date:
* @object: #GUPnPDIDLLiteObject
*
* Get the date of the @object.
*
* Return value: The date of the @object, or %NULL.
**/
const char *
gupnp_didl_lite_object_get_date (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_element_content (priv->xml_node, "date");
}
/**
* gupnp_didl_lite_object_get_track_number:
* @object: #GUPnPDIDLLiteObject
*
* Get the original track number of the @object.
*
* Return value: The original track number of the @object, or -1.
**/
int
gupnp_didl_lite_object_get_track_number (GUPnPDIDLLiteObject *object)
{
const char *str;
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), -1);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
str = av_xml_util_get_child_element_content (priv->xml_node,
"originalTrackNumber");
if (str == NULL)
return -1;
return atoi (str);
}
/**
* gupnp_didl_lite_object_get_dlna_managed:
* @object: #GUPnPDIDLLiteObject
*
* Get the 'dlna:dlnaManaged' attribute of the @object.
*
* Return value: The 'dlna:dlnaManaged' attribute of the @object.
**/
GUPnPOCMFlags
gupnp_didl_lite_object_get_dlna_managed (GUPnPDIDLLiteObject *object)
{
const char *str;
GUPnPOCMFlags dlna_managed;
g_return_val_if_fail (object != NULL, GUPNP_OCM_FLAGS_NONE);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object),
GUPNP_OCM_FLAGS_NONE);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
str = av_xml_util_get_attribute_content (priv->xml_node,
"dlnaManaged");
if (str == NULL)
return GUPNP_OCM_FLAGS_NONE;
sscanf (str, "%08x", &dlna_managed);
return dlna_managed;
}
/**
* gupnp_didl_lite_object_get_update_id:
* @object: #GUPnPDIDLLiteObject
*
* Get the update ID of the @object.
*
* Return value: The update ID of the @object.
**/
guint
gupnp_didl_lite_object_get_update_id (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (object != NULL, 0);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), 0);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_uint_child_element (priv->xml_node,
"objectUpdateID",
0);
}
/**
* gupnp_didl_lite_object_update_id_is_set:
* @object: #GUPnPDIDLLiteObject
*
* Get whether the update ID of the @object is set.
*
* Return value: %TRUE if update ID is set, otherwise %FALSE
**/
gboolean
gupnp_didl_lite_object_update_id_is_set (GUPnPDIDLLiteObject *object)
{
const char *content;
g_return_val_if_fail (object != NULL, FALSE);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), FALSE);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
content = av_xml_util_get_child_element_content (priv->xml_node,
"objectUpdateID");
return content != NULL;
}
/**
* gupnp_didl_lite_object_get_resources:
* @object: #GUPnPDIDLLiteObject
*
* Use this function to retreive resources from the @object.
*
* Return value: (element-type GUPnPDIDLLiteResource*) (transfer full): The list
* of resources belonging to @object, or %NULL. #g_list_free the
* returned list after usage and unref each resource in it.
**/
GList *
gupnp_didl_lite_object_get_resources (GUPnPDIDLLiteObject *object)
{
GList *resources = NULL;
GList *res = NULL;
GList *ret = NULL;
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
resources = gupnp_didl_lite_object_get_properties (object, "res");
for (res = resources; res; res = res->next) {
GUPnPDIDLLiteResource *resource;
xmlNode *res_node;
res_node = (xmlNode *) res->data;
/* Create a resource struct out of DIDLLite XML */
resource = gupnp_didl_lite_resource_new_from_xml (res_node,
priv->xml_doc,
priv->dlna_ns,
priv->pv_ns);
ret = g_list_append (ret, resource);
}
g_list_free (resources);
return ret;
}
/**
* gupnp_didl_lite_object_get_compat_resource:
* @object: #GUPnPDIDLLiteObject
* @sink_protocol_info: The SinkProtocolInfo string from MediaRenderer
* @lenient: Enable lenient mode
*
* Use this function to get a resource from the @object that is compatible with
* any of the protocols specified in the @sink_protocol_info. The value of
* @sink_protocol_info will typically be acquired from 'Sink' argument of
* 'GetProtocolInfo' action or 'SinkProtocolInfo' state-variable of a
* ConnectionManager service.
*
* If @lenient is #TRUE, the first resource in the list is returned instead of
* %NULL if none of resources and protocols are found to be compatible.
*
* Returns: (transfer full): The resource belonging to @object that is comaptible with
* any of the protocols specified in @sink_protocol_info, or %NULL. Unref after
* usage.
**/
GUPnPDIDLLiteResource *
gupnp_didl_lite_object_get_compat_resource
(GUPnPDIDLLiteObject *object,
const char *sink_protocol_info,
gboolean lenient)
{
GUPnPDIDLLiteResource *resource = NULL;
GList *resources = NULL;
GList *compat_resources = NULL;
GList *res;
char **protocols = NULL;
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
g_return_val_if_fail (sink_protocol_info != NULL, NULL);
resources = gupnp_didl_lite_object_get_resources (object);
if (resources == NULL)
return NULL;
protocols = g_strsplit (sink_protocol_info, ",", -1);
for (res = resources;
res != NULL;
res = res->next) {
resource = (GUPnPDIDLLiteResource *) res->data;
if (is_resource_compatible (resource, protocols))
compat_resources = g_list_append (compat_resources,
resource);
}
g_strfreev (protocols);
protocols = NULL;
resource = NULL;
if (compat_resources != NULL) {
/* Try to find non-transcoded resource */
res = g_list_find_custom (compat_resources,
NULL,
(GCompareFunc)
is_non_transcoded_resource);
if (res != NULL)
resource = (GUPnPDIDLLiteResource *) res->data;
else
/* Just use the first compatible resource */
resource = (GUPnPDIDLLiteResource *)
compat_resources->data;
} else if (lenient)
/* Just use the first resource */
resource = (GUPnPDIDLLiteResource *) resources->data;
/* Unref all resources except for the one we just took */
for (res = resources; res; res = res->next)
if (res->data != resource)
g_object_unref (res->data);
g_list_free (resources);
g_list_free (compat_resources);
return resource;
}
/**
* gupnp_didl_lite_object_set_upnp_class:
* @object: The #GUPnPDIDLLiteObject
* @upnp_class: The UPnP class as string.
*
* Set the UPnP class of the @object to @upnp_class.
**/
void
gupnp_didl_lite_object_set_upnp_class (GUPnPDIDLLiteObject *object,
const char *upnp_class)
{
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
av_xml_util_set_child (priv->xml_node,
GUPNP_XML_NAMESPACE_UPNP,
&(priv->upnp_ns),
priv->xml_doc->doc,
"class",
upnp_class);
g_object_notify (G_OBJECT (object), "upnp-class");
}
/**
* gupnp_didl_lite_object_set_id:
* @object: #GUPnPDIDLLiteObject
* @id: The ID
*
* Set the ID of the @object to @id.
**/
void
gupnp_didl_lite_object_set_id (GUPnPDIDLLiteObject *object,
const char *id)
{
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
xmlSetProp (priv->xml_node,
(unsigned char *) "id",
(unsigned char *) id);
g_object_notify (G_OBJECT (object), "id");
}
/**
* gupnp_didl_lite_object_set_parent_id:
* @object: #GUPnPDIDLLiteObject
* @parent_id: The parent ID
*
* Set the ID of the parent of the @object to @parent_id.
**/
void
gupnp_didl_lite_object_set_parent_id (GUPnPDIDLLiteObject *object,
const char *parent_id)
{
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
xmlSetProp (priv->xml_node,
(unsigned char *) "parentID",
(unsigned char *) parent_id);
g_object_notify (G_OBJECT (object), "parent-id");
}
/**
* gupnp_didl_lite_object_set_restricted:
* @object: #GUPnPDIDLLiteObject
* @restricted: The restricted status
*
* Set the restricted status of @object to @restricted.
**/
void
gupnp_didl_lite_object_set_restricted (GUPnPDIDLLiteObject *object,
gboolean restricted)
{
const char *str;
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
if (restricted)
str = "1";
else
str = "0";
xmlSetProp (priv->xml_node,
(unsigned char *) "restricted",
(unsigned char *) str);
g_object_notify (G_OBJECT (object), "restricted");
}
/**
* gupnp_didl_lite_object_set_title:
* @object: #GUPnPDIDLLiteObject
* @title: The title
*
* Set the title of the @object to @title.
**/
void
gupnp_didl_lite_object_set_title (GUPnPDIDLLiteObject *object,
const char *title)
{
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
av_xml_util_set_child (priv->xml_node,
GUPNP_XML_NAMESPACE_DC,
&(priv->dc_ns),
priv->xml_doc->doc,
"title",
title);
g_object_notify (G_OBJECT (object), "title");
}
/**
* gupnp_didl_lite_object_set_creator:
* @object: #GUPnPDIDLLiteObject
* @creator: The creator
*
* Set the creator of the @object to @creator.
**/
void
gupnp_didl_lite_object_set_creator (GUPnPDIDLLiteObject *object,
const char *creator)
{
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
av_xml_util_set_child (priv->xml_node,
GUPNP_XML_NAMESPACE_DC,
&(priv->dc_ns),
priv->xml_doc->doc,
"creator",
creator);
g_object_notify (G_OBJECT (object), "creator");
}
/**
* gupnp_didl_lite_object_add_creator:
* @object: The #GUPnPDIDLLiteObject
*
* Add a new creator node to the @object and return the associated
* #GUPnPDIDLLiteContributor object.
*
* Returns: (transfer full): A new #GUPnPDIDLLiteContributor object. Unref after usage.
**/
GUPnPDIDLLiteContributor *
gupnp_didl_lite_object_add_creator (GUPnPDIDLLiteObject *object)
{
xmlNode *res_node;
g_return_val_if_fail (object != NULL, NULL);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
res_node = xmlNewChild (priv->xml_node,
priv->dc_ns,
(unsigned char *) "creator",
NULL);
return gupnp_didl_lite_contributor_new_from_xml (res_node,
priv->xml_doc);
}
/**
* gupnp_didl_lite_object_set_artist:
* @object: The #GUPnPDIDLLiteObject
* @artist: The Artist
*
* Set the Artist of the @object to @artist.
*
* Deprecated: 0.5.3: Use #gupnp_didl_lite_object_add_artist instead.
**/
void
gupnp_didl_lite_object_set_artist (GUPnPDIDLLiteObject *object,
const char *artist)
{
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
av_xml_util_set_child (priv->xml_node,
GUPNP_XML_NAMESPACE_UPNP,
&(priv->upnp_ns),
priv->xml_doc->doc,
"artist",
artist);
g_object_notify (G_OBJECT (object), "artist");
}
/**
* gupnp_didl_lite_object_add_artist:
* @object: The #GUPnPDIDLLiteObject
*
* Add a new Artist node to the @object and return the associated
* #GUPnPDIDLLiteContributor object.
*
* Returns: (transfer full): A new #GUPnPDIDLLiteContributor object. Unref after usage.
**/
GUPnPDIDLLiteContributor *
gupnp_didl_lite_object_add_artist (GUPnPDIDLLiteObject *object)
{
xmlNode *res_node;
g_return_val_if_fail (object != NULL, NULL);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
res_node = xmlNewChild (priv->xml_node,
priv->upnp_ns,
(unsigned char *) "artist",
NULL);
return gupnp_didl_lite_contributor_new_from_xml (res_node,
priv->xml_doc);
}
/**
* gupnp_didl_lite_object_set_author:
* @object: The #GUPnPDIDLLiteObject
* @author: The Author
*
* Set the Author of the @object to @author.
*
* Deprecated: 0.5.3: Use #gupnp_didl_lite_object_add_author instead.
**/
void
gupnp_didl_lite_object_set_author (GUPnPDIDLLiteObject *object,
const char *author)
{
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
av_xml_util_set_child (priv->xml_node,
GUPNP_XML_NAMESPACE_DC,
&(priv->upnp_ns),
priv->xml_doc->doc,
"author",
author);
g_object_notify (G_OBJECT (object), "author");
}
/**
* gupnp_didl_lite_object_add_author:
* @object: The #GUPnPDIDLLiteObject
*
* Add a new author node to the @object and return the associated
* #GUPnPDIDLLiteContributor object.
*
* Returns: (transfer full): A new #GUPnPDIDLLiteContributor object. Unref after usage.
**/
GUPnPDIDLLiteContributor *
gupnp_didl_lite_object_add_author (GUPnPDIDLLiteObject *object)
{
xmlNode *res_node;
g_return_val_if_fail (object != NULL, NULL);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
res_node = xmlNewChild (priv->xml_node,
priv->upnp_ns,
(unsigned char *) "author",
NULL);
return gupnp_didl_lite_contributor_new_from_xml (res_node,
priv->xml_doc);
}
/**
* gupnp_didl_lite_object_set_genre:
* @object: The #GUPnPDIDLLiteObject
* @genre: The Genre
*
* Set the genre of the @object to @genre.
**/
void
gupnp_didl_lite_object_set_genre (GUPnPDIDLLiteObject *object,
const char *genre)
{
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
av_xml_util_set_child (priv->xml_node,
GUPNP_XML_NAMESPACE_UPNP,
&(priv->upnp_ns),
priv->xml_doc->doc,
"genre",
genre);
g_object_notify (G_OBJECT (object), "genre");
}
/**
* gupnp_didl_lite_object_set_write_status:
* @object: #GUPnPDIDLLiteObject
* @write_status: The write status string
*
* Set the write status of the @object to @write_status.
**/
void
gupnp_didl_lite_object_set_write_status (GUPnPDIDLLiteObject *object,
const char *write_status)
{
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
av_xml_util_set_child (priv->xml_node,
GUPNP_XML_NAMESPACE_DC,
&(priv->dc_ns),
priv->xml_doc->doc,
"writeStatus",
write_status);
g_object_notify (G_OBJECT (object), "write-status");
}
/**
* gupnp_didl_lite_object_set_album:
* @object: #GUPnPDIDLLiteObject
* @album: The album string
*
* Set the album of the @object to @album.
**/
void
gupnp_didl_lite_object_set_album (GUPnPDIDLLiteObject *object,
const char *album)
{
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
av_xml_util_set_child (priv->xml_node,
GUPNP_XML_NAMESPACE_UPNP,
&(priv->upnp_ns),
priv->xml_doc->doc,
"album",
album);
g_object_notify (G_OBJECT (object), "album");
}
/**
* gupnp_didl_lite_object_set_album_art:
* @object: #GUPnPDIDLLiteObject
* @album_art: The URI of album art
*
* Set the URI to album art of the @object to @album_art.
**/
void
gupnp_didl_lite_object_set_album_art (GUPnPDIDLLiteObject *object,
const char *album_art)
{
xmlNode *node;
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
node = av_xml_util_set_child (priv->xml_node,
GUPNP_XML_NAMESPACE_UPNP,
&(priv->upnp_ns),
priv->xml_doc->doc,
"albumArtURI",
album_art);
av_xml_util_get_ns (priv->xml_doc->doc,
GUPNP_XML_NAMESPACE_DLNA,
&(priv->dlna_ns));
xmlSetNsProp (node,
priv->dlna_ns,
(const unsigned char *) "profileID",
(const unsigned char *) "JPEG_TN");
g_object_notify (G_OBJECT (object), "album-art");
}
/**
* gupnp_didl_lite_object_set_description:
* @object: #GUPnPDIDLLiteObject
* @description: The description string
*
* Set the description of the @object to @description.
**/
void
gupnp_didl_lite_object_set_description (GUPnPDIDLLiteObject *object,
const char *description)
{
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
av_xml_util_set_child (priv->xml_node,
GUPNP_XML_NAMESPACE_DC,
&(priv->dc_ns),
priv->xml_doc->doc,
"description",
description);
g_object_notify (G_OBJECT (object), "description");
}
/**
* gupnp_didl_lite_object_set_date:
* @object: #GUPnPDIDLLiteObject
* @date: The date string
*
* Set the date of the @object to @date.
**/
void
gupnp_didl_lite_object_set_date (GUPnPDIDLLiteObject *object,
const char *date)
{
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
av_xml_util_set_child (priv->xml_node,
GUPNP_XML_NAMESPACE_DC,
&(priv->dc_ns),
priv->xml_doc->doc,
"date",
date);
g_object_notify (G_OBJECT (object), "date");
}
/**
* gupnp_didl_lite_object_set_track_number:
* @object: #GUPnPDIDLLiteObject
* @track_number: The original track number
*
* Set the original track number of the @object to @track_number.
**/
void
gupnp_didl_lite_object_set_track_number (GUPnPDIDLLiteObject *object,
int track_number)
{
char *str;
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
str = g_strdup_printf ("%d", track_number);
av_xml_util_set_child (priv->xml_node,
GUPNP_XML_NAMESPACE_UPNP,
&(priv->upnp_ns),
priv->xml_doc->doc,
"originalTrackNumber",
str);
g_free (str);
g_object_notify (G_OBJECT (object), "track-number");
}
/**
* gupnp_didl_lite_object_set_dlna_managed:
* @object: #GUPnPDIDLLiteObject
* @dlna_managed: The #GUPnPOCMFlags.
*
* Set the 'dlna:dlnaManaged' attribute of the @object to @dlna_managed.
**/
void
gupnp_didl_lite_object_set_dlna_managed (GUPnPDIDLLiteObject *object,
GUPnPOCMFlags dlna_managed)
{
char *str;
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
av_xml_util_get_ns (priv->xml_doc->doc,
GUPNP_XML_NAMESPACE_DLNA,
&(priv->dlna_ns));
str = g_strdup_printf ("%08x", dlna_managed);
xmlSetNsProp (priv->xml_node,
priv->dlna_ns,
(xmlChar *) "dlnaManaged",
(xmlChar *) str);
g_free (str);
g_object_notify (G_OBJECT (object), "dlna-managed");
}
/**
* gupnp_didl_lite_object_set_update_id:
* @object: #GUPnPDIDLLiteObject
* @update_id: Update ID
*
* Set the update ID of the @object.
**/
void
gupnp_didl_lite_object_set_update_id (GUPnPDIDLLiteObject *object,
guint update_id)
{
char *str;
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
str = g_strdup_printf ("%u", update_id);
av_xml_util_set_child (priv->xml_node,
GUPNP_XML_NAMESPACE_UPNP,
&(priv->upnp_ns),
priv->xml_doc->doc,
"objectUpdateID",
str);
g_free (str);
g_object_notify (G_OBJECT (object), "update-id");
}
/**
* gupnp_didl_lite_object_unset_update_id:
* @object: #GUPnPDIDLLiteObject
*
* Unset the update ID property of the @object.
**/
void
gupnp_didl_lite_object_unset_update_id (GUPnPDIDLLiteObject *object)
{
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
av_xml_util_unset_child (priv->xml_node,
"objectUpdateID");
g_object_notify (G_OBJECT (object), "update-id");
}
/**
* gupnp_didl_lite_object_add_resource:
* @object: A #GUPnPDIDLLiteObject
*
* Creates a new resource, attaches it to @object and returns it.
*
* Returns: (transfer full): A new #GUPnPDIDLLiteResource object. Unref after usage.
**/
GUPnPDIDLLiteResource *
gupnp_didl_lite_object_add_resource (GUPnPDIDLLiteObject *object)
{
xmlNode *res_node;
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
res_node = xmlNewChild (priv->xml_node,
NULL,
(unsigned char *) "res",
NULL);
return gupnp_didl_lite_resource_new_from_xml (res_node,
priv->xml_doc,
priv->dlna_ns,
priv->pv_ns);
}
/**
* gupnp_didl_lite_object_add_descriptor:
* @object: A #GUPnPDIDLLiteObject
*
* Creates a new descriptor, attaches it to @object and returns it.
*
* Returns: (transfer full): A new #GUPnPDIDLLiteDescriptor object. Unref after usage.
**/
GUPnPDIDLLiteDescriptor *
gupnp_didl_lite_object_add_descriptor (GUPnPDIDLLiteObject *object)
{
xmlNode *desc_node;
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
desc_node =
xmlNewChild (priv->xml_node, NULL, (xmlChar *) "desc", NULL);
return gupnp_didl_lite_descriptor_new_from_xml (desc_node,
priv->xml_doc);
}
/**
* gupnp_didl_lite_object_get_title_xml_string:
* @object: A #GUPnPDIDLLiteObject
*
* Creates a string representation of the DIDL-Lite XML fragment related to the
* object title.
*
* Return value: A DIDL-Lite XML fragment string, or %NULL. #g_free after usage.
**/
char *
gupnp_didl_lite_object_get_title_xml_string (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_string (priv->xml_node,
priv->xml_doc->doc,
"title");
}
/**
* gupnp_didl_lite_object_get_date_xml_string:
* @object: A #GUPnPDIDLLiteObject
*
* Creates a string representation of the DIDL-Lite XML fragment related to the
* object date.
*
* Return value: A DIDL-Lite XML fragment string, or %NULL. #g_free after usage.
**/
char *
gupnp_didl_lite_object_get_date_xml_string (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_string (priv->xml_node,
priv->xml_doc->doc,
"date");
}
/**
* gupnp_didl_lite_object_get_upnp_class_xml_string:
* @object: A #GUPnPDIDLLiteObject
*
* Creates a string representation of the DIDL-Lite XML fragment related to the
* object UPnP class.
*
* Return value: A DIDL-Lite XML fragment string, or %NULL. #g_free after usage.
**/
char *
gupnp_didl_lite_object_get_upnp_class_xml_string (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_string (priv->xml_node,
priv->xml_doc->doc,
"class");
}
/**
* gupnp_didl_lite_object_get_album_xml_string:
* @object: A #GUPnPDIDLLiteObject
*
* Creates a string representation of the DIDL-Lite XML fragment related to the
* object album.
*
* Return value: A DIDL-Lite XML fragment string, or %NULL. #g_free after usage.
**/
char *
gupnp_didl_lite_object_get_album_xml_string (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_string (priv->xml_node,
priv->xml_doc->doc,
"album");
}
/**
* gupnp_didl_lite_object_get_track_number_xml_string:
* @object: A #GUPnPDIDLLiteObject
*
* Creates a string representation of the DIDL-Lite XML fragment related to the
* object track number.
*
* Return value: A DIDL-Lite XML fragment string, or %NULL. #g_free after usage.
**/
char *
gupnp_didl_lite_object_get_track_number_xml_string (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
return av_xml_util_get_child_string (priv->xml_node,
priv->xml_doc->doc,
"originalTrackNumber");
}
/**
* gupnp_didl_lite_object_get_artists_xml_string:
* @object: A #GUPnPDIDLLiteObject
*
* Creates a string representation of the DIDL-Lite XML fragments related to the
* object artists.
*
* Return value: A DIDL-Lite XML fragment string, or %NULL. #g_free after usage.
**/
char *
gupnp_didl_lite_object_get_artists_xml_string (GUPnPDIDLLiteObject *object)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL);
return get_contributors_xml_string_by_name (object, "artist");
}
/**
* gupnp_didl_lite_object_unset_artists:
* @object: #GUPnPDIDLLiteObject
*
* Unset the artists properties of the @object.
**/
void
gupnp_didl_lite_object_unset_artists (GUPnPDIDLLiteObject *object)
{
g_return_if_fail (object != NULL);
g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object));
unset_contributors_by_name (object, "artist");
g_object_notify (G_OBJECT (object), "artist");
}
/* GENERAL DOCS ABOUT FRAGMENT APPLYING.
*
* The function applying fragments takes two arrays of fragments. One
* array contains current fragments and another one contains new
* fragments. Both arrays have to be of equal length and have more
* then zero elements. Each of fragments in both arrays make a pair
* (i.e. first/second/third/... fragment in current array and
* first/second/third/... fragment in new array form a pair). Each
* fragment can have zero, one or more XML elements.
*
* For each fragment pair first we check if current fragment is indeed
* a part of this object's document. If it is then we check validity
* of new fragment for applying. If it is then we replace the current
* fragment with new fragment in object's document copy and validate
* the modified document against didl-lite schema. After all fragment
* pairs are processed we replace a part describing this object in
* original document with respective one in modified document.
*
* Checking if current fragment is a part of object's document is in
* essence checking for deep equality of document's node and this
* fragment (i.e. element name and properties have to be equal, same
* for children).
*
* Checking if new fragment is valid for applying is about checking
* whether element in new fragment is either a context (i.e. both
* current element and new element are deep equal) or element
* modification (i.e. changes attributes but element name is still the
* same). There may be a case when there are more elements in current
* fragment than in new fragment then those excessive elements are
* checked whether they can be really removed. The other case is when
* there are more elements in new fragments than in current fragment -
* in such situation we check if additions are valid.
*
* By checking validity of modification, removals or additions we mean
* that no read-only properties are changed. Additionaly, for
* removals, we check if required properties are not removed.
*
* This approach may fail in some more twisted cases.
*/
/**
* gupnp_didl_lite_object_apply_fragments:
* @object: The #GUPnPDIDLLiteObject
* @current_fragments: (array length=current_size) (transfer none): XML
* fragments of @object.
* @current_size: Size of @current_fragments or -1.
* @new_fragments: (array length=new_size) (transfer none): Substitutes
* for @current_fragments.
* @new_size: Size of @new_fragments or -1.
*
* Updates object by applying @new_fragments in places of
* @current_fragments. For @current_size and @new_size -1 can be
* passed when respectively @current_fragments and @new_fragments are
* NULL terminated.
*
* Returns: Result of operation.
*/
GUPnPDIDLLiteFragmentResult
gupnp_didl_lite_object_apply_fragments (GUPnPDIDLLiteObject *object,
gchar **current_fragments,
gint current_size,
gchar **new_fragments,
gint new_size)
{
DocNode modified;
DocNode original;
GUPnPDIDLLiteFragmentResult result;
gint iter;
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object),
GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR);
g_return_val_if_fail (current_fragments != NULL,
GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_INVALID);
g_return_val_if_fail (new_fragments != NULL,
GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_INVALID);
result = GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK;
modified.doc = NULL;
if (current_size < 0)
current_size = g_strv_length (current_fragments);
if (new_size < 0)
new_size = g_strv_length (new_fragments);
if (current_size != new_size) {
result = GUPNP_DIDL_LITE_FRAGMENT_RESULT_MISMATCH;
goto out;
}
if (!current_size) {
result = GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_INVALID;
goto out;
}
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
original.doc = priv->xml_doc->doc;
original.node = priv->xml_node;
modified.doc = xmlCopyDoc (original.doc, 1);
if (modified.doc == NULL) {
result = GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR;
goto out;
}
modified.node = av_xml_util_find_node (modified.doc->children,
original.node);
if (modified.node == NULL) {
result = GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR;
goto out;
}
for (iter = 0; iter < new_size; ++iter) {
const gchar *current_fragment = current_fragments[iter];
const gchar *new_fragment = new_fragments[iter];
result = fragment_util_check_fragments (&original,
&modified,
current_fragment,
new_fragment,
didl_lite_xsd);
if (result != GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK)
goto out;
}
if (!fragment_util_apply_modification (&priv->xml_node,
&modified))
result = GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR;
out:
if (modified.doc != NULL)
xmlFreeDoc (modified.doc);
return result;
}
/**
* gupnp_didl_lite_object_get_xml_string:
* @object: #GUPnPDIDLLiteObject
*
* Get the representation of this object as an XML string.
* Returns: (transfer full): XML representation of this object as string.
**/
char *
gupnp_didl_lite_object_get_xml_string (GUPnPDIDLLiteObject *object)
{
xmlBuffer *buffer = NULL;
char *ret = NULL;
GUPnPDIDLLiteObjectPrivate *priv;
priv = gupnp_didl_lite_object_get_instance_private (object);
buffer = xmlBufferCreate ();
xmlNodeDump (buffer, priv->xml_doc->doc, priv->xml_node, 0, 0);
ret = g_strndup ((char *) xmlBufferContent (buffer),
xmlBufferLength (buffer));
xmlBufferFree (buffer);
return ret;
}
/**
* gupnp_format_date_time_for_didl_lite:
* @date_time: DateTime to format
*
* Get the representation of DateTime as an ISO8601 string.
*
* DLNA requires a specific subset of ISO8601
* Returns: (transfer full): @date_time formatted as an ISO8601 string
*
* Since: 0.14.1
*/
char *
gupnp_format_date_time_for_didl_lite (GDateTime *date_time, gboolean date_only)
{
g_return_val_if_fail (date_time != NULL, NULL);
if (date_only) {
return g_date_time_format (date_time, "%F");
}
const char *format = "%FT%H:%M:%S";
char *base_string = g_date_time_format (date_time, format);
GString *iso_string = g_string_new (base_string);
// Check if we have sub-second precision. If so, we use that as well,
// but cannot use %f since that will use microsecond precision, but DLNA
// only allows for millisecond so we append the milliseconds manually
if (g_date_time_get_microsecond (date_time) % G_TIME_SPAN_SECOND != 0) {
g_string_append_printf (
iso_string,
".%03d",
g_date_time_get_microsecond (date_time) / 1000);
}
GTimeSpan utc_offset = g_date_time_get_utc_offset (date_time);
if (utc_offset == 0) {
g_string_append (iso_string, "Z");
} else {
char *time_zone = g_date_time_format (date_time, "%:z");
g_string_append (iso_string, time_zone);
g_free (time_zone);
}
g_free (base_string);
return g_string_free (iso_string, FALSE);
}
0707010000003A000081A4000000000000000000000001686045150000236A000000000000000000000000000000000000003500000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-object.h/*
* Copyright (C) 2009 Nokia Corporation.
* Copyright (C) 2007, 2008 OpenedHand Ltd.
* Copyright (C) 2012 Intel Corporation
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
* Jorn Baayen <jorn@openedhand.com>
* Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_OBJECT_H
#define GUPNP_DIDL_LITE_OBJECT_H
#include <stdarg.h>
#include <glib-object.h>
#include <libxml/tree.h>
#include "gupnp-didl-lite-resource.h"
#include "gupnp-didl-lite-descriptor.h"
#include "gupnp-didl-lite-contributor.h"
#include "gupnp-av-enums.h"
G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE(GUPnPDIDLLiteObject,
gupnp_didl_lite_object,
GUPNP,
DIDL_LITE_OBJECT,
GObject)
#define GUPNP_TYPE_DIDL_LITE_OBJECT \
(gupnp_didl_lite_object_get_type ())
typedef struct _GUPnPDIDLLiteObjectPrivate GUPnPDIDLLiteObjectPrivate;
struct _GUPnPDIDLLiteObjectClass {
GObjectClass parent_class;
/* future padding */
void (* _gupnp_reserved1) (void);
void (* _gupnp_reserved2) (void);
void (* _gupnp_reserved3) (void);
void (* _gupnp_reserved4) (void);
};
xmlNode *
gupnp_didl_lite_object_get_xml_node (GUPnPDIDLLiteObject *object);
xmlNsPtr
gupnp_didl_lite_object_get_upnp_namespace
(GUPnPDIDLLiteObject *object);
xmlNsPtr
gupnp_didl_lite_object_get_dc_namespace (GUPnPDIDLLiteObject *object);
xmlNsPtr
gupnp_didl_lite_object_get_dlna_namespace
(GUPnPDIDLLiteObject *object);
xmlNsPtr
gupnp_didl_lite_object_get_pv_namespace
(GUPnPDIDLLiteObject *object);
const char *
gupnp_didl_lite_object_get_upnp_class (GUPnPDIDLLiteObject *object);
const char *
gupnp_didl_lite_object_get_id (GUPnPDIDLLiteObject *object);
const char *
gupnp_didl_lite_object_get_parent_id (GUPnPDIDLLiteObject *object);
GList *
gupnp_didl_lite_object_get_properties (GUPnPDIDLLiteObject *object,
const char *name);
gboolean
gupnp_didl_lite_object_is_restricted_set (GUPnPDIDLLiteObject *object);
gboolean
gupnp_didl_lite_object_get_restricted (GUPnPDIDLLiteObject *object);
const char *
gupnp_didl_lite_object_get_title (GUPnPDIDLLiteObject *object);
const char *
gupnp_didl_lite_object_get_creator (GUPnPDIDLLiteObject *object);
#ifndef GUPNP_DISABLE_DEPRECATED
const char *
gupnp_didl_lite_object_get_artist (GUPnPDIDLLiteObject *object);
const char *
gupnp_didl_lite_object_get_author (GUPnPDIDLLiteObject *object);
#endif /* GUPNP_DISABLE_DEPRECATED */
GList *
gupnp_didl_lite_object_get_creators (GUPnPDIDLLiteObject *object);
GList *
gupnp_didl_lite_object_get_artists (GUPnPDIDLLiteObject *object);
GList *
gupnp_didl_lite_object_get_authors (GUPnPDIDLLiteObject *object);
GList *
gupnp_didl_lite_object_get_descriptors (GUPnPDIDLLiteObject *object);
const char *
gupnp_didl_lite_object_get_genre (GUPnPDIDLLiteObject *object);
const char *
gupnp_didl_lite_object_get_write_status (GUPnPDIDLLiteObject *object);
const char *
gupnp_didl_lite_object_get_album (GUPnPDIDLLiteObject *object);
const char *
gupnp_didl_lite_object_get_album_art (GUPnPDIDLLiteObject *object);
const char *
gupnp_didl_lite_object_get_description (GUPnPDIDLLiteObject *object);
const char *
gupnp_didl_lite_object_get_date (GUPnPDIDLLiteObject *object);
int
gupnp_didl_lite_object_get_track_number (GUPnPDIDLLiteObject *object);
GUPnPOCMFlags
gupnp_didl_lite_object_get_dlna_managed (GUPnPDIDLLiteObject *object);
guint
gupnp_didl_lite_object_get_update_id (GUPnPDIDLLiteObject *object);
gboolean
gupnp_didl_lite_object_update_id_is_set (GUPnPDIDLLiteObject *object);
GList *
gupnp_didl_lite_object_get_resources (GUPnPDIDLLiteObject *object);
GUPnPDIDLLiteResource *
gupnp_didl_lite_object_get_compat_resource
(GUPnPDIDLLiteObject *object,
const char
*sink_protocol_info,
gboolean lenient);
GUPnPDIDLLiteResource *
gupnp_didl_lite_object_add_resource (GUPnPDIDLLiteObject *object);
GUPnPDIDLLiteDescriptor *
gupnp_didl_lite_object_add_descriptor (GUPnPDIDLLiteObject *object);
void
gupnp_didl_lite_object_set_upnp_class (GUPnPDIDLLiteObject *object,
const char *upnp_class);
void
gupnp_didl_lite_object_set_id (GUPnPDIDLLiteObject *object,
const char *id);
void
gupnp_didl_lite_object_set_parent_id (GUPnPDIDLLiteObject *object,
const char *parent_id);
void
gupnp_didl_lite_object_set_restricted (GUPnPDIDLLiteObject *object,
gboolean restricted);
void
gupnp_didl_lite_object_set_title (GUPnPDIDLLiteObject *object,
const char *title);
void
gupnp_didl_lite_object_set_creator (GUPnPDIDLLiteObject *object,
const char *creator);
#ifndef GUPNP_DISABLE_DEPRECATED
void
gupnp_didl_lite_object_set_artist (GUPnPDIDLLiteObject *object,
const char *artist);
void
gupnp_didl_lite_object_set_author (GUPnPDIDLLiteObject *object,
const char *author);
#endif /* GUPNP_DISABLE_DEPRECATED */
GUPnPDIDLLiteContributor *
gupnp_didl_lite_object_add_creator (GUPnPDIDLLiteObject *object);
GUPnPDIDLLiteContributor *
gupnp_didl_lite_object_add_artist (GUPnPDIDLLiteObject *object);
GUPnPDIDLLiteContributor *
gupnp_didl_lite_object_add_author (GUPnPDIDLLiteObject *object);
void
gupnp_didl_lite_object_set_genre (GUPnPDIDLLiteObject *object,
const char *genre);
void
gupnp_didl_lite_object_set_write_status (GUPnPDIDLLiteObject *object,
const char *write_status);
void
gupnp_didl_lite_object_set_album (GUPnPDIDLLiteObject *object,
const char *album);
void
gupnp_didl_lite_object_set_album_art (GUPnPDIDLLiteObject *object,
const char *album_art);
void
gupnp_didl_lite_object_set_description (GUPnPDIDLLiteObject *object,
const char *description);
void
gupnp_didl_lite_object_set_date (GUPnPDIDLLiteObject *object,
const char *date);
void
gupnp_didl_lite_object_set_track_number (GUPnPDIDLLiteObject *object,
int track_number);
void
gupnp_didl_lite_object_set_dlna_managed (GUPnPDIDLLiteObject *object,
GUPnPOCMFlags dlna_managed);
void
gupnp_didl_lite_object_set_update_id (GUPnPDIDLLiteObject *object,
guint update_id);
void
gupnp_didl_lite_object_unset_update_id (GUPnPDIDLLiteObject *object);
char *
gupnp_didl_lite_object_get_title_xml_string
(GUPnPDIDLLiteObject *object);
char *
gupnp_didl_lite_object_get_date_xml_string
(GUPnPDIDLLiteObject *object);
char *
gupnp_didl_lite_object_get_upnp_class_xml_string
(GUPnPDIDLLiteObject *object);
char *
gupnp_didl_lite_object_get_album_xml_string
(GUPnPDIDLLiteObject *object);
char *
gupnp_didl_lite_object_get_track_number_xml_string
(GUPnPDIDLLiteObject *object);
char *
gupnp_didl_lite_object_get_artists_xml_string
(GUPnPDIDLLiteObject *object);
void
gupnp_didl_lite_object_unset_artists (GUPnPDIDLLiteObject *object);
GUPnPDIDLLiteFragmentResult
gupnp_didl_lite_object_apply_fragments
(GUPnPDIDLLiteObject *object,
gchar **current_fragments,
gint current_size,
gchar **new_fragments,
gint new_size);
char *
gupnp_didl_lite_object_get_xml_string (GUPnPDIDLLiteObject *object);
char *
gupnp_format_date_time_for_didl_lite (GDateTime *date_time, gboolean date_only);
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_OBJECT_H__ */
0707010000003B000081A4000000000000000000000001686045150000029D000000000000000000000000000000000000003D00000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-parser-private.h/*
* Copyright (C) 2012 Intel Corporation.
*
* Authors: Jens Georg <jensg@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_PARSER_PRIVATE_H
#define GUPNP_DIDL_LITE_PARSER_PRIVATE_H
#include "gupnp-didl-lite-parser.h"
G_BEGIN_DECLS
G_GNUC_INTERNAL gboolean
gupnp_didl_lite_parser_parse_didl_recursive (GUPnPDIDLLiteParser *parser,
const char *didl,
gboolean recursive,
GError **error);
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_PARSER_PRIVATE_H__ */
0707010000003C000081A40000000000000000000000016860451500003B82000000000000000000000000000000000000003500000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-parser.c/*
* Copyright (C) 2007 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
*
* Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPDIDLLiteParser:
*
* A/V DIDL-Lite XML parser
*
* #GUPnPDIDLLiteParser parses DIDL-Lite XML strings.
*
*/
#include <config.h>
#include <string.h>
#include <ctype.h>
#include "gupnp-av.h"
#include "gupnp-didl-lite-object-private.h"
#include "xml-util.h"
#include "gupnp-didl-lite-parser-private.h"
G_DEFINE_TYPE (GUPnPDIDLLiteParser,
gupnp_didl_lite_parser,
G_TYPE_OBJECT)
enum {
OBJECT_AVAILABLE,
ITEM_AVAILABLE,
CONTAINER_AVAILABLE,
SIGNAL_LAST
};
static guint signals[SIGNAL_LAST];
static gboolean
verify_didl_attributes (xmlNode *node)
{
const char *content;
content = av_xml_util_get_child_element_content (node, "date");
if (content) {
enum {
NONE,
YEAR,
YEARMONTH_HYPHEN,
MONTH,
MONTHDAY_HYPHEN,
DAY,
END
};
/* try to roughly verify the passed date with ^\d{4}-\d{2}-\d{2} */
char *ptr = (char *) content;
int idx = 0, state = NONE;
while (*ptr) {
switch (*ptr) {
case '-':
if (state == YEAR && idx == 4)
state = YEARMONTH_HYPHEN;
else if (state == MONTH && (idx == 6 || idx == 7))
state = MONTHDAY_HYPHEN;
else
return FALSE;
break;
default:
if (!isdigit (*ptr))
return FALSE;
if (state == NONE)
state = YEAR;
else if (state == YEARMONTH_HYPHEN)
state = MONTH;
else if (state == MONTHDAY_HYPHEN)
state = DAY;
else if (state == DAY) {
if (*(ptr-1) != '-' && *(ptr-2) != '-')
return FALSE;
}
}
ptr++;
idx++;
if (*ptr == '\0') {
if (state == DAY)
break;
else
return FALSE;
}
if (idx == 10)
break;
}
}
if (av_xml_util_get_attribute_content (node, "restricted") != NULL) {
return av_xml_util_verify_attribute_is_boolean (node,
"restricted");
}
return TRUE;
}
static gboolean
parse_elements (GUPnPDIDLLiteParser *parser,
xmlNode *node,
GUPnPAVXMLDoc *xml_doc,
xmlNs *upnp_ns,
xmlNs *dc_ns,
xmlNs *dlna_ns,
xmlNs *pv_ns,
gboolean recursive,
GError **error);
static void
gupnp_didl_lite_parser_init (G_GNUC_UNUSED GUPnPDIDLLiteParser *parser)
{
}
static void
gupnp_didl_lite_parser_dispose (GObject *object)
{
GObjectClass *gobject_class;
gobject_class = G_OBJECT_CLASS (gupnp_didl_lite_parser_parent_class);
gobject_class->dispose (object);
}
static void
gupnp_didl_lite_parser_class_init (GUPnPDIDLLiteParserClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gupnp_didl_lite_parser_dispose;
/**
* GUPnPDIDLLiteParser::object-available:
* @parser: The #GUPnPDIDLLiteParser that received the signal
* @object: The now available #GUPnPDIDLLiteObject
*
* The ::object-available signal is emitted each time an object is
* found in the DIDL-Lite XML being parsed.
**/
signals[OBJECT_AVAILABLE] =
g_signal_new ("object-available",
GUPNP_TYPE_DIDL_LITE_PARSER,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GUPnPDIDLLiteParserClass,
object_available),
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
GUPNP_TYPE_DIDL_LITE_OBJECT);
/**
* GUPnPDIDLLiteParser::item-available:
* @parser: The #GUPnPDIDLLiteParser that received the signal
* @item: The now available #GUPnPDIDLLiteItem
*
* The ::item-available signal is emitted each time an item is found in
* the DIDL-Lite XML being parsed.
**/
signals[ITEM_AVAILABLE] =
g_signal_new ("item-available",
GUPNP_TYPE_DIDL_LITE_PARSER,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GUPnPDIDLLiteParserClass,
item_available),
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
GUPNP_TYPE_DIDL_LITE_ITEM);
/**
* GUPnPDIDLLiteParser::container-available:
* @parser: The #GUPnPDIDLLiteParser that received the signal
* @container: The now available #GUPnPDIDLLiteContainer
*
* The ::container-available signal is emitted each time a container is
* found in the DIDL-Lite XML being parsed.
**/
signals[CONTAINER_AVAILABLE] =
g_signal_new ("container-available",
GUPNP_TYPE_DIDL_LITE_PARSER,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GUPnPDIDLLiteParserClass,
container_available),
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
GUPNP_TYPE_DIDL_LITE_CONTAINER);
}
/**
* gupnp_didl_lite_parser_new:
*
* Return value: A new #GUPnPDIDLLiteParser object.
**/
GUPnPDIDLLiteParser *
gupnp_didl_lite_parser_new (void)
{
return g_object_new (GUPNP_TYPE_DIDL_LITE_PARSER, NULL);
}
/**
* gupnp_didl_lite_parser_parse_didl:
* @parser: A #GUPnPDIDLLiteParser
* @didl: The DIDL-Lite XML string to be parsed
* @error: The location where to store any error, or NULL
*
* Parses DIDL-Lite XML string @didl, emitting the ::object-available,
* ::item-available and ::container-available signals appropriately during the
* process.
*
* Return value: TRUE on success.
**/
gboolean
gupnp_didl_lite_parser_parse_didl (GUPnPDIDLLiteParser *parser,
const char *didl,
GError **error)
{
return gupnp_didl_lite_parser_parse_didl_recursive (parser,
didl,
FALSE,
error);
}
/**
* gupnp_didl_lite_parser_parse_didl_recursive:
* @parser: A #GUPnPDIDLLiteParser
* @didl: The DIDL-Lite XML string to be parsed
* @error: The location where to store any error, or %NULL
*
* Parses DIDL-Lite XML string @didl, emitting the ::object-available,
* ::item-available and ::container-available signals appropriately during the
* process.
*
* Return value: TRUE on success.
**/
gboolean
gupnp_didl_lite_parser_parse_didl_recursive (GUPnPDIDLLiteParser *parser,
const char *didl,
gboolean recursive,
GError **error)
{
xmlDoc *doc;
xmlNode *element;
xmlNs *upnp_ns = NULL;
xmlNs *dc_ns = NULL;
xmlNs *dlna_ns = NULL;
xmlNs *pv_ns = NULL;
GUPnPAVXMLDoc *xml_doc = NULL;
gboolean result;
doc = xmlReadMemory (didl,
strlen (didl),
NULL,
NULL,
XML_PARSE_NONET | XML_PARSE_RECOVER);
if (doc == NULL) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_PARSE,
"Could not parse DIDL-Lite XML:\n%s",
didl);
return FALSE;
}
/* Get a pointer to root element */
element = av_xml_util_get_element ((xmlNode *) doc,
"DIDL-Lite",
NULL);
if (element == NULL) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_PARSE,
"No 'DIDL-Lite' node in the DIDL-Lite XML:\n%s",
didl);
xmlFreeDoc (doc);
return FALSE;
}
if (element->children == NULL) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_EMPTY,
"Empty 'DIDL-Lite' node in the DIDL-Lite XML:\n%s",
didl);
xmlFreeDoc (doc);
return FALSE;
}
/* Create namespaces if they don't exist */
upnp_ns = av_xml_util_lookup_namespace (doc, GUPNP_XML_NAMESPACE_UPNP);
if (! upnp_ns)
upnp_ns = av_xml_util_create_namespace
(xmlDocGetRootElement (doc),
GUPNP_XML_NAMESPACE_UPNP);
dc_ns = av_xml_util_lookup_namespace (doc, GUPNP_XML_NAMESPACE_DC);
if (! dc_ns)
dc_ns = av_xml_util_create_namespace
(xmlDocGetRootElement (doc),
GUPNP_XML_NAMESPACE_DC);
dlna_ns = av_xml_util_lookup_namespace (doc, GUPNP_XML_NAMESPACE_DLNA);
if (! dlna_ns)
dlna_ns = av_xml_util_create_namespace
(xmlDocGetRootElement (doc),
GUPNP_XML_NAMESPACE_DLNA);
pv_ns = av_xml_util_lookup_namespace (doc, GUPNP_XML_NAMESPACE_PV);
if (! pv_ns)
pv_ns = av_xml_util_create_namespace
(xmlDocGetRootElement (doc),
GUPNP_XML_NAMESPACE_PV);
xml_doc = av_xml_doc_new (doc);
result = parse_elements (parser,
element,
xml_doc,
upnp_ns,
dc_ns,
dlna_ns,
pv_ns,
recursive,
error);
av_xml_doc_unref (xml_doc);
return result;
}
static gboolean
parse_elements (GUPnPDIDLLiteParser *parser,
xmlNode *node,
GUPnPAVXMLDoc *xml_doc,
xmlNs *upnp_ns,
xmlNs *dc_ns,
xmlNs *dlna_ns,
xmlNs *pv_ns,
gboolean recursive,
GError **error)
{
xmlNode *element;
for (element = node->children; element; element = element->next) {
GUPnPDIDLLiteObject *object;
object = gupnp_didl_lite_object_new_from_xml (element, xml_doc,
upnp_ns, dc_ns,
dlna_ns, pv_ns);
if (object == NULL)
continue;
if (GUPNP_IS_DIDL_LITE_CONTAINER (object)) {
g_signal_emit (parser,
signals[CONTAINER_AVAILABLE],
0,
object);
if (recursive &&
!parse_elements (parser,
element,
xml_doc,
upnp_ns,
dc_ns,
dlna_ns,
pv_ns,
recursive,
error)) {
g_object_unref (object);
return FALSE;
}
} else if (GUPNP_IS_DIDL_LITE_ITEM (object)) {
node = gupnp_didl_lite_object_get_xml_node (object);
if (!verify_didl_attributes (node)) {
g_object_unref (object);
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_PARSE,
"Could not parse DIDL-Lite XML");
return FALSE;
}
g_signal_emit (parser,
signals[ITEM_AVAILABLE],
0,
object);
}
g_signal_emit (parser,
signals[OBJECT_AVAILABLE],
0,
object);
g_object_unref (object);
}
return TRUE;
}
0707010000003D000081A400000000000000000000000168604515000006DB000000000000000000000000000000000000003500000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-parser.h/*
* Copyright (C) 2007 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
*
* Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef __GUPNP_DIDL_LITE_PARSER_H__
#define __GUPNP_DIDL_LITE_PARSER_H__
#include "gupnp-didl-lite-container.h"
#include "gupnp-didl-lite-item.h"
G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE(GUPnPDIDLLiteParser,
gupnp_didl_lite_parser,
GUPNP,
DIDL_LITE_PARSER,
GObject)
#define GUPNP_TYPE_DIDL_LITE_PARSER \
(gupnp_didl_lite_parser_get_type ())
struct _GUPnPDIDLLiteParserClass {
GObjectClass parent_class;
/* signals */
void (* object_available) (GUPnPDIDLLiteParser *parser,
GUPnPDIDLLiteObject *object);
void (* item_available) (GUPnPDIDLLiteParser *parser,
GUPnPDIDLLiteItem *item);
void (* container_available) (GUPnPDIDLLiteParser *parser,
GUPnPDIDLLiteContainer *container);
/* future padding */
void (* _gupnp_reserved1) (void);
void (* _gupnp_reserved2) (void);
void (* _gupnp_reserved3) (void);
void (* _gupnp_reserved4) (void);
void (* _gupnp_reserved5) (void);
};
GUPnPDIDLLiteParser *
gupnp_didl_lite_parser_new (void);
gboolean
gupnp_didl_lite_parser_parse_didl (GUPnPDIDLLiteParser *parser,
const char *didl,
GError **error);
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_PARSER_H__ */
0707010000003E000081A40000000000000000000000016860451500000304000000000000000000000000000000000000003F00000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-resource-private.h/*
* Copyright (C) 2009 Nokia Corporation.
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_RESOURCE_PRIVATE_H
#define GUPNP_DIDL_LITE_RESOURCE_PRIVATE_H
#include "xml-util.h"
#include "gupnp-didl-lite-resource.h"
#include <stdarg.h>
#include <glib-object.h>
#include <libxml/tree.h>
G_BEGIN_DECLS
GUPnPDIDLLiteResource *
gupnp_didl_lite_resource_new_from_xml (xmlNode *xml_node,
GUPnPAVXMLDoc *xml_doc,
xmlNs *dlna_ns,
xmlNs *pv_ns);
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_RESOURCE_PRIVATE_H__ */
0707010000003F000081A40000000000000000000000016860451500010F69000000000000000000000000000000000000003700000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-resource.c/*
* Copyright (C) 2009 Nokia Corporation.
* Copyright (C) 2007, 2008 OpenedHand Ltd.
* Copyright (C) 2012 Intel Corporation
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
* Jorn Baayen <jorn@openedhand.com>
* Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPDIDLLiteResource:
*
* DIDL-Lite Resource
*
* #GUPnPDIDLLiteResource respresent a DIDL-Lite resource (res) element.
*/
#include <config.h>
#include <string.h>
#include "gupnp-didl-lite-resource.h"
#include "gupnp-didl-lite-resource-private.h"
#include "xml-util.h"
#include "time-utils.h"
#include "xsd-data.h"
struct _GUPnPDIDLLiteResourcePrivate {
xmlNode *xml_node;
GUPnPAVXMLDoc *xml_doc;
xmlNs *dlna_ns;
xmlNs *pv_ns;
GUPnPProtocolInfo *protocol_info;
};
typedef struct _GUPnPDIDLLiteResourcePrivate GUPnPDIDLLiteResourcePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GUPnPDIDLLiteResource,
gupnp_didl_lite_resource,
G_TYPE_OBJECT)
enum {
PROP_0,
PROP_XML_NODE,
PROP_XML_DOC,
PROP_DLNA_NAMESPACE,
PROP_PV_NAMESPACE,
PROP_URI,
PROP_IMPORT_URI,
PROP_PROTOCOL_INFO,
PROP_SIZE,
PROP_SIZE64,
PROP_CLEAR_TEXT_SIZE,
PROP_DURATION,
PROP_BITRATE,
PROP_SAMPLE_FREQ,
PROP_BITS_PER_SAMPLE,
PROP_PROTECTION,
PROP_AUDIO_CHANNELS,
PROP_WIDTH,
PROP_HEIGHT,
PROP_COLOR_DEPTH,
PROP_UPDATE_COUNT,
PROP_TRACK_TOTAL,
PROP_SUBTITLE_FILE_TYPE,
PROP_SUBTITLE_FILE_URI
};
static void
get_resolution_info (xmlNodePtr xml_node, int *width, int *height)
{
const char *resolution;
char **tokens;
if (width)
*width = 0;
if (height)
*height = 0;
resolution = av_xml_util_get_attribute_content (xml_node, "resolution");
if (resolution == NULL)
return;
tokens = g_strsplit (resolution, "x", -1);
if (tokens == NULL || tokens[0] == NULL || tokens[1] == NULL) {
g_warning ("Failed to resolution string '%s'\n", resolution);
} else {
if (width)
*width = atoi (tokens[0]);
if (height)
*height = atoi (tokens[1]);
}
g_strfreev (tokens);
}
static void
on_protocol_info_changed (GUPnPProtocolInfo *info,
G_GNUC_UNUSED GParamSpec *pspec,
gpointer user_data)
{
GUPnPDIDLLiteResource *resource = GUPNP_DIDL_LITE_RESOURCE (user_data);
gupnp_didl_lite_resource_set_protocol_info (resource, info);
}
static void
gupnp_didl_lite_resource_init (GUPnPDIDLLiteResource *resource)
{
}
static void
gupnp_didl_lite_resource_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteResource *resource = GUPNP_DIDL_LITE_RESOURCE (object);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
switch (property_id) {
case PROP_XML_NODE:
priv->xml_node = g_value_get_pointer (value);
break;
case PROP_XML_DOC:
priv->xml_doc = g_value_dup_boxed (value);
break;
case PROP_URI:
gupnp_didl_lite_resource_set_uri (resource,
g_value_get_string (value));
break;
case PROP_IMPORT_URI:
gupnp_didl_lite_resource_set_import_uri
(resource,
g_value_get_string (value));
break;
case PROP_PROTOCOL_INFO:
gupnp_didl_lite_resource_set_protocol_info
(resource,
g_value_get_object (value));
break;
case PROP_SIZE:
gupnp_didl_lite_resource_set_size (resource,
g_value_get_long (value));
break;
case PROP_SIZE64:
gupnp_didl_lite_resource_set_size64 (resource,
g_value_get_int64 (value));
break;
case PROP_DLNA_NAMESPACE:
priv->dlna_ns = g_value_get_pointer (value);
break;
case PROP_PV_NAMESPACE:
priv->pv_ns = g_value_get_pointer (value);
break;
case PROP_CLEAR_TEXT_SIZE:
gupnp_didl_lite_resource_set_cleartext_size (resource,
g_value_get_int64 (value));
break;
case PROP_DURATION:
gupnp_didl_lite_resource_set_duration
(resource,
g_value_get_long (value));
break;
case PROP_BITRATE:
gupnp_didl_lite_resource_set_bitrate (resource,
g_value_get_int (value));
break;
case PROP_SAMPLE_FREQ:
gupnp_didl_lite_resource_set_sample_freq
(resource,
g_value_get_int (value));
break;
case PROP_BITS_PER_SAMPLE:
gupnp_didl_lite_resource_set_bits_per_sample
(resource,
g_value_get_int (value));
break;
case PROP_PROTECTION:
gupnp_didl_lite_resource_set_protection
(resource,
g_value_get_string (value));
break;
case PROP_AUDIO_CHANNELS:
gupnp_didl_lite_resource_set_audio_channels
(resource,
g_value_get_int (value));
break;
case PROP_WIDTH:
gupnp_didl_lite_resource_set_width (resource,
g_value_get_int (value));
break;
case PROP_HEIGHT:
gupnp_didl_lite_resource_set_height (resource,
g_value_get_int (value));
break;
case PROP_COLOR_DEPTH:
gupnp_didl_lite_resource_set_color_depth
(resource,
g_value_get_int (value));
break;
case PROP_UPDATE_COUNT:
gupnp_didl_lite_resource_set_update_count
(resource,
g_value_get_uint (value));
break;
case PROP_TRACK_TOTAL:
gupnp_didl_lite_resource_set_track_total
(resource,
g_value_get_uint (value));
break;
case PROP_SUBTITLE_FILE_TYPE:
gupnp_didl_lite_resource_set_subtitle_file_type
(resource,
g_value_get_string (value));
break;
case PROP_SUBTITLE_FILE_URI:
gupnp_didl_lite_resource_set_subtitle_file_uri
(resource,
g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_resource_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteResource *resource;
resource = GUPNP_DIDL_LITE_RESOURCE (object);
switch (property_id) {
case PROP_XML_NODE:
g_value_set_pointer
(value,
gupnp_didl_lite_resource_get_xml_node (resource));
break;
case PROP_URI:
g_value_set_string
(value,
gupnp_didl_lite_resource_get_uri (resource));
break;
case PROP_IMPORT_URI:
g_value_set_string
(value,
gupnp_didl_lite_resource_get_import_uri (resource));
break;
case PROP_PROTOCOL_INFO:
g_value_set_object
(value,
gupnp_didl_lite_resource_get_protocol_info (resource));
break;
case PROP_SIZE:
g_value_set_long (value,
gupnp_didl_lite_resource_get_size (resource));
break;
case PROP_SIZE64:
g_value_set_int64 (value,
gupnp_didl_lite_resource_get_size64 (resource));
break;
case PROP_DLNA_NAMESPACE:
g_value_set_pointer
(value,
gupnp_didl_lite_resource_get_dlna_namespace (resource));
break;
case PROP_PV_NAMESPACE:
g_value_set_pointer
(value,
gupnp_didl_lite_resource_get_pv_namespace (resource));
break;
case PROP_CLEAR_TEXT_SIZE:
g_value_set_int64
(value,
gupnp_didl_lite_resource_get_cleartext_size (resource));
break;
case PROP_DURATION:
g_value_set_long
(value,
gupnp_didl_lite_resource_get_duration (resource));
break;
case PROP_BITRATE:
g_value_set_int
(value,
gupnp_didl_lite_resource_get_bitrate (resource));
break;
case PROP_BITS_PER_SAMPLE:
g_value_set_int
(value,
gupnp_didl_lite_resource_get_bits_per_sample
(resource));
break;
case PROP_SAMPLE_FREQ:
g_value_set_int
(value,
gupnp_didl_lite_resource_get_sample_freq (resource));
break;
case PROP_PROTECTION:
g_value_set_string
(value,
gupnp_didl_lite_resource_get_protection (resource));
break;
case PROP_AUDIO_CHANNELS:
g_value_set_int
(value,
gupnp_didl_lite_resource_get_audio_channels
(resource));
break;
case PROP_WIDTH:
g_value_set_int (value,
gupnp_didl_lite_resource_get_width (resource));
break;
case PROP_HEIGHT:
g_value_set_int
(value,
gupnp_didl_lite_resource_get_height (resource));
break;
case PROP_COLOR_DEPTH:
g_value_set_int
(value,
gupnp_didl_lite_resource_get_color_depth (resource));
break;
case PROP_UPDATE_COUNT:
g_value_set_uint
(value,
gupnp_didl_lite_resource_get_update_count (resource));
break;
case PROP_TRACK_TOTAL:
g_value_set_uint
(value,
gupnp_didl_lite_resource_get_track_total (resource));
break;
case PROP_SUBTITLE_FILE_TYPE:
g_value_set_string
(value,
gupnp_didl_lite_resource_get_subtitle_file_type
(resource));
break;
case PROP_SUBTITLE_FILE_URI:
g_value_set_string
(value,
gupnp_didl_lite_resource_get_subtitle_file_uri
(resource));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_resource_dispose (GObject *object)
{
GObjectClass *object_class;
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (
GUPNP_DIDL_LITE_RESOURCE (object));
g_clear_pointer (&priv->xml_doc, av_xml_doc_unref);
g_clear_object (&priv->protocol_info);
object_class = G_OBJECT_CLASS (gupnp_didl_lite_resource_parent_class);
object_class->dispose (object);
}
static void
gupnp_didl_lite_resource_class_init (GUPnPDIDLLiteResourceClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->set_property = gupnp_didl_lite_resource_set_property;
object_class->get_property = gupnp_didl_lite_resource_get_property;
object_class->dispose = gupnp_didl_lite_resource_dispose;
/**
* GUPnPDIDLLiteResource:xml-node:
*
* The pointer to res node in XML document.
**/
g_object_class_install_property
(object_class,
PROP_XML_NODE,
g_param_spec_pointer ("xml-node",
"XMLNode",
"The pointer to res node in XML"
" document.",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:xml-doc:
*
* The reference to XML document containing this object.
*
* Internal property.
*
* Stability: Private
**/
g_object_class_install_property
(object_class,
PROP_XML_DOC,
g_param_spec_boxed ("xml-doc",
"XMLDoc",
"The reference to XML document"
" containing this object.",
av_xml_doc_get_type (),
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:uri:
*
* The URI associated with this resource.
**/
g_object_class_install_property
(object_class,
PROP_URI,
g_param_spec_string ("uri",
"URI",
"The URI associated with this resource",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:import-uri:
*
* The Import URI associated with this resource.
**/
g_object_class_install_property
(object_class,
PROP_IMPORT_URI,
g_param_spec_string ("import-uri",
"ImportURI",
"The import URI associated with this"
" resource",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:protocol-info:
*
* The protocol info associated with this resource.
**/
g_object_class_install_property
(object_class,
PROP_PROTOCOL_INFO,
g_param_spec_object ("protocol-info",
"ProtocolInfo",
"The protocol info associated with this"
" resource",
GUPNP_TYPE_PROTOCOL_INFO,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:size:
*
* The size (in bytes) of this resource.
**/
g_object_class_install_property
(object_class,
PROP_SIZE,
g_param_spec_long ("size",
"Size",
"The size (in bytes) of this resource.",
-1,
G_MAXLONG,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:size64:
*
* The size (in bytes) of this resource.
**/
g_object_class_install_property
(object_class,
PROP_SIZE64,
g_param_spec_int64 ("size64",
"Size64",
"The size (in bytes) of this resource.",
-1,
G_MAXINT64,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:clearTextsize:
*
* The size (in bytes) of this resource.
**/
g_object_class_install_property
(object_class,
PROP_CLEAR_TEXT_SIZE,
g_param_spec_int64 ("cleartext-size",
"ClearTextSize",
"The clear text size (in bytes) of this resource.",
-1,
G_MAXLONG,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:dlna-namespace:
*
* Pointer to the DLNA metadata namespace registered with the
* resource object.
*
**/
g_object_class_install_property
(object_class,
PROP_DLNA_NAMESPACE,
g_param_spec_pointer ("dlna-namespace",
"XML namespace",
"Pointer to the DLNA metadata namespace "
"registered with the resource.",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:pv-namespace:
*
* Pointer to the PV metadata namespace registered with the
* resource object.
*
**/
g_object_class_install_property
(object_class,
PROP_PV_NAMESPACE,
g_param_spec_pointer ("pv-namespace",
"XML namespace",
"Pointer to the PV metadata namespace "
"registered with the resource.",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* GUPnPDIDLLiteResource:duration:
*
* The duration (in seconds) of this resource.
**/
g_object_class_install_property
(object_class,
PROP_DURATION,
g_param_spec_long ("duration",
"Duration",
"The duration (in seconds) of this"
" resource.",
-1,
G_MAXLONG,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:bitrate:
*
* The bitrate of this resource.
**/
g_object_class_install_property
(object_class,
PROP_BITRATE,
g_param_spec_int ("bitrate",
"Bitrate",
"The bitrate of this resource.",
-1,
G_MAXINT,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:sample-freq:
*
* The sample frequency of this resource.
**/
g_object_class_install_property
(object_class,
PROP_SAMPLE_FREQ,
g_param_spec_int ("sample-freq",
"SampleFrequency",
"The sample frequency of this resource.",
-1,
G_MAXINT,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:bits-per-sample:
*
* The sample size of this resource.
**/
g_object_class_install_property
(object_class,
PROP_BITS_PER_SAMPLE,
g_param_spec_int ("bits-per-sample",
"BitsPerSample",
"The sample size of this resource.",
-1,
G_MAXINT,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:protection:
*
* The protection system used for this resource.
**/
g_object_class_install_property
(object_class,
PROP_PROTECTION,
g_param_spec_string ("protection",
"Protection",
"The protection system used by this"
" resource.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:audio-channels:
*
* The number of audio channels in this resource.
**/
g_object_class_install_property
(object_class,
PROP_AUDIO_CHANNELS,
g_param_spec_int ("audio-channels",
"AudioChannels",
"The number of audio channels in this"
" resource.",
-1,
G_MAXINT,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:width:
*
* The width of this image/video resource.
**/
g_object_class_install_property
(object_class,
PROP_WIDTH,
g_param_spec_int ("width",
"Width",
"The width of this image/video resource.",
-1,
G_MAXINT,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:height:
*
* The height of this image/video resource.
**/
g_object_class_install_property
(object_class,
PROP_HEIGHT,
g_param_spec_int ("height",
"Height",
"The height of this image/video resource.",
-1,
G_MAXINT,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:color-depth:
*
* The color-depth of this image/video resource.
**/
g_object_class_install_property
(object_class,
PROP_COLOR_DEPTH,
g_param_spec_int ("color-depth",
"ColorDepth",
"The color-depth of this image/video"
" resource.",
-1,
G_MAXINT,
-1,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:update_count:
*
* The update count of this resource.
**/
g_object_class_install_property
(object_class,
PROP_UPDATE_COUNT,
g_param_spec_uint ("update-count",
"UpdateCount",
"The update count of this resource.",
0,
G_MAXUINT,
0,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteResource:track-total:
*
* Number of tracks in a DIDL_S or DIDL_V resource.
**/
g_object_class_install_property
(object_class,
PROP_TRACK_TOTAL,
g_param_spec_uint ("track-total",
"TrackTotal",
"The number of tracks of this "
"resource.",
0,
G_MAXUINT,
0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* GUPnPDIDLLiteResource:subtitle-file-type:
*
* Type of external subtitle file. Usually SRT or SMI.
**/
g_object_class_install_property
(object_class,
PROP_SUBTITLE_FILE_TYPE,
g_param_spec_string ("subtitle-file-type",
"Subtitle file type",
"Type of the external subtitle "
"file",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* GUPnPDIDLLiteResource:subtitle-file-uri:
*
* Uri to external subtitle file.
**/
g_object_class_install_property
(object_class,
PROP_SUBTITLE_FILE_TYPE,
g_param_spec_string ("subtitle-file-uri",
"Subtitle file uri",
"Uri of the external subtitle "
"file",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}
/**
* gupnp_didl_lite_resource_new_from_xml:
* @xml_node: The pointer to 'res' node in XML document
* @xml_doc: The reference to XML document containing this resource
*
* Creates a new #GUPnPDIDLLiteResource for the @xml_node.
*
* Return value: A new #GUPnPDIDLLiteResource object. Unref after usage.
**/
GUPnPDIDLLiteResource *
gupnp_didl_lite_resource_new_from_xml (xmlNode *xml_node,
GUPnPAVXMLDoc *xml_doc,
xmlNs *dlna_ns,
xmlNs *pv_ns)
{
return g_object_new (GUPNP_TYPE_DIDL_LITE_RESOURCE,
"xml-node", xml_node,
"xml-doc", xml_doc,
"dlna-namespace", dlna_ns,
"pv-namespace", pv_ns,
NULL);
}
/**
* gupnp_didl_lite_resource_get_xml_node:
* @resource: The #GUPnPDIDLLiteResource
*
* Get the pointer to res node in XML document.
*
* Returns: (transfer none): The pointer to res node in XML document.
**/
xmlNode *
gupnp_didl_lite_resource_get_xml_node (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), NULL);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return priv->xml_node;
}
/**
* gupnp_didl_lite_resource_get_dlna_namespace:
* @resource: The #GUPnPDIDLLiteObject
*
* Get the pointer to the DLNA metadata namespace registered with the XML
* document containing this object.
*
* Returns: (transfer none): The pointer to DLNA namespace in XML document.
**/
xmlNsPtr
gupnp_didl_lite_resource_get_dlna_namespace (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), NULL);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return priv->dlna_ns;
}
/**
* gupnp_didl_lite_resource_get_pv_namespace:
* @resource: The #GUPnPDIDLLiteObject
*
* Get the pointer to the DLNA metadata namespace registered with the XML
* document containing this object.
*
* Returns: (transfer none): The pointer to DLNA namespace in XML document.
**/
xmlNsPtr
gupnp_didl_lite_resource_get_pv_namespace (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), NULL);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return priv->pv_ns;
}
/**
* gupnp_didl_lite_resource_get_uri:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the URI associated with the @resource.
*
* Return value:(transfer none)(nullable): The of URI the @resource or %NULL.
**/
const char *
gupnp_didl_lite_resource_get_uri (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), NULL);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
if (G_UNLIKELY (priv->xml_node->children == NULL))
return NULL;
return (const char *) priv->xml_node->children->content;
}
/**
* gupnp_didl_lite_resource_get_import_uri:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the import URI associated with the @resource.
*
* Return value: The import URI or %NULL.
**/
const char *
gupnp_didl_lite_resource_get_import_uri (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), NULL);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_attribute_content (priv->xml_node, "importUri");
}
/**
* gupnp_didl_lite_resource_get_protocol_info:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the protocol info associated with the @resource.
*
* Returns: (transfer none)(nullable): The protocol info associated with the
* @resource or %NULL. The returned object must not be unrefed.
**/
GUPnPProtocolInfo *
gupnp_didl_lite_resource_get_protocol_info (GUPnPDIDLLiteResource *resource)
{
GUPnPProtocolInfo *info;
const char *protocol_info;
GError *error;
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), NULL);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
if (priv->protocol_info != NULL)
return priv->protocol_info;
protocol_info = av_xml_util_get_attribute_content (priv->xml_node,
"protocolInfo");
if (protocol_info == NULL)
return NULL;
error = NULL;
info = gupnp_protocol_info_new_from_string (protocol_info, &error);
if (info == NULL) {
g_warning ("Error parsing protocolInfo '%s': %s",
protocol_info,
error->message);
g_error_free (error);
}
priv->protocol_info = info;
return info;
}
/**
* gupnp_didl_lite_resource_get_size:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the size (in bytes) of the @resource.
*
* Return value: The size (in bytes) of the @resource or -1.
**/
glong
gupnp_didl_lite_resource_get_size (GUPnPDIDLLiteResource *resource)
{
return (glong) gupnp_didl_lite_resource_get_size64 (resource);
}
/**
* gupnp_didl_lite_resource_get_size64:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the size (in bytes) of the @resource.
*
* Return value: The size (in bytes) of the @resource or -1.
**/
gint64
gupnp_didl_lite_resource_get_size64 (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_int64_attribute (priv->xml_node, "size", -1);
}
/**
* gupnp_didl_lite_resource_get_cleartext_size:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the size (in bytes) of the @resource.
*
* Return value: The size (in bytes) of the @resource or -1.
**/
gint64
gupnp_didl_lite_resource_get_cleartext_size (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_int64_attribute (priv->xml_node,
"cleartextSize",
-1);
}
/**
* gupnp_didl_lite_resource_get_duration:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the duration (in seconds) of the @resource.
*
* Return value: The duration (in seconds) of the @resource or -1.
**/
glong
gupnp_didl_lite_resource_get_duration (GUPnPDIDLLiteResource *resource)
{
const char *duration_str;
long duration;
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
duration_str =
av_xml_util_get_attribute_content (priv->xml_node, "duration");
duration = seconds_from_time (duration_str);
return duration;
}
/**
* gupnp_didl_lite_resource_get_bitrate:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the bitrate (in bytes per second) of the @resource.
*
* Return value: The bitrate (in bytes per second) of the @resource or -1.
**/
int
gupnp_didl_lite_resource_get_bitrate (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_long_attribute (priv->xml_node, "bitrate", -1);
}
/**
* gupnp_didl_lite_resource_get_sample_freq:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the sample frequency of the @resource.
*
* Return value: The sample frequency of the @resource or -1.
**/
int
gupnp_didl_lite_resource_get_sample_freq (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_long_attribute (priv->xml_node,
"sampleFrequency",
-1);
}
/**
* gupnp_didl_lite_resource_get_bits_per_sample:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the sample size of the @resource.
*
* Return value: The number of bits per sample of the @resource or -1.
**/
int
gupnp_didl_lite_resource_get_bits_per_sample (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_long_attribute (priv->xml_node,
"bitsPerSample",
-1);
}
/**
* gupnp_didl_lite_resource_get_protection:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the protection system used by the @resource.
*
* Return value: The protection system in use by the @resource or %NULL.
**/
const char *
gupnp_didl_lite_resource_get_protection (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), NULL);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_attribute_content (priv->xml_node, "protection");
}
/**
* gupnp_didl_lite_resource_get_audio_channels:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the number of audio channels in the @resource.
*
* Return value: The number of audio channels in the @resource or -1.
**/
int
gupnp_didl_lite_resource_get_audio_channels (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_long_attribute (priv->xml_node,
"nrAudioChannels",
-1);
}
/**
* gupnp_didl_lite_resource_get_width:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the width of this image/video resource.
*
* Return value: The width of this image/video resource or -1.
**/
int
gupnp_didl_lite_resource_get_width (GUPnPDIDLLiteResource *resource)
{
int width = -1;
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
get_resolution_info (priv->xml_node, &width, NULL);
return width;
}
/**
* gupnp_didl_lite_resource_get_height:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the height of this image/video resource.
*
* Return value: The height of the @resource or -1.
**/
int
gupnp_didl_lite_resource_get_height (GUPnPDIDLLiteResource *resource)
{
int height = -1;
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
get_resolution_info (priv->xml_node, NULL, &height);
return height;
}
/**
* gupnp_didl_lite_resource_get_color_depth:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the color-depth of this image/video resource.
*
* Return value: The color depth of the @resource or -1.
**/
int
gupnp_didl_lite_resource_get_color_depth (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_long_attribute (priv->xml_node,
"colorDepth",
-1);
}
/**
* gupnp_didl_lite_resource_get_update_count:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the update count of this resource.
*
* Return value: The update count of the @resource.
**/
guint
gupnp_didl_lite_resource_get_update_count (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), 0);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_uint_attribute (priv->xml_node,
"updateCount",
-1);
}
/**
* gupnp_didl_lite_resource_get_track_total:
* @resource: A #GUPnPDIDLLiteResource
*
* Get the total track count of this resource.
*
* Return value: The total track count of the @resource.
**/
guint
gupnp_didl_lite_resource_get_track_total (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), 0);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_uint_attribute (priv->xml_node,
"trackTotal",
-1);
}
/**
* gupnp_didl_lite_resource_update_count_is_set:
* @resource: A #GUPnPDIDLLiteResource
*
* Check whether the update count property of this resource is set.
*
* Return value: %TRUE if set, otherwise %FALSE.
**/
gboolean
gupnp_didl_lite_resource_update_count_is_set (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), FALSE);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_attribute_content (priv->xml_node,
"updateCount") != NULL;
}
/**
* gupnp_didl_lite_resource_track_total_is_set:
* @resource: A #GUPnPDIDLLiteResource
*
* Check whether the total track count property of this resource is set.
*
* Return value: %TRUE if set, otherwise %FALSE.
**/
gboolean
gupnp_didl_lite_resource_track_total_is_set (GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), FALSE);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_attribute_content (priv->xml_node,
"trackTotal") != NULL;
}
/**
* gupnp_didl_lite_resource_set_uri:
* @resource: A #GUPnPDIDLLiteResource
* @uri: The URI as string
*
* Set the URI associated with the @resource.
**/
void
gupnp_didl_lite_resource_set_uri (GUPnPDIDLLiteResource *resource,
const char *uri)
{
xmlChar *escaped;
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
g_return_if_fail (uri != NULL);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
escaped = xmlEncodeSpecialChars (priv->xml_doc->doc,
(const unsigned char *) uri);
xmlNodeSetContent (priv->xml_node, escaped);
xmlFree (escaped);
g_object_notify (G_OBJECT (resource), "uri");
}
/**
* gupnp_didl_lite_resource_set_import_uri:
* @resource: A #GUPnPDIDLLiteResource
* @import_uri: The URI as string
*
* Set the import URI associated with the @resource.
**/
void
gupnp_didl_lite_resource_set_import_uri (GUPnPDIDLLiteResource *resource,
const char *import_uri)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
// FIXME: Why is this URI not escaped?
xmlSetProp (priv->xml_node,
(unsigned char *) "importUri",
(unsigned char *) import_uri);
g_object_notify (G_OBJECT (resource), "import-uri");
}
/**
* gupnp_didl_lite_resource_set_protocol_info:
* @resource: A #GUPnPDIDLLiteResource
* @info: The protocol string
*
* Set the protocol info associated with the @resource.
**/
void
gupnp_didl_lite_resource_set_protocol_info (GUPnPDIDLLiteResource *resource,
GUPnPProtocolInfo *info)
{
char *str;
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
str = gupnp_protocol_info_to_string (info);
xmlSetProp (priv->xml_node,
(unsigned char *) "protocolInfo",
(unsigned char *) str);
g_free (str);
/* Get a ref first in case it's the same object that we already have */
g_object_ref (info);
g_clear_object (&priv->protocol_info);
priv->protocol_info = info;
/* We need to listen to changes to properties so we update the
* corresponding xml property.
*/
g_signal_handlers_disconnect_by_func (info,
(gpointer) on_protocol_info_changed,
resource);
g_signal_connect (info,
"notify",
G_CALLBACK (on_protocol_info_changed),
resource);
g_object_notify (G_OBJECT (resource), "protocol-info");
}
/**
* gupnp_didl_lite_resource_set_size:
* @resource: A #GUPnPDIDLLiteResource
* @size: The size (in bytes)
*
* Set the size (in bytes) of the @resource. Passing a negative number will
* unset this property.
**/
void
gupnp_didl_lite_resource_set_size (GUPnPDIDLLiteResource *resource,
glong size)
{
gupnp_didl_lite_resource_set_size64 (resource, size);
}
/**
* gupnp_didl_lite_resource_set_size64:
* @resource: A #GUPnPDIDLLiteResource
* @size: The size (in bytes)
*
* Set the size (in bytes) of the @resource. Passing a negative number will
* unset this property.
**/
void
gupnp_didl_lite_resource_set_size64 (GUPnPDIDLLiteResource *resource,
gint64 size)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
if (size < 0)
xmlUnsetProp (priv->xml_node, (unsigned char *) "size");
else {
char *str;
str = g_strdup_printf ("%" G_GINT64_FORMAT, size);
xmlSetProp (priv->xml_node,
(unsigned char *) "size",
(unsigned char *) str);
g_free (str);
}
g_object_notify (G_OBJECT (resource), "size64");
g_object_notify (G_OBJECT (resource), "size");
}
/**
* gupnp_didl_lite_resource_set_cleartext_size:
* @resource: A #GUPnPDIDLLiteResource
* @cleartext_size: The size (in bytes)
*
* Set the size (in bytes) of the @resource. Passing a negative number will
* unset this property.
**/
void
gupnp_didl_lite_resource_set_cleartext_size
(GUPnPDIDLLiteResource *resource,
gint64 cleartext_size)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
if (cleartext_size < 0)
xmlUnsetNsProp (priv->xml_node,
priv->dlna_ns,
(unsigned char *) "cleartextSize");
else {
char *str;
str = g_strdup_printf ("%" G_GINT64_FORMAT, cleartext_size);
av_xml_util_get_ns (priv->xml_doc->doc,
GUPNP_XML_NAMESPACE_DLNA,
&(priv->dlna_ns));
xmlSetNsProp (priv->xml_node,
priv->dlna_ns,
(unsigned char *) "cleartextSize",
(unsigned char *) str);
g_free (str);
}
g_object_notify (G_OBJECT (resource), "cleartext-size");
}
/**
* gupnp_didl_lite_resource_set_duration:
* @resource: A #GUPnPDIDLLiteResource
* @duration: The duration (in seconds)
*
* Set the duration (in seconds) of the @resource. Passing a negative number
* will unset this property.
**/
void
gupnp_didl_lite_resource_set_duration (GUPnPDIDLLiteResource *resource,
glong duration)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
if (duration < 0)
xmlUnsetProp (priv->xml_node, (unsigned char *) "duration");
else {
char *str;
str = seconds_to_time (duration);
xmlSetProp (priv->xml_node,
(unsigned char *) "duration",
(unsigned char *) str);
g_free (str);
}
g_object_notify (G_OBJECT (resource), "duration");
}
/**
* gupnp_didl_lite_resource_set_bitrate:
* @resource: A #GUPnPDIDLLiteResource
* @bitrate: The bitrate
*
* Set the bitrate (in bytes per second) of the @resource. Passing a negative
* number will unset this property.
**/
void
gupnp_didl_lite_resource_set_bitrate (GUPnPDIDLLiteResource *resource,
int bitrate)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
if (bitrate < 0)
xmlUnsetProp (priv->xml_node, (unsigned char *) "bitrate");
else {
char *str;
str = g_strdup_printf ("%d", bitrate);
xmlSetProp (priv->xml_node,
(unsigned char *) "bitrate",
(unsigned char *) str);
g_free (str);
}
g_object_notify (G_OBJECT (resource), "bitrate");
}
/**
* gupnp_didl_lite_resource_set_sample_freq:
* @resource: A #GUPnPDIDLLiteResource
* @sample_freq: The sample frequency
*
* Set the sample frequency of the @resource. Passing a negative number will
* unset this property.
**/
void
gupnp_didl_lite_resource_set_sample_freq (GUPnPDIDLLiteResource *resource,
int sample_freq)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
if (sample_freq < 0)
xmlUnsetProp (priv->xml_node,
(unsigned char *) "sampleFrequency");
else {
char *str;
str = g_strdup_printf ("%d", sample_freq);
xmlSetProp (priv->xml_node,
(unsigned char *) "sampleFrequency",
(unsigned char *) str);
g_free (str);
}
g_object_notify (G_OBJECT (resource), "sample-freq");
}
/**
* gupnp_didl_lite_resource_set_bits_per_sample:
* @resource: A #GUPnPDIDLLiteResource
* @sample_size: The number of bits per sample
*
* Set the sample size of the @resource. Passing a negative number will unset
* this property.
**/
void
gupnp_didl_lite_resource_set_bits_per_sample
(GUPnPDIDLLiteResource *resource,
int sample_size)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
if (sample_size < 0)
xmlUnsetProp (priv->xml_node,
(unsigned char *) "bitsPerSample");
else {
av_xml_util_set_prop (priv->xml_node,
"bitsPerSample",
"%d",
sample_size);
}
g_object_notify (G_OBJECT (resource), "bits-per-sample");
}
/**
* gupnp_didl_lite_resource_set_protection:
* @resource: A #GUPnPDIDLLiteResource
* @protection: The protection system identifier as string
*
* Set the protection system used by the @resource. Passing a negative number
* will unset this property.
**/
void
gupnp_didl_lite_resource_set_protection (GUPnPDIDLLiteResource *resource,
const char *protection)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
xmlSetProp (priv->xml_node,
(unsigned char *) "protection",
(unsigned char *) protection);
g_object_notify (G_OBJECT (resource), "protection");
}
/**
* gupnp_didl_lite_resource_set_audio_channels:
* @resource: A #GUPnPDIDLLiteResource
* @n_channels: The number of channels
*
* Set the number of audio channels in the @resource. Passing a negative number
* will unset this property.
**/
void
gupnp_didl_lite_resource_set_audio_channels (GUPnPDIDLLiteResource *resource,
int n_channels)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
if (n_channels < 0)
xmlUnsetProp (priv->xml_node,
(unsigned char *) "nrAudioChannels");
else {
av_xml_util_set_int_prop (priv->xml_node,
"nrAudioChannels",
n_channels);
}
g_object_notify (G_OBJECT (resource), "audio-channels");
}
/**
* gupnp_didl_lite_resource_set_width:
* @resource: A #GUPnPDIDLLiteResource
* @width: The width
*
* Set the width of this image/video resource. Setting both width and height to
* a negative number will unset the resolution property.
**/
void
gupnp_didl_lite_resource_set_width (GUPnPDIDLLiteResource *resource,
int width)
{
int height = -1;
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
get_resolution_info (priv->xml_node, NULL, &height);
if (width < 0 && height < 0)
xmlUnsetProp (priv->xml_node,
(unsigned char *) "resolution");
else {
av_xml_util_set_prop (priv->xml_node, "resolution", "%dx%d", width, height);
}
g_object_notify (G_OBJECT (resource), "width");
}
/**
* gupnp_didl_lite_resource_set_height:
* @resource: A #GUPnPDIDLLiteResource
* @height: The height
*
* Set the height of this image/video resource. Setting both width and height to
* a negative number will unset the resolution property.
**/
void
gupnp_didl_lite_resource_set_height (GUPnPDIDLLiteResource *resource,
int height)
{
int width = -1;
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
get_resolution_info (priv->xml_node, &width, NULL);
if (width < 0 && height < 0)
xmlUnsetProp (priv->xml_node,
(unsigned char *) "resolution");
else {
av_xml_util_set_prop (priv->xml_node, "resolution", "%dx%d", width, height);
}
g_object_notify (G_OBJECT (resource), "height");
}
/**
* gupnp_didl_lite_resource_set_color_depth:
* @resource: A #GUPnPDIDLLiteResource
* @color_depth: The color-depth
*
* Set the color-depth of this image/video resource. Passing a negative number
* will unset this property.
**/
void
gupnp_didl_lite_resource_set_color_depth (GUPnPDIDLLiteResource *resource,
int color_depth)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
if (color_depth < 0)
xmlUnsetProp (priv->xml_node, (unsigned char *) "colorDepth");
else {
av_xml_util_set_prop (priv->xml_node,
"colorDepth",
"%d",
color_depth);
}
g_object_notify (G_OBJECT (resource), "color-depth");
}
/**
* gupnp_didl_lite_resource_set_update_count:
* @resource: A #GUPnPDIDLLiteResource
* @update_count: The update_count
*
* Set the update count of this resource.
**/
void
gupnp_didl_lite_resource_set_update_count (GUPnPDIDLLiteResource *resource,
guint update_count)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
av_xml_util_set_prop (priv->xml_node,
"updateCount",
"%u",
update_count);
g_object_notify (G_OBJECT (resource), "update-count");
}
/**
* gupnp_didl_lite_resource_set_track_total:
* @resource: A #GUPnPDIDLLiteResource
* @track_total: The total number of tracks in this resource
*
* Set the total number of tracks in this resource.
**/
void
gupnp_didl_lite_resource_set_track_total (GUPnPDIDLLiteResource *resource,
guint track_total)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
av_xml_util_get_ns (priv->xml_doc->doc,
GUPNP_XML_NAMESPACE_DLNA,
&(priv->dlna_ns));
av_xml_util_set_ns_prop (priv->xml_node,
priv->dlna_ns,
"trackTotal",
"%u",
track_total);
g_object_notify (G_OBJECT (resource), "track-total");
}
/**
* gupnp_didl_lite_resource_unset_update_count:
* @resource: A #GUPnPDIDLLiteResource
*
* Unset the update count of this resource.
**/
void
gupnp_didl_lite_resource_unset_update_count (GUPnPDIDLLiteResource *resource)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
xmlUnsetProp (priv->xml_node, (unsigned char *) "updateCount");
g_object_notify (G_OBJECT (resource), "update-count");
}
/**
* gupnp_didl_lite_resource_unset_track_total:
* @resource: A #GUPnPDIDLLiteResource
*
* Unset the total track count of this resource.
**/
void
gupnp_didl_lite_resource_unset_track_total (GUPnPDIDLLiteResource *resource)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
av_xml_util_get_ns (priv->xml_doc->doc,
GUPNP_XML_NAMESPACE_DLNA,
&(priv->dlna_ns));
xmlUnsetNsProp (priv->xml_node,
priv->dlna_ns,
(unsigned char *) "trackTotal");
g_object_notify (G_OBJECT (resource), "track-total");
}
/**
* gupnp_didl_lite_resource_get_subtitle_file_uri:
* @resource: A #GUPnPDIDLLiteResource
*
* Returns: The content of the subtitleFileUri property or %NULL when not set.
*
* Since: 0.12.4
**/
const char *
gupnp_didl_lite_resource_get_subtitle_file_uri
(GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), NULL);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_attribute_content (priv->xml_node,
"subtitleFileUri");
}
/**
* gupnp_didl_lite_resource_get_subtitle_file_type:
* @resource: A #GUPnPDIDLLiteResource
*
* Returns: The content of the subtitleFileType property or %NULL
*
* Since: 0.12.4
**/
const char *
gupnp_didl_lite_resource_get_subtitle_file_type
(GUPnPDIDLLiteResource *resource)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), NULL);
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
return av_xml_util_get_attribute_content (priv->xml_node,
"subtitleFileType");
}
/**
* gupnp_didl_lite_resource_set_subtitle_file_uri:
* @resource: A #GUPnPDIDLLiteResource
* @uri: (allow-none): An URI to an external subtitle file or %NULL to remove.
*
* Set the URI of an external subtitle file to be used with this resource.
* When @uri is %NULL the value is removed.
*
* Since: 0.12.4
**/
void
gupnp_didl_lite_resource_set_subtitle_file_uri
(GUPnPDIDLLiteResource *resource,
const char *uri)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
if (uri == NULL)
xmlUnsetNsProp (priv->xml_node,
priv->pv_ns,
(unsigned char *) "subtitleFileUri");
else {
av_xml_util_get_ns (priv->xml_doc->doc,
GUPNP_XML_NAMESPACE_PV,
&(priv->pv_ns));
xmlSetNsProp (priv->xml_node,
priv->pv_ns,
(unsigned char *) "subtitleFileUri",
(xmlChar *) uri);
}
g_object_notify (G_OBJECT (resource), "subtitle-file-uri");
}
/**
* gupnp_didl_lite_resource_set_subtitle_file_type:
* @resource: A #GUPnPDIDLLiteResource
* @type: (allow-none): An URI to an external subtitle file
*
* Set the type of an external subtitle file, specified via
* pv:subtitleFileUri using gupnp_didl_lite_resource_set_subtitle_file_uri().
*
* When @type is %NULL the value is removed.
*
* Since: 0.12.4
**/
void
gupnp_didl_lite_resource_set_subtitle_file_type
(GUPnPDIDLLiteResource *resource,
const char *type)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
GUPnPDIDLLiteResourcePrivate *priv =
gupnp_didl_lite_resource_get_instance_private (resource);
if (type == NULL)
xmlUnsetNsProp (priv->xml_node,
priv->pv_ns,
(unsigned char *) "subtitleFileType");
else {
av_xml_util_get_ns (priv->xml_doc->doc,
GUPNP_XML_NAMESPACE_PV,
&(priv->pv_ns));
xmlSetNsProp (priv->xml_node,
priv->pv_ns,
(unsigned char *) "subtitleFileType",
(xmlChar *) type);
}
g_object_notify (G_OBJECT (resource), "subtitle-file-type");
}
07070100000040000081A40000000000000000000000016860451500001D6A000000000000000000000000000000000000003700000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-resource.h/*
* Copyright (C) 2009 Nokia Corporation.
* Copyright (C) 2007, 2008 OpenedHand Ltd.
* Copyright (C) 2012 Intel Corporation
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
* Jorn Baayen <jorn@openedhand.com>
* Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_RESOURCE_H
#define GUPNP_DIDL_LITE_RESOURCE_H
#include <stdarg.h>
#include <glib-object.h>
#include <glib.h>
#include <libxml/tree.h>
#include "gupnp-dlna.h"
#include "gupnp-protocol-info.h"
G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE(GUPnPDIDLLiteResource,
gupnp_didl_lite_resource,
GUPNP,
DIDL_LITE_RESOURCE,
GObject)
#define GUPNP_TYPE_DIDL_LITE_RESOURCE \
(gupnp_didl_lite_resource_get_type ())
struct _GUPnPDIDLLiteResourceClass {
GObjectClass parent_class;
/* future padding */
void (* _gupnp_reserved1) (void);
void (* _gupnp_reserved2) (void);
void (* _gupnp_reserved3) (void);
void (* _gupnp_reserved4) (void);
};
void
gupnp_didl_lite_resource_set_uri (GUPnPDIDLLiteResource *resource,
const char *uri);
void
gupnp_didl_lite_resource_set_import_uri (GUPnPDIDLLiteResource *resource,
const char *import_uri);
void
gupnp_didl_lite_resource_set_protocol_info
(GUPnPDIDLLiteResource *resource,
GUPnPProtocolInfo *info);
void
gupnp_didl_lite_resource_set_size (GUPnPDIDLLiteResource *resource,
glong size);
void
gupnp_didl_lite_resource_set_size64 (GUPnPDIDLLiteResource *resource,
gint64 size);
void
gupnp_didl_lite_resource_set_cleartext_size
(GUPnPDIDLLiteResource *resource,
gint64 cleartext_size);
void
gupnp_didl_lite_resource_set_duration (GUPnPDIDLLiteResource *resource,
glong duration);
void
gupnp_didl_lite_resource_set_bitrate (GUPnPDIDLLiteResource *resource,
int bitrate);
void
gupnp_didl_lite_resource_set_sample_freq
(GUPnPDIDLLiteResource *resource,
int sample_freq);
void
gupnp_didl_lite_resource_set_bits_per_sample
(GUPnPDIDLLiteResource *resource,
int sample_size);
void
gupnp_didl_lite_resource_set_protection (GUPnPDIDLLiteResource *resource,
const char *protection);
void
gupnp_didl_lite_resource_set_audio_channels
(GUPnPDIDLLiteResource *resource,
int n_channels);
void
gupnp_didl_lite_resource_set_width (GUPnPDIDLLiteResource *resource,
int width);
void
gupnp_didl_lite_resource_set_height (GUPnPDIDLLiteResource *resource,
int height);
void
gupnp_didl_lite_resource_set_color_depth
(GUPnPDIDLLiteResource *resource,
int color_depth);
void
gupnp_didl_lite_resource_set_update_count
(GUPnPDIDLLiteResource *resource,
guint update_count);
void
gupnp_didl_lite_resource_set_track_total
(GUPnPDIDLLiteResource *resource,
guint track_total);
void
gupnp_didl_lite_resource_unset_track_total
(GUPnPDIDLLiteResource *resource);
void
gupnp_didl_lite_resource_unset_update_count
(GUPnPDIDLLiteResource *resource);
void
gupnp_didl_lite_resource_set_subtitle_file_uri
(GUPnPDIDLLiteResource *resource,
const char *uri);
void
gupnp_didl_lite_resource_set_subtitle_file_type
(GUPnPDIDLLiteResource *resource,
const char *type);
xmlNode *
gupnp_didl_lite_resource_get_xml_node (GUPnPDIDLLiteResource *resource);
xmlNsPtr
gupnp_didl_lite_resource_get_dlna_namespace
(GUPnPDIDLLiteResource *resource);
xmlNsPtr
gupnp_didl_lite_resource_get_pv_namespace
(GUPnPDIDLLiteResource *resource);
const char *
gupnp_didl_lite_resource_get_uri (GUPnPDIDLLiteResource *resource);
const char *
gupnp_didl_lite_resource_get_import_uri (GUPnPDIDLLiteResource *resource);
GUPnPProtocolInfo *
gupnp_didl_lite_resource_get_protocol_info
(GUPnPDIDLLiteResource *resource);
long
gupnp_didl_lite_resource_get_size (GUPnPDIDLLiteResource *resource);
gint64
gupnp_didl_lite_resource_get_size64 (GUPnPDIDLLiteResource *resource);
gint64
gupnp_didl_lite_resource_get_cleartext_size
(GUPnPDIDLLiteResource *resource);
long
gupnp_didl_lite_resource_get_duration (GUPnPDIDLLiteResource *resource);
int
gupnp_didl_lite_resource_get_bitrate (GUPnPDIDLLiteResource *resource);
int
gupnp_didl_lite_resource_get_sample_freq
(GUPnPDIDLLiteResource *resource);
int
gupnp_didl_lite_resource_get_bits_per_sample
(GUPnPDIDLLiteResource *resource);
const char *
gupnp_didl_lite_resource_get_protection (GUPnPDIDLLiteResource *resource);
int
gupnp_didl_lite_resource_get_audio_channels
(GUPnPDIDLLiteResource *resource);
int
gupnp_didl_lite_resource_get_width (GUPnPDIDLLiteResource *resource);
int
gupnp_didl_lite_resource_get_height (GUPnPDIDLLiteResource *resource);
int
gupnp_didl_lite_resource_get_color_depth
(GUPnPDIDLLiteResource *resource);
guint
gupnp_didl_lite_resource_get_update_count
(GUPnPDIDLLiteResource *resource);
gboolean
gupnp_didl_lite_resource_update_count_is_set
(GUPnPDIDLLiteResource *resource);
guint
gupnp_didl_lite_resource_get_track_total
(GUPnPDIDLLiteResource *resource);
gboolean
gupnp_didl_lite_resource_track_total_is_set
(GUPnPDIDLLiteResource *resource);
const char *
gupnp_didl_lite_resource_get_subtitle_file_uri
(GUPnPDIDLLiteResource *resource);
const char *
gupnp_didl_lite_resource_get_subtitle_file_type
(GUPnPDIDLLiteResource *resource);
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_RESOURCE_H__ */
07070100000041000081A40000000000000000000000016860451500000314000000000000000000000000000000000000003D00000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-writer-private.h/*
* Copyright (C) 2012 Intel Corporation.
*
* Authors: Jens Georg <jensg@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_WRITER_PRIVATE_H
#define GUPNP_DIDL_LITE_WRITER_PRIVATE_H
#include "gupnp-didl-lite-writer.h"
#include "gupnp-didl-lite-container.h"
G_BEGIN_DECLS
G_GNUC_INTERNAL GUPnPDIDLLiteItem *
gupnp_didl_lite_writer_add_container_child_item
(GUPnPDIDLLiteWriter *writer,
GUPnPDIDLLiteContainer *container);
G_GNUC_INTERNAL void
gupnp_didl_lite_writer_filter_tags (GUPnPDIDLLiteWriter *writer,
const char *filter);
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_WRITER_PRIVATE_H__ */
07070100000042000081A40000000000000000000000016860451500005A42000000000000000000000000000000000000003500000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-writer.c/*
* Copyright (C) 2007, 2008 OpenedHand Ltd.
* Copyright (C) 2012 Intel Corporation.
*
* Authors: Jorn Baayen <jorn@openedhand.com>
* Jens Georg <jensg@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPDIDLLiteWriter:
*
* DIDL-Lite fragment writer
*
* #GUPnPDIDLLiteWriter is a helper class for writing DIDL-Lite fragments.
*/
#include <config.h>
#include <string.h>
#include "gupnp-didl-lite-writer.h"
#include "gupnp-didl-lite-object.h"
#include "gupnp-didl-lite-object-private.h"
#include "gupnp-didl-lite-descriptor-private.h"
#include "gupnp-didl-lite-writer-private.h"
#include "xml-util.h"
struct _GUPnPDIDLLiteWriterPrivate {
xmlNode *xml_node;
GUPnPAVXMLDoc *xml_doc;
xmlNs *upnp_ns;
xmlNs *dc_ns;
xmlNs *dlna_ns;
xmlNs *pv_ns;
char *language;
};
typedef struct _GUPnPDIDLLiteWriterPrivate GUPnPDIDLLiteWriterPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GUPnPDIDLLiteWriter,
gupnp_didl_lite_writer,
G_TYPE_OBJECT)
enum {
PROP_0,
PROP_XML_NODE,
PROP_LANGUAGE,
};
static int
compare_prop (const char *a, xmlAttr *attr)
{
const char *p;
char *parent_name;
char *attr_name;
int ret = -1;
if (attr->ns != NULL)
attr_name = g_strjoin (":", attr->ns->prefix, attr->name, NULL);
else
attr_name = g_strdup ((const char *) attr->name);
if (attr->parent->ns != NULL)
parent_name = g_strjoin (":",
attr->parent->ns->prefix,
attr->parent->name,
NULL);
else
parent_name = g_strdup ((const char *) attr->parent->name);
p = strstr (a, "@");
if (p)
if (p == a)
/* Top-level property */
ret = strcmp (a + 1, attr_name);
else
ret = strncmp (a, parent_name, p - a) ||
strcmp (p + 1, attr_name);
else
ret = strcmp (a, attr_name);
g_free (attr_name);
g_free (parent_name);
return ret;
}
static gboolean
is_attribute_forbidden (xmlAttr *attr,
GList *allowed)
{
return g_list_find_custom (allowed,
attr,
(GCompareFunc) compare_prop) == NULL;
}
static int
compare_node_name (const char *a, const char *b)
{
const char *p;
int len, result;
if (a[0] == '@')
/* Filter is for top-level property */
return -1;
p = strstr (a, "@");
if (p != NULL)
/* Compare only the string before '@' */
len = p - a;
else
len = strlen (a);
result = strncmp (a, b, len);
if (result == 0) {
/* Avoid that we return a match although only prefixes match like
* in upnp:album and upnp:albumArtUri, cf. bgo#687462 */
return strlen (b) - len;
}
return result;
}
static gboolean
is_node_forbidden (xmlNode *node,
GList *allowed,
const char *ns)
{
char *name;
gboolean ret;
if (ns != NULL)
name = g_strjoin (":", ns, node->name, NULL);
else
name = g_strdup ((const char *) node->name);
ret = g_list_find_custom (allowed,
name,
(GCompareFunc) compare_node_name) == NULL;
g_free (name);
return ret;
}
static gboolean
is_container_standard_prop (const char *name,
const char *namespace,
const char *upnp_class)
{
return g_strcmp0 (upnp_class, "object.container.storageFolder") == 0 &&
g_strcmp0 (namespace, "upnp") == 0 &&
strcmp (name, "storageUsed") == 0;
}
static gboolean
is_standard_prop (const char *name,
const char *namespace,
const char *parent_name)
{
return strcmp (name, "id") == 0 ||
strcmp (name, "parentID") == 0 ||
strcmp (name, "restricted") == 0 ||
strcmp (name, "refID") == 0 ||
(g_strcmp0 (namespace, "dc") == 0 &&
strcmp (name, "title") == 0) ||
(g_strcmp0 (namespace, "upnp") == 0 &&
strcmp (name, "class") == 0) ||
(g_strcmp0 (parent_name, "res") == 0 &&
strcmp (name, "protocolInfo") == 0);
}
static void
filter_attributes (xmlNode *node,
GList *allowed)
{
xmlAttr *attr;
GList *forbidden = NULL;
GList *l;
/* Find forbidden properties */
for (attr = node->properties; attr != NULL; attr = attr->next)
if (!is_standard_prop ((const char *) attr->name,
NULL,
(const char *) attr->parent->name) &&
is_attribute_forbidden (attr, allowed))
forbidden = g_list_append (forbidden, attr);
/* Now unset forbidden properties */
for (l = forbidden; l != NULL; l = l->next)
xmlRemoveProp ((xmlAttr *) l->data);
g_list_free (forbidden);
}
static void
filter_node (xmlNode *node,
GList *allowed,
gboolean tags_only)
{
xmlNode *child;
GList *forbidden = NULL;
GList *l;
gboolean is_container = FALSE;
const char *container_class = NULL;
if (!tags_only)
filter_attributes (node, allowed);
if (strcmp ((const char *) node->name, "container") == 0) {
is_container = TRUE;
container_class = av_xml_util_get_child_element_content
(node, "class");
}
forbidden = NULL;
for (child = node->children; child != NULL; child = child->next) {
const char *ns = NULL;
if (xmlNodeIsText (child))
continue;
if (child->ns != NULL)
ns = (const char *) child->ns->prefix;
if (!(is_container && is_container_standard_prop
((const char *) child->name,
ns,
container_class)) &&
!is_standard_prop ((const char *) child->name,
ns,
(const char *) node->name) &&
is_node_forbidden (child, allowed, ns))
forbidden = g_list_append (forbidden, child);
}
/* Now remove the forbidden nodes */
for (l = forbidden; l != NULL; l = l->next) {
xmlNode *n;
n = (xmlNode *) l->data;
xmlUnlinkNode (n);
xmlFreeNode (n);
}
g_list_free (forbidden);
/* Recurse */
for (child = node->children; child != NULL; child = child->next)
if (!xmlNodeIsText (child))
filter_node (child, allowed, tags_only);
}
static void
apply_filter (GUPnPDIDLLiteWriter *writer,
const char *filter,
gboolean tags_only)
{
char **tokens;
GList *allowed = NULL;
unsigned short i;
xmlNode *node;
g_return_if_fail (GUPNP_IS_DIDL_LITE_WRITER (writer));
g_return_if_fail (filter != NULL);
GUPnPDIDLLiteWriterPrivate *priv =
gupnp_didl_lite_writer_get_instance_private (writer);
if (filter[0] == '*')
return; /* Wildcard */
tokens = g_strsplit (filter, ",", -1);
g_return_if_fail (tokens != NULL);
for (i = 0; tokens[i] != NULL; i++)
allowed = g_list_append (allowed, tokens[i]);
for (node = priv->xml_node->children; node != NULL; node = node->next)
filter_node (node, allowed, tags_only);
g_list_free (allowed);
g_strfreev (tokens);
}
static void
gupnp_didl_lite_writer_init (GUPnPDIDLLiteWriter *writer)
{
}
static void
gupnp_didl_lite_writer_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteWriter *writer;
writer = GUPNP_DIDL_LITE_WRITER (object);
GUPnPDIDLLiteWriterPrivate *priv =
gupnp_didl_lite_writer_get_instance_private (writer);
switch (property_id) {
case PROP_LANGUAGE:
priv->language = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_writer_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GUPnPDIDLLiteWriter *writer;
writer = GUPNP_DIDL_LITE_WRITER (object);
switch (property_id) {
case PROP_XML_NODE:
g_value_set_pointer
(value, gupnp_didl_lite_writer_get_xml_node (writer));
break;
case PROP_LANGUAGE:
g_value_set_string
(value, gupnp_didl_lite_writer_get_language (writer));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_didl_lite_writer_constructed (GObject *object)
{
GObjectClass *object_class;
xmlDoc *doc;
GUPnPDIDLLiteWriterPrivate *priv =
gupnp_didl_lite_writer_get_instance_private (
GUPNP_DIDL_LITE_WRITER (object));
doc = xmlNewDoc ((unsigned char *) "1.0");
priv->xml_doc = av_xml_doc_new (doc);
priv->xml_node = xmlNewDocNode (priv->xml_doc->doc,
NULL,
(unsigned char *) "DIDL-Lite",
NULL);
xmlDocSetRootElement (priv->xml_doc->doc, priv->xml_node);
av_xml_util_create_namespace (priv->xml_node,
GUPNP_XML_NAMESPACE_DIDL_LITE);
if (priv->language)
xmlSetProp (priv->xml_node,
(unsigned char *) "lang",
(unsigned char *) priv->language);
object_class = G_OBJECT_CLASS (gupnp_didl_lite_writer_parent_class);
if (object_class->constructed != NULL)
object_class->constructed (object);
}
static void
gupnp_didl_lite_writer_dispose (GObject *object)
{
GObjectClass *object_class;
GUPnPDIDLLiteWriterPrivate *priv =
gupnp_didl_lite_writer_get_instance_private (
GUPNP_DIDL_LITE_WRITER (object));
g_clear_pointer (&priv->xml_doc, av_xml_doc_unref);
object_class = G_OBJECT_CLASS (gupnp_didl_lite_writer_parent_class);
object_class->dispose (object);
}
static void
gupnp_didl_lite_writer_finalize (GObject *object)
{
GObjectClass *object_class;
GUPnPDIDLLiteWriterPrivate *priv =
gupnp_didl_lite_writer_get_instance_private (
GUPNP_DIDL_LITE_WRITER (object));
g_free (priv->language);
object_class = G_OBJECT_CLASS (gupnp_didl_lite_writer_parent_class);
object_class->finalize (object);
}
static void
gupnp_didl_lite_writer_class_init (GUPnPDIDLLiteWriterClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->set_property = gupnp_didl_lite_writer_set_property;
object_class->get_property = gupnp_didl_lite_writer_get_property;
object_class->constructed = gupnp_didl_lite_writer_constructed;
object_class->dispose = gupnp_didl_lite_writer_dispose;
object_class->finalize = gupnp_didl_lite_writer_finalize;
/**
* GUPnPDIDLLiteWriter:xml-node:
*
* The pointer to root node in XML document.
**/
g_object_class_install_property
(object_class,
PROP_XML_NODE,
g_param_spec_pointer ("xml-node",
"XMLNode",
"The pointer to root node in XML"
" document.",
G_PARAM_READABLE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPDIDLLiteWriter:language:
*
* The language the DIDL-Lite fragment is in.
*
**/
g_object_class_install_property
(object_class,
PROP_LANGUAGE,
g_param_spec_string ("language",
"Language",
"The language the DIDL-Lite fragment"
" is in.",
NULL,
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
}
/**
* gupnp_didl_lite_writer_new:
* @language: (allow-none):The language the DIDL-Lite fragment is in, or %NULL
*
* Note: @language should always be set to %NULL, DLNA does not support the
* language parameter.
*
* Return value: A new #GUPnPDIDLLiteWriter object.
**/
GUPnPDIDLLiteWriter *
gupnp_didl_lite_writer_new (const char *language)
{
return g_object_new (GUPNP_TYPE_DIDL_LITE_WRITER,
"language", language,
NULL);
}
/**
* gupnp_didl_lite_writer_add_item:
* @writer: A #GUPnPDIDLLiteWriter
*
* Creates a new item, attaches it to @writer and returns it.
*
* Returns: (transfer full): A new #GUPnPDIDLLiteItem object. Unref after usage.
**/
GUPnPDIDLLiteItem *
gupnp_didl_lite_writer_add_item (GUPnPDIDLLiteWriter *writer)
{
xmlNode *item_node;
GUPnPDIDLLiteObject *object;
GUPnPDIDLLiteWriterPrivate *priv =
gupnp_didl_lite_writer_get_instance_private (writer);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_WRITER (writer), NULL);
item_node = xmlNewChild (priv->xml_node,
NULL,
(unsigned char *) "item",
NULL);
object = gupnp_didl_lite_object_new_from_xml (item_node,
priv->xml_doc,
priv->upnp_ns,
priv->dc_ns,
priv->dlna_ns,
priv->pv_ns);
return GUPNP_DIDL_LITE_ITEM (object);
}
/**
* gupnp_didl_lite_writer_add_container_child_item:
* @writer: #GUPnPDIDLLiteWriter
* @container: #GUPnPDIDLLiteContainer
*
* Add a child item to a container. This is only useful in DIDL_S playlist
* creation.
*
* Returns: (transfer full): A new #GUPnPDIDLLiteItem object. Unref after
* usage.
**/
GUPnPDIDLLiteItem *
gupnp_didl_lite_writer_add_container_child_item
(GUPnPDIDLLiteWriter *writer,
GUPnPDIDLLiteContainer *container)
{
xmlNode *item_node, *container_node;
GUPnPDIDLLiteObject *object;
GUPnPDIDLLiteWriterPrivate *priv =
gupnp_didl_lite_writer_get_instance_private (writer);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), NULL);
object = GUPNP_DIDL_LITE_OBJECT (container);
container_node = gupnp_didl_lite_object_get_xml_node (object);
item_node = xmlNewChild (container_node,
NULL,
(xmlChar *) "item",
NULL);
object = gupnp_didl_lite_object_new_from_xml (item_node,
priv->xml_doc,
priv->upnp_ns,
priv->dc_ns,
priv->dlna_ns,
priv->pv_ns);
return GUPNP_DIDL_LITE_ITEM (object);
}
/**
* gupnp_didl_lite_writer_add_container:
* @writer: A #GUPnPDIDLLiteWriter
*
* Creates a new container, attaches it to @writer and returns it.
*
* Returns: (transfer full): A new #GUPnPDIDLLiteContainer object. Unref after usage.
**/
GUPnPDIDLLiteContainer *
gupnp_didl_lite_writer_add_container (GUPnPDIDLLiteWriter *writer)
{
xmlNode *container_node;
GUPnPDIDLLiteObject *object;
GUPnPDIDLLiteWriterPrivate *priv =
gupnp_didl_lite_writer_get_instance_private (writer);
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_WRITER (writer), NULL);
container_node = xmlNewChild (priv->xml_node,
NULL,
(unsigned char *) "container",
NULL);
object = gupnp_didl_lite_object_new_from_xml (container_node,
priv->xml_doc,
priv->upnp_ns,
priv->dc_ns,
priv->dlna_ns,
priv->pv_ns);
return GUPNP_DIDL_LITE_CONTAINER (object);
}
/**
* gupnp_didl_lite_writer_add_descriptor:
* @writer: A #GUPnPDIDLLiteWriter
*
* Creates a new descriptor, attaches it to @object and returns it.
*
* Returns: (transfer full): A new #GUPnPDIDLLiteDescriptor object. Unref after usage.
**/
GUPnPDIDLLiteDescriptor *
gupnp_didl_lite_writer_add_descriptor (GUPnPDIDLLiteWriter *writer)
{
xmlNode *desc_node;
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_WRITER (writer), NULL);
GUPnPDIDLLiteWriterPrivate *priv =
gupnp_didl_lite_writer_get_instance_private (writer);
desc_node = xmlNewChild (priv->xml_node,
NULL,
(unsigned char *) "desc",
NULL);
return gupnp_didl_lite_descriptor_new_from_xml (desc_node,
priv->xml_doc);
}
/**
* gupnp_didl_lite_writer_get_string:
* @writer: A #GUPnPDIDLLiteWriter
*
* Creates a string representation of the DIDL-Lite XML document.
*
* Return value: The DIDL-Lite XML string, or %NULL. #g_free after usage.
**/
char *
gupnp_didl_lite_writer_get_string (GUPnPDIDLLiteWriter *writer)
{
xmlBuffer *buffer;
char *ret;
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_WRITER (writer), NULL);
GUPnPDIDLLiteWriterPrivate *priv =
gupnp_didl_lite_writer_get_instance_private (writer);
buffer = xmlBufferCreate ();
xmlNodeDump (buffer, priv->xml_doc->doc, priv->xml_node, 0, 0);
ret = g_strndup ((char *) xmlBufferContent (buffer),
xmlBufferLength (buffer));
xmlBufferFree (buffer);
return ret;
}
/**
* gupnp_didl_lite_writer_get_xml_node:
* @writer: The #GUPnPDIDLLiteWriter
*
* Get the pointer to root node in XML document.
*
* Returns: (transfer none): The pointer to root node in XML document.
**/
xmlNode *
gupnp_didl_lite_writer_get_xml_node (GUPnPDIDLLiteWriter *writer)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_WRITER (writer), NULL);
GUPnPDIDLLiteWriterPrivate *priv =
gupnp_didl_lite_writer_get_instance_private (writer);
return priv->xml_node;
}
/**
* gupnp_didl_lite_writer_get_language:
* @writer: #GUPnPDIDLLiteWriter
*
* Get the language the DIDL-Lite fragment is in.
*
* Returns: (transfer none): The language of the @writer, or %NULL.
**/
const char *
gupnp_didl_lite_writer_get_language (GUPnPDIDLLiteWriter *writer)
{
g_return_val_if_fail (GUPNP_IS_DIDL_LITE_WRITER (writer), NULL);
GUPnPDIDLLiteWriterPrivate *priv =
gupnp_didl_lite_writer_get_instance_private (writer);
return priv->language;
}
/**
* gupnp_didl_lite_writer_filter:
* @writer: A #GUPnPDIDLLiteWriter
* @filter: A filter string
*
* Clears the DIDL-Lite XML document of the properties not specified in the
* @filter. The passed filter string would typically come from the 'Filter'
* argument of Browse or Search actions from a ContentDirectory control point.
* Please refer to Section 2.3.15 of UPnP AV ContentDirectory version 3
* specification for details on this string.
**/
void
gupnp_didl_lite_writer_filter (GUPnPDIDLLiteWriter *writer,
const char *filter)
{
apply_filter (writer, filter, FALSE);
}
/**
* gupnp_didl_lite_writer_filter_tags:
* @writer: A #GUPnPDIDLLiteWriter
* @filter: A filter string
*
* Clears the DIDL-Lite XML document of the properties not specified in the
* @filter. The passed filter string would typically come from the 'Filter'
* argument of Browse or Search actions from a ContentDirectory control point.
* Please refer to Section 2.3.15 of UPnP AV ContentDirectory version 3
* specification for details on this string.
*
* In contrast to gupnp_didl_lite_writer_filter(), this function only removes
* unwanted tags but leaves all attributes in-place.
*
* Return value: None.
**/
void
gupnp_didl_lite_writer_filter_tags (GUPnPDIDLLiteWriter *writer,
const char *filter)
{
apply_filter (writer, filter, TRUE);
}
07070100000043000081A40000000000000000000000016860451500000812000000000000000000000000000000000000003500000000gupnp-av-0.14.4/libgupnp-av/gupnp-didl-lite-writer.h/*
* Copyright (C) 2007, 2008 OpenedHand Ltd.
*
* Authors: Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_WRITER_H
#define GUPNP_DIDL_LITE_WRITER_H
#include <stdarg.h>
#include <glib-object.h>
#include "gupnp-dlna.h"
#include "gupnp-didl-lite-item.h"
#include "gupnp-didl-lite-container.h"
#include "gupnp-didl-lite-resource.h"
#include "gupnp-didl-lite-descriptor.h"
G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE(GUPnPDIDLLiteWriter,
gupnp_didl_lite_writer,
GUPNP,
DIDL_LITE_WRITER,
GObject)
#define GUPNP_TYPE_DIDL_LITE_WRITER \
(gupnp_didl_lite_writer_get_type ())
struct _GUPnPDIDLLiteWriterClass {
GObjectClass parent_class;
/* future padding */
void (* _gupnp_reserved1) (void);
void (* _gupnp_reserved2) (void);
void (* _gupnp_reserved3) (void);
void (* _gupnp_reserved4) (void);
};
#define GUPNP_DIDL_LITE_WRITER_NAMESPACE_DC "dc"
#define GUPNP_DIDL_LITE_WRITER_NAMESPACE_UPNP "upnp"
#define GUPNP_DIDL_LITE_WRITER_NAMESPACE_DLNA "dlna"
#define GUPNP_DIDL_LITE_WRITER_NAMESPACE_PV "pv"
GUPnPDIDLLiteWriter *
gupnp_didl_lite_writer_new (const char *language);
GUPnPDIDLLiteItem *
gupnp_didl_lite_writer_add_item (GUPnPDIDLLiteWriter *writer);
GUPnPDIDLLiteContainer *
gupnp_didl_lite_writer_add_container (GUPnPDIDLLiteWriter *writer);
GUPnPDIDLLiteDescriptor *
gupnp_didl_lite_writer_add_descriptor (GUPnPDIDLLiteWriter *writer);
xmlNode *
gupnp_didl_lite_writer_get_xml_node (GUPnPDIDLLiteWriter *writer);
char *
gupnp_didl_lite_writer_get_string (GUPnPDIDLLiteWriter *writer);
const char *
gupnp_didl_lite_writer_get_language (GUPnPDIDLLiteWriter *writer);
void
gupnp_didl_lite_writer_filter (GUPnPDIDLLiteWriter *writer,
const char *filter);
G_END_DECLS
#endif /* GUPNP_DIDL_LITE_WRITER_H */
07070100000044000081A400000000000000000000000168604515000018E3000000000000000000000000000000000000002900000000gupnp-av-0.14.4/libgupnp-av/gupnp-dlna.c/*
* Copyright (C) 2009 Nokia Corporation.
*
* Authors: Zeeshan Ali <zeeshanak@gnome.org>
* <zeeshan.ali@nokia.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include "gupnp-dlna.h"
GType
gupnp_dlna_conversion_get_type (void)
{
static GType type = 0;
if (type == 0) {
static const GFlagsValue values[] = {
{ GUPNP_DLNA_CONVERSION_NONE,
"GUPNP_DLNA_CONVERSION_NONE",
"none" },
{ GUPNP_DLNA_CONVERSION_TRANSCODED,
"GUPNP_DLNA_CONVERSION_TRANSCODED",
"transcoded" },
{ 0, NULL, NULL }
};
type = g_flags_register_static
(g_intern_static_string ("GUPnPDLNAConversion"),
values);
}
return type;
}
GType
gupnp_dlna_operation_get_type (void)
{
static GType type = 0;
if (type == 0) {
static const GFlagsValue values[] = {
{ GUPNP_DLNA_OPERATION_NONE,
"GUPNP_DLNA_OPERATION_NONE",
"none" },
{ GUPNP_DLNA_OPERATION_RANGE,
"GUPNP_DLNA_OPERATION_RANGE",
"range" },
{ GUPNP_DLNA_OPERATION_TIMESEEK,
"GUPNP_DLNA_OPERATION_TIMESEEK",
"timeseek" },
{ 0, NULL, NULL }
};
type = g_flags_register_static
(g_intern_static_string ("GUPnPDLNAOperation"),
values);
}
return type;
}
GType
gupnp_dlna_flags_get_type (void)
{
static GType type = 0;
if (type == 0) {
static const GFlagsValue values[] = {
{ GUPNP_DLNA_FLAGS_NONE,
"GUPNP_DLNA_FLAGS_NONE",
"none" },
{ GUPNP_DLNA_FLAGS_SENDER_PACED,
"GUPNP_DLNA_FLAGS_SENDER_PACED",
"sender-paced" },
{ GUPNP_DLNA_FLAGS_TIME_BASED_SEEK,
"GUPNP_DLNA_FLAGS_TIME_BASED_SEEK",
"time-based-seek" },
{ GUPNP_DLNA_FLAGS_BYTE_BASED_SEEK,
"GUPNP_DLNA_FLAGS_BYTE_BASED_SEEK",
"byte-based-seek" },
{ GUPNP_DLNA_FLAGS_PLAY_CONTAINER,
"GUPNP_DLNA_FLAGS_PLAY_CONTAINER",
"play-container" },
{ GUPNP_DLNA_FLAGS_S0_INCREASE,
"GUPNP_DLNA_FLAGS_S0_INCREASE",
"s0-increase" },
{ GUPNP_DLNA_FLAGS_SN_INCREASE,
"GUPNP_DLNA_FLAGS_SN_INCREASE",
"sn-increase" },
{ GUPNP_DLNA_FLAGS_RTSP_PAUSE,
"GUPNP_DLNA_FLAGS_RTSP_PAUSE",
"rtsp-pause" },
{ GUPNP_DLNA_FLAGS_STREAMING_TRANSFER_MODE,
"GUPNP_DLNA_FLAGS_STREAMING_TRANSFER_MODE",
"streaming-transfer-mode" },
{ GUPNP_DLNA_FLAGS_INTERACTIVE_TRANSFER_MODE,
"GUPNP_DLNA_FLAGS_INTERACTIVE_TRANSFER_MODE",
"interactive-transfer-mode" },
{ GUPNP_DLNA_FLAGS_BACKGROUND_TRANSFER_MODE,
"GUPNP_DLNA_FLAGS_BACKGROUND_TRANSFER_MODE",
"background-transfer-mode" },
{ GUPNP_DLNA_FLAGS_CONNECTION_STALL,
"GUPNP_DLNA_FLAGS_CONNECTION_STALL",
"connection-stall" },
{ GUPNP_DLNA_FLAGS_DLNA_V15,
"GUPNP_DLNA_FLAGS_DLNA_V15",
"dlna-v15" },
{ GUPNP_DLNA_FLAGS_LINK_PROTECTED_CONTENT,
"GUPNP_DLNA_FLAGS_LINK_PROTECTED_CONTENT",
"link-protected-content" },
{ GUPNP_DLNA_FLAGS_CLEAR_TEXT_BYTE_SEEK_FULL,
"GUPNP_DLNA_FLAGS_CLEAR_TEXT_BYTE_SEEK_FULL",
"cleartext-byteseek-full" },
{ GUPNP_DLNA_FLAGS_LOP_CLEAR_TEXT_BYTE_SEEK,
"GUPNP_DLNA_FLAGS_LOP_CLEAR_TEXT_BYTE_SEEK",
"lop-cleartext-byteseek" },
{ 0, NULL, NULL }
};
type = g_flags_register_static
(g_intern_static_string ("GUPnPDLNAFlags"),
values);
}
return type;
}
GType
gupnp_ocm_flags_get_type (void)
{
static GType type = 0;
if (type == 0) {
static const GFlagsValue values[] = {
{ GUPNP_OCM_FLAGS_NONE,
"GUPNP_OCM_FLAGS_NONE",
"none" },
{ GUPNP_OCM_FLAGS_UPLOAD,
"GUPNP_OCM_FLAGS_UPLOAD",
"upload" },
{ GUPNP_OCM_FLAGS_CREATE_CONTAINER,
"GUPNP_OCM_FLAGS_CREATE_CONTAINER",
"create-container" },
{ GUPNP_OCM_FLAGS_DESTROYABLE,
"GUPNP_OCM_FLAGS_DESTROYABLE",
"destroyable" },
{ GUPNP_OCM_FLAGS_UPLOAD_DESTROYABLE,
"GUPNP_OCM_FLAGS_UPLOAD_DESTROYABLE",
"upload-destroyable" },
{ GUPNP_OCM_FLAGS_CHANGE_METADATA,
"GUPNP_OCM_FLAGS_CHANGE_METADATA",
"change-metadata" },
{ 0, NULL, NULL }
};
type = g_flags_register_static
(g_intern_static_string ("GUPnPOCMFlags"),
values);
}
return type;
}
07070100000045000081A4000000000000000000000001686045150000155B000000000000000000000000000000000000002900000000gupnp-av-0.14.4/libgupnp-av/gupnp-dlna.h/*
* Copyright (C) 2007, 2008 OpenedHand Ltd.
*
* Authors: Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DLNA_H
#define GUPNP_DLNA_H
#include <glib-object.h>
G_BEGIN_DECLS
GType
gupnp_dlna_conversion_get_type (void) G_GNUC_CONST;
#define GUPNP_TYPE_DLNA_CONVERSION (gupnp_dlna_conversion_get_type ())
/**
* GUPnPDLNAConversion:
* @GUPNP_DLNA_CONVERSION_NONE: Content is in original source format
* @GUPNP_DLNA_CONVERSION_TRANSCODED: Content is transcoded
*
* The DLNA conversion flags for a resource.
*
**/
typedef enum {
GUPNP_DLNA_CONVERSION_NONE = 0,
GUPNP_DLNA_CONVERSION_TRANSCODED = 1
} GUPnPDLNAConversion;
GType
gupnp_dlna_operation_get_type (void) G_GNUC_CONST;
#define GUPNP_TYPE_DLNA_OPERATION (gupnp_dlna_operation_get_type ())
/**
* GUPnPDLNAOperation:
* @GUPNP_DLNA_OPERATION_NONE: Resource does not support seeking of any type
* @GUPNP_DLNA_OPERATION_RANGE: Resource supports byte-seek
* @GUPNP_DLNA_OPERATION_TIMESEEK: Resource supports time-seek
*
* The seek operations supported by a resource.
*
**/
typedef enum {
GUPNP_DLNA_OPERATION_NONE = 0x00,
GUPNP_DLNA_OPERATION_RANGE = 0x01,
GUPNP_DLNA_OPERATION_TIMESEEK = 0x10
} GUPnPDLNAOperation;
GType
gupnp_dlna_flags_get_type (void) G_GNUC_CONST;
#define GUPNP_TYPE_DLNA_FLAGS (gupnp_dlna_flags_get_type ())
/**
* GUPnPDLNAFlags:
* @GUPNP_DLNA_FLAGS_NONE: No flags
* @GUPNP_DLNA_FLAGS_SENDER_PACED: Content source is the clock source during
* transport
* @GUPNP_DLNA_FLAGS_TIME_BASED_SEEK: Limited Operation: time-seek supported
* @GUPNP_DLNA_FLAGS_BYTE_BASED_SEEK: Limited Operation: byte-seek supported
* @GUPNP_DLNA_FLAGS_PLAY_CONTAINER: Resource supports 'Container Playback'
* @GUPNP_DLNA_FLAGS_S0_INCREASE: Content does not have a fixed beginning
* @GUPNP_DLNA_FLAGS_SN_INCREASE: Content does not have a fixed end
* @GUPNP_DLNA_FLAGS_RTSP_PAUSE: RTSP resource supports pausing of media
* transfer
* @GUPNP_DLNA_FLAGS_STREAMING_TRANSFER_MODE: Streaming transfer mode supported
* @GUPNP_DLNA_FLAGS_INTERACTIVE_TRANSFER_MODE: Interactive transfer mode
* supported
* @GUPNP_DLNA_FLAGS_BACKGROUND_TRANSFER_MODE: Background transfer mode
* supported
* @GUPNP_DLNA_FLAGS_CONNECTION_STALL: No content transfer when paused.
* @GUPNP_DLNA_FLAGS_DLNA_V15: DLNAv1.5 version flag
* @GUPNP_DLNA_FLAGS_LINK_PROTECTED_CONTENT: The content is protected.
* @GUPNP_DLNA_FLAGS_CLEAR_TEXT_BYTE_SEEK_FULL: Full byte seek on cleartext
* domain is supported.
* @GUPNP_DLNA_FLAGS_LOP_CLEAR_TEXT_BYTE_SEEK: Limited operations on
* byte seek in cleartext domain.
*
* The miscellaneous operations supported by a resource. For details on these
* flags please refer to section 7.3.37.2 of DLNA Networked Device
* Interoperability Guidelines Volume 1, October 2006.
*
* Updated DTCP Flags based on 2011 Guidelines, section 7.4.1.3.23.2
*
**/
typedef enum {
GUPNP_DLNA_FLAGS_NONE = 0,
GUPNP_DLNA_FLAGS_SENDER_PACED = (1 << 31),
GUPNP_DLNA_FLAGS_TIME_BASED_SEEK = (1 << 30),
GUPNP_DLNA_FLAGS_BYTE_BASED_SEEK = (1 << 29),
GUPNP_DLNA_FLAGS_PLAY_CONTAINER = (1 << 28),
GUPNP_DLNA_FLAGS_S0_INCREASE = (1 << 27),
GUPNP_DLNA_FLAGS_SN_INCREASE = (1 << 26),
GUPNP_DLNA_FLAGS_RTSP_PAUSE = (1 << 25),
GUPNP_DLNA_FLAGS_STREAMING_TRANSFER_MODE = (1 << 24),
GUPNP_DLNA_FLAGS_INTERACTIVE_TRANSFER_MODE = (1 << 23),
GUPNP_DLNA_FLAGS_BACKGROUND_TRANSFER_MODE = (1 << 22),
GUPNP_DLNA_FLAGS_CONNECTION_STALL = (1 << 21),
GUPNP_DLNA_FLAGS_DLNA_V15 = (1 << 20),
GUPNP_DLNA_FLAGS_LINK_PROTECTED_CONTENT = (1 << 16),
GUPNP_DLNA_FLAGS_CLEAR_TEXT_BYTE_SEEK_FULL = (1 << 15),
GUPNP_DLNA_FLAGS_LOP_CLEAR_TEXT_BYTE_SEEK = (1 << 14)
} GUPnPDLNAFlags;
/**
* GUPnPOCMFlags:
* @GUPNP_OCM_FLAGS_NONE: No flags
* @GUPNP_OCM_FLAGS_UPLOAD: Indicates support for content upload.
* @GUPNP_OCM_FLAGS_CREATE_CONTAINER: Indicates support for creation of child
* container.
* @GUPNP_OCM_FLAGS_DESTROYABLE: This object is destroyable.
* @GUPNP_OCM_FLAGS_UPLOAD_DESTROYABLE: Indicates support for upload of
* destroyable content.
* @GUPNP_OCM_FLAGS_CHANGE_METADATA: Indicates support for changing metadata.
*
* The DLNA OCM flags supported by a DIDL-Lite Object. For details on these
* flags please refer to section 7.3.118.4 of DLNA Networked Device
* Interoperability Guidelines Volume 1, October 2006.
*
**/
typedef enum {
GUPNP_OCM_FLAGS_NONE = 0x0,
GUPNP_OCM_FLAGS_UPLOAD = 0x01,
GUPNP_OCM_FLAGS_CREATE_CONTAINER = 0x02,
GUPNP_OCM_FLAGS_DESTROYABLE = 0x04,
GUPNP_OCM_FLAGS_UPLOAD_DESTROYABLE = 0x08,
GUPNP_OCM_FLAGS_CHANGE_METADATA = 0x10
} GUPnPOCMFlags;
GType
gupnp_ocm_flags_get_type (void) G_GNUC_CONST;
#define GUPNP_TYPE_OCM_FLAGS (gupnp_ocm_flags_get_type ())
G_END_DECLS
#endif /* GUPNP_DLNA_H */
07070100000046000081A40000000000000000000000016860451500001805000000000000000000000000000000000000003800000000gupnp-av-0.14.4/libgupnp-av/gupnp-feature-list-parser.c/*
* Copyright (C) 2012 Intel Corporation.
*
* Authors: Regis Merlino <regis.merlino@intel.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPFeatureListParser:
*
* FeatureList state variable XML parser
*
* #GUPnPFeatureListParser parses XML strings from ContentDirectory
* FeatureList state variable.
*
*/
#include <config.h>
#include <string.h>
#include "gupnp-feature-list-parser.h"
#include "gupnp-av.h"
#include "xml-util.h"
struct _GUPnPFeatureListParser {
GObject parent;
};
/* GUPnPFeatureListParser */
G_DEFINE_TYPE (GUPnPFeatureListParser,
gupnp_feature_list_parser,
G_TYPE_OBJECT)
static void
gupnp_feature_list_parser_init (G_GNUC_UNUSED GUPnPFeatureListParser *parser)
{
/* Nothing to do here */
}
static void
gupnp_feature_list_parser_finalize (GObject *object)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (gupnp_feature_list_parser_parent_class);
object_class->finalize (object);
}
static void
gupnp_feature_list_parser_class_init (GUPnPFeatureListParserClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gupnp_feature_list_parser_finalize;
}
/**
* gupnp_feature_list_parser_new:
*
* Return value: A new #GUPnPFeatureListParser object.
**/
GUPnPFeatureListParser *
gupnp_feature_list_parser_new (void)
{
return g_object_new (GUPNP_TYPE_FEATURE_LIST_PARSER, NULL);
}
static char *
get_feature_object_ids (xmlNode *feature)
{
xmlNode *element;
const char *content;
GString *object_ids = g_string_new ("");
for (element = feature->children; element; element = element->next) {
const char *name = (const char *) element->name;
if (g_ascii_strcasecmp (name, "objectIDs") == 0) {
content = (const char *) xmlNodeGetContent (element);
if (strlen (content) == 0)
continue;
if (object_ids->len > 0)
g_string_append_c (object_ids, ',');
g_string_append (object_ids, content);
}
}
return g_string_free (object_ids, FALSE);
}
/**
* gupnp_feature_list_parser_parse_text:
* @parser: A #GUPnPFeatureListParser
* @text: The feature list string to be parsed
* @error: The location where to store the error information if any, or NULL
*
* Parses @text and returns the list of available features.
* If an error occurred @error will be set.
*
* Return value: (transfer full) (element-type GUPnPFeature)(nullable): The list
*of features or %NULL if an error occurred.
**/
GList *
gupnp_feature_list_parser_parse_text
(G_GNUC_UNUSED GUPnPFeatureListParser *parser,
const char *text,
GError **error)
{
xmlDoc *doc;
xmlNode *element;
GList *feature_list = NULL;
doc = xmlReadMemory (text,
strlen (text),
NULL,
NULL,
XML_PARSE_NONET | XML_PARSE_RECOVER);
if (doc == NULL) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_PARSE,
"Could not parse FeatureList XML:\n%s",
text);
return NULL;
}
/* Get a pointer to root element */
element = av_xml_util_get_element ((xmlNode *) doc, "Features", NULL);
if (element == NULL) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_PARSE,
"No 'Features' node in the XML:\n%s",
text);
xmlFreeDoc (doc);
return NULL;
}
for (element = element->children; element; element = element->next) {
GUPnPFeature *feature;
const char *name;
const char *version;
char *object_ids;
if (g_ascii_strcasecmp ((char *) element->name,
"Feature") == 0) {
name = av_xml_util_get_attribute_content (element,
"name");
version = av_xml_util_get_attribute_content (element,
"version");
if (!name || !version) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
"Invalid attributes in 'Feature' "
"node in the XML:\n%s",
text);
xmlFreeDoc (doc);
if (feature_list)
g_list_free_full (feature_list,
g_object_unref);
return NULL;
}
object_ids = get_feature_object_ids (element);
feature = g_object_new (GUPNP_TYPE_FEATURE,
"name", name,
"version", version,
"object-ids", object_ids,
NULL);
feature_list = g_list_append (feature_list, feature);
g_free (object_ids);
}
}
xmlFreeDoc (doc);
return feature_list;
}
07070100000047000081A4000000000000000000000001686045150000039A000000000000000000000000000000000000003800000000gupnp-av-0.14.4/libgupnp-av/gupnp-feature-list-parser.h/*
* Copyright (C) 2012 Intel Corporation.
*
* Authors: Regis Merlino <regis.merlino@intel.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_FEATURE_LIST_PARSER_H
#define GUPNP_FEATURE_LIST_PARSER_H
#include <glib-object.h>
#include "gupnp-feature.h"
G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (GUPnPFeatureListParser,
gupnp_feature_list_parser,
GUPNP,
FEATURE_LIST_PARSER,
GObject)
#define GUPNP_TYPE_FEATURE_LIST_PARSER (gupnp_feature_list_parser_get_type ())
GUPnPFeatureListParser *
gupnp_feature_list_parser_new (void);
GList *
gupnp_feature_list_parser_parse_text (GUPnPFeatureListParser *parser,
const char *text,
GError **error);
G_END_DECLS
#endif /* __GUPNP_FEATURE_LIST_PARSER_H_ */
07070100000048000081A40000000000000000000000016860451500001977000000000000000000000000000000000000002C00000000gupnp-av-0.14.4/libgupnp-av/gupnp-feature.c/*
* Copyright (C) 2012 Intel Corporation
*
* Authors: Regis Merlino <regis.merlino@intel.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPFeature:
*
* ContentDirectory feature
*
* #GUPnPFeature respresent a Feature element.
*/
#include <config.h>
#include "gupnp-feature.h"
struct _GUPnPFeaturePrivate {
char *name;
char *version;
char *object_ids;
};
typedef struct _GUPnPFeaturePrivate GUPnPFeaturePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GUPnPFeature,
gupnp_feature,
G_TYPE_OBJECT)
enum {
PROP_0,
PROP_NAME,
PROP_VERSION,
PROP_OBJECT_IDS
};
static void
gupnp_feature_init (GUPnPFeature *object)
{
}
static void
gupnp_feature_finalize (GObject *object)
{
GObjectClass *object_class;
GUPnPFeaturePrivate *priv;
priv = gupnp_feature_get_instance_private (GUPNP_FEATURE (object));
g_free (priv->name);
g_free (priv->version);
g_free (priv->object_ids);
object_class = G_OBJECT_CLASS (gupnp_feature_parent_class);
object_class->finalize (object);
}
static void
gupnp_feature_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GUPnPFeature *feature;
feature = GUPNP_FEATURE (object);
switch (property_id) {
case PROP_NAME:
g_value_set_string (value, gupnp_feature_get_name (feature));
break;
case PROP_VERSION:
g_value_set_string (value, gupnp_feature_get_version (feature));
break;
case PROP_OBJECT_IDS:
g_value_set_string (value,
gupnp_feature_get_object_ids (feature));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_feature_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GUPnPFeaturePrivate *priv =
gupnp_feature_get_instance_private (GUPNP_FEATURE (object));
switch (property_id) {
case PROP_NAME:
priv->name = g_value_dup_string (value);
break;
case PROP_VERSION:
priv->version = g_value_dup_string (value);
break;
case PROP_OBJECT_IDS:
priv->object_ids = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_feature_class_init (GUPnPFeatureClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gupnp_feature_get_property;
object_class->set_property = gupnp_feature_set_property;
object_class->finalize = gupnp_feature_finalize;
/**
* GUPnPFeature:name:
*
* The name of this feature.
**/
g_object_class_install_property
(object_class,
PROP_NAME,
g_param_spec_string ("name",
"Name",
"The name of this feature.",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPFeature:version:
*
* The version of this feature.
**/
g_object_class_install_property
(object_class,
PROP_VERSION,
g_param_spec_string ("version",
"Version",
"The version of this feature.",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPFeature:object-ids:
*
* The object IDs related to this feature.
**/
g_object_class_install_property
(object_class,
PROP_OBJECT_IDS,
g_param_spec_string ("object-ids",
"Object IDs",
"The object IDs of this feature.",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
}
/**
* gupnp_feature_get_name:
* @feature: #GUPnPFeature
*
* Get the name of the @feature.
*
* Return value: The name of the @feature.
**/
const char *
gupnp_feature_get_name (GUPnPFeature *feature)
{
GUPnPFeaturePrivate *priv =
gupnp_feature_get_instance_private (GUPNP_FEATURE (feature));
return priv->name;
}
/**
* gupnp_feature_get_version:
* @feature: #GUPnPFeature
*
* Get the version of the @feature.
*
* Return value: The version of the @feature.
**/
const char *
gupnp_feature_get_version (GUPnPFeature *feature)
{
GUPnPFeaturePrivate *priv =
gupnp_feature_get_instance_private (GUPNP_FEATURE (feature));
return priv->version;
}
/**
* gupnp_feature_get_object_ids:
* @feature: #GUPnPFeature
*
* Get the object IDs related to the @feature.
*
* Return value: The object IDs related to the @feature.
**/
const char *
gupnp_feature_get_object_ids (GUPnPFeature *feature)
{
GUPnPFeaturePrivate *priv =
gupnp_feature_get_instance_private (GUPNP_FEATURE (feature));
return priv->object_ids;
}
07070100000049000081A4000000000000000000000001686045150000031F000000000000000000000000000000000000002C00000000gupnp-av-0.14.4/libgupnp-av/gupnp-feature.h/*
* Copyright (C) 2012 Intel Corporation.
*
* Authors: Regis Merlino <regis.merlino@intel.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_FEATURE_H
#define GUPNP_FEATURE_H
#include <glib-object.h>
G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE(GUPnPFeature,
gupnp_feature,
GUPNP,
FEATURE,
GObject)
#define GUPNP_TYPE_FEATURE (gupnp_feature_get_type ())
struct _GUPnPFeatureClass {
GObjectClass parent_class;
};
const char *
gupnp_feature_get_name (GUPnPFeature *feature);
const char *
gupnp_feature_get_version (GUPnPFeature *feature);
const char *
gupnp_feature_get_object_ids (GUPnPFeature *feature);
G_END_DECLS
#endif /* GUPNP_FEATURE_H */
0707010000004A000081A40000000000000000000000016860451500001D97000000000000000000000000000000000000003700000000gupnp-av-0.14.4/libgupnp-av/gupnp-last-change-parser.c/*
* Copyright (C) 2007 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
* Copyright (C) 2007 OpenedHand Ltd
*
* Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
* Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPLastChangeParser:
*
* A/V LastChange event XML parser
*
* #GUPnPLastChangeParser parses XML strings from LastChange events that are
* generated by AVTransport and RenderingControl services.
*
*/
#include <config.h>
#include <gobject/gvaluecollector.h>
#include "gupnp-last-change-parser.h"
#include "gvalue-util.h"
#include "xml-util.h"
G_DEFINE_TYPE (GUPnPLastChangeParser,
gupnp_last_change_parser,
G_TYPE_OBJECT)
static void
gupnp_last_change_parser_init (G_GNUC_UNUSED GUPnPLastChangeParser *parser)
{
}
static void
gupnp_last_change_parser_dispose (GObject *object)
{
GObjectClass *gobject_class;
gobject_class = G_OBJECT_CLASS (gupnp_last_change_parser_parent_class);
gobject_class->dispose (object);
}
static void
gupnp_last_change_parser_class_init (GUPnPLastChangeParserClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gupnp_last_change_parser_dispose;
}
/* Reads a value of state variable @variable_name to an initialised GValue pair
* from the InstanceID node of a LastChange xml doc */
static gboolean
read_state_variable (const char *variable_name,
GValue *value,
xmlNode *instance_node)
{
xmlNode *variable_node;
const char *val_str;
variable_node = av_xml_util_get_element (instance_node,
variable_name,
NULL);
if (!variable_node)
return FALSE;
val_str = av_xml_util_get_attribute_content (variable_node, "val");
if (!val_str) {
g_warning ("No value provided for variable \"%s\" in "
"LastChange event",
variable_name);
return FALSE;
}
av_gvalue_util_set_value_from_string (value, val_str);
return TRUE;
}
static xmlNode *
get_instance_node (xmlDoc *doc,
guint instance_id)
{
xmlNode *node;
if (doc->children == NULL)
return NULL;
for (node = doc->children->children;
node;
node = node->next) {
if (node->type != XML_ELEMENT_NODE)
continue;
if (!xmlStrcmp (node->name, BAD_CAST ("InstanceID")) &&
av_xml_util_get_uint_attribute (node, "val", 0) ==
instance_id)
break;
}
return node;
}
/**
* gupnp_last_change_parser_new:
*
* Return value: A new #GUPnPLastChangeParser
**/
GUPnPLastChangeParser *
gupnp_last_change_parser_new (void)
{
return g_object_new (GUPNP_TYPE_LAST_CHANGE_PARSER,
NULL);
}
/**
* gupnp_last_change_parser_parse_last_change_valist:
* @parser: A #GUPnPLastChangeParser
* @instance_id: The ID of the AV instance caller is interested in
* @last_change_xml: The xml from the "LastChange" event to parse
* @error: The location where to store any error, or NULL
* @var_args: A va_list of tuples of state variable name, state variable type,
* and state variable value location, terminated with NULL. The state variable
* values should be freed after use
*
* See gupnp_last_change_parser_parse_last_change(); this version takes a
* va_list for use by language bindings.
*
* Return value: TRUE on success.
**/
gboolean
gupnp_last_change_parser_parse_last_change_valist
(G_GNUC_UNUSED GUPnPLastChangeParser *parser,
guint instance_id,
const char *last_change_xml,
GError **error,
va_list var_args)
{
const char *variable_name;
xmlDoc *doc;
xmlNode *instance_node;
g_return_val_if_fail (last_change_xml, FALSE);
doc = xmlParseDoc ((const xmlChar *) last_change_xml);
if (doc == NULL) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_PARSE,
"Could not parse LastChange xml");
return FALSE;
}
instance_node = get_instance_node (doc, instance_id);
if (instance_node == NULL) {
/* This is not an error since the caller of this function
* doesn't (need to) know if the instance of his interest is
* part of the LastChange event received.
*/
xmlFreeDoc (doc);
return FALSE;
}
/* Variables */
variable_name = va_arg (var_args, const char *);
while (variable_name) {
GType variable_type;
GValue value = { 0, };
char *copy_error = NULL;
variable_type = va_arg (var_args, GType);
g_value_init (&value, variable_type);
if (read_state_variable (variable_name,
&value,
instance_node)) {
G_VALUE_LCOPY (&value, var_args, 0, ©_error);
} else {
va_arg (var_args, gpointer);
}
g_value_unset (&value);
if (copy_error) {
g_warning ("Error copying value: %s", copy_error);
g_free (copy_error);
}
variable_name = va_arg (var_args, const char *);
}
/* Cleanup */
xmlFreeDoc (doc);
return TRUE;
}
/**
* gupnp_last_change_parser_parse_last_change:
* @parser: A #GUPnPLastChangeParser
* @instance_id: The ID of the AV instance caller is interested in
* @last_change_xml: The xml from the "LastChange" event to parse
* @error: The location where to store any error, or NULL
* @...: tuples of state variable name, state variable type, and state
* variable value location, terminated with NULL. The state variable values
* should be freed after use.
*
* Parses the xml fragment from a LastChange event.
*
* Return value: TRUE on success.
**/
gboolean
gupnp_last_change_parser_parse_last_change
(GUPnPLastChangeParser *parser,
guint instance_id,
const char *last_change_xml,
GError **error,
...)
{
va_list var_args;
gboolean ret;
va_start (var_args, error);
ret = gupnp_last_change_parser_parse_last_change_valist
(parser,
instance_id,
last_change_xml,
error,
var_args);
va_end (var_args);
return ret;
}
0707010000004B000081A40000000000000000000000016860451500000787000000000000000000000000000000000000003700000000gupnp-av-0.14.4/libgupnp-av/gupnp-last-change-parser.h/*
* Copyright (C) 2007 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
* Copyright (C) 2007 OpenedHand Ltd
*
* Authors: Zeeshan Ali Khattak <zeenix@gstreamer.net>
* Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_LAST_CHANGE_PARSER_H
#define GUPNP_LAST_CHANGE_PARSER_H
#include <glib-object.h>
G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE (GUPnPLastChangeParser,
gupnp_last_change_parser,
GUPNP,
LAST_CHANGE_PARSER,
GObject)
#define GUPNP_TYPE_LAST_CHANGE_PARSER (gupnp_last_change_parser_get_type ())
struct _GUPnPLastChangeParserClass {
GObjectClass parent_class;
/* future padding */
void (* _gupnp_reserved1) (void);
void (* _gupnp_reserved2) (void);
void (* _gupnp_reserved3) (void);
void (* _gupnp_reserved4) (void);
};
GUPnPLastChangeParser *
gupnp_last_change_parser_new (void);
gboolean
gupnp_last_change_parser_parse_last_change_valist
(GUPnPLastChangeParser *parser,
guint instance_id,
const char *last_change_xml,
GError **error,
va_list var_args);
gboolean
gupnp_last_change_parser_parse_last_change
(GUPnPLastChangeParser *parser,
guint instance_id,
const char *last_change_xml,
GError **error,
...) G_GNUC_NULL_TERMINATED;
G_END_DECLS
#endif /* __GUPNP_LAST_CHANGE_PARSER_H__ */
0707010000004C000081A40000000000000000000000016860451500004B62000000000000000000000000000000000000003500000000gupnp-av-0.14.4/libgupnp-av/gupnp-media-collection.c/*
* Copyright (C) 2012 Intel Corporation.
*
* Authors: Jens Georg <jensg@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPMediaCollection:
*
* Media collection writer
*
* #GUPnPMediaCollection is a helper class for writing media collection files.
**/
#include <config.h>
#include "gupnp-media-collection.h"
#include "gupnp-didl-lite-writer.h"
#include "gupnp-didl-lite-writer-private.h"
#include "gupnp-didl-lite-parser.h"
#include "gupnp-didl-lite-parser-private.h"
// DIDL_S allowed tags as per DLNA Guidelines 11.1
#define DIDL_S_FILTER "dc:title,dc:creator,upnp:class,upnp:album,res,item," \
"container,dlna:lifetime"
struct _GUPnPMediaCollectionPrivate {
GUPnPDIDLLiteWriter *writer;
GUPnPDIDLLiteObject *container;
GList *items;
gboolean mutable;
char *data;
};
typedef struct _GUPnPMediaCollectionPrivate GUPnPMediaCollectionPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GUPnPMediaCollection,
gupnp_media_collection,
G_TYPE_OBJECT)
enum {
PROP_0,
PROP_AUTHOR,
PROP_TITLE,
PROP_MUTABLE,
PROP_DATA,
};
static void
reparent_children (GUPnPMediaCollection *collection)
{
GList *it;
xmlNode *container_node;
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (collection);
container_node = gupnp_didl_lite_object_get_xml_node (priv->container);
/* Reverse iterate the list to get the correct order in XML */
it = g_list_last (priv->items);
while (it) {
xmlNode *node;
node = gupnp_didl_lite_object_get_xml_node (
GUPNP_DIDL_LITE_OBJECT (it->data));
xmlUnlinkNode (node);
xmlAddChild (container_node, node);
it = it->prev;
}
}
static void
on_container_available (GUPnPMediaCollection *self,
GUPnPDIDLLiteContainer *container,
G_GNUC_UNUSED gpointer user_data)
{
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (self);
/* According to media format spec, there's only one container allowed;
* We allow any number of containers, but only the last one wins. */
g_clear_object (&priv->container);
priv->container = GUPNP_DIDL_LITE_OBJECT (g_object_ref (container));
}
static void
on_item_available (GUPnPMediaCollection *self,
GUPnPDIDLLiteItem *item,
G_GNUC_UNUSED gpointer user_data)
{
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (self);
priv->items = g_list_prepend (priv->items, g_object_ref (item));
}
static void
parse_data (GUPnPMediaCollection *collection, const char *data)
{
GUPnPDIDLLiteParser *parser;
GError *error = NULL;
gboolean result;
parser = gupnp_didl_lite_parser_new ();
g_signal_connect_swapped (G_OBJECT (parser),
"container-available",
G_CALLBACK (on_container_available),
collection);
g_signal_connect_swapped (G_OBJECT (parser),
"item-available",
G_CALLBACK (on_item_available),
collection);
result = gupnp_didl_lite_parser_parse_didl_recursive (parser,
data,
TRUE,
&error);
if (!result) {
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (collection);
g_warning ("Failed to parse DIDL-Lite: %s", error->message);
g_error_free (error);
g_clear_object (&priv->container);
if (priv->items) {
g_list_free_full (priv->items, g_object_unref);
priv->items = NULL;
}
}
}
static void
gupnp_media_collection_init (GUPnPMediaCollection *collection)
{
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (collection);
/* Initialize as mutable and decide later on in constructed() if we
* really are. */
priv->mutable = TRUE;
}
static void
gupnp_media_collection_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GUPnPMediaCollection *collection = GUPNP_MEDIA_COLLECTION (object);
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (collection);
switch (property_id) {
case PROP_AUTHOR:
gupnp_media_collection_set_author (collection,
g_value_get_string (value));
break;
case PROP_TITLE:
gupnp_media_collection_set_title (collection,
g_value_get_string (value));
break;
case PROP_DATA:
priv->data = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_media_collection_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GUPnPMediaCollection *collection;
collection = GUPNP_MEDIA_COLLECTION (object);
switch (property_id) {
case PROP_AUTHOR:
g_value_set_string
(value, gupnp_media_collection_get_author (collection));
break;
case PROP_TITLE:
g_value_set_string
(value, gupnp_media_collection_get_title (collection));
break;
case PROP_MUTABLE:
g_value_set_boolean
(value, gupnp_media_collection_get_mutable (collection));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_media_collection_constructed (GObject *object)
{
GUPnPMediaCollection *collection;
GObjectClass *object_class;
collection = GUPNP_MEDIA_COLLECTION (object);
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (collection);
/* Check if we have some data. If there's data, we assume that the
* user meant to parse a playlist. We ignore title and author then. */
if (priv->data != NULL) {
g_clear_object (&priv->container);
g_clear_object (&priv->writer);
parse_data (collection, priv->data);
priv->mutable = FALSE;
} else if (priv->writer == NULL) {
priv->writer = gupnp_didl_lite_writer_new (NULL);
priv->mutable = TRUE;
}
/* Chain up */
object_class = G_OBJECT_CLASS (gupnp_media_collection_parent_class);
if (object_class->constructed != NULL)
object_class->constructed (object);
}
static void
gupnp_media_collection_dispose (GObject *object)
{
GUPnPMediaCollection *collection;
GObjectClass *object_class;
collection = GUPNP_MEDIA_COLLECTION (object);
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (collection);
g_clear_object (&priv->writer);
if (priv->items) {
g_list_free_full (priv->items, g_object_unref);
priv->items = NULL;
}
g_clear_object (&priv->container);
g_clear_pointer (&priv->data, g_free);
object_class = G_OBJECT_CLASS (gupnp_media_collection_parent_class);
object_class->dispose (object);
}
static void
gupnp_media_collection_class_init (GUPnPMediaCollectionClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->set_property = gupnp_media_collection_set_property;
object_class->get_property = gupnp_media_collection_get_property;
object_class->constructed = gupnp_media_collection_constructed;
object_class->dispose = gupnp_media_collection_dispose;
/**
* GUPnPMediaCollection:author:
*
* The author of this media collection.
**/
g_object_class_install_property
(object_class,
PROP_AUTHOR,
g_param_spec_string ("author",
"Author",
"The author of this collection",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
/**
* GUPnPMediaCollection:title:
*
* The title of this media collection.
**/
g_object_class_install_property
(object_class,
PROP_AUTHOR,
g_param_spec_string ("title",
"Title",
"The title of this collection",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
/**
* GUPnPMediaCollection:mutable:
*
* Whether this media collation is modifyable or not.
**/
g_object_class_install_property
(object_class,
PROP_MUTABLE,
g_param_spec_boolean ("mutable",
"Mutable",
"The mutability of this collection",
FALSE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* GUPnPMediaCollection:data:
*
* Block of data to parse a collection from. If data is set upon
* construction it will override the other properties and create a
* unmutable collection parsed from data.
**/
g_object_class_install_property
(object_class,
PROP_DATA,
g_param_spec_string ("data",
"Data",
"Data to construct the playlist from",
NULL,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}
/**
* gupnp_media_collection_new:
*
* Create a new writable media collection.
*
* Returns: (transfer full): A new #GUPnPMediaCollection.
**/
GUPnPMediaCollection *
gupnp_media_collection_new (void)
{
return g_object_new (GUPNP_TYPE_MEDIA_COLLECTION, NULL);
}
/**
* gupnp_media_collection_new_from_string:
* @data: XML string.
*
* Parse a new #GUPnPMediaCollection from a block of XML data.
*
* Returns: (transfer full): A new #GUPnPMediaCollection.
**/
GUPnPMediaCollection *
gupnp_media_collection_new_from_string (const char *data)
{
return g_object_new (GUPNP_TYPE_MEDIA_COLLECTION,
"data", data,
NULL);
}
/**
* gupnp_media_collection_set_title:
* @collection: #GUPnPMediaCollection
* @title: New Title of this collection;
*
* Set the title of a #GUPnPMediaCollection.
**/
void
gupnp_media_collection_set_title (GUPnPMediaCollection *collection,
const char *title)
{
GUPnPDIDLLiteContainer *container;
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (collection);
g_return_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection));
g_return_if_fail (priv->mutable);
if (title == NULL)
return;
if (priv->container != NULL) {
gupnp_didl_lite_object_set_title (priv->container, title);
return;
}
if (priv->writer == NULL)
priv->writer = gupnp_didl_lite_writer_new (NULL);
container = gupnp_didl_lite_writer_add_container (priv->writer);
priv->container = GUPNP_DIDL_LITE_OBJECT (container);
reparent_children (collection);
gupnp_didl_lite_object_set_title (priv->container, title);
}
/**
* gupnp_media_collection_get_title:
* @collection: #GUPnPMediaCollection
*
* Returns: (nullable)(transfer none): The title of this media collection or %NULL if not set.
**/
const char *
gupnp_media_collection_get_title (GUPnPMediaCollection *collection)
{
g_return_val_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection), NULL);
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (collection);
if (priv->container == NULL)
return NULL;
return gupnp_didl_lite_object_get_title (priv->container);
}
/**
* gupnp_media_collection_set_author:
* @collection: #GUPnPMediaCollection
* @author: New author of this media collection.
*
* Set the author of the media collection
**/
void
gupnp_media_collection_set_author (GUPnPMediaCollection *collection,
const char *author)
{
GUPnPDIDLLiteContainer *container;
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (collection);
g_return_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection));
g_return_if_fail (priv->mutable);
if (author == NULL)
return;
if (priv->container != NULL) {
gupnp_didl_lite_object_set_creator (priv->container, author);
return;
}
if (priv->writer == NULL)
priv->writer = gupnp_didl_lite_writer_new (NULL);
container = gupnp_didl_lite_writer_add_container (priv->writer);
priv->container = GUPNP_DIDL_LITE_OBJECT (container);
reparent_children (collection);
gupnp_didl_lite_object_set_creator (priv->container, author);
}
/**
* gupnp_media_collection_get_author:
* @collection: #GUPnPMediaCollection
*
* Returns: The author of this media collection or %NULL if not set.
**/
const char *
gupnp_media_collection_get_author (GUPnPMediaCollection *collection)
{
g_return_val_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection), NULL);
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (collection);
if (priv->container == NULL)
return NULL;
return gupnp_didl_lite_object_get_creator (priv->container);
}
/**
* gupnp_media_collection_add_item:
* @collection: #GUPnPMediaCollection
*
* Return value: (transfer full): A new #GUPnPDIDLLiteItem object. Unref after
* use.
**/
GUPnPDIDLLiteItem *
gupnp_media_collection_add_item (GUPnPMediaCollection *collection)
{
GUPnPDIDLLiteItem *item = NULL;
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (collection);
g_return_val_if_fail (collection != NULL, NULL);
g_return_val_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection), NULL);
g_return_val_if_fail (priv->mutable, NULL);
if (priv->container != NULL)
item = gupnp_didl_lite_writer_add_container_child_item (
priv->writer,
GUPNP_DIDL_LITE_CONTAINER (priv->container));
else
item = gupnp_didl_lite_writer_add_item (priv->writer);
/* Keep a reference of the object in case we need to do reparenting */
priv->items = g_list_prepend (priv->items, g_object_ref (item));
/* Mandatory in DLNA for object. Not specified if mandatory for
* DIDL_S, but to avoid problems with clients reusing their normal
* DIDL-Lite parser, we set it here if the application doesn't.
*/
gupnp_didl_lite_object_set_restricted (GUPNP_DIDL_LITE_OBJECT (item),
TRUE);
return item;
}
/**
* gupnp_media_collection_get_string:
* @collection: #GUPnPMediaCollection
*
* Return value: (transfer full): XML string representing this media
* collection. g_free() after use. If the colleciton is not mutable, returns a
* copy of the original string.
**/
char *
gupnp_media_collection_get_string (GUPnPMediaCollection *collection)
{
g_return_val_if_fail (collection != NULL, NULL);
g_return_val_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection), NULL);
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (collection);
if (priv->data)
return g_strdup (priv->data);
gupnp_didl_lite_writer_filter_tags (priv->writer, DIDL_S_FILTER);
return gupnp_didl_lite_writer_get_string (priv->writer);
}
/**
* gupnp_media_collection_get_items:
* @collection: #GUPnPMediaCollection
*
* Return value: (transfer full)(element-type GUPnPDIDLLiteItem): A #GList
* containing the elemens of this collection, in proper order. Unref all items
* and free the list after use.
**/
GList *
gupnp_media_collection_get_items (GUPnPMediaCollection *collection)
{
g_return_val_if_fail (collection != NULL, NULL);
g_return_val_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection), NULL);
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (collection);
return g_list_reverse (
g_list_copy_deep (priv->items, (GCopyFunc) g_object_ref, NULL));
}
/**
* gupnp_media_collection_get_mutable:
* @collection: #GUPnPMediaCollection
*
* Return value: #TRUE if the collections is modifiable, #FALSE otherwise.
**/
gboolean
gupnp_media_collection_get_mutable (GUPnPMediaCollection *collection)
{
g_return_val_if_fail (collection != NULL, FALSE);
g_return_val_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection), FALSE);
GUPnPMediaCollectionPrivate *priv =
gupnp_media_collection_get_instance_private (collection);
return priv->mutable;
}
0707010000004D000081A40000000000000000000000016860451500000765000000000000000000000000000000000000003500000000gupnp-av-0.14.4/libgupnp-av/gupnp-media-collection.h/*
* Copyright (C) 2012 Intel Corporation.
*
* Authors: Jens Georg <jensg@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_DIDL_LITE_MEDIA_COLLECTION_H
#define GUPNP_DIDL_LITE_MEDIA_COLLECTION_H
#include <glib-object.h>
#include "gupnp-didl-lite-item.h"
G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE (GUPnPMediaCollection,
gupnp_media_collection,
GUPNP,
MEDIA_COLLECTION,
GObject)
#define GUPNP_TYPE_MEDIA_COLLECTION (gupnp_media_collection_get_type ())
struct _GUPnPMediaCollectionClass {
GObjectClass parent_class;
/* padding */
void (* _gupnp_reserved1) (void);
void (* _gupnp_reserved2) (void);
void (* _gupnp_reserved3) (void);
void (* _gupnp_reserved4) (void);
};
GUPnPMediaCollection *
gupnp_media_collection_new (void);
GUPnPMediaCollection *
gupnp_media_collection_new_from_string (const char *data);
void
gupnp_media_collection_set_title (GUPnPMediaCollection *collection,
const char *title);
const char *
gupnp_media_collection_get_title (GUPnPMediaCollection *collection);
void
gupnp_media_collection_set_author (GUPnPMediaCollection *collection,
const char *author);
const char *
gupnp_media_collection_get_author (GUPnPMediaCollection *collection);
GUPnPDIDLLiteItem *
gupnp_media_collection_add_item (GUPnPMediaCollection *collection);
char *
gupnp_media_collection_get_string (GUPnPMediaCollection *collection);
GList *
gupnp_media_collection_get_items (GUPnPMediaCollection *collection);
gboolean
gupnp_media_collection_get_mutable (GUPnPMediaCollection *collection);
G_END_DECLS
#endif /* GUPNP_DIDL_LITE_MEDIA_COLLECTION_H */
0707010000004E000081A4000000000000000000000001686045150000825C000000000000000000000000000000000000003200000000gupnp-av-0.14.4/libgupnp-av/gupnp-protocol-info.c/*
* Copyright (C) 2009 Nokia Corporation.
* Copyright (C) 2007, 2008 OpenedHand Ltd.
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
* Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPProtocolInfo:
*
* UPnP AV ProtocolInfo
*
* #GUPnPProtocolInfo provides a convenient API to deal with ProtocolInfo
* strings used in UPnP AV specifications.
*/
#include <config.h>
#include <string.h>
#include <stdlib.h>
#include "gupnp-protocol-info.h"
#include "gupnp-av-error.h"
struct _GUPnPProtocolInfoPrivate {
char *protocol;
char *network;
char *mime_type;
char *dlna_profile;
char **play_speeds;
GUPnPDLNAConversion dlna_conversion;
GUPnPDLNAOperation dlna_operation;
GUPnPDLNAFlags dlna_flags;
};
typedef struct _GUPnPProtocolInfoPrivate GUPnPProtocolInfoPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GUPnPProtocolInfo,
gupnp_protocol_info,
G_TYPE_OBJECT)
enum {
PROP_0,
PROP_PROTOCOL,
PROP_NETWORK,
PROP_MIME_TYPE,
PROP_DLNA_PROFILE,
PROP_PLAY_SPEEDS,
PROP_DLNA_CONVERSION,
PROP_DLNA_OPERATION,
PROP_DLNA_FLAGS
};
static void
parse_additional_info (const char *additional_info,
GUPnPProtocolInfo *info)
{
char **tokens = NULL;
short i;
if (strcmp (additional_info, "*") == 0)
return;
tokens = g_strsplit (additional_info, ";", -1);
if (tokens == NULL) {
g_warning ("Invalid additional info in DIDL-Lite info: %s",
additional_info);
return;
}
for (i = 0; tokens[i]; i++) {
char *p;
p = g_strstr_len (tokens[i],
strlen (tokens[i]),
"DLNA.ORG_PN=");
if (p != NULL) {
p += 12; /* end of "DLNA.ORG_PN=" */
gupnp_protocol_info_set_dlna_profile (info, p);
continue;
}
p = g_strstr_len (tokens[i],
strlen (tokens[i]),
"DLNA.ORG_PS=");
if (p != NULL) {
char **play_speeds;
p += 12; /* end of "DLNA.ORG_PS=" */
play_speeds = g_strsplit (p, ",", -1);
gupnp_protocol_info_set_play_speeds
(info,
(const char **) play_speeds);
g_strfreev (play_speeds);
continue;
}
p = g_strstr_len (tokens[i],
strlen (tokens[i]),
"DLNA.ORG_CI=");
if (p != NULL) {
p += 12; /* end of "DLNA.ORG_CI=" */
gupnp_protocol_info_set_dlna_conversion (info,
atoi (p));
continue;
}
p = g_strstr_len (tokens[i],
strlen (tokens[i]),
"DLNA.ORG_OP=");
if (p != NULL) {
p += 12; /* end of "DLNA.ORG_OP=" */
gupnp_protocol_info_set_dlna_operation
(info,
strtoul (p, NULL, 16));
continue;
}
p = g_strstr_len (tokens[i],
strlen (tokens[i]),
"DLNA.ORG_FLAGS=");
if (p != NULL) {
p += 15; /* end of "DLNA.ORG_FLAGS=" */
if (strlen (p) > 8)
p[8] = '\0';
gupnp_protocol_info_set_dlna_flags
(info,
strtoul (p, NULL, 16));
continue;
}
}
g_strfreev (tokens);
}
static gboolean
is_transport_compat (GUPnPProtocolInfo *info1,
GUPnPProtocolInfo *info2)
{
const char *protocol1;
const char *protocol2;
protocol1 = gupnp_protocol_info_get_protocol (info1);
protocol2 = gupnp_protocol_info_get_protocol (info2);
if (protocol1[0] != '*' &&
protocol2[0] != '*' &&
g_ascii_strcasecmp (protocol1, protocol2) != 0)
return FALSE;
else if (g_ascii_strcasecmp ("internal", protocol1) == 0 &&
strcmp (gupnp_protocol_info_get_network (info1),
gupnp_protocol_info_get_network (info2)) != 0)
/* Host must be the same in case of INTERNAL protocol */
return FALSE;
else
return TRUE;
}
static gboolean
is_content_format_compat (GUPnPProtocolInfo *info1,
GUPnPProtocolInfo *info2)
{
const char *mime_type1;
const char *mime_type2;
mime_type1 = gupnp_protocol_info_get_mime_type (info1);
mime_type2 = gupnp_protocol_info_get_mime_type (info2);
if (mime_type1 [0] != '*' &&
mime_type2 [0] != '*' &&
g_ascii_strcasecmp (mime_type1, mime_type2) != 0 &&
/* Handle special case for LPCM: It is the only content type that
* make use of mime-type parameters that we know of.
*
* Example: audio/L16;rate=44100;channels=2
*/
!((g_ascii_strcasecmp (mime_type1, "audio/L16") == 0 &&
g_ascii_strncasecmp (mime_type2, "audio/L16", 9) == 0) ||
(g_ascii_strcasecmp (mime_type2, "audio/L16") == 0 &&
g_ascii_strncasecmp (mime_type1, "audio/L16", 9) == 0)))
return FALSE;
else
return TRUE;
}
static gboolean
is_additional_info_compat (GUPnPProtocolInfo *info1,
GUPnPProtocolInfo *info2)
{
const char *profile1;
const char *profile2;
profile1 = gupnp_protocol_info_get_dlna_profile (info1);
profile2 = gupnp_protocol_info_get_dlna_profile (info2);
if (profile1 == NULL ||
profile2 == NULL ||
profile1 [0] == '*' ||
profile2 [0] == '*' ||
g_ascii_strcasecmp (profile1, profile2) == 0)
return TRUE;
else
return FALSE;
}
static void
add_dlna_info (GString *str,
GUPnPProtocolInfo *info)
{
const char *dlna_profile;
const char **speeds;
GUPnPDLNAConversion conversion;
GUPnPDLNAOperation operation;
GUPnPDLNAFlags flags;
dlna_profile = gupnp_protocol_info_get_dlna_profile (info);
if (dlna_profile == NULL) {
g_string_append_printf (str, ":");
} else {
g_string_append_printf (str, ":DLNA.ORG_PN=%s;", dlna_profile);
}
operation = gupnp_protocol_info_get_dlna_operation (info);
if (operation != GUPNP_DLNA_OPERATION_NONE &&
/* the OP parameter is only allowed for the "http-get"
* and "rtsp-rtp-udp" protocols
*/
(strcmp (gupnp_protocol_info_get_protocol (info),
"http-get") == 0 ||
strcmp (gupnp_protocol_info_get_protocol (info),
"rtsp-rtp-udp") == 0))
g_string_append_printf (str, "DLNA.ORG_OP=%.2x;", operation);
/* Specify PS parameter if list of play speeds is provided */
speeds = gupnp_protocol_info_get_play_speeds (info);
if (speeds != NULL) {
int i;
g_string_append (str, "DLNA.ORG_PS=");
for (i = 0; speeds[i]; i++) {
g_string_append (str, speeds[i]);
if (speeds[i + 1])
g_string_append_c (str, ',');
}
g_string_append_c (str, ';');
}
conversion = gupnp_protocol_info_get_dlna_conversion (info);
/* omit the CI parameter for non-converted content */
if (conversion != GUPNP_DLNA_CONVERSION_NONE)
g_string_append_printf (str, "DLNA.ORG_CI=%d;", conversion);
flags = gupnp_protocol_info_get_dlna_flags (info);
/* Omit the FLAGS parameter if no or DLNA profile are set */
if (flags != GUPNP_DLNA_FLAGS_NONE && dlna_profile != NULL) {
g_string_append_printf (str, "DLNA.ORG_FLAGS=%.8x", flags);
/* append 24 reserved hex-digits */
g_string_append_printf (str,
"0000" "0000" "0000"
"0000" "0000" "0000");
}
/* if nothing of the above was set, use the "match all" rule */
switch (str->str[str->len - 1]) {
case ':':
g_string_append_c (str, '*');
break;
case ';':
g_string_erase (str, str->len - 1, 1);
break;
default:
break;
}
}
static void
gupnp_protocol_info_init (GUPnPProtocolInfo *info)
{
}
static void
gupnp_protocol_info_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GUPnPProtocolInfo *info;
info = GUPNP_PROTOCOL_INFO (object);
switch (property_id) {
case PROP_PROTOCOL:
gupnp_protocol_info_set_protocol (info,
g_value_get_string (value));
break;
case PROP_NETWORK:
gupnp_protocol_info_set_network (info,
g_value_get_string (value));
break;
case PROP_MIME_TYPE:
gupnp_protocol_info_set_mime_type (info,
g_value_get_string (value));
break;
case PROP_DLNA_PROFILE:
gupnp_protocol_info_set_dlna_profile
(info,
g_value_get_string (value));
break;
case PROP_PLAY_SPEEDS:
gupnp_protocol_info_set_play_speeds (info,
g_value_get_boxed (value));
break;
case PROP_DLNA_CONVERSION:
gupnp_protocol_info_set_dlna_conversion
(info,
g_value_get_flags (value));
break;
case PROP_DLNA_OPERATION:
gupnp_protocol_info_set_dlna_operation
(info,
g_value_get_flags (value));
break;
case PROP_DLNA_FLAGS:
gupnp_protocol_info_set_dlna_flags
(info,
g_value_get_flags (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_protocol_info_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GUPnPProtocolInfo *info;
info = GUPNP_PROTOCOL_INFO (object);
switch (property_id) {
case PROP_PROTOCOL:
g_value_set_string (value,
gupnp_protocol_info_get_protocol (info));
break;
case PROP_NETWORK:
g_value_set_string (value,
gupnp_protocol_info_get_network (info));
break;
case PROP_MIME_TYPE:
g_value_set_string (value,
gupnp_protocol_info_get_mime_type (info));
break;
case PROP_DLNA_PROFILE:
g_value_set_string
(value,
gupnp_protocol_info_get_dlna_profile (info));
break;
case PROP_PLAY_SPEEDS:
g_value_set_boxed (value,
gupnp_protocol_info_get_play_speeds (info));
break;
case PROP_DLNA_CONVERSION:
g_value_set_flags
(value,
gupnp_protocol_info_get_dlna_conversion
(info));
break;
case PROP_DLNA_OPERATION:
g_value_set_flags
(value,
gupnp_protocol_info_get_dlna_operation (info));
break;
case PROP_DLNA_FLAGS:
g_value_set_flags (value,
gupnp_protocol_info_get_dlna_flags (info));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gupnp_protocol_info_finalize (GObject *object)
{
GObjectClass *object_class;
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (
GUPNP_PROTOCOL_INFO (object));
g_free (priv->protocol);
g_free (priv->network);
g_free (priv->mime_type);
g_free (priv->dlna_profile);
g_clear_pointer(&priv->play_speeds,g_strfreev);
object_class = G_OBJECT_CLASS (gupnp_protocol_info_parent_class);
object_class->finalize (object);
}
static void
gupnp_protocol_info_class_init (GUPnPProtocolInfoClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->set_property = gupnp_protocol_info_set_property;
object_class->get_property = gupnp_protocol_info_get_property;
object_class->finalize = gupnp_protocol_info_finalize;
/**
* GUPnPProtocolInfo:protocol:
*
* The protocol of this info.
**/
g_object_class_install_property
(object_class,
PROP_PROTOCOL,
g_param_spec_string ("protocol",
"Protocol",
"The protocol of this info.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPProtocolInfo:network:
*
* The network this info is associated with.
**/
g_object_class_install_property
(object_class,
PROP_NETWORK,
g_param_spec_string ("network",
"Network",
"The network this info is associated"
" with.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPProtocolInfo:mime-type:
*
* The MIME-type of this info.
**/
g_object_class_install_property
(object_class,
PROP_MIME_TYPE,
g_param_spec_string ("mime-type",
"MIMEType",
"The MIME-type of this info.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPProtocolInfo:dlna-profile:
*
* The DLNA profile of this info.
**/
g_object_class_install_property
(object_class,
PROP_DLNA_PROFILE,
g_param_spec_string ("dlna-profile",
"DLNAProfile",
"The DLNA profile of this info.",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPProtocolInfo:play-speeds:
*
* The allowed play speeds on this info in the form of array of
* strings.
**/
g_object_class_install_property
(object_class,
PROP_PLAY_SPEEDS,
g_param_spec_boxed ("play-speeds",
"PlaySpeeds",
"The allowed play speeds on this"
" info in the form of array of"
" strings.",
G_TYPE_STRV,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
/**
* GUPnPProtocolInfo:dlna-conversion:
*
* The DLNA conversion flags.
**/
g_object_class_install_property (
object_class,
PROP_DLNA_CONVERSION,
g_param_spec_flags ("dlna-conversion",
"DLNAConversion",
"The DLNA conversion flags.",
GUPNP_TYPE_DLNA_CONVERSION,
GUPNP_DLNA_CONVERSION_NONE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
/**
* GUPnPProtocolInfo:dlna-operation:
*
* The DLNA operation flags.
**/
g_object_class_install_property (
object_class,
PROP_DLNA_OPERATION,
g_param_spec_flags ("dlna-operation",
"DLNAOperation",
"The DLNA operation flags.",
GUPNP_TYPE_DLNA_OPERATION,
GUPNP_DLNA_OPERATION_NONE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
/**
* GUPnPProtocolInfo:dlna-flags:
*
* Various generic DLNA flags.
**/
g_object_class_install_property (
object_class,
PROP_DLNA_FLAGS,
g_param_spec_flags ("dlna-flags",
"DLNAFlags",
"Various generic DLNA flags.",
GUPNP_TYPE_DLNA_FLAGS,
GUPNP_DLNA_FLAGS_NONE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
}
/**
* gupnp_protocol_info_new:
*
* Return value: A new #GUPnPProtocolInfo object. Unref after usage.
**/
GUPnPProtocolInfo *
gupnp_protocol_info_new (void)
{
return g_object_new (GUPNP_TYPE_PROTOCOL_INFO,
NULL);
}
/**
* gupnp_protocol_info_new_from_string:
* @protocol_info: The protocol info string
* @error: The location where to store any error, or NULL
*
* Parses the @protocol_info string and creates a new #GUPnPProtocolInfo object
* as a result.
*
* Return value: A new #GUPnPProtocolInfo object. Unref after usage.
**/
GUPnPProtocolInfo *
gupnp_protocol_info_new_from_string (const char *protocol_info,
GError **error)
{
// FIXME: make a property...
GUPnPProtocolInfo *info;
char **tokens;
g_return_val_if_fail (protocol_info != NULL, NULL);
tokens = g_strsplit (protocol_info, ":", 4);
if (tokens[0] == NULL ||
tokens[1] == NULL ||
tokens[2] == NULL ||
tokens[3] == NULL) {
g_set_error (error,
GUPNP_PROTOCOL_ERROR,
GUPNP_PROTOCOL_ERROR_INVALID_SYNTAX,
"Failed to parse protocolInfo string: \n%s",
protocol_info);
g_strfreev (tokens);
return NULL;
}
info = gupnp_protocol_info_new ();
gupnp_protocol_info_set_protocol (info, tokens[0]);
gupnp_protocol_info_set_network (info, tokens[1]);
gupnp_protocol_info_set_mime_type (info, tokens[2]);
parse_additional_info (tokens[3], info);
g_strfreev (tokens);
return info;
}
/**
* gupnp_protocol_info_to_string:
* @info: The #GUPnPProtocolInfo
*
* Provides the string representation of @info.
*
* Return value:(transfer full)(nullable): String representation of @info.
* #g_free after usage.
**/
char *
gupnp_protocol_info_to_string (GUPnPProtocolInfo *info)
{
GString *str;
const char *protocol;
const char *mime_type;
const char *network;
g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL);
protocol = gupnp_protocol_info_get_protocol (info);
mime_type = gupnp_protocol_info_get_mime_type (info);
network = gupnp_protocol_info_get_network (info);
g_return_val_if_fail (protocol != NULL, NULL);
g_return_val_if_fail (mime_type != NULL, NULL);
str = g_string_new ("");
g_string_append (str, protocol);
g_string_append_c (str, ':');
if (network != NULL)
g_string_append (str, network);
else
g_string_append_c (str, '*');
g_string_append_c (str, ':');
g_string_append (str, mime_type);
add_dlna_info (str, info);
return g_string_free (str, FALSE);
}
/**
* gupnp_protocol_info_get_protocol:
* @info: A #GUPnPProtocolInfo
*
* Get the protocol of this info.
*
* Return value:(transfer none)(nullable): The protocol of this info or %NULL. This string should not
* be freed.
**/
const char *
gupnp_protocol_info_get_protocol (GUPnPProtocolInfo *info)
{
g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL);
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
return priv->protocol;
}
/**
* gupnp_protocol_info_get_network:
* @info: A #GUPnPProtocolInfo
*
* Get the network this info is associated with.
*
* Return value:(transfer none)(nullable): The network string or %NULL. This string should not be freed.
**/
const char *
gupnp_protocol_info_get_network (GUPnPProtocolInfo *info)
{
g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL);
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
return priv->network;
}
/**
* gupnp_protocol_info_get_mime_type:
* @info: A #GUPnPProtocolInfo
*
* Get the MIME-type of this info.
*
* Return value:(transfer none)(nullable): The MIME-type of this info or %NULL. This string should not
* be freed.
**/
const char *
gupnp_protocol_info_get_mime_type (GUPnPProtocolInfo *info)
{
g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL);
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
return priv->mime_type;
}
/**
* gupnp_protocol_info_get_dlna_profile:
* @info: A #GUPnPProtocolInfo
*
* Get the DLNA profile of this info.
*
* Return value:(transfer none)(nullable): The DLNA profile of this info or %NULL. This string should
* not be freed.
**/
const char *
gupnp_protocol_info_get_dlna_profile (GUPnPProtocolInfo *info)
{
g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL);
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
return priv->dlna_profile;
}
/**
* gupnp_protocol_info_get_play_speeds:
* @info: A #GUPnPProtocolInfo
*
* Get the allowed play speeds on this info in the form of array of strings.
*
* Returns: (transfer none)(nullable): The allowed play speeds as array of strings or %NULL. This
* return array and it's content must not be modified or freed.
**/
const char **
gupnp_protocol_info_get_play_speeds (GUPnPProtocolInfo *info)
{
g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL);
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
return (const char **) priv->play_speeds;
}
/**
* gupnp_protocol_info_get_dlna_conversion:
* @info: A #GUPnPProtocolInfo
*
* Get the DLNA conversion flags.
*
* Return value: The DLNA conversion flags.
**/
GUPnPDLNAConversion
gupnp_protocol_info_get_dlna_conversion (GUPnPProtocolInfo *info)
{
g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info),
GUPNP_DLNA_CONVERSION_NONE);
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
return priv->dlna_conversion;
}
/**
* gupnp_protocol_info_get_dlna_operation:
* @info: A #GUPnPProtocolInfo
*
* Get the DLNA operation flags.
*
* Return value: The DLNA operation flags.
**/
GUPnPDLNAOperation
gupnp_protocol_info_get_dlna_operation (GUPnPProtocolInfo *info)
{
g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info),
GUPNP_DLNA_OPERATION_NONE);
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
return priv->dlna_operation;
}
/**
* gupnp_protocol_info_get_dlna_flags:
* @info: A #GUPnPProtocolInfo
*
* Get the gereric DLNA flags.
*
* Return value: The generic DLNA flags.
**/
GUPnPDLNAFlags
gupnp_protocol_info_get_dlna_flags (GUPnPProtocolInfo *info)
{
g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info),
GUPNP_DLNA_FLAGS_NONE);
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
return priv->dlna_flags;
}
/**
* gupnp_protocol_info_set_protocol:
* @info: A #GUPnPProtocolInfo
* @protocol: The protocol string
*
* Set the protocol of this info.
**/
void
gupnp_protocol_info_set_protocol (GUPnPProtocolInfo *info,
const char *protocol)
{
g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
g_free (priv->protocol);
priv->protocol = g_strdup (protocol);
g_object_notify (G_OBJECT (info), "protocol");
}
/**
* gupnp_protocol_info_set_network:
* @info: A #GUPnPProtocolInfo
* @network: The network string
*
* Set the network this info is associated with.
**/
void
gupnp_protocol_info_set_network (GUPnPProtocolInfo *info,
const char *network)
{
g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
g_free (priv->network);
priv->network = g_strdup (network);
g_object_notify (G_OBJECT (info), "network");
}
/**
* gupnp_protocol_info_set_mime_type:
* @info: A #GUPnPProtocolInfo
* @mime_type: The MIME-type string
*
* Set the MIME-type of this info.
**/
void
gupnp_protocol_info_set_mime_type (GUPnPProtocolInfo *info,
const char *mime_type)
{
g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
g_free (priv->mime_type);
priv->mime_type = g_strdup (mime_type);
g_object_notify (G_OBJECT (info), "mime-type");
}
/**
* gupnp_protocol_info_set_dlna_profile:
* @info: A #GUPnPProtocolInfo
* @profile: The DLNA profile string
*
* Set the DLNA profile of this info.
**/
void
gupnp_protocol_info_set_dlna_profile (GUPnPProtocolInfo *info,
const char *profile)
{
g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
g_free (priv->dlna_profile);
priv->dlna_profile = g_strdup (profile);
g_object_notify (G_OBJECT (info), "dlna-profile");
}
/**
* gupnp_protocol_info_set_play_speeds:
* @info: A #GUPnPProtocolInfo
* @speeds: (array zero-terminated=1): The allowed play speeds
*
* Set the allowed play speeds on this info in the form of array of strings.
* The array must be %NULL-terminated.
**/
void
gupnp_protocol_info_set_play_speeds (GUPnPProtocolInfo *info,
const char **speeds)
{
g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
if (priv->play_speeds)
g_strfreev (priv->play_speeds);
priv->play_speeds = (char **) g_boxed_copy (G_TYPE_STRV, speeds);
g_object_notify (G_OBJECT (info), "play-speeds");
}
/**
* gupnp_protocol_info_set_dlna_conversion:
* @info: A #GUPnPProtocolInfo
* @conversion: The bitwise OR of one or more DLNA conversion flags
*
* Set the DLNA conversion flags.
**/
void
gupnp_protocol_info_set_dlna_conversion (GUPnPProtocolInfo *info,
GUPnPDLNAConversion conversion)
{
g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
priv->dlna_conversion = conversion;
g_object_notify (G_OBJECT (info), "dlna-conversion");
}
/**
* gupnp_protocol_info_set_dlna_operation:
* @info: A #GUPnPProtocolInfo
* @operation: The bitwise OR of one or more DLNA operation flags
*
* Set the DLNA operation flags.
**/
void
gupnp_protocol_info_set_dlna_operation (GUPnPProtocolInfo *info,
GUPnPDLNAOperation operation)
{
g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
priv->dlna_operation = operation;
g_object_notify (G_OBJECT (info), "dlna-operation");
}
/**
* gupnp_protocol_info_set_dlna_flags:
* @info: A #GUPnPProtocolInfo
* @flags: The bitwise OR of one or more generic DLNA flags
*
* Set the gereric DLNA flags.
**/
void
gupnp_protocol_info_set_dlna_flags (GUPnPProtocolInfo *info,
GUPnPDLNAFlags flags)
{
g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
GUPnPProtocolInfoPrivate *priv =
gupnp_protocol_info_get_instance_private (info);
priv->dlna_flags = flags;
g_object_notify (G_OBJECT (info), "dlna-flags");
}
/**
* gupnp_protocol_info_is_compatible:
* @info1: The first #GUPnPProtocolInfo
* @info2: The second #GUPnPProtocolInfo
*
* Checks if the given protocolInfo string is compatible with @info.
*
* Return value: #TRUE if @protocol_info is compatible with @info, otherwise
* #FALSE.
**/
gboolean
gupnp_protocol_info_is_compatible (GUPnPProtocolInfo *info1,
GUPnPProtocolInfo *info2)
{
g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info1), FALSE);
g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info2), FALSE);
return is_transport_compat (info1, info2) &&
is_content_format_compat (info1, info2) &&
is_additional_info_compat (info1, info2);
}
0707010000004F000081A40000000000000000000000016860451500000CE7000000000000000000000000000000000000003200000000gupnp-av-0.14.4/libgupnp-av/gupnp-protocol-info.h/*
* Copyright (C) 2009 Nokia Corporation.
* Copyright (C) 2007, 2008 OpenedHand Ltd.
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
* Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_PROTOCOL_INFO_H
#define GUPNP_PROTOCOL_INFO_H
#include <stdarg.h>
#include <glib-object.h>
#include "gupnp-dlna.h"
G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE (GUPnPProtocolInfo,
gupnp_protocol_info,
GUPNP,
PROTOCOL_INFO,
GObject)
#define GUPNP_TYPE_PROTOCOL_INFO (gupnp_protocol_info_get_type ())
struct _GUPnPProtocolInfoClass {
GObjectClass parent_class;
/* future padding */
void (* _gupnp_reserved1) (void);
void (* _gupnp_reserved2) (void);
void (* _gupnp_reserved3) (void);
void (* _gupnp_reserved4) (void);
};
GUPnPProtocolInfo *
gupnp_protocol_info_new (void);
GUPnPProtocolInfo *
gupnp_protocol_info_new_from_string (const char *protocol_info,
GError **error);
char *
gupnp_protocol_info_to_string (GUPnPProtocolInfo *info);
gboolean
gupnp_protocol_info_is_compatible (GUPnPProtocolInfo *info1,
GUPnPProtocolInfo *info2);
void
gupnp_protocol_info_set_protocol (GUPnPProtocolInfo *info,
const char *protocol);
void
gupnp_protocol_info_set_network (GUPnPProtocolInfo *info,
const char *network);
void
gupnp_protocol_info_set_mime_type (GUPnPProtocolInfo *info,
const char *mime_type);
void
gupnp_protocol_info_set_dlna_profile (GUPnPProtocolInfo *info,
const char *profile);
void
gupnp_protocol_info_set_play_speeds (GUPnPProtocolInfo *info,
const char **speeds);
void
gupnp_protocol_info_set_dlna_conversion (GUPnPProtocolInfo *info,
GUPnPDLNAConversion conversion);
void
gupnp_protocol_info_set_dlna_operation (GUPnPProtocolInfo *info,
GUPnPDLNAOperation operation);
void
gupnp_protocol_info_set_dlna_flags (GUPnPProtocolInfo *info,
GUPnPDLNAFlags flags);
const char *
gupnp_protocol_info_get_protocol (GUPnPProtocolInfo *info);
const char *
gupnp_protocol_info_get_network (GUPnPProtocolInfo *info);
const char *
gupnp_protocol_info_get_mime_type (GUPnPProtocolInfo *info);
const char *
gupnp_protocol_info_get_dlna_profile (GUPnPProtocolInfo *info);
const char **
gupnp_protocol_info_get_play_speeds (GUPnPProtocolInfo *info);
GUPnPDLNAConversion
gupnp_protocol_info_get_dlna_conversion (GUPnPProtocolInfo *info);
GUPnPDLNAOperation
gupnp_protocol_info_get_dlna_operation (GUPnPProtocolInfo *info);
GUPnPDLNAFlags
gupnp_protocol_info_get_dlna_flags (GUPnPProtocolInfo *info);
G_END_DECLS
#endif /* GUPNP_PROTOCOL_INFO_H */
07070100000050000081A400000000000000000000000168604515000050E0000000000000000000000000000000000000003B00000000gupnp-av-0.14.4/libgupnp-av/gupnp-search-criteria-parser.c/*
* Copyright (C) 2008 OpenedHand Ltd.
*
* Authors: Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
/**
* GUPnPSearchCriteriaParser:
*
* A/V search criteria parser
*
* #GUPnPSearchCriteriaParser parses ContentDirectory search criteria
* strings.
*
* Note that no signals will be emitted if a wildcard is specified,
* and that the user is responsible for ensuring precedence of conjunction
* over disjunction.
*/
#include <config.h>
#include <string.h>
#include "gupnp-search-criteria-parser.h"
#include "gupnp-av-marshal.h"
/* GType for GUPNPSearchCriteriaOp */
GType
gupnp_search_criteria_op_get_type (void)
{
static GType type = 0;
if (type == 0) {
static const GEnumValue values[] = {
{ GUPNP_SEARCH_CRITERIA_OP_EQ,
"GUPNP_SEARCH_CRITERIA_OP_EQ",
"EQ" },
{ GUPNP_SEARCH_CRITERIA_OP_NEQ,
"GUPNP_SEARCH_CRITERIA_OP_NEQ",
"NEQ" },
{ GUPNP_SEARCH_CRITERIA_OP_LESS,
"GUPNP_SEARCH_CRITERIA_OP_LESS",
"LESS" },
{ GUPNP_SEARCH_CRITERIA_OP_LEQ,
"GUPNP_SEARCH_CRITERIA_OP_LEQ",
"LEQ" },
{ GUPNP_SEARCH_CRITERIA_OP_GREATER,
"GUPNP_SEARCH_CRITERIA_OP_GREATER",
"GREATER" },
{ GUPNP_SEARCH_CRITERIA_OP_GEQ,
"GUPNP_SEARCH_CRITERIA_OP_GEQ",
"GEQ" },
{ GUPNP_SEARCH_CRITERIA_OP_CONTAINS,
"GUPNP_SEARCH_CRITERIA_OP_CONTAINS",
"CONTAINS" },
{ GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN,
"GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN",
"DOES_NOT_CONTAIN" },
{ GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM,
"GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM",
"DERIVED_FROM" },
{ GUPNP_SEARCH_CRITERIA_OP_EXISTS,
"GUPNP_SEARCH_CRITERIA_OP_EXISTS",
"EXISTS" },
{ 0, NULL, NULL }
};
type = g_enum_register_static
(g_intern_static_string (
"GUPnPSearchCriteriaOp"),
values);
}
return type;
}
/* GUPnPSearchCriteriaParserError */
GQuark
gupnp_search_criteria_parser_error_quark (void)
{
return g_quark_from_static_string
("gupnp-search-criteria-parser-error-quark");
}
struct _GUPnPSearchCriteriaParserPrivate {
GScanner *scanner;
};
typedef struct _GUPnPSearchCriteriaParserPrivate
GUPnPSearchCriteriaParserPrivate;
/* GUPnPSearchCriteriaParser */
G_DEFINE_TYPE_WITH_PRIVATE (GUPnPSearchCriteriaParser,
gupnp_search_criteria_parser,
G_TYPE_OBJECT)
enum {
BEGIN_PARENS,
END_PARENS,
CONJUNCTION,
DISJUNCTION,
EXPRESSION,
SIGNAL_LAST
};
static guint signals[SIGNAL_LAST];
/* Additional parsable symbols */
enum {
SYMBOL_ASTERISK = G_TOKEN_LAST + 11,
SYMBOL_AND = G_TOKEN_LAST + 12,
SYMBOL_OR = G_TOKEN_LAST + 13,
SYMBOL_TRUE = G_TOKEN_LAST + 14,
SYMBOL_FALSE = G_TOKEN_LAST + 15
};
#define NUM_SYMBOLS 15
struct {
const char *name;
int token;
} symbols[NUM_SYMBOLS] = {
{ "*",
SYMBOL_ASTERISK },
{ "and",
SYMBOL_AND },
{ "or",
SYMBOL_OR },
{ "=",
GUPNP_SEARCH_CRITERIA_OP_EQ },
{ "!=",
GUPNP_SEARCH_CRITERIA_OP_NEQ },
{ "<",
GUPNP_SEARCH_CRITERIA_OP_LESS },
{ "<=",
GUPNP_SEARCH_CRITERIA_OP_LEQ },
{ ">",
GUPNP_SEARCH_CRITERIA_OP_GREATER },
{ ">=",
GUPNP_SEARCH_CRITERIA_OP_GEQ },
{ "contains",
GUPNP_SEARCH_CRITERIA_OP_CONTAINS },
{ "doesNotContain",
GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN },
{ "derivedfrom",
GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM },
{ "exists",
GUPNP_SEARCH_CRITERIA_OP_EXISTS },
{ "true",
SYMBOL_TRUE },
{ "false",
SYMBOL_FALSE }
};
static void
gupnp_search_criteria_parser_init (GUPnPSearchCriteriaParser *parser)
{
GUPnPSearchCriteriaParserPrivate *priv =
gupnp_search_criteria_parser_get_instance_private (parser);
/* Set up GScanner */
priv->scanner = g_scanner_new (NULL);
priv->scanner->config->cset_skip_characters = (char *)" \t\n\r\012"
"\013\014\015";
priv->scanner->config->scan_identifier_1char = TRUE;
priv->scanner->config->cset_identifier_first = (char *) G_CSET_a_2_z
"_*<>=!@"
G_CSET_A_2_Z;
priv->scanner->config->cset_identifier_nth = (char *)G_CSET_a_2_z
"_0123456789=:@"
G_CSET_A_2_Z
G_CSET_LATINS
G_CSET_LATINC;
priv->scanner->config->symbol_2_token = TRUE;
/* Add symbols */
for (int i = 0; i < NUM_SYMBOLS; i++) {
g_scanner_scope_add_symbol (priv->scanner,
0,
symbols[i].name,
GINT_TO_POINTER (symbols[i].token));
}
}
static void
gupnp_search_criteria_parser_finalize (GObject *object)
{
GObjectClass *gobject_class;
GUPnPSearchCriteriaParser *parser;
parser = GUPNP_SEARCH_CRITERIA_PARSER (object);
GUPnPSearchCriteriaParserPrivate *priv =
gupnp_search_criteria_parser_get_instance_private (parser);
/* Destroy GScanner */
g_scanner_destroy (priv->scanner);
gobject_class =
G_OBJECT_CLASS (gupnp_search_criteria_parser_parent_class);
gobject_class->dispose (object);
}
static void
gupnp_search_criteria_parser_class_init
(GUPnPSearchCriteriaParserClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gupnp_search_criteria_parser_finalize;
/**
* GUPnPSearchCriteriaParser::begin-parens:
* @parser: The #GUPnPSearchCriteriaParser that received the signal
*
* The ::begin_parens signal is emitted to mark the beginning of a
* parenthetical expression.
**/
signals[BEGIN_PARENS] =
g_signal_new ("begin-parens",
GUPNP_TYPE_SEARCH_CRITERIA_PARSER,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GUPnPSearchCriteriaParserClass,
begin_parens),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
/**
* GUPnPSearchCriteriaParser::end-parens:
* @parser: The #GUPnPSearchCriteriaParser that received the signal
*
* The ::end_parens signal is emitted to mark the end of a parenthetical
* expression.
**/
signals[END_PARENS] =
g_signal_new ("end-parens",
GUPNP_TYPE_SEARCH_CRITERIA_PARSER,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GUPnPSearchCriteriaParserClass,
end_parens),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
/**
* GUPnPSearchCriteriaParser::conjunction:
* @parser: The #GUPnPSearchCriteriaParser that received the signal
*
* The ::conjuction signal is emitted whenever a conjuction marker
* (and) is parsed.
**/
signals[CONJUNCTION] =
g_signal_new ("conjunction",
GUPNP_TYPE_SEARCH_CRITERIA_PARSER,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GUPnPSearchCriteriaParserClass,
conjunction),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
/**
* GUPnPSearchCriteriaParser::disjunction:
* @parser: The #GUPnPSearchCriteriaParser that received the signal
*
* The ::disjuction signal is emitted whenever a disjuction marker
* (or&rpar is parsed.
**/
signals[DISJUNCTION] =
g_signal_new ("disjunction",
GUPNP_TYPE_SEARCH_CRITERIA_PARSER,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GUPnPSearchCriteriaParserClass,
disjunction),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
/**
* GUPnPSearchCriteriaParser::expression:
* @parser: The #GUPnPSearchCriteriaParser that received the signal
* @property: The property
* @op: The operator as #GUPnPSearchCriteriaOp
* @value: The value as string
* @error: Place-holder for any possible errors from handler
*
* The ::expression signal is emitted whenever an expression is parsed.
* Set @error and return %FALSE if an error occurred.
**/
signals[EXPRESSION] =
g_signal_new ("expression",
GUPNP_TYPE_SEARCH_CRITERIA_PARSER,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GUPnPSearchCriteriaParserClass,
expression),
NULL,
NULL,
gupnp_av_marshal_BOOLEAN__STRING_UINT_STRING_POINTER,
G_TYPE_BOOLEAN,
4,
G_TYPE_STRING,
GUPNP_TYPE_SEARCH_CRITERIA_OP,
G_TYPE_STRING,
G_TYPE_POINTER);
}
/**
* gupnp_search_criteria_parser_new:
*
* Return value: A new #GUPnPSearchCriteriaParser object.
**/
GUPnPSearchCriteriaParser *
gupnp_search_criteria_parser_new (void)
{
return g_object_new (GUPNP_TYPE_SEARCH_CRITERIA_PARSER, NULL);
}
/* Scan a relExp portion of a search criteria string */
static gboolean
scan_rel_exp (GUPnPSearchCriteriaParser *parser,
GError **error)
{
GTokenValue value;
gboolean ret;
guint token;
GUPnPSearchCriteriaOp op;
char *arg1;
GUPnPSearchCriteriaParserPrivate *priv =
gupnp_search_criteria_parser_get_instance_private (parser);
token = g_scanner_get_next_token (priv->scanner);
g_assert (token == G_TOKEN_IDENTIFIER); /* Already checked */
value = g_scanner_cur_value (priv->scanner);
arg1 = g_strdup (value.v_string);
token = g_scanner_get_next_token (priv->scanner);
switch (token) {
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:
case GUPNP_SEARCH_CRITERIA_OP_CONTAINS:
case GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN:
case GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM:
op = token;
token = g_scanner_get_next_token (priv->scanner);
if (token != G_TOKEN_STRING) {
g_set_error (error,
GUPNP_SEARCH_CRITERIA_PARSER_ERROR,
GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED,
"Expected quoted string at position %u",
g_scanner_cur_position (priv->scanner));
ret = FALSE;
break;
}
value = g_scanner_cur_value (priv->scanner);
g_signal_emit (parser,
signals[EXPRESSION],
0,
arg1,
op,
value.v_string,
error,
&ret);
break;
case GUPNP_SEARCH_CRITERIA_OP_EXISTS:
op = token;
token = g_scanner_get_next_token (priv->scanner);
switch (token) {
case SYMBOL_TRUE:
g_signal_emit (parser, signals[EXPRESSION], 0,
arg1, op, "true", error, &ret);
break;
case SYMBOL_FALSE:
g_signal_emit (parser, signals[EXPRESSION], 0,
arg1, op, "false", error, &ret);
break;
default:
g_set_error (error,
GUPNP_SEARCH_CRITERIA_PARSER_ERROR,
GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED,
"Expected boolean value at position %u",
g_scanner_cur_position (priv->scanner));
ret = FALSE;
break;
}
break;
default:
g_set_error (error,
GUPNP_SEARCH_CRITERIA_PARSER_ERROR,
GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED,
"Expected operator at position %u",
g_scanner_cur_position (priv->scanner));
ret = FALSE;
}
g_free (arg1);
return ret;
}
static gboolean
scan_search_exp (GUPnPSearchCriteriaParser *parser,
GError **error);
/* Scan a Logical operator and the part after that */
static gboolean
scan_logical_op (GUPnPSearchCriteriaParser *parser,
GError **error)
{
gboolean ret;
guint token;
GUPnPSearchCriteriaParserPrivate *priv =
gupnp_search_criteria_parser_get_instance_private (parser);
token = g_scanner_peek_next_token (priv->scanner);
switch (token) {
case SYMBOL_AND:
g_scanner_get_next_token (priv->scanner);
g_signal_emit (parser, signals[CONJUNCTION], 0);
ret = scan_search_exp (parser, error);
break;
case SYMBOL_OR:
g_scanner_get_next_token (priv->scanner);
g_signal_emit (parser, signals[DISJUNCTION], 0);
ret = scan_search_exp (parser, error);
break;
default:
ret = TRUE;
break;
}
return ret;
}
/* Scan a searchExp portion of a search criteria string */
static gboolean
scan_search_exp (GUPnPSearchCriteriaParser *parser,
GError **error)
{
gboolean ret;
guint token;
GUPnPSearchCriteriaParserPrivate *priv =
gupnp_search_criteria_parser_get_instance_private (parser);
token = g_scanner_peek_next_token (priv->scanner);
switch (token) {
case G_TOKEN_LEFT_PAREN:
g_scanner_get_next_token (priv->scanner);
g_signal_emit (parser, signals[BEGIN_PARENS], 0);
ret = scan_search_exp (parser, error);
if (ret == FALSE)
break;
token = g_scanner_get_next_token (priv->scanner);
if (token != G_TOKEN_RIGHT_PAREN) {
g_set_error (
error,
GUPNP_SEARCH_CRITERIA_PARSER_ERROR,
GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED,
"Expected right parenthesis at position %u",
g_scanner_cur_position (priv->scanner));
ret = FALSE;
break;
}
g_signal_emit (parser, signals[END_PARENS], 0);
ret = scan_logical_op (parser, error);
break;
case G_TOKEN_IDENTIFIER:
ret = scan_rel_exp (parser, error);
if (ret == FALSE)
break;
ret = scan_logical_op (parser, error);
break;
default:
g_scanner_get_next_token (priv->scanner);
g_set_error (error,
GUPNP_SEARCH_CRITERIA_PARSER_ERROR,
GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED,
"Expected property name or left parenthesis at "
"position %u",
g_scanner_cur_position (priv->scanner));
ret = FALSE;
}
return ret;
}
/**
* gupnp_search_criteria_parser_parse_text:
* @parser: A #GUPnPSearchCriteriaParser
* @text: The search criteria string to be parsed
* @error: The location where to store the error information if any, or NULL
*
* Parses @text, emitting the various defined signals on the way. If an
* error occured @error will be set.
*
* Return value: TRUE on success.
**/
gboolean
gupnp_search_criteria_parser_parse_text (GUPnPSearchCriteriaParser *parser,
const char *text,
GError **error)
{
gboolean ret;
guint token;
g_return_val_if_fail (GUPNP_IS_SEARCH_CRITERIA_PARSER (parser),
FALSE);
g_return_val_if_fail (text != NULL, FALSE);
GUPnPSearchCriteriaParserPrivate *priv =
gupnp_search_criteria_parser_get_instance_private (parser);
/* Feed into scanner */
g_scanner_input_text (priv->scanner, text, strlen (text));
token = g_scanner_peek_next_token (priv->scanner);
if (token == SYMBOL_ASTERISK) {
g_scanner_get_next_token (priv->scanner);
/* Do nothing. */
ret = TRUE;
} else
ret = scan_search_exp (parser, error);
if (ret == TRUE) {
/* Confirm that we have EOF now */
token = g_scanner_get_next_token (priv->scanner);
if (token != G_TOKEN_EOF) {
g_set_error (error,
GUPNP_SEARCH_CRITERIA_PARSER_ERROR,
GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED,
"Expected EOF at position %u",
g_scanner_cur_position (priv->scanner));
}
}
return ret;
}
07070100000051000081A40000000000000000000000016860451500000F07000000000000000000000000000000000000003B00000000gupnp-av-0.14.4/libgupnp-av/gupnp-search-criteria-parser.h/*
* Copyright (C) 2008 OpenedHand Ltd.
*
* Authors: Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GUPNP_SEARCH_CRITERIA_PARSER_H
#define GUPNP_SEARCH_CRITERIA_PARSER_H
#include <glib-object.h>
G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE(GUPnPSearchCriteriaParser,
gupnp_search_criteria_parser,
GUPNP,
SEARCH_CRITERIA_PARSER,
GObject)
#define GUPNP_TYPE_SEARCH_CRITERIA_PARSER \
(gupnp_search_criteria_parser_get_type ())
/**
* GUPnPSearchCriteriaOp:
* @GUPNP_SEARCH_CRITERIA_OP_EQ: '='
* @GUPNP_SEARCH_CRITERIA_OP_NEQ: '!='
* @GUPNP_SEARCH_CRITERIA_OP_LESS: '<'
* @GUPNP_SEARCH_CRITERIA_OP_LEQ: '<='
* @GUPNP_SEARCH_CRITERIA_OP_GREATER: '>'
* @GUPNP_SEARCH_CRITERIA_OP_GEQ: '>='
* @GUPNP_SEARCH_CRITERIA_OP_CONTAINS: 'contains'
* @GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN: 'doesNotContain'
* @GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM: 'derivedFrom'
* @GUPNP_SEARCH_CRITERIA_OP_EXISTS: 'exists'
*
* The possible operators in SearchCriteria strings.
*
**/
typedef enum {
/* G_TYPE_STRING */
GUPNP_SEARCH_CRITERIA_OP_EQ = G_TOKEN_LAST + 1,
GUPNP_SEARCH_CRITERIA_OP_NEQ = G_TOKEN_LAST + 2,
GUPNP_SEARCH_CRITERIA_OP_LESS = G_TOKEN_LAST + 3,
GUPNP_SEARCH_CRITERIA_OP_LEQ = G_TOKEN_LAST + 4,
GUPNP_SEARCH_CRITERIA_OP_GREATER = G_TOKEN_LAST + 5,
GUPNP_SEARCH_CRITERIA_OP_GEQ = G_TOKEN_LAST + 6,
GUPNP_SEARCH_CRITERIA_OP_CONTAINS = G_TOKEN_LAST + 7,
GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN = G_TOKEN_LAST + 8,
GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM = G_TOKEN_LAST + 9,
/* G_TYPE_BOOLEAN */
GUPNP_SEARCH_CRITERIA_OP_EXISTS = G_TOKEN_LAST + 10
} GUPnPSearchCriteriaOp;
GType
gupnp_search_criteria_op_get_type (void) G_GNUC_CONST;
#define GUPNP_TYPE_SEARCH_CRITERIA_OP (gupnp_search_criteria_op_get_type ())
#define GUPNP_SEARCH_CRITERIA_PARSER_ERROR \
(gupnp_search_criteria_parser_error_quark ())
GQuark
gupnp_search_criteria_parser_error_quark (void);
/**
* GUPnPSearchCriteriaParserError:
* @GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED: Parsing the search criteria
* failed.
**/
typedef enum {
GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED
} GUPnPSearchCriteriaParserError;
struct _GUPnPSearchCriteriaParserClass {
GObjectClass parent_class;
/* signals */
void (* begin_parens) (GUPnPSearchCriteriaParser *parser);
void (* end_parens) (GUPnPSearchCriteriaParser *parser);
void (* conjunction) (GUPnPSearchCriteriaParser *parser);
void (* disjunction) (GUPnPSearchCriteriaParser *parser);
gboolean (* expression) (GUPnPSearchCriteriaParser *parser,
const char *property,
GUPnPSearchCriteriaOp op,
const char *value,
GError **error);
/* future padding */
void (* _gupnp_reserved1) (void);
void (* _gupnp_reserved2) (void);
void (* _gupnp_reserved3) (void);
void (* _gupnp_reserved4) (void);
};
GUPnPSearchCriteriaParser *
gupnp_search_criteria_parser_new (void);
gboolean
gupnp_search_criteria_parser_parse_text (GUPnPSearchCriteriaParser *parser,
const char *text,
GError **error);
G_END_DECLS
#endif /* GUPNP_SEARCH_CRITERIA_PARSER_H */
07070100000052000081A40000000000000000000000016860451500000E38000000000000000000000000000000000000002A00000000gupnp-av-0.14.4/libgupnp-av/gvalue-util.c/*
* Copyright (C) 2007 OpenedHand Ltd.
*
* Author: Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include <string.h>
#include <stdlib.h>
#include "gvalue-util.h"
gboolean
av_gvalue_util_set_value_from_string (GValue *value, const char *str)
{
GValue tmp_value = {0, };
int i;
long l;
double d;
g_return_val_if_fail (str != NULL, FALSE);
switch (G_VALUE_TYPE (value)) {
case G_TYPE_STRING:
g_value_set_string (value, str);
break;
case G_TYPE_CHAR:
g_value_set_schar (value, *str);
break;
case G_TYPE_UCHAR:
g_value_set_uchar (value, *str);
break;
case G_TYPE_INT:
i = atoi (str);
g_value_set_int (value, i);
break;
case G_TYPE_UINT:
i = atoi (str);
g_value_set_uint (value, (guint) i);
break;
case G_TYPE_INT64:
i = atoi (str);
g_value_set_int64 (value, (gint64) i);
break;
case G_TYPE_UINT64:
i = atoi (str);
g_value_set_uint64 (value, (guint64) i);
break;
case G_TYPE_LONG:
l = atol (str);
g_value_set_long (value, l);
break;
case G_TYPE_ULONG:
l = atol (str);
g_value_set_ulong (value, (gulong) l);
break;
case G_TYPE_FLOAT:
d = atof (str);
g_value_set_float (value, (float) d);
break;
case G_TYPE_DOUBLE:
d = atof (str);
g_value_set_float (value, d);
break;
case G_TYPE_BOOLEAN:
if (g_ascii_strcasecmp (str, "true") == 0 ||
g_ascii_strcasecmp (str, "yes") == 0)
g_value_set_boolean (value, TRUE);
else if (g_ascii_strcasecmp (str, "false") == 0 ||
g_ascii_strcasecmp (str, "no") == 0)
g_value_set_boolean (value, FALSE);
else {
i = atoi (str);
g_value_set_boolean (value, i ? TRUE : FALSE);
}
break;
default:
/* Try to convert */
if (g_value_type_transformable (G_TYPE_STRING,
G_VALUE_TYPE (value))) {
g_value_init (&tmp_value, G_TYPE_STRING);
g_value_set_static_string (&tmp_value, str);
g_value_transform (&tmp_value, value);
g_value_unset (&tmp_value);
} else if (g_value_type_transformable (G_TYPE_INT,
G_VALUE_TYPE (value))) {
i = atoi (str);
g_value_init (&tmp_value, G_TYPE_INT);
g_value_set_int (&tmp_value, i);
g_value_transform (&tmp_value, value);
g_value_unset (&tmp_value);
} else {
g_warning ("Failed to transform integer "
"value to type %s",
G_VALUE_TYPE_NAME (value));
return FALSE;
}
break;
}
return TRUE;
}
07070100000053000081A4000000000000000000000001686045150000015A000000000000000000000000000000000000002A00000000gupnp-av-0.14.4/libgupnp-av/gvalue-util.h/*
* Copyright (C) 2007 OpenedHand Ltd.
*
* Author: Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef GVALUE_UTIL_H
#define GVALUE_UTIL_H
#include <glib-object.h>
G_GNUC_INTERNAL gboolean
av_gvalue_util_set_value_from_string (GValue *value, const char *str);
#endif /* __GVALUE_UTIL_H__ */
07070100000054000081A40000000000000000000000016860451500000C0E000000000000000000000000000000000000002800000000gupnp-av-0.14.4/libgupnp-av/meson.buildmarshall_sources = gnome.genmarshal('gupnp-av-marshal', prefix : 'gupnp_av_marshal', sources : 'gupnp-av-marshal.list')
introspection_sources = [
'gupnp-av-error.c',
'gupnp-cds-last-change-parser.c',
'gupnp-didl-lite-container.c',
'gupnp-didl-lite-contributor.c',
'gupnp-didl-lite-createclass.c',
'gupnp-didl-lite-descriptor.c',
'gupnp-didl-lite-item.c',
'gupnp-didl-lite-object.c',
'gupnp-didl-lite-parser.c',
'gupnp-didl-lite-resource.c',
'gupnp-didl-lite-writer.c',
'gupnp-dlna.c',
'gupnp-feature.c',
'gupnp-feature-list-parser.c',
'gupnp-last-change-parser.c',
'gupnp-media-collection.c',
'gupnp-protocol-info.c',
'gupnp-search-criteria-parser.c'
]
v = meson.project_version().split('.')
soversion = 3
library_minor = v[0].to_int() * 100 + v[1].to_int()
library_micro = v[2].to_int()
version = '@0@.@1@.@2@'.format(soversion, library_minor, library_micro)
version_arr = version.split('.')
major_version = version_arr[0].to_int()
minor_version = version_arr[1].to_int()
micro_version = version_arr[2].to_int()
current = major_version + minor_version + 1
interface_age = micro_version
darwin_versions = [current, '@0@.@1@'.format(current, interface_age)]
gupnp_av_lib = library('gupnp-av-1.0',
[
introspection_sources,
'fragment-util.c',
'gvalue-util.c',
'time-utils.c',
'xml-util.c',
'xsd-data.c',
marshall_sources,
],
install: true,
version : version,
c_args : common_cflags,
include_directories : config_h_inc,
dependencies : [glib, gobject, libxml],
darwin_versions : darwin_versions,
)
gupnp_av = declare_dependency(link_with : gupnp_av_lib, include_directories : include_directories('..'))
meson.override_dependency('gupnp-av-1.0', gupnp_av)
public_headers = [
'gupnp-av-enums.h',
'gupnp-av-error.h',
'gupnp-av.h',
'gupnp-cds-last-change-parser.h',
'gupnp-didl-lite-container.h',
'gupnp-didl-lite-contributor.h',
'gupnp-didl-lite-createclass.h',
'gupnp-didl-lite-descriptor.h',
'gupnp-didl-lite-item.h',
'gupnp-didl-lite-object.h',
'gupnp-didl-lite-parser.h',
'gupnp-didl-lite-resource.h',
'gupnp-didl-lite-writer.h',
'gupnp-dlna.h',
'gupnp-feature.h',
'gupnp-feature-list-parser.h',
'gupnp-last-change-parser.h',
'gupnp-media-collection.h',
'gupnp-protocol-info.h',
'gupnp-search-criteria-parser.h',
]
install_headers(
public_headers,
subdir : 'gupnp-av-1.0/libgupnp-av'
)
if get_option('introspection')
gupnp_av_gir = gnome.generate_gir(
gupnp_av_lib,
sources : [public_headers, introspection_sources],
namespace : 'GUPnPAV',
nsversion : '1.0',
identifier_prefix : 'GUPnP',
symbol_prefix : 'gupnp',
export_packages : 'gupnp-av-1.0',
includes : ['GObject-2.0', 'libxml2-2.0'],
install : true
)
endif
07070100000055000081A400000000000000000000000168604515000004AC000000000000000000000000000000000000002900000000gupnp-av-0.14.4/libgupnp-av/time-utils.c/*
* Copyright (C) 2012 Intel Corporation.
*
* Authors: Jens Georg <jensg@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include <glib.h>
#include "time-utils.h"
#define SEC_PER_MIN 60
#define SEC_PER_HOUR 3600
long
seconds_from_time (const char *time_str)
{
char **tokens;
gdouble seconds = -1;
if (time_str == NULL)
return -1;
tokens = g_strsplit (time_str, ":", -1);
if (tokens[0] == NULL ||
tokens[1] == NULL ||
tokens[2] == NULL)
goto return_point;
seconds = g_strtod (tokens[2], NULL);
seconds += g_strtod (tokens[1], NULL) * SEC_PER_MIN;
seconds += g_strtod (tokens[0], NULL) * SEC_PER_HOUR;
return_point:
g_strfreev (tokens);
return (long) seconds;
}
char *
seconds_to_time (long seconds)
{
char *str;
if (seconds < 0)
return NULL;
str = g_strdup_printf ("%ld:%.2ld:%.2ld.000",
seconds / (60 * 60),
(seconds / 60) % 60,
seconds % 60);
return str;
}
07070100000056000081A40000000000000000000000016860451500000175000000000000000000000000000000000000002900000000gupnp-av-0.14.4/libgupnp-av/time-utils.h/*
* Copyright (C) 2012 Intel Corporation.
*
* Authors: Jens Georg <jensg@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef TIME_UTILS_H
#define TIME_UTILS_H
G_BEGIN_DECLS
G_GNUC_INTERNAL long
seconds_from_time (const char *time_string);
G_GNUC_INTERNAL char *
seconds_to_time (long seconds);
G_END_DECLS
#endif /* __TIME_UTILS_H__ */
07070100000057000081A40000000000000000000000016860451500004221000000000000000000000000000000000000002700000000gupnp-av-0.14.4/libgupnp-av/xml-util.c/*
* Copyright (C) 2006, 2007 OpenedHand Ltd.
* Copyright (C) 2007 Zeeshan Ali.
* Copyright (C) 2012 Intel Corporation
*
* Author: Jorn Baayen <jorn@openedhand.com>
* Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
* Author: Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include <string.h>
#include <glib/gprintf.h>
#include "xml-util.h"
typedef struct _GUPnPXMLNamespaceDescription
{
const char *uri;
const char *prefix;
} GUPnPXMLNamespaceDescription;
static GUPnPXMLNamespaceDescription gupnp_xml_namespaces[] =
{
{ "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/", NULL },
{ "http://purl.org/dc/elements/1.1/", "dc" },
{ "urn:schemas-dlna-org:metadata-1-0/", "dlna" },
{ "http://www.pv.com/pvns/", "pv" },
{ "urn:schemas-upnp-org:metadata-1-0/upnp/", "upnp" },
{ NULL, NULL }
};
GUPnPAVXMLDoc *
av_xml_doc_new (xmlDoc *doc)
{
GUPnPAVXMLDoc *ret = NULL;
g_return_val_if_fail (doc, NULL);
ret = g_rc_box_new0(GUPnPAVXMLDoc);
ret->doc = doc;
return ret;
}
static void
av_xml_doc_free (GUPnPAVXMLDoc *doc)
{
g_clear_pointer (&doc->doc, xmlFreeDoc);
}
void
av_xml_doc_unref (GUPnPAVXMLDoc *doc)
{
g_rc_box_release_full (doc, (GFreeFunc) av_xml_doc_free);
}
xmlNode *
av_xml_util_get_element (xmlNode *node,
...)
{
va_list var_args;
va_start (var_args, node);
while (TRUE) {
const char *arg;
arg = va_arg (var_args, const char *);
if (!arg)
break;
for (node = node->children; node; node = node->next) {
if (node->name == NULL)
continue;
if (!g_ascii_strcasecmp (arg, (char *) node->name))
break;
}
if (!node)
break;
}
va_end (var_args);
return node;
}
GList *
av_xml_util_get_child_elements_by_name (xmlNode *node, const char *name)
{
GList *children = NULL;
for (node = node->children; node; node = node->next) {
if (node->name == NULL)
continue;
if (strcmp (name, (char *) node->name) == 0) {
children = g_list_append (children, node);
}
}
return children;
}
const char *
av_xml_util_get_child_element_content (xmlNode *node,
const char *child_name)
{
xmlNode *child_node;
const char *content;
child_node = av_xml_util_get_element (node, child_name, NULL);
if (!child_node || !(child_node->children))
return NULL;
content = (const char *) child_node->children->content;
if (!content)
return NULL;
return content;
}
guint
av_xml_util_get_uint_child_element (xmlNode *node,
const char *child_name,
guint default_value)
{
const char *content;
content = av_xml_util_get_child_element_content (node, child_name);
if (!content)
return default_value;
return strtoul (content, NULL, 0);
}
guint64
av_xml_util_get_uint64_child_element (xmlNode *node,
const char *child_name,
guint64 default_value)
{
const char *content;
content = av_xml_util_get_child_element_content (node, child_name);
if (!content)
return default_value;
return g_ascii_strtoull (content, NULL, 0);
}
const char *
av_xml_util_get_attribute_content (xmlNode *node,
const char *attribute_name)
{
xmlAttr *attribute;
for (attribute = node->properties;
attribute;
attribute = attribute->next) {
if (attribute->name == NULL)
continue;
if (strcmp (attribute_name, (char *) attribute->name) == 0)
break;
}
if (attribute)
return (const char *) attribute->children->content;
else
return NULL;
}
gboolean
av_xml_util_get_boolean_attribute (xmlNode *node,
const char *attribute_name)
{
const char *content;
gchar *str;
gboolean ret;
content = av_xml_util_get_attribute_content (node, attribute_name);
if (!content)
return FALSE;
str = (char *) content;
if (g_ascii_strcasecmp (str, "true") == 0 ||
g_ascii_strcasecmp (str, "yes") == 0)
ret = TRUE;
else if (g_ascii_strcasecmp (str, "false") == 0 ||
g_ascii_strcasecmp (str, "no") == 0)
ret = FALSE;
else {
int i;
i = atoi (str);
ret = i ? TRUE : FALSE;
}
return ret;
}
guint
av_xml_util_get_uint_attribute (xmlNode *node,
const char *attribute_name,
guint default_value)
{
return (guint) av_xml_util_get_long_attribute (node,
attribute_name,
(glong) default_value);
}
gint
av_xml_util_get_int_attribute (xmlNode *node,
const char *attribute_name,
gint default_value)
{
return (gint) av_xml_util_get_long_attribute (node,
attribute_name,
(glong) default_value);
}
glong
av_xml_util_get_long_attribute (xmlNode *node,
const char *attribute_name,
glong default_value)
{
return (glong) av_xml_util_get_int64_attribute (node,
attribute_name,
(gint64) default_value);
}
gint64
av_xml_util_get_int64_attribute (xmlNode *node,
const char *attribute_name,
gint64 default_value)
{
const char *content;
content = av_xml_util_get_attribute_content (node, attribute_name);
if (!content)
return default_value;
return g_ascii_strtoll (content, NULL, 0);
}
xmlNode *
av_xml_util_set_child (xmlNode *parent_node,
GUPnPXMLNamespace ns,
xmlNsPtr *xmlns,
xmlDoc *doc,
const char *name,
const char *value)
{
xmlNode *node;
xmlChar *escaped;
node = av_xml_util_get_element (parent_node, name, NULL);
if (node == NULL) {
xmlNsPtr ns_ptr = NULL;
ns_ptr = av_xml_util_get_ns (doc, ns, xmlns);
node = xmlNewChild (parent_node,
ns_ptr,
(unsigned char *) name,
NULL);
}
escaped = xmlEncodeSpecialChars (doc, (const unsigned char *) value);
xmlNodeSetContent (node, escaped);
xmlFree (escaped);
return node;
}
void
av_xml_util_unset_child (xmlNode *parent_node,
const char *name)
{
xmlNode *node;
node = av_xml_util_get_element (parent_node, name, NULL);
if (node != NULL) {
xmlUnlinkNode (node);
xmlFreeNode (node);
}
}
gboolean
av_xml_util_verify_attribute_is_boolean (xmlNode *node,
const char *attribute_name)
{
const char *content;
char *str;
content = av_xml_util_get_attribute_content (node, attribute_name);
if (content == NULL)
return FALSE;
str = (char *) content;
return g_ascii_strcasecmp (str, "true") == 0 ||
g_ascii_strcasecmp (str, "yes") == 0 ||
g_ascii_strcasecmp (str, "false") == 0 ||
g_ascii_strcasecmp (str, "no") == 0 ||
g_ascii_strcasecmp (str, "0") == 0 ||
g_ascii_strcasecmp (str, "1") == 0;
}
char *
av_xml_util_get_child_string (xmlNode *parent_node,
xmlDoc *doc,
const char *name)
{
xmlBuffer *buffer;
char *ret;
xmlNode *node;
node = av_xml_util_get_element (parent_node, name, NULL);
if (!node)
return NULL;
buffer = xmlBufferCreate ();
xmlNodeDump (buffer,
doc,
node,
0,
0);
ret = g_strndup ((char *) xmlBufferContent (buffer),
xmlBufferLength (buffer));
xmlBufferFree (buffer);
return ret;
}
gboolean
av_xml_util_node_deep_equal (xmlNode *first,
xmlNode *second)
{
GHashTable *first_attributes;
xmlAttr *attribute;
gboolean equal;
if (first == NULL && second == NULL)
return TRUE;
if (first == NULL || second == NULL)
return FALSE;
if (xmlStrcmp (first->name, second->name))
return FALSE;
equal = FALSE;
first_attributes = av_xml_util_get_attributes_map (first);
/* compare attributes */
for (attribute = second->properties;
attribute != NULL;
attribute = attribute->next) {
const xmlChar *value = NULL;
const xmlChar *key = attribute->name;
if (g_hash_table_lookup_extended (first_attributes,
key,
NULL,
(gpointer *) &value))
if (!xmlStrcmp (value, attribute->children->content)) {
g_hash_table_remove (first_attributes, key);
continue;
}
goto out;
}
if (g_hash_table_size (first_attributes))
goto out;
/* compare content */
if (xmlStrcmp (first->content, second->content))
goto out;
equal = TRUE;
out:
g_hash_table_unref (first_attributes);
if (equal) {
xmlNode *first_child;
xmlNode *second_child;
for (first_child = first->children,
second_child = second->children;
first_child != NULL && second_child != NULL;
first_child = first_child->next,
second_child = second_child->next)
if (!av_xml_util_node_deep_equal (first_child,
second_child))
return FALSE;
if (first_child != NULL || second_child != NULL)
return FALSE;
}
return equal;
}
xmlNode *
av_xml_util_find_node (xmlNode *haystack,
xmlNode *needle)
{
xmlNodePtr iter;
if (av_xml_util_node_deep_equal (haystack, needle))
return haystack;
for (iter = haystack->children; iter != NULL; iter = iter->next) {
xmlNodePtr found_node = av_xml_util_find_node (iter, needle);
if (found_node != NULL)
return found_node;
}
return NULL;
}
xmlNode *
av_xml_util_copy_node (xmlNode *node)
{
xmlNode *dup = xmlCopyNode (node, 1);
/* TODO: remove useless namespace definition. */
return dup;
}
GHashTable *
av_xml_util_get_attributes_map (xmlNode *node)
{
xmlAttr *attribute;
GHashTable *attributes_map = g_hash_table_new (g_str_hash,
g_str_equal);
for (attribute = node->properties;
attribute != NULL;
attribute = attribute->next)
g_hash_table_insert (attributes_map,
(gpointer) attribute->name,
(gpointer) attribute->children->content);
return attributes_map;
}
/**
* av_xml_util_create_namespace:
* @root: (allow-none): Document root node or %NULL for anonymous ns.
* @ns: Namespace
* @returns: Newly created namespace on root node
*/
xmlNsPtr
av_xml_util_create_namespace (xmlNodePtr root, GUPnPXMLNamespace ns)
{
g_return_val_if_fail (ns < GUPNP_XML_NAMESPACE_COUNT, NULL);
return xmlNewNs (root,
(const xmlChar *) gupnp_xml_namespaces[ns].uri,
(const xmlChar *) gupnp_xml_namespaces[ns].prefix);
}
/**
* av_xml_util_lookup_namespace:
* @doc: #xmlDoc
* @ns: namespace to look up (except DIDL-Lite, which doesn't have a prefix)
* @returns: %NULL if namespace does not exist, a pointer to the namespace
* otherwise.
*/
xmlNsPtr
av_xml_util_lookup_namespace (xmlDocPtr doc, GUPnPXMLNamespace ns)
{
xmlNsPtr *ns_list, *it, retval = NULL;
const char *ns_prefix = NULL;
const char *ns_uri = NULL;
g_return_val_if_fail (ns < GUPNP_XML_NAMESPACE_COUNT, NULL);
ns_prefix = gupnp_xml_namespaces[ns].prefix;
ns_uri = gupnp_xml_namespaces[ns].uri;
ns_list = xmlGetNsList (doc, xmlDocGetRootElement (doc));
if (ns_list == NULL)
return NULL;
for (it = ns_list; *it != NULL; it++) {
const char *it_prefix = (const char *) (*it)->prefix;
const char *it_uri = (const char *) (*it)->href;
if (it_prefix == NULL) {
if (ns_prefix != NULL)
continue;
if (g_ascii_strcasecmp (it_uri, ns_uri) == 0) {
retval = *it;
break;
}
continue;
}
if (g_ascii_strcasecmp (it_prefix, ns_prefix) == 0) {
retval = *it;
break;
}
}
xmlFree (ns_list);
return retval;
}
/**
* av_xml_util_get_ns:
* @doc: A #xmlDoc.
* @ns: A #GUPnPXMLNamespace.
* @ns_out: (out) (allow-none): return location for the namespace or %NULL.
*
* Lazy-create a XML namespace on @doc.
*
* If @ns_out is non-%NULL, the function will return @ns_out immediately.
* @returns: either the existing #xmlNsPtr or a newly created one.
*/
xmlNsPtr
av_xml_util_get_ns (xmlDocPtr doc, GUPnPXMLNamespace ns, xmlNsPtr *ns_out)
{
xmlNsPtr tmp_ns;
/* User supplied namespace, just return that */
if (ns_out != NULL && *ns_out != NULL)
return *ns_out;
tmp_ns = av_xml_util_lookup_namespace (doc, ns);
if (!tmp_ns)
tmp_ns = av_xml_util_create_namespace
(xmlDocGetRootElement (doc),
ns);
if (ns_out != NULL)
*ns_out = tmp_ns;
return tmp_ns;
}
void
av_xml_util_set_int_prop (xmlNodePtr node, const char *name, int value)
{
char *str;
str = g_strdup_printf ("%d", value);
xmlSetProp (node, (unsigned char *) name, (unsigned char *) str);
g_free (str);
}
void
av_xml_util_set_prop (xmlNodePtr node,
const char *name,
const char *format,
...)
{
va_list args;
va_start (args, format);
char *str = NULL;
g_vasprintf (&str, format, args);
xmlSetProp (node, (xmlChar *) name, (xmlChar *) str);
g_free (str);
va_end (args);
}
void
av_xml_util_set_ns_prop (xmlNodePtr node,
xmlNsPtr ns,
const char *name,
const char *format,
...)
{
va_list args;
va_start (args, format);
char *str = NULL;
g_vasprintf(&str, format, args);
xmlSetNsProp (node, ns, (xmlChar *) name, (xmlChar *) str);
g_free (str);
va_end (args);
}
G_DEFINE_BOXED_TYPE (GUPnPAVXMLDoc, av_xml_doc, g_rc_box_acquire, av_xml_doc_unref)
07070100000058000081A40000000000000000000000016860451500001693000000000000000000000000000000000000002700000000gupnp-av-0.14.4/libgupnp-av/xml-util.h/*
* Copyright (C) 2006, 2007 OpenedHand Ltd.
* Copyright (C) 2007 Zeeshan Ali.
* Copyright (C) 2012 Intel Corporation
*
* Author: Jorn Baayen <jorn@openedhand.com>
* Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
* Author: Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef XML_UTIL_H
#define XML_UTIL_H
#include <glib.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <stdarg.h>
#include <glib-object.h>
typedef enum _GUPnPXMLNamespace
{
GUPNP_XML_NAMESPACE_DIDL_LITE,
GUPNP_XML_NAMESPACE_DC,
GUPNP_XML_NAMESPACE_DLNA,
GUPNP_XML_NAMESPACE_PV,
GUPNP_XML_NAMESPACE_UPNP,
GUPNP_XML_NAMESPACE_COUNT
} GUPnPXMLNamespace;
G_BEGIN_DECLS
typedef struct _GPnPAVXMLDoc
{
xmlDoc *doc;
} GUPnPAVXMLDoc;
G_GNUC_INTERNAL GUPnPAVXMLDoc *
av_xml_doc_new (xmlDoc *doc);
G_GNUC_INTERNAL GUPnPAVXMLDoc *
av_xml_doc_ref (GUPnPAVXMLDoc *doc);
G_GNUC_INTERNAL void
av_xml_doc_unref (GUPnPAVXMLDoc *doc);
G_GNUC_INTERNAL GType
av_xml_doc_get_type (void) G_GNUC_CONST;
/* Misc utilities for inspecting xmlNodes */
G_GNUC_INTERNAL xmlNode *
av_xml_util_get_element (xmlNode *node,
...) G_GNUC_NULL_TERMINATED;
G_GNUC_INTERNAL GList *
av_xml_util_get_child_elements_by_name (xmlNode *node,
const char *name);
G_GNUC_INTERNAL const char *
av_xml_util_get_child_element_content (xmlNode *node,
const char *child_name);
G_GNUC_INTERNAL guint
av_xml_util_get_uint_child_element (xmlNode *node,
const char *child_name,
guint default_value);
G_GNUC_INTERNAL guint64
av_xml_util_get_uint64_child_element (xmlNode *node,
const char *child_name,
guint64 default_value);
G_GNUC_INTERNAL const char *
av_xml_util_get_attribute_content (xmlNode *node,
const char *attribute_name);
G_GNUC_INTERNAL gboolean
av_xml_util_get_boolean_attribute (xmlNode *node,
const char *attribute_name);
G_GNUC_INTERNAL guint
av_xml_util_get_uint_attribute (xmlNode *node,
const char *attribute_name,
guint default_value);
G_GNUC_INTERNAL gint
av_xml_util_get_int_attribute (xmlNode *node,
const char *attribute_name,
gint default_value);
G_GNUC_INTERNAL glong
av_xml_util_get_long_attribute (xmlNode *node,
const char *attribute_name,
glong default_value);
G_GNUC_INTERNAL gint64
av_xml_util_get_int64_attribute (xmlNode *node,
const char *attribute_name,
gint64 default_value);
G_GNUC_INTERNAL xmlNode *
av_xml_util_set_child (xmlNode *parent_node,
GUPnPXMLNamespace ns,
xmlNsPtr *namespace,
xmlDoc *doc,
const char *name,
const char *value);
G_GNUC_INTERNAL void
av_xml_util_unset_child (xmlNode *parent_node,
const char *name);
G_GNUC_INTERNAL gboolean
av_xml_util_verify_attribute_is_boolean (xmlNode *node,
const char *attribute_name);
G_GNUC_INTERNAL char *
av_xml_util_get_child_string (xmlNode *parent_node,
xmlDoc *doc,
const char *name);
G_GNUC_INTERNAL gboolean
av_xml_util_node_deep_equal (xmlNode *first,
xmlNode *second);
G_GNUC_INTERNAL xmlNode *
av_xml_util_find_node (xmlNode *haystack,
xmlNode *needle);
G_GNUC_INTERNAL xmlNode *
av_xml_util_copy_node (xmlNode *node);
G_GNUC_INTERNAL GHashTable *
av_xml_util_get_attributes_map (xmlNode *node);
G_GNUC_INTERNAL xmlNsPtr
av_xml_util_create_namespace (xmlNodePtr root,
GUPnPXMLNamespace ns);
G_GNUC_INTERNAL xmlNsPtr
av_xml_util_lookup_namespace (xmlDocPtr doc,
GUPnPXMLNamespace ns);
G_GNUC_INTERNAL xmlNsPtr
av_xml_util_get_ns (xmlDocPtr doc,
GUPnPXMLNamespace ns,
xmlNsPtr *ns_out);
G_GNUC_INTERNAL void
av_xml_util_set_int_prop (xmlNodePtr node, const char *name, int value);
G_GNUC_INTERNAL void
av_xml_util_set_prop (xmlNodePtr node, const char *name, const char *format, ...) G_GNUC_PRINTF(3, 4);
G_GNUC_INTERNAL void
av_xml_util_set_ns_prop (xmlNodePtr node, xmlNsPtr ns, const char *name, const char *format, ...) G_GNUC_PRINTF(4, 5);
G_END_DECLS
#endif /* __XML_UTIL_H__ */
07070100000059000081A40000000000000000000000016860451500000E5D000000000000000000000000000000000000002700000000gupnp-av-0.14.4/libgupnp-av/xsd-data.c/*
* Copyright (C) 2012 Intel Corporation
*
* Authors: Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include <libxml/parser.h>
#include <libxml/xmlschemas.h>
#include "xsd-data.h"
struct _XSDData {
xmlSchemaPtr schema;
xmlSchemaValidCtxtPtr valid_context;
};
XSDData *
xsd_data_new (const gchar *xsd_file)
{
XSDData *xsd_data = g_slice_new0 (XSDData);
gboolean failed = TRUE;
xmlSchemaParserCtxtPtr context = xmlSchemaNewParserCtxt (xsd_file);
if (context == NULL)
/* unable to create a parser context for the schema */
goto out;
xsd_data->schema = xmlSchemaParse (context);
if (xsd_data->schema == NULL)
/* the schema itself is not valid */
goto out;
xsd_data->valid_context = xmlSchemaNewValidCtxt (xsd_data->schema);
if (xsd_data->valid_context == NULL)
/* unable to create a validation context for the schema */
goto out;
failed = FALSE;
out:
if (context != NULL)
xmlSchemaFreeParserCtxt (context);
if (failed) {
xsd_data_free (xsd_data);
xsd_data = NULL;
}
return xsd_data;
}
void
xsd_data_free (XSDData *xsd_data)
{
if (xsd_data == NULL)
return;
g_clear_pointer (&xsd_data->valid_context, xmlSchemaFreeValidCtxt);
g_clear_pointer (&xsd_data->schema, xmlSchemaFree);
g_slice_free (XSDData, xsd_data);
}
gboolean
xsd_data_validate_doc (XSDData *xsd_data,
xmlDoc *doc)
{
static xmlSAXHandler empty_handler = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
XML_SAX2_MAGIC,
NULL,
NULL,
NULL,
NULL
};
xmlChar *dump = NULL;
int size = 0;
xmlParserInputBufferPtr buffer = NULL;
gboolean result = FALSE;
if (xsd_data == NULL)
return TRUE;
xmlDocDumpMemory (doc, &dump, &size);
if (dump == NULL)
goto out;
g_debug ("Doc dump:\n%s", dump);
buffer = xmlParserInputBufferCreateMem ((char *) dump,
size,
XML_CHAR_ENCODING_NONE);
if (buffer == NULL)
goto out;
if (!xmlSchemaValidateStream (xsd_data->valid_context,
buffer,
XML_CHAR_ENCODING_NONE,
&empty_handler,
NULL))
result = TRUE;
out:
/* Commented out, because it crashes because of double free. I
* suppose that it is freed by xmlSchemaValidateStream.
*/
/*
if (buffer)
xmlFreeParserInputBuffer (buffer);
*/
if (dump != NULL)
xmlFree (dump);
return result;
}
0707010000005A000081A4000000000000000000000001686045150000027D000000000000000000000000000000000000002700000000gupnp-av-0.14.4/libgupnp-av/xsd-data.h/*
* Copyright (C) 2012 Intel Corporation
*
* Authors: Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef XSD_DATA_H
#define XSD_DATA_H
#include <glib.h>
#include <libxml/tree.h>
G_BEGIN_DECLS
typedef struct _XSDData XSDData;
G_GNUC_INTERNAL XSDData *
xsd_data_new (const gchar *xsd_file);
G_GNUC_INTERNAL void
xsd_data_free (XSDData *data);
G_GNUC_INTERNAL gboolean
xsd_data_validate_doc (XSDData *data,
xmlDoc *doc);
G_END_DECLS
#endif /* __XSD_DATA_H__ */
0707010000005B000081A40000000000000000000000016860451500000FC0000000000000000000000000000000000000001C00000000gupnp-av-0.14.4/meson.buildproject('gupnp-av', 'c', version : '0.14.4', default_options: ['c_std=c11'], meson_version: '>= 0.58.0')
gnome = import('gnome')
glib_version = '2.58'
gobject = dependency('gobject-2.0', version : '>= ' + glib_version)
glib = dependency('glib-2.0', version : '>= ' + glib_version)
libxml = dependency('libxml-2.0')
GUPNP_AV_API_NAME='gupnp-av-1.0'
cc = meson.get_compiler('c')
# Compiler flags, taken from the Xorg macros
if cc.get_id() == 'msvc'
# Compiler options taken from msvc_recommended_pragmas.h
# in GLib, based on _Win32_Programming_ by Rector and Newcomer
test_cflags = [
'-we4002', # too many actual parameters for macro
'-we4003', # not enough actual parameters for macro
'-w14010', # single-line comment contains line-continuation character
'-we4013', # 'function' undefined; assuming extern returning int
'-w14016', # no function return type; using int as default
'-we4020', # too many actual parameters
'-we4021', # too few actual parameters
'-we4027', # function declared without formal parameter list
'-we4029', # declared formal parameter list different from definition
'-we4033', # 'function' must return a value
'-we4035', # 'function' : no return value
'-we4045', # array bounds overflow
'-we4047', # different levels of indirection
'-we4049', # terminating line number emission
'-we4053', # an expression of type void was used as an operand
'-we4071', # no function prototype given
'-we4819', # the file contains a character that cannot be represented in the current code page
]
elif cc.get_id() == 'gcc' or cc.get_id() == 'clang'
test_cflags = [
'-Wpointer-arith',
'-Wmissing-declarations',
'-Wformat=2',
'-Wstrict-prototypes',
'-Wmissing-prototypes',
'-Wnested-externs',
'-Wbad-function-cast',
'-Wold-style-definition',
'-Wunused',
'-Wuninitialized',
'-Wshadow',
'-Wmissing-noreturn',
'-Wmissing-format-attribute',
'-Wredundant-decls',
'-Wlogical-op',
'-Werror=implicit',
'-Werror=nonnull',
'-Werror=init-self',
'-Werror=main',
'-Werror=missing-braces',
'-Werror=sequence-point',
'-Werror=return-type',
'-Werror=trigraphs',
'-Werror=array-bounds',
'-Werror=write-strings',
'-Werror=address',
'-Werror=int-to-pointer-cast',
'-Werror=pointer-to-int-cast',
'-fno-strict-aliasing',
'-Wno-int-conversion',
]
else
test_cflags = []
endif
common_cflags = cc.get_supported_arguments(test_cflags)
#add_project_arguments(cc.get_supported_arguments('-Werror=deprecated-declarations'), language: 'c')
conf = configuration_data()
conf.set_quoted('DATADIR', join_paths(get_option('prefix'), get_option('datadir'), 'gupnp-av'))
conf.set_quoted('VERSION', meson.project_version())
conf.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_' + glib_version.underscorify())
conf.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_' + glib_version.underscorify())
subdir('internal')
subdir('libgupnp-av')
subdir('tests')
subdir('data')
pkg = import('pkgconfig')
pkg.generate(
gupnp_av_lib,
requires : [
'glib-2.0',
'gobject-2.0',
'gio-2.0',
'libxml-2.0'
],
subdirs : 'gupnp-av-1.0',
description : 'GObject-based AV specific UPnP library'
)
gidocgen_dep = dependency('gi-docgen', version: '>= 2021.1',
fallback: ['gi-docgen', 'dummy_dep'],
native: true,
required: get_option('gtk_doc') and get_option('introspection')
)
if get_option('gtk_doc')
gidocgen_dep = dependency('gi-docgen', version: '>= 2021.1',
fallback: ['gi-docgen', 'dummy_dep'],
required: get_option('gtk_doc') and get_option('introspection')
)
subdir('doc')
endif
if get_option('introspection') and get_option('vapi')
subdir('vala')
endif
if not meson.is_subproject()
meson.add_dist_script('build-aux/dist-docs.py')
endif
0707010000005C000081A4000000000000000000000001686045150000013E000000000000000000000000000000000000002200000000gupnp-av-0.14.4/meson_options.txtoption('introspection', type : 'boolean', value : true, description : 'Build GObject-Introspection files')
option('vapi', type : 'boolean', value : true, description : 'Build VALA API files (needs introspection=true)')
option('gtk_doc', type : 'boolean', value : false, description : 'Generate the API documentation')
0707010000005D000041ED0000000000000000000000026860451500000000000000000000000000000000000000000000001C00000000gupnp-av-0.14.4/subprojects0707010000005E000081A4000000000000000000000001686045150000009F000000000000000000000000000000000000002B00000000gupnp-av-0.14.4/subprojects/gi-docgen.wrap[wrap-git]
directory=gi-docgen
url=https://gitlab.gnome.org/GNOME/gi-docgen.git
push-url=ssh://git@gitlab.gnome.org:GNOME/gi-docgen.git
revision=main
depth=1
0707010000005F000041ED0000000000000000000000026860451500000000000000000000000000000000000000000000001600000000gupnp-av-0.14.4/tests07070100000060000081A40000000000000000000000016860451500000ABE000000000000000000000000000000000000003200000000gupnp-av-0.14.4/tests/check-feature-list-parser.c/*
* Copyright (C) 2012 Intel Corporation
*
* Authors: Regis Merlino <regis.merlino@intel.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include <libgupnp-av/gupnp-feature-list-parser.h>
#include <stdlib.h>
#include <string.h>
static const char * const names[] = {
"BOOKMARK",
"EPG",
};
static const char * const versions[] = {
"1",
"2",
};
static const char * const ids[] = {
"bookmark1,bookmark2,bookmark3",
"epg1,epg2",
};
static const char *text =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<Features "
"xmlns=\"urn:schemas-upnp-org:av:avs\" "
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
"xsi:schemaLocation=\""
"urn:schemas-upnp-org:av:avs "
"http://www.upnp.org/schemas/av/avs-v1-20060531.xsd\">"
"<Feature name=\"BOOKMARK\" version=\"1\">"
"<objectIDs>bookmark1</objectIDs>"
"<objectIDs>bookmark2,bookmark3</objectIDs>"
"</Feature>"
"<Feature name=\"EPG\" version=\"2\">"
"<objectIDs>epg1,epg2</objectIDs>"
"</Feature>"
"</Features>";
static gboolean
check_feature (GUPnPFeature *feature)
{
static int index = 0;
if (strcmp (names[index], gupnp_feature_get_name (feature)))
return FALSE;
if (strcmp (versions[index], gupnp_feature_get_version (feature)))
return FALSE;
if (strcmp (ids[index], gupnp_feature_get_object_ids (feature)))
return FALSE;
index++;
return TRUE;
}
int
main (G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
{
GUPnPFeatureListParser *parser;
GError *error;
GList *features;
GList *item;
gboolean success = TRUE;
parser = gupnp_feature_list_parser_new ();
error = NULL;
features = gupnp_feature_list_parser_parse_text (parser, text, &error);
if (features == NULL) {
g_printerr ("Parse error: %s\n", error->message);
g_error_free (error);
return EXIT_FAILURE;
}
for (item = features; item != NULL; item = g_list_next (item)) {
success = check_feature ((GUPnPFeature *) item->data);
if (!success)
break;
}
g_print ("\n");
g_list_free_full (features, g_object_unref);
g_object_unref (parser);
return (success) ? EXIT_SUCCESS : EXIT_FAILURE;
}
07070100000061000081A40000000000000000000000016860451500000571000000000000000000000000000000000000002500000000gupnp-av-0.14.4/tests/check-search.c/*
* Copyright (C) 2008 OpenedHand Ltd.
*
* Authors: Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include <libgupnp-av/gupnp-search-criteria-parser.h>
#include <stdlib.h>
static const char * const searches[] = {
"dc:title contains \"foo\"",
"dc:title contains 'foo'",
"upnp:class = \"object.container.person.musicArtist\"",
"upnp:class = \"object.container.person.musicArtist\" and @refID exists false",
};
int
main (G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
{
GUPnPSearchCriteriaParser *parser;
GError *error;
guint i;
parser = gupnp_search_criteria_parser_new ();
for (i = 0; i < G_N_ELEMENTS (searches); i++) {
error = NULL;
gupnp_search_criteria_parser_parse_text (parser, searches[i], &error);
if (error) {
g_printerr ("\n\nCannot parse '%s': %s\n",
searches[i], error->message);
g_error_free (error);
return EXIT_FAILURE;
}
/* TODO: obviously an important next step is to verify that the
data was actually parsed correctly */
g_print (".");
}
g_print ("\n");
return EXIT_SUCCESS;
}
07070100000062000081A40000000000000000000000016860451500001B16000000000000000000000000000000000000002200000000gupnp-av-0.14.4/tests/fragments.c/*
* Copyright (C) 2012 Intel Corporation
*
* Authors: Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include <glib-object.h>
#include <libgupnp-av/gupnp-didl-lite-object.h>
#include <libgupnp-av/gupnp-didl-lite-writer.h>
#include <libgupnp-av/gupnp-didl-lite-item.h>
/* creates an item described by:
static const gchar * const didllite =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<DIDL-Lite\n"
"xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n"
"xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\"\n"
"xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\"\n"
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
"xsi:schemaLocation=\"\n"
"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\n"
"http://www.upnp.org/schemas/av/didl-lite.xsd\n"
"urn:schemas-upnp-org:metadata-1-0/upnp/\n"
"http://www.upnp.org/schemas/av/upnp.xsd\">\n"
"<item id=\"$id\" parentID=\"$parent_id\" restricted=\"0\">\n"
"<dc:title>Try a little tenderness</dc:title>\n"
"<upnp:class>object.item.audioItem.musicTrack</upnp:class>\n"
"<res protocolInfo=\"http-get:*:audio/mpeg:*\" size=\"3558000\">\n"
"http://168.192.1.1/audio197.mp3\n"
"</res>\n"
"<upnp:artist>Unknown</upnp:artist>\n"
"</item>\n"
"</DIDL-Lite>\n";
*/
static GUPnPDIDLLiteObject *
get_item (GUPnPDIDLLiteWriter *writer, guint id, guint parent_id)
{
GUPnPDIDLLiteItem *item = gupnp_didl_lite_writer_add_item (writer);
GUPnPDIDLLiteObject *object = GUPNP_DIDL_LITE_OBJECT (item);
GUPnPDIDLLiteContributor *artist;
GUPnPDIDLLiteResource *resource;
GUPnPProtocolInfo *info;
gchar *str_id = g_strdup_printf ("%u", id);
gupnp_didl_lite_object_set_id (object, str_id);
g_free (str_id);
str_id = g_strdup_printf ("%u", parent_id);
gupnp_didl_lite_object_set_parent_id (object, str_id);
g_free (str_id);
gupnp_didl_lite_object_set_restricted (object, FALSE);
gupnp_didl_lite_object_set_title (object, "Try a little tenderness");
gupnp_didl_lite_object_set_upnp_class
(object,
"object.item.audioItem.musicTrack");
artist = gupnp_didl_lite_object_add_artist (object);
gupnp_didl_lite_contributor_set_name (artist, "Unknown");
g_object_unref (artist);
resource = gupnp_didl_lite_object_add_resource (object);
info = gupnp_protocol_info_new ();
gupnp_protocol_info_set_protocol (info, "http-get");
gupnp_protocol_info_set_network (info, "*");
gupnp_protocol_info_set_mime_type (info, "audio/mpeg");
gupnp_didl_lite_resource_set_protocol_info (resource, info);
g_object_unref (info);
gupnp_didl_lite_resource_set_size (resource, 3558000);
gupnp_didl_lite_resource_set_uri (resource,
"http://168.192.1.1/audio197.mp3");
g_object_unref (resource);
return object;
}
static const gchar *current_fragments[] = {
/* 1 */
"<upnp:class>object.item.audioItem.musicTrack</upnp:class>",
/* 2 */
"",
/* 3 */
"<upnp:artist>Unknown</upnp:artist>",
/* 4 */
"<dc:title>Try a little tenderness</dc:title>"
};
static const gchar *new_fragments[] = {
/* 1 */
"<upnp:class>object.item.audioItem.musicTrack</upnp:class>"
"<upnp:genre>Obscure</upnp:genre>",
/* 2 */
"<upnp:genre>Even more obscure</upnp:genre>",
/* 3 */
"",
/* 4 */
"<dc:title>Cthulhu fhtagn</dc:title>"
};
static void
debug_dump (GUPnPDIDLLiteObject *object)
{
xmlChar *dump = NULL;
xmlNodePtr node = gupnp_didl_lite_object_get_xml_node (object);
xmlDocPtr doc = node->doc;
xmlDocDumpMemory (doc, &dump, NULL);
g_debug ("Obj dump:\n%s", dump);
xmlFree (dump);
}
int main (void)
{
GUPnPDIDLLiteObject *temp_object;
GUPnPDIDLLiteObject *object;
GUPnPDIDLLiteFragmentResult result;
GUPnPDIDLLiteWriter *writer;
int retval = 1;
const gchar *value;
GList* artists;
GUPnPDIDLLiteContributor *artist;
g_setenv ("GUPNP_AV_DATADIR", ABS_TOP_SRCDIR G_DIR_SEPARATOR_S "data", FALSE);
writer = gupnp_didl_lite_writer_new (NULL);
temp_object = get_item (writer, 3, 2);
object = get_item (writer, 18, 13);
debug_dump (object);
result = gupnp_didl_lite_object_apply_fragments (object,
(char **) current_fragments,
G_N_ELEMENTS (current_fragments),
(char **) new_fragments,
G_N_ELEMENTS (new_fragments));
debug_dump (object);
if (result != GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK) {
g_warning ("Applying fragments failed.");
goto out;
}
value = gupnp_didl_lite_object_get_title (object);
if (g_strcmp0 (value, "Cthulhu fhtagn")) {
g_warning ("Title is '%s', should be 'Cthulhu fhtagn'.", value);
goto out;
}
artists = gupnp_didl_lite_object_get_artists (object);
if (artists) {
g_warning ("Should be no artists.");
g_list_free_full (artists, g_object_unref);
goto out;
}
value = gupnp_didl_lite_object_get_title (temp_object);
if (g_strcmp0 (value, "Try a little tenderness")) {
g_warning ("Title is '%s', should be 'Try a little tenderness'.", value);
goto out;
}
artists = gupnp_didl_lite_object_get_artists (temp_object);
if (!artists) {
g_warning ("Should be one artist, there are none.");
goto out;
}
if (artists->next) {
g_list_free_full (artists, g_object_unref);
g_warning ("Should be one artist, there are more.");
goto out;
}
artist = g_object_ref (artists->data);
g_list_free_full (artists, g_object_unref);
value = gupnp_didl_lite_contributor_get_name (artist);
if (g_strcmp0 (value, "Unknown")) {
g_object_unref (artist);
g_warning ("Artist is '%s', but should be 'Unknown'.", value);
goto out;
}
g_object_unref (artist);
retval = 0;
out:
g_object_unref (object);
g_object_unref (temp_object);
g_object_unref (writer);
return retval;
}
07070100000063000041ED0000000000000000000000026860451500000000000000000000000000000000000000000000001C00000000gupnp-av-0.14.4/tests/gtest07070100000064000041ED0000000000000000000000026860451500000000000000000000000000000000000000000000002100000000gupnp-av-0.14.4/tests/gtest/data07070100000065000041ED0000000000000000000000026860451500000000000000000000000000000000000000000000003100000000gupnp-av-0.14.4/tests/gtest/data/cds-last-change07070100000066000081A40000000000000000000000016860451500000107000000000000000000000000000000000000004800000000gupnp-av-0.14.4/tests/gtest/data/cds-last-change/00-cds-last-change.xml<?xml version="1.0" encoding="UTF-8"?>
<StateEvent
xmlns="urn:schemas-upnp-org:av:cds-event"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
http://www.upnp.org/schemas/av/cds-event.xsd">
</StateEvent>
07070100000067000081A4000000000000000000000001686045150000032F000000000000000000000000000000000000004800000000gupnp-av-0.14.4/tests/gtest/data/cds-last-change/01-cds-last-change.xml<?xml version="1.0" encoding="UTF-8"?>
<StateEvent
xmlns="urn:schemas-upnp-org:av:cds-event"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
http://www.upnp.org/schemas/av/cds-event.xsd">
<objAdd objID="s002" updateID="213" objParentID="s001"
objClass="object.container.album" stUpdate="1"/>
<objMod objID="s001" updateID="214" stUpdate="1"/>
<objAdd objID="s003" updateID="215" objParentID="s001"
objClass="object.item.audioItem" stUpdate="0"/>
<objAdd objID="s004" updateID="216" objParentID="s002"
objClass="object.item.audioItem" stUpdate="1"/>
<objDel objID="s003" updateID="217" stUpdate="0"/>
<objMod objID="s001" updateID="218" stUpdate="0"/>
<objMod objID="s004" updateID="219" stUpdate="1"/>
<stDone objID="s001" updateID="219"/>
</StateEvent>
07070100000068000081A400000000000000000000000168604515000001AB000000000000000000000000000000000000004800000000gupnp-av-0.14.4/tests/gtest/data/cds-last-change/02-cds-last-change.xml<?xml version="1.0" encoding="UTF-8"?>
<StateEvent
xmlns="urn:schemas-upnp-org:av:cds-event"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
http://www.upnp.org/schemas/av/cds-event.xsd">
<objAdd objID="Album001" updateID="101" objParentID="0"
objClass="object.container.album.musicAlbum" stUpdate="0"/>
<objMod objID="0" updateID="102" stUpdate="0"/>
</StateEvent>
07070100000069000081A40000000000000000000000016860451500000250000000000000000000000000000000000000004800000000gupnp-av-0.14.4/tests/gtest/data/cds-last-change/03-cds-last-change.xml<?xml version="1.0" encoding="UTF-8"?>
<StateEvent
xmlns="urn:schemas-upnp-org:av:cds-event"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
http://www.upnp.org/schemas/av/cds-event.xsd">
<objAdd objID="Album001" updateID="101" objParentID="0"
objClass="object.container.album.musicAlbum" stUpdate="0"/>
<objMod objID="0" updateID="102" stUpdate="0"/>
<objAdd objID="Song001" updateID="103" objParentID="Album001"
objClass="object.item.audioItem" stUpdate="0"/>
<objMod objID="Album001" updateID="104" stUpdate="0"/>
</StateEvent>
0707010000006A000081A40000000000000000000000016860451500000362000000000000000000000000000000000000004800000000gupnp-av-0.14.4/tests/gtest/data/cds-last-change/04-cds-last-change.xml<?xml version="1.0" encoding="UTF-8"?>
<StateEvent
xmlns="urn:schemas-upnp-org:av:cds-event"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
http://www.upnp.org/schemas/av/cds-event.xsd">
<objAdd objID="Album001" updateID="101" objParentID="0"
objClass="object.container.album.musicAlbum" stUpdate="0"/>
<objMod objID="0" updateID="102" stUpdate="0"/>
<objAdd objID="Song001" updateID="103" objParentID="Album001"
objClass="object.item.audioItem" stUpdate="0"/>
<objMod objID="Album001" updateID="104" stUpdate="0"/>
<objAdd objID="Song002" updateID="105" objParentID="Album001"
objClass="object.item.audioItem" stUpdate="0"/>
<objMod objID="Album001" updateID="106" stUpdate="0"/>
<objDel objID="Song001" updateID="107" stUpdate="0"/>
<objMod objID="Album001" updateID="108" stUpdate="0"/>
</StateEvent>
0707010000006B000081A40000000000000000000000016860451500000362000000000000000000000000000000000000004800000000gupnp-av-0.14.4/tests/gtest/data/cds-last-change/05-cds-last-change.xml<?xml version="1.0" encoding="UTF-8"?>
<StateEvent
xmlns="urn:schemas-upnp-org:av:cds-event"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
http://www.upnp.org/schemas/av/cds-event.xsd">
<objAdd objID="Album001" updateID="101" objParentID="0"
objClass="object.container.album.musicAlbum" stUpdate="0"/>
<objMod objID="0" updateID="102" stUpdate="0"/>
<objAdd objID="Song001" updateID="103" objParentID="Album001"
objClass="object.item.audioItem" stUpdate="0"/>
<objMod objID="Album001" updateID="104" stUpdate="0"/>
<objAdd objID="Song002" updateID="105" objParentID="Album001"
objClass="object.item.audioItem" stUpdate="0"/>
<objMod objID="Album001" updateID="106" stUpdate="0"/>
<objDel objID="Song001" updateID="107" stUpdate="0"/>
<objMod objID="Album001" updateID="108" stUpdate="0"/>
</StateEvent>
0707010000006C000081A400000000000000000000000168604515000001AC000000000000000000000000000000000000004800000000gupnp-av-0.14.4/tests/gtest/data/cds-last-change/06-cds-last-change.xml<?xml version="1.0" encoding="UTF-8"?>
<StateEvent
xmlns="urn:schemas-upnp-org:av:cds-event"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
http://www.upnp.org/schemas/av/cds-event.xsd">
<objAdd objID="Song003" updateID="109" objParentID="Album001"
objClass="object.item.audioItem" stUpdate="0"/>
<objMod objID="Album001" updateID="110" stUpdate="0"/>
</StateEvent>
0707010000006D000081A40000000000000000000000016860451500000279000000000000000000000000000000000000004800000000gupnp-av-0.14.4/tests/gtest/data/cds-last-change/07-cds-last-change.xml<?xml version="1.0" encoding="UTF-8"?>
<StateEvent
xmlns="urn:schemas-upnp-org:av:cds-event"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
http://www.upnp.org/schemas/av/cds-event.xsd">
<objAdd objID="Song003" updateID="234" objParentID="Album001"
objClass="object.item.audioItem" stUpdate="1"/>
<objMod objID="Album001" updateID="235" stUpdate="1"/>
<objMod objID="Song001" updateID="236" stUpdate="1"/>
<objDel objID="Song002" updateID="237" stUpdate="1"/>
<objMod objID="Album001" updateID="238" stUpdate="1"/>
<stDone objID="Album001" updateID="238"/>
</StateEvent>
0707010000006E000081A400000000000000000000000168604515000002D2000000000000000000000000000000000000002800000000gupnp-av-0.14.4/tests/gtest/meson.buildtest_env = [
'GUPNP_AV_DATADIR="@0@"'.format(join_paths(meson.project_source_root(), 'data')),
'MALLOC_PERTURB_=170',
'MALLOC_CHECK_=2'
]
tests = [
'regression',
'didl-lite-object',
'media-collection',
'last-change-parser',
'cds-last-change-parser'
]
foreach subtest : tests
test_name = 'test-' + subtest
test_source = test_name + '.c'
test(
test_name,
executable(
test_name,
test_source,
dependencies : [gupnp_av, gobject, libxml],
include_directories: config_h_inc,
c_args: [common_cflags, '-DDATA_PATH="@0@"'.format(meson.current_source_dir())]
),
env : test_env
)
endforeach
0707010000006F000081A4000000000000000000000001686045150000408D000000000000000000000000000000000000003A00000000gupnp-av-0.14.4/tests/gtest/test-cds-last-change-parser.c/*
* Copyright (C) 2012 Intel Corporation
*
* Author: Jens Georg <jensg@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include <stdio.h>
#include <string.h>
#include <libgupnp-av/gupnp-cds-last-change-parser.h>
typedef struct {
GUPnPCDSLastChangeEvent event;
const char *object_id;
const char *parent_id;
const char *class;
guint32 update_id;
gboolean is_st_update;
} TestReferenceEntry;
typedef struct {
const char *file_name;
guint entry_count;
TestReferenceEntry data[100];
} TestReference;
TestReference test_reference_data[] = {
{
"00-cds-last-change.xml",
0,
{}
},
{
"01-cds-last-change.xml",
8,
{
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
"s002",
"s001",
"object.container.album",
213,
TRUE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"s001",
NULL,
NULL,
214,
TRUE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
"s003",
"s001",
"object.item.audioItem",
215,
FALSE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
"s004",
"s002",
"object.item.audioItem",
216,
TRUE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED,
"s003",
NULL,
NULL,
217,
FALSE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"s001",
NULL,
NULL,
218,
FALSE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"s004",
NULL,
NULL,
219,
TRUE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_ST_DONE,
"s001",
NULL,
NULL,
219,
FALSE
}
}
},
{
"02-cds-last-change.xml",
2,
{
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
"Album001",
"0",
"object.container.album.musicAlbum",
101,
FALSE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"0",
NULL,
NULL,
102,
FALSE
}
}
},
{
"03-cds-last-change.xml",
4,
{
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
"Album001",
"0",
"object.container.album.musicAlbum",
101,
FALSE
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"0",
NULL,
NULL,
102,
FALSE
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
"Song001",
"Album001",
"object.item.audioItem",
103,
FALSE
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"Album001",
NULL,
NULL,
104,
FALSE
}
}
},
{
"04-cds-last-change.xml",
8,
{
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
"Album001",
"0",
"object.container.album.musicAlbum",
101,
FALSE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"0",
NULL,
NULL,
102,
FALSE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
"Song001",
"Album001",
"object.item.audioItem",
103,
FALSE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"Album001",
NULL,
NULL,
104,
FALSE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
"Song002",
"Album001",
"object.item.audioItem",
105,
FALSE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"Album001",
NULL,
NULL,
106,
FALSE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED,
"Song001",
NULL,
NULL,
107,
FALSE
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"Album001",
NULL,
NULL,
108,
FALSE
}
}
},
{
"05-cds-last-change.xml",
8,
{
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
"Album001",
"0",
"object.container.album.musicAlbum",
101,
FALSE
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"0",
NULL,
NULL,
102,
FALSE
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
"Song001",
"Album001",
"object.item.audioItem",
103,
FALSE
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"Album001",
NULL,
NULL,
104,
FALSE
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
"Song002",
"Album001",
"object.item.audioItem",
105,
FALSE
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"Album001",
NULL,
NULL,
106,
FALSE
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED,
"Song001",
NULL,
NULL,
107,
FALSE
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"Album001",
NULL,
NULL,
108,
FALSE
}
}
},
{
"06-cds-last-change.xml",
2,
{
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
"Song003",
"Album001",
"object.item.audioItem",
109,
FALSE
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"Album001",
NULL,
NULL,
110,
FALSE
}
}
},
{
"07-cds-last-change.xml",
6,
{
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
"Song003",
"Album001",
"object.item.audioItem",
234,
TRUE
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"Album001",
NULL,
NULL,
235,
TRUE
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"Song001",
NULL,
NULL,
236,
TRUE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED,
"Song002",
NULL,
NULL,
237,
TRUE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
"Album001",
NULL,
NULL,
238,
TRUE,
},
{
GUPNP_CDS_LAST_CHANGE_EVENT_ST_DONE,
"Album001",
NULL,
NULL,
238,
FALSE,
}
}
}
};
static void
compare_entries (const char *file, GList *entries)
{
guint reference_size, i, j;
GList *it = entries;
reference_size = G_N_ELEMENTS (test_reference_data);
/* Find reference entries */
for (i = 0; i < reference_size; i++) {
if (strcmp (test_reference_data[i].file_name, file) != 0)
continue;
g_assert_cmpint (g_list_length (entries),
==,
test_reference_data[i].entry_count);
for (j = 0;
j < test_reference_data[i].entry_count;
j++, it = it->next) {
TestReferenceEntry* entry;
entry = &test_reference_data[i].data[j];
g_assert_cmpstr (entry->class, ==,
gupnp_cds_last_change_entry_get_class (it->data));
g_assert_cmpstr (entry->parent_id, ==,
gupnp_cds_last_change_entry_get_parent_id (it->data));
g_assert_cmpuint (entry->update_id, ==,
gupnp_cds_last_change_entry_get_update_id (it->data));
g_assert_cmpstr (entry->object_id, ==,
gupnp_cds_last_change_entry_get_object_id (it->data));
g_assert_cmpint (entry->event, ==,
gupnp_cds_last_change_entry_get_event (it->data));
g_assert_cmpint (entry->is_st_update, ==,
gupnp_cds_last_change_entry_is_subtree_update (it->data));
}
return;
}
g_message ("No reference entry found for file %s", file);
g_assert_not_reached ();
}
static void
test_parse_spec_samples (void)
{
GDir *dir;
GError *error = NULL;
const char *file;
char *data_path;
GUPnPCDSLastChangeParser *parser;
parser = gupnp_cds_last_change_parser_new ();
data_path = g_build_filename (DATA_PATH,
"data",
"cds-last-change",
NULL);
dir = g_dir_open (data_path, 0, &error);
g_assert_no_error (error);
while ((file = g_dir_read_name (dir)) != NULL) {
char *contents;
gsize length;
char *file_path;
GList *entries;
if (g_str_has_prefix (file, ".") ||
g_str_has_suffix (file, "~"))
continue;
file_path = g_build_filename (data_path, file, NULL);
g_file_get_contents (file_path, &contents, &length, &error);
g_assert_no_error (error);
g_free (file_path);
entries = gupnp_cds_last_change_parser_parse (parser,
contents,
&error);
g_assert_no_error (error);
compare_entries (file, entries);
g_list_free_full (entries,
(GDestroyNotify) gupnp_cds_last_change_entry_unref);
g_free (contents);
}
g_object_unref (parser);
g_dir_close (dir);
g_free (data_path);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/cds-last-change/parse-spec-samples",
test_parse_spec_samples);
return g_test_run ();
}
07070100000070000081A400000000000000000000000168604515000004C1000000000000000000000000000000000000003400000000gupnp-av-0.14.4/tests/gtest/test-didl-lite-object.c/*
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include <libgupnp-av/gupnp-didl-lite-object.h>
#include <libgupnp-av/gupnp-didl-lite-writer.h>
static void
namespace_getters (void)
{
GUPnPDIDLLiteWriter *writer = gupnp_didl_lite_writer_new (NULL);
GUPnPDIDLLiteObject *object = GUPNP_DIDL_LITE_OBJECT (gupnp_didl_lite_writer_add_item (writer));
xmlNs *namespace;
namespace = gupnp_didl_lite_object_get_upnp_namespace (object);
g_assert (namespace != NULL);
g_assert_cmpstr ((char *) namespace->prefix, ==, "upnp");
namespace = gupnp_didl_lite_object_get_dlna_namespace (object);
g_assert (namespace != NULL);
g_assert_cmpstr ((char *) namespace->prefix, ==, "dlna");
namespace = gupnp_didl_lite_object_get_dc_namespace (object);
g_assert (namespace != NULL);
g_assert_cmpstr ((char *) namespace->prefix, ==, "dc");
namespace = gupnp_didl_lite_object_get_pv_namespace (object);
g_assert (namespace != NULL);
g_assert_cmpstr ((char *) namespace->prefix, ==, "pv");
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/didl-lite-object/namespace-getters", namespace_getters);
g_test_run ();
return 0;
}
07070100000071000081A400000000000000000000000168604515000023DB000000000000000000000000000000000000003600000000gupnp-av-0.14.4/tests/gtest/test-last-change-parser.c/*
* Copyright (C) 2012 Intel Corporation
*
* Author: Krzesimir Nowak <krnowak@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include <libgupnp-av/gupnp-last-change-parser.h>
#define TEST_GENERAL \
"<?xml version=\"1.0\" encoding=\"UTF-8\"?> " \
"<Event " \
"xmlns=\"urn:schemas-upnp-org:metadata-1-0/RCS/\" " \
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \
"xsi:schemaLocation=\" " \
"urn:schemas-upnp-org:metadata-1-0/RCS/ " \
"http://www.upnp.org/schemas/av/rcs-event-v1-20060531.xsd\"> " \
"<InstanceID val=\"0\"> " \
"<Foo val=\"-13\"/> " \
"<Bar val=\"ajwaj\"/> " \
"</InstanceID> " \
"<InstanceID val=\"1\"> " \
"<Baz val=\"true\"/> " \
"<Qux val=\"42\"/> " \
"</InstanceID> " \
"</Event>"
#define BOGUS_TEXT "This is not an XML document!"
#define TEST_TWO_MUTES \
"<?xml version=\"1.0\" encoding=\"UTF-8\"?> " \
"<Event " \
"xmlns=\"urn:schemas-upnp-org:metadata-1-0/RCS/\" " \
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \
"xsi:schemaLocation=\" " \
"urn:schemas-upnp-org:metadata-1-0/RCS/ " \
"http://www.upnp.org/schemas/av/rcs-event-v1-20060531.xsd\"> " \
"<InstanceID val=\"0\"> " \
"<Mute channel=\"Master\" val=\"0\"/> " \
"<Mute channel=\"CF\" val=\"1\"/> " \
"</InstanceID> " \
"</Event>"
static void
general (void)
{
GUPnPLastChangeParser *parser = gupnp_last_change_parser_new ();
GError *error1 = NULL;
GError *error2 = NULL;
gboolean r1;
gboolean r2;
gint foo = -1;
gchar *bar = NULL;
gboolean baz = FALSE;
guint qux = G_MAXUINT;;
r1 = gupnp_last_change_parser_parse_last_change (parser,
0,
TEST_GENERAL,
&error1,
"Foo",
G_TYPE_INT,
&foo,
"Bar",
G_TYPE_STRING,
&bar,
NULL);
r2 = gupnp_last_change_parser_parse_last_change (parser,
1,
TEST_GENERAL,
&error2,
"Baz",
G_TYPE_BOOLEAN,
&baz,
"Qux",
G_TYPE_UINT,
&qux,
NULL);
g_object_unref (parser);
g_assert (r1 == TRUE);
g_assert_no_error (error1);
g_assert_cmpint (foo, ==, -13);
g_assert_cmpstr (bar, ==, "ajwaj");
g_free (bar);
g_assert (r2 == TRUE);
g_assert_no_error (error2);
g_assert (baz == TRUE);
g_assert_cmpuint (qux, ==, 42);
}
static void
bogus_text (void)
{
GUPnPLastChangeParser *parser = gupnp_last_change_parser_new ();
GError *error = NULL;
gboolean r;
int whatever = -1;
r = gupnp_last_change_parser_parse_last_change (parser,
0,
BOGUS_TEXT,
&error,
"whatever",
G_TYPE_INT,
&whatever,
NULL);
g_object_unref (parser);
g_assert (r == FALSE);
g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE);
g_assert_cmpint (whatever, ==, -1);
}
static void
nonexistent_instance (void)
{
GUPnPLastChangeParser *parser = gupnp_last_change_parser_new ();
GError *error = NULL;
gboolean r;
gint foo = -1;
gchar *bar = NULL;
gboolean baz = FALSE;
guint qux = G_MAXUINT;;
r = gupnp_last_change_parser_parse_last_change (parser,
42,
TEST_GENERAL,
&error,
"Foo",
G_TYPE_INT,
&foo,
"Bar",
G_TYPE_STRING,
&bar,
"Baz",
G_TYPE_BOOLEAN,
&baz,
"Qux",
G_TYPE_UINT,
&qux,
NULL);
g_object_unref (parser);
g_assert (r == FALSE);
g_assert_no_error (error);
g_assert_cmpint (foo, ==, -1);
g_assert_cmpstr (bar, ==, NULL);
g_assert (baz == FALSE);
g_assert_cmpuint (qux, ==, G_MAXUINT);
}
/* FIXME: We really have no way to test whether some variable does not
exist. In the test below I set baz to FALSE and qux to G_MAXUINT
and check whether those variables have still the same values after
parsing. It may happen that those variable existed in LastChange
document and had exactly those values. */
static void
nonexistent_variable (void)
{
GUPnPLastChangeParser *parser = gupnp_last_change_parser_new ();
GError *error = NULL;
gboolean r;
gboolean baz = FALSE;
guint qux = G_MAXUINT;;
r = gupnp_last_change_parser_parse_last_change (parser,
0,
TEST_GENERAL,
&error,
"Baz",
G_TYPE_BOOLEAN,
&baz,
"Qux",
G_TYPE_UINT,
&qux,
NULL);
g_object_unref (parser);
g_assert (r == TRUE);
g_assert_no_error (error);
g_assert (baz == FALSE);
g_assert_cmpuint (qux, ==, G_MAXUINT);
}
/* FIXME: There is no possibility for fine-grained selection of
variables we want to extract. There can be two "Mute" variables on
different "channel"s, but currently the code can only take the
first "Mute" variable ignoring "channel" attribute. */
static void
two_mutes (void)
{
GUPnPLastChangeParser *parser = gupnp_last_change_parser_new ();
GError *error = NULL;
gint master_mute = -1;
gint cf_mute = -1;
gboolean r;
r = gupnp_last_change_parser_parse_last_change (parser,
0,
TEST_TWO_MUTES,
&error,
"Mute",
G_TYPE_INT,
&master_mute,
"Mute",
G_TYPE_INT,
&cf_mute,
NULL);
g_object_unref (parser);
g_assert (r == TRUE);
g_assert_no_error (error);
g_assert_cmpint (master_mute, ==, 0);
g_message ("Omitting the check of \"Mute\" for \"CF\" channel as this test "
"fails, because of design issues.");
//g_assert_cmpint (cf_mute, ==, 1);
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/last-change-parser/general", general);
g_test_add_func ("/last-change-parser/bogus-text", bogus_text);
g_test_add_func ("/last-change-parser/nonexistent-instance", nonexistent_instance);
g_test_add_func ("/last-change-parser/nonexistent-variable", nonexistent_variable);
g_test_add_func ("/last-change-parser/two-mutes", two_mutes);
g_test_run ();
return 0;
}
07070100000072000081A400000000000000000000000168604515000053CC000000000000000000000000000000000000003400000000gupnp-av-0.14.4/tests/gtest/test-media-collection.c/*
* Copyright (C) 2012 Intel Corporation.
* Copyright (C) 2013 Jens Georg <mail@jensge.org>
*
* Author: Jens Georg <jensg@openismus.com>
* Jens Georg <mail@jensge.org>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include <string.h>
#include <libgupnp-av/gupnp-media-collection.h>
/* Flat DIDL_S playlist */
#define TEST_PARSE_COLLECTION_1 \
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \
"<DIDL-Lite" \
" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"" \
" xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\"" \
" xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\"" \
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" \
" xsi:schemaLocation=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" \
" http://www.upnp.org/schemas/av/didl-lite-v2-20060531.xsd" \
" urn:schemas-upnp-org:metadata-1-0/upnp/" \
" http://www.upnp.org/schemas/av/upnp-v2-20060531.xsd\">" \
" <item id=\"\" parentID=\"0\" restricted=\"0\">" \
" <dc:title>Song1</dc:title>" \
" <upnp:class>object.item.audioItem</upnp:class>" \
" <res protocolInfo=\"*:*:*:*\" />" \
" <upnp:artist></upnp:artist>" \
" </item>" \
" <item id=\"\" parentID=\"0\" restricted=\"0\">" \
" <dc:title>Song2</dc:title>" \
" <upnp:class>object.item.audioItem</upnp:class>" \
" <res protocolInfo=\"*:*:*:*\" />" \
" </item>" \
" <item id=\"\" parentID=\"0\" restricted=\"0\">" \
" <dc:title>Song3</dc:title>" \
" <upnp:class>object.item.audioItem</upnp:class>" \
" <res protocolInfo=\"*:*:*:*\" />" \
" </item>" \
"</DIDL-Lite>"
/* Nested DIDL_S playlist */
#define TEST_PARSE_COLLECTION_2 \
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \
"<DIDL-Lite" \
" xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\"" \
" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"" \
" xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\"" \
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" \
" xsi:schemaLocation=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" \
" http://www.upnp.org/schemas/av/didl-lite-v2-20060531.xsd" \
" urn:schemas-upnp-org:metadata-1-0/upnp/" \
" http://www.upnp.org/schemas/av/upnp-v2-20060531.xsd\">" \
" <container id=\"1\" parentID=\"0\" restricted=\"0\">" \
" <dc:title>NonFlatCollection</dc:title>" \
" <dc:creator>NonFlatCollection Author</dc:creator>" \
" <item id=\"\" parentID=\"1\" restricted=\"0\">" \
" <dc:title>Song1</dc:title>" \
" <upnp:class>object.item.audioItem</upnp:class>" \
" <res protocolInfo=\"*:*:*:*\" />" \
" <upnp:artist></upnp:artist>" \
" </item>" \
" <item id=\"\" parentID=\"1\" restricted=\"0\">" \
" <dc:title>Song2</dc:title>" \
" <upnp:class>object.item.audioItem</upnp:class>" \
" <res protocolInfo=\"*:*:*:*\" />" \
" </item>" \
" <item id=\"\" parentID=\"1\" restricted=\"0\">" \
" <dc:title>Song3</dc:title>" \
" <upnp:class>object.item.audioItem</upnp:class>" \
" <res protocolInfo=\"*:*:*:*\" />" \
" </item>" \
" </container>" \
"</DIDL-Lite>"
#define TEST_CREATE_FLAT \
"<DIDL-Lite " \
"xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" " \
"xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " \
"xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\">" \
"<item restricted=\"1\">" \
"<dc:title>Song1</dc:title>" \
"<upnp:class>object.item.audioItem</upnp:class>" \
"<res>http://example.com/song1.mp3</res>" \
"</item>" \
"<item restricted=\"1\">" \
"<dc:title>Song2</dc:title>" \
"<upnp:class>object.item.audioItem</upnp:class>" \
"<res>http://example.com/song2.mp3</res>" \
"</item>" \
"<item restricted=\"1\">" \
"<dc:title>Song3</dc:title>" \
"<upnp:class>object.item.audioItem</upnp:class>" \
"<res>http://example.com/song3.mp3</res>" \
"</item>" \
"</DIDL-Lite>"
#define TEST_CREATE_FULL \
"<DIDL-Lite " \
"xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" " \
"xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " \
"xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\">" \
"<container>" \
"<dc:title>TestCollection1</dc:title>" \
"<dc:creator>TestCollection1Author</dc:creator>" \
"<item restricted=\"1\">" \
"<dc:title>Song1</dc:title>" \
"<upnp:class>object.item.audioItem</upnp:class>" \
"<res>http://example.com/song1.mp3</res>" \
"</item>" \
"<item restricted=\"1\">" \
"<dc:title>Song2</dc:title>" \
"<upnp:class>object.item.audioItem</upnp:class>" \
"<res>http://example.com/song2.mp3</res>" \
"</item>" \
"<item restricted=\"1\">" \
"<dc:title>Song3</dc:title>" \
"<upnp:class>object.item.audioItem</upnp:class>" \
"<res>http://example.com/song3.mp3</res>" \
"</item>" \
"</container>" \
"</DIDL-Lite>"
#define TEST_CREATE_FULL_REPARENT \
"<DIDL-Lite " \
"xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" " \
"xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " \
"xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\">" \
"<container>" \
"<item restricted=\"1\">" \
"<dc:title>Song1</dc:title>" \
"<upnp:class>object.item.audioItem</upnp:class>" \
"<res>http://example.com/song1.mp3</res>" \
"</item>" \
"<item restricted=\"1\">" \
"<dc:title>Song2</dc:title>" \
"<upnp:class>object.item.audioItem</upnp:class>" \
"<res>http://example.com/song2.mp3</res>" \
"</item>" \
"<item restricted=\"1\">" \
"<dc:title>Song3</dc:title>" \
"<upnp:class>object.item.audioItem</upnp:class>" \
"<res>http://example.com/song3.mp3</res>" \
"</item>" \
"<dc:title>TestCollection1</dc:title>" \
"<dc:creator>TestCollection1Author</dc:creator>" \
"</container>" \
"</DIDL-Lite>"
#define TEST_PARSE_NO_XML "This is just some random text"
static void
test_didl_collection_construction (void)
{
GUPnPMediaCollection *collection;
/* Check that a collection created via auxillary function is mutable */
collection = gupnp_media_collection_new ();
g_assert (gupnp_media_collection_get_mutable (collection));
g_object_unref (collection);
/* Check that a collection created via auxillary parse function is
* not mutable */
collection = gupnp_media_collection_new_from_string
(TEST_PARSE_COLLECTION_1);
g_assert (!gupnp_media_collection_get_mutable (collection));
g_object_unref (collection);
/* Check that creating a collection via g_object_new and title/author
* properties set is mutable */
collection = g_object_new (GUPNP_TYPE_MEDIA_COLLECTION,
"title", "test01collection",
"author", "test01author",
NULL);
g_assert (gupnp_media_collection_get_mutable (collection));
g_object_unref (collection);
/* Check that creating a collection via g_object_new and data is not
* mutable */
collection = g_object_new (GUPNP_TYPE_MEDIA_COLLECTION,
"data", TEST_PARSE_COLLECTION_1,
NULL);
g_assert (!gupnp_media_collection_get_mutable (collection));
g_object_unref (collection);
/* Check that creating a collection with all properties set will result
* in a collection that ignored "title" and "author" properties.
*/
collection = g_object_new (GUPNP_TYPE_MEDIA_COLLECTION,
"title", "test01collection",
"author", "test01author",
"data", TEST_PARSE_COLLECTION_1,
NULL);
g_assert (!gupnp_media_collection_get_mutable (collection));
g_assert_cmpstr (gupnp_media_collection_get_author (collection), ==,
NULL);
g_assert_cmpstr (gupnp_media_collection_get_title (collection), ==,
NULL);
g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
TEST_PARSE_COLLECTION_1);
g_object_unref (collection);
}
static void
test_didl_collection_parse_flat (void)
{
GUPnPMediaCollection *collection;
GList *items, *it;
collection = gupnp_media_collection_new_from_string
(TEST_PARSE_COLLECTION_1);
g_assert_cmpstr (gupnp_media_collection_get_author (collection), ==,
NULL);
g_assert_cmpstr (gupnp_media_collection_get_title (collection), ==,
NULL);
g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
TEST_PARSE_COLLECTION_1);
it = items = gupnp_media_collection_get_items (collection);
g_assert_cmpint (g_list_length (items), ==, 3);
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song1");
it = it->next;
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song2");
it = it->next;
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song3");
g_list_free_full (items, (GDestroyNotify) g_object_unref);
}
static void
test_didl_collection_parse_full (void)
{
GUPnPMediaCollection *collection;
GList *items, *it;
collection = gupnp_media_collection_new_from_string
(TEST_PARSE_COLLECTION_2);
g_assert_cmpstr (gupnp_media_collection_get_author (collection), ==,
"NonFlatCollection Author");
g_assert_cmpstr (gupnp_media_collection_get_title (collection), ==,
"NonFlatCollection");
g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
TEST_PARSE_COLLECTION_2);
it = items = gupnp_media_collection_get_items (collection);
g_assert_cmpint (g_list_length (items), ==, 3);
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song1");
it = it->next;
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song2");
it = it->next;
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song3");
g_list_free_full (items, (GDestroyNotify) g_object_unref);
}
#define ERROR_MESSAGE "Failed to parse DIDL-Lite: No 'DIDL-Lite' node in the DIDL-Lite XML:"
static gboolean
ignore_xml_parse_error (G_GNUC_UNUSED const gchar *log_domain,
G_GNUC_UNUSED GLogLevelFlags log_level,
const gchar *message,
G_GNUC_UNUSED gpointer user_data)
{
if (strncmp (message,
ERROR_MESSAGE,
g_utf8_strlen (ERROR_MESSAGE, -1) - 1) == 0) {
return FALSE;
}
return TRUE;
}
static void
test_didl_collection_parse_invalid (void)
{
GUPnPMediaCollection *collection;
GList *items;
g_test_log_set_fatal_handler (ignore_xml_parse_error, NULL);
collection = gupnp_media_collection_new_from_string (TEST_PARSE_NO_XML);
items = gupnp_media_collection_get_items (collection);
g_assert (items == NULL);
g_object_unref (collection);
}
static void
test_didl_collection_create_flat (void)
{
GUPnPMediaCollection *collection;
GUPnPDIDLLiteItem *item;
GList *items, *it;
GUPnPDIDLLiteResource *res;
collection = gupnp_media_collection_new ();
item = gupnp_media_collection_add_item (collection);
gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
"Song1");
gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
"object.item.audioItem");
res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
gupnp_didl_lite_resource_set_uri (res, "http://example.com/song1.mp3");
g_object_unref (res);
g_object_unref (item);
item = gupnp_media_collection_add_item (collection);
gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
"Song2");
gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
"object.item.audioItem");
res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
gupnp_didl_lite_resource_set_uri (res, "http://example.com/song2.mp3");
g_object_unref (res);
g_object_unref (item);
item = gupnp_media_collection_add_item (collection);
gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
"Song3");
gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
"object.item.audioItem");
res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
gupnp_didl_lite_resource_set_uri (res, "http://example.com/song3.mp3");
g_object_unref (res);
g_object_unref (item);
it = items = gupnp_media_collection_get_items (collection);
g_assert_cmpint (g_list_length (items), ==, 3);
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song1");
it = it->next;
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song2");
it = it->next;
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song3");
g_list_free_full (items, (GDestroyNotify) g_object_unref);
g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
TEST_CREATE_FLAT);
}
static void
test_didl_collection_create_full (void)
{
GUPnPMediaCollection *collection;
GUPnPDIDLLiteItem *item;
GList *items, *it;
GUPnPDIDLLiteResource *res;
collection = gupnp_media_collection_new ();
gupnp_media_collection_set_title (collection, "TestCollection1");
gupnp_media_collection_set_author (collection, "TestCollection1Author");
item = gupnp_media_collection_add_item (collection);
gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
"Song1");
gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
"object.item.audioItem");
res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
gupnp_didl_lite_resource_set_uri (res, "http://example.com/song1.mp3");
g_object_unref (res);
g_object_unref (item);
item = gupnp_media_collection_add_item (collection);
gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
"Song2");
gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
"object.item.audioItem");
res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
gupnp_didl_lite_resource_set_uri (res, "http://example.com/song2.mp3");
g_object_unref (res);
g_object_unref (item);
item = gupnp_media_collection_add_item (collection);
gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
"Song3");
gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
"object.item.audioItem");
res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
gupnp_didl_lite_resource_set_uri (res, "http://example.com/song3.mp3");
g_object_unref (res);
g_object_unref (item);
it = items = gupnp_media_collection_get_items (collection);
g_assert_cmpint (g_list_length (items), ==, 3);
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song1");
it = it->next;
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song2");
it = it->next;
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song3");
g_list_free_full (items, (GDestroyNotify) g_object_unref);
g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
TEST_CREATE_FULL);
}
static void
test_didl_collection_create_reparent (void)
{
GUPnPMediaCollection *collection;
GUPnPDIDLLiteItem *item;
GList *items, *it;
GUPnPDIDLLiteResource *res;
collection = gupnp_media_collection_new ();
item = gupnp_media_collection_add_item (collection);
gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
"Song1");
gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
"object.item.audioItem");
res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
gupnp_didl_lite_resource_set_uri (res, "http://example.com/song1.mp3");
g_object_unref (res);
g_object_unref (item);
item = gupnp_media_collection_add_item (collection);
gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
"Song2");
gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
"object.item.audioItem");
res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
gupnp_didl_lite_resource_set_uri (res, "http://example.com/song2.mp3");
g_object_unref (res);
g_object_unref (item);
item = gupnp_media_collection_add_item (collection);
gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
"Song3");
gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
"object.item.audioItem");
res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
gupnp_didl_lite_resource_set_uri (res, "http://example.com/song3.mp3");
g_object_unref (res);
g_object_unref (item);
it = items = gupnp_media_collection_get_items (collection);
/* Force reparenting of the items in the XML */
gupnp_media_collection_set_title (collection, "TestCollection1");
gupnp_media_collection_set_author (collection, "TestCollection1Author");
g_assert_cmpint (g_list_length (items), ==, 3);
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song1");
it = it->next;
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song2");
it = it->next;
g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
"Song3");
g_list_free_full (items, (GDestroyNotify) g_object_unref);
g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
TEST_CREATE_FULL_REPARENT);
}
int main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/didl/collection/construction",
test_didl_collection_construction);
g_test_add_func ("/didl/collection/parse_flat",
test_didl_collection_parse_flat);
g_test_add_func ("/didl/collection/parse_full",
test_didl_collection_parse_full);
g_test_add_func ("/didl/collection/parse_invalid",
test_didl_collection_parse_invalid);
g_test_add_func ("/didl/collection/create_flat",
test_didl_collection_create_flat);
g_test_add_func ("/didl/collection/create_full",
test_didl_collection_create_full);
g_test_add_func ("/didl/collection/create_reparent",
test_didl_collection_create_reparent);
return g_test_run ();
}
07070100000073000081A400000000000000000000000168604515000026EB000000000000000000000000000000000000002E00000000gupnp-av-0.14.4/tests/gtest/test-regression.c/*
* Copyright (C) 2012 Openismus GmbH
*
* Author: Jens Georg <jensg@openismus.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include <libgupnp-av/gupnp-didl-lite-parser.h>
#include <libgupnp-av/gupnp-didl-lite-writer.h>
#define TEST_DIDL_BGO674319 \
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \
"<DIDL-Lite" \
" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"" \
" xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\"" \
" xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\"" \
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" \
" xsi:schemaLocation=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" \
" http://www.upnp.org/schemas/av/didl-lite-v2-20060531.xsd" \
" urn:schemas-upnp-org:metadata-1-0/upnp/" \
" http://www.upnp.org/schemas/av/upnp-v2-20060531.xsd\">" \
" <item id=\"\" parentID=\"0\" restricted=\"0\">" \
" <dc:title>New Song</dc:title>" \
" <upnp:class>object.item.audioItem</upnp:class>" \
" <res protocolInfo=\"*:*:*:*\" />" \
" <upnp:artist></upnp:artist>" \
" </item>" \
"</DIDL-Lite>"
#define TEST_DIDL_BGO705564 \
"<DIDL-Lite xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" " \
"xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" " \
"xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\">" \
"<item>" \
"<upnp:albumArtURI dlna:profileID=\"JPEG_TN\">" \
"http://example.com/album.jpg"\
"</upnp:albumArtURI>"\
"</item>" \
"</DIDL-Lite>"
#define TEST_DIDL_BGO770174 \
"<DIDL-Lite xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " \
"xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" " \
"xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" " \
"xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\">\n" \
"<container id=\"0\" parentID=\"-1\" restricted=\"1\" childCount=\"4\" searchable=\"1\">" \
"<upnp:searchClass includeDerived=\"1\">object.item.audioItem</upnp:searchClass>" \
"<upnp:searchClass includeDerived=\"1\">object.item.imageItem</upnp:searchClass>" \
"<upnp:searchClass includeDerived=\"1\">object.item.videoItem</upnp:searchClass>" \
"<dc:title>root</dc:title>" \
"<upnp:class>object.container.storageFolder</upnp:class>" \
"<upnp:storageUsed>-1</upnp:storageUsed>" \
"</container>" \
"</DIDL-Lite>"
#define TEST_DIDL_GGO11 \
"<DIDL-Lite xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" " \
"xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " \
"xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\">" \
"<item id=\"0/1/Disque dur/Vidéos/MEGAFORCE.avi\" " \
"parentID=\"0/1/Disque dur/Vidéos\">" \
"<dc:title>MEGAFORCE.avi</dc:title>" \
"<upnp:class>object.item.videoItem</upnp:class>" \
"<dc:date>%s</dc:date>" \
"<res protocolInfo=\"http-get:*:video/x-msvideo:DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=21F00000000000000000000000000000\" size=\"880839598\">" \
"http://192.168.1.254:52424/files/Disque%%20dur/Vid%%C3%%A9os/MEGAFORCE.avi" \
"</res>" \
"</item>" \
"</DIDL-Lite>"
static void
test_ggo11 (void)
{
GUPnPDIDLLiteParser *parser;
guint i;
struct {
const char *date;
gboolean success;
} date_tests[] = {
{ "2008-2-28", TRUE },
{ "200-2-28", FALSE },
{ "2008-02-28", TRUE },
{ "2008-2--28", FALSE },
{ "2008-02-8", TRUE },
{ "2008-102-8", FALSE },
{ "2008-2-128", FALSE },
{ "", TRUE },
{ "0-1-2", FALSE },
{ "2008-2-", FALSE },
{ "2021-04-23T18:18:42Z", TRUE },
{ ":", FALSE }
};
parser = gupnp_didl_lite_parser_new ();
for (i = 0; i < G_N_ELEMENTS (date_tests); i++) {
g_autofree char *didl = g_strdup_printf (TEST_DIDL_GGO11, date_tests[i].date);
g_test_message ("Testing validity of date '%s', expecting %s",
date_tests[i].date,
date_tests[i].success ? "success" : "failure");
g_assert_true (gupnp_didl_lite_parser_parse_didl (parser, didl, NULL) == date_tests[i].success);
}
g_clear_object (&parser);
}
static void
test_bgo674319_on_object_available (G_GNUC_UNUSED GUPnPDIDLLiteParser *parser,
GUPnPDIDLLiteObject *object,
gpointer user_data)
{
GUPnPDIDLLiteObject **out = (GUPnPDIDLLiteObject **) user_data;
*out = g_object_ref (object);
}
static void
test_bgo674319 (void)
{
GUPnPDIDLLiteParser *parser;
GUPnPDIDLLiteObject *object = NULL;
GList *artists;
parser = gupnp_didl_lite_parser_new ();
g_signal_connect (parser,
"object-available",
G_CALLBACK (test_bgo674319_on_object_available),
&object);
g_assert (gupnp_didl_lite_parser_parse_didl (parser, TEST_DIDL_BGO674319, NULL));
g_assert (object != NULL);
artists = gupnp_didl_lite_object_get_artists (object);
g_assert (artists == NULL);
}
static void
test_bgo687462 (void)
{
GUPnPDIDLLiteWriter *writer;
GUPnPDIDLLiteObject *object;
writer = gupnp_didl_lite_writer_new (NULL);
object = (GUPnPDIDLLiteObject *)
gupnp_didl_lite_writer_add_item (writer);
gupnp_didl_lite_object_set_album (object, "Test");
g_assert_cmpstr (gupnp_didl_lite_object_get_album (object), ==, "Test");
gupnp_didl_lite_object_set_album_art (object, "AlbumArt");
g_assert_cmpstr (gupnp_didl_lite_object_get_album_art (object), ==, "AlbumArt");
gupnp_didl_lite_writer_filter (writer, "upnp:album");
g_assert_cmpstr (gupnp_didl_lite_object_get_album (object), ==, "Test");
g_assert (gupnp_didl_lite_object_get_album_art (object) == NULL);
}
static void
test_bgo705564 (void)
{
GUPnPDIDLLiteWriter *writer;
GUPnPDIDLLiteObject *object;
char *xml;
writer = gupnp_didl_lite_writer_new (NULL);
object = (GUPnPDIDLLiteObject *)
gupnp_didl_lite_writer_add_item (writer);
gupnp_didl_lite_object_set_album_art (object,
"http://example.com/album.jpg");
xml = gupnp_didl_lite_writer_get_string (writer);
g_assert_cmpstr (xml, ==, TEST_DIDL_BGO705564);
g_free (xml);
g_object_unref (object);
g_object_unref (writer);
}
#if 0
static void
test_bgo753314 (void)
{
GUPnPDIDLLiteObject *object;
GUPnPDIDLLiteWriter *writer;
GUPnPDIDLLiteResource *resource;
GUPnPProtocolInfo *pi;
GList *list = NULL;
GUPnPDLNAFlags flags = GUPNP_DLNA_FLAGS_NONE;
flags = GUPNP_DLNA_FLAGS_BYTE_BASED_SEEK |
GUPNP_DLNA_FLAGS_STREAMING_TRANSFER_MODE |
GUPNP_DLNA_FLAGS_BACKGROUND_TRANSFER_MODE;
writer = gupnp_didl_lite_writer_new (NULL);
object = (GUPnPDIDLLiteObject *)
gupnp_didl_lite_writer_add_item (writer);
resource = gupnp_didl_lite_object_add_resource (object);
pi = gupnp_protocol_info_new ();
gupnp_protocol_info_set_protocol (pi, "http");
gupnp_protocol_info_set_mime_type (pi, "video/mp4");
gupnp_protocol_info_set_dlna_flags (pi, flags);
gupnp_didl_lite_resource_set_protocol_info (resource, pi);
g_object_unref (pi);
g_object_unref (resource);
list = gupnp_didl_lite_object_get_resources (object);
g_assert_cmpint (g_list_length (list), ==, 1);
resource = list->data;
pi = gupnp_didl_lite_resource_get_protocol_info (resource);
g_assert_cmpint (gupnp_protocol_info_get_dlna_flags (pi), ==, flags);
g_object_unref (resource);
g_object_unref (object);
g_object_unref (writer);
}
#endif
static void
test_bgo770174_on_object_available (G_GNUC_UNUSED GUPnPDIDLLiteParser *parser,
GUPnPDIDLLiteObject *object,
gpointer user_data)
{
GUPnPDIDLLiteObject **out = (GUPnPDIDLLiteObject **) user_data;
*out = g_object_ref (object);
}
static void
test_bgo770174 (void)
{
GUPnPDIDLLiteParser *parser;
GUPnPDIDLLiteObject *object = NULL;
gint storage_used = 0;
parser = gupnp_didl_lite_parser_new ();
g_signal_connect (parser,
"object-available",
G_CALLBACK (test_bgo770174_on_object_available),
&object);
g_assert (gupnp_didl_lite_parser_parse_didl (parser, TEST_DIDL_BGO770174, NULL));
g_assert (object != NULL);
storage_used = gupnp_didl_lite_container_get_storage_used
(GUPNP_DIDL_LITE_CONTAINER (object));
g_assert_cmpint (storage_used, ==, -1);
}
int main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/bugs/gnome/674319", test_bgo674319);
g_test_add_func ("/bugs/gnome/687462", test_bgo687462);
g_test_add_func ("/bugs/gnome/705564", test_bgo705564);
/* g_test_add_func ("/bugs/gnome/753314", test_bgo753314); */
g_test_add_func ("/bugs/gnome/770174", test_bgo770174);
g_test_add_func ("/bugs/gnome/11", test_ggo11);
g_test_run ();
return 0;
}
07070100000074000081A400000000000000000000000168604515000003F3000000000000000000000000000000000000002200000000gupnp-av-0.14.4/tests/meson.buildexecutable(
'test-search-criteria-parser',
[
'test-search-criteria-parser.c'
],
c_args : common_cflags,
include_directories: config_h_inc,
dependencies : [gobject, libxml, gupnp_av]
)
check_search = executable(
'check-search',
'check-search.c',
c_args : common_cflags,
include_directories: config_h_inc,
dependencies : [gobject, libxml, gupnp_av]
)
check_feature_list_parser = executable(
'check-feature-list-parser',
'check-feature-list-parser.c',
c_args : common_cflags,
include_directories: config_h_inc,
dependencies : [gobject, libxml, gupnp_av]
)
fragments = executable(
'fragments',
'fragments.c',
c_args : [common_cflags, '-DABS_TOP_SRCDIR="@0@"'.format(meson.project_source_root())],
include_directories: config_h_inc,
dependencies : [gobject, libxml, gupnp_av]
)
test('check-search', check_search)
test('check-feature-list-parser', check_feature_list_parser)
test('fragments', fragments)
subdir('gtest')
07070100000075000081A40000000000000000000000016860451500000AE5000000000000000000000000000000000000003400000000gupnp-av-0.14.4/tests/test-search-criteria-parser.c/*
* Copyright (C) 2008 OpenedHand Ltd.
*
* Authors: Jorn Baayen <jorn@openedhand.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <config.h>
#include <libgupnp-av/gupnp-search-criteria-parser.h>
#include <stdlib.h>
static void
begin_parens_cb (G_GNUC_UNUSED GUPnPSearchCriteriaParser *parser,
G_GNUC_UNUSED gpointer user_data)
{
g_print ("(");
}
static void
end_parens_cb (G_GNUC_UNUSED GUPnPSearchCriteriaParser *parser,
G_GNUC_UNUSED gpointer user_data)
{
g_print (")");
}
static void
conjunction_cb (G_GNUC_UNUSED GUPnPSearchCriteriaParser *parser,
G_GNUC_UNUSED gpointer user_data)
{
g_print (" and ");
}
static void
disjunction_cb (G_GNUC_UNUSED GUPnPSearchCriteriaParser *parser,
G_GNUC_UNUSED gpointer user_data)
{
g_print (" or ");
}
static gboolean
expression_cb (G_GNUC_UNUSED GUPnPSearchCriteriaParser *parser,
const char *property,
GUPnPSearchCriteriaOp op,
const char *value,
G_GNUC_UNUSED GError **error,
G_GNUC_UNUSED gpointer user_data)
{
g_print ("%s %d %s", property, op, value);
return TRUE;
}
int
main (int argc, char **argv)
{
GUPnPSearchCriteriaParser *parser;
GError *error;
g_assert (argc == 2);
parser = gupnp_search_criteria_parser_new ();
g_signal_connect (parser,
"begin_parens",
G_CALLBACK (begin_parens_cb),
NULL);
g_signal_connect (parser,
"end_parens",
G_CALLBACK (end_parens_cb),
NULL);
g_signal_connect (parser,
"conjunction",
G_CALLBACK (conjunction_cb),
NULL);
g_signal_connect (parser,
"disjunction",
G_CALLBACK (disjunction_cb),
NULL);
g_signal_connect (parser,
"expression",
G_CALLBACK (expression_cb),
NULL);
error = NULL;
gupnp_search_criteria_parser_parse_text (parser, argv[1], &error);
if (error != NULL) {
g_printerr ("Parse error: %s\n", error->message);
g_error_free (error);
return EXIT_FAILURE;
}
g_print ("\n");
g_object_unref (parser);
return EXIT_SUCCESS;
}
07070100000076000041ED0000000000000000000000026860451500000000000000000000000000000000000000000000001500000000gupnp-av-0.14.4/vala07070100000077000081A400000000000000000000000168604515000001BA000000000000000000000000000000000000002A00000000gupnp-av-0.14.4/vala/GUPnPAV-1.0.metadataGUPnPAV cheader_filename="libgupnp-av/gupnp-av.h"
*.get_*_namespace type="Xml.Ns*"
*.xml_node type="Xml.Node*"
*.dlna_namespace type="Xml.Ns*"
*.pv_namespace type="Xml.Ns*"
*.dc_namespace type="Xml.Ns*"
*.upnp_namespace type="Xml.Ns*"
DIDL_LITE_WRITER_NAMESPACE_* skip
SearchCriteriaParserError skip
SearchCriteriaParser
.expression skip
ProtocolError skip
protocol_error_quark skip
format_date_time_for_didl_lite.date_only default=false
07070100000078000081A40000000000000000000000016860451500000838000000000000000000000000000000000000002E00000000gupnp-av-0.14.4/vala/gupnp-av-1.0-custom.vala/*
* Copyright (C) 2008 OpenedHand Ltd.
* Copyright (C) 2012 Jens Georg.
*
* Author: Jussi Kukkonen <jku@o-hand.com>
* Jens Georg <mail@jensge.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
namespace GUPnP {
public class DIDLLiteWriter : GLib.Object {
[CCode (cname = "GUPNP_DIDL_LITE_WRITER_NAMESPACE_DC")]
public const string NAMESPACE_DC;
[CCode (cname = "GUPNP_DIDL_LITE_WRITER_NAMESPACE_UPNP")]
public const string NAMESPACE_UPNP;
[CCode (cname = "GUPNP_DIDL_LITE_WRITER_NAMESPACE_DLNA")]
public const string NAMESPACE_DLNA;
}
public errordomain SearchCriteriaParserError {
[CCode (cname = "GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED")]
FAILED
}
[CCode (cheader_filename = "libgupnp-av/gupnp-av.h", cprefix = "GUPNP_PROTOCOL_ERROR_")]
public errordomain ProtocolError {
INVALID_SYNTAX,
OTHER;
public static GLib.Quark quark ();
}
public class SearchCriteriaParser : GLib.Object {
public virtual signal bool expression (string property, GUPnP.SearchCriteriaOp op, string value, GLib.Error error);
}
public class LastChangeParser : GLib.Object {
public bool parse_last_change (uint instance_id, string last_change_xml, ...) throws GLib.Error;
}
}
07070100000079000081A4000000000000000000000001686045150000000B000000000000000000000000000000000000002700000000gupnp-av-0.14.4/vala/gupnp-av-1.0.depslibxml-2.0
0707010000007A000081A400000000000000000000000168604515000000F3000000000000000000000000000000000000002100000000gupnp-av-0.14.4/vala/meson.buildgnome.generate_vapi(
'gupnp-av-1.0',
metadata_dirs : meson.current_source_dir(),
sources : [
gupnp_av_gir.get(0),
'gupnp-av-1.0-custom.vala'
],
packages : ['gobject-2.0', 'libxml-2.0'],
install : true
)
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!1600 blocks