diff --git a/CMakeLists.txt b/CMakeLists.txt index f4aa8680..fb9b7ec0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,19 +8,22 @@ ## # Running cmake in a tree in which we have run ./configure ; make -# creates src/exv_conf.h which conflicts with cmake's own exv_conf.h +# creates include/exiv2/exv_conf.h which conflicts with cmake's own exv_conf.h # This causes incorrect compilation and linking errors. # # It's OK to delete this as it will be recreated on demand by /Makefile -if( EXISTS "${CMAKE_SOURCE_DIR}/src/exv_conf.h" ) - file(REMOVE "${CMAKE_SOURCE_DIR}/src/exv_conf.h") +if( EXISTS "${CMAKE_SOURCE_DIR}/include/exiv2/exv_conf.h" ) + file(REMOVE "${CMAKE_SOURCE_DIR}/include/exiv2/exv_conf.h") endif() ## -SET(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required -CMAKE_MINIMUM_REQUIRED( VERSION 2.6 ) +CMAKE_MINIMUM_REQUIRED( VERSION 2.8 ) PROJECT( exiv2 ) +cmake_policy(SET CMP0042 NEW) # enable MACOSX_RPATH support +SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + + SET( PACKAGE_COPYRIGHT "Andreas Huggel" ) SET( PACKAGE_BUGREPORT "ahuggel@gmx.net" ) SET( PACKAGE "exiv2" ) @@ -43,6 +46,8 @@ OPTION( EXIV2_ENABLE_LENSDATA "Build including lens data" OPTION( EXIV2_ENABLE_COMMERCIAL "Build with the EXV_COMMERCIAL_VERSION symbol set" OFF ) OPTION( EXIV2_ENABLE_BUILD_SAMPLES "Build the unit tests" ON ) OPTION( EXIV2_ENABLE_BUILD_PO "Build translations files" OFF ) +OPTION( EXIV2_ENABLE_CURL "USE Libcurl for HttpIo" ON ) +OPTION( EXIV2_ENABLE_SSH "USE Libssh for SshIo" ON ) IF( MINGW OR UNIX ) IF ( CMAKE_CXX_COMPILER STREQUAL "g++" OR CMAKE_C_COMPILER STREQUAL "gcc" ) @@ -57,8 +62,12 @@ IF( MINGW OR UNIX ) ENDIF() ENDIF( MINGW OR UNIX ) +INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/ ${CMAKE_SOURCE_DIR}/include/ ${CMAKE_SOURCE_DIR}/include/exiv2/) if( MSVC ) + + # cmake_policy(SET CMP0008) + include(CMake_msvc.txt) msvc_runtime_report() msvc_runtime_configure(${EXIV2_ENABLE_SHARED}) @@ -68,6 +77,8 @@ if( MSVC ) set(E expat-2.1.0) set(Z zlib-1.2.7) + set(C curl-7.39.0) + set(C libssh-0.5.5) if( NOT IS_DIRECTORY ./../${E} ) set(OUT_OF_SOURCE 1) @@ -80,7 +91,21 @@ if( MSVC ) include_directories( ${EXPAT_INCLUDE_DIR} msvc64\\include src\\include) endif() - FIND_PACKAGE(ZLIB QUIET) + # FIND_PACKAGE(CURL) + if ( NOT CURL_FOUND ) + set(CURL_LIBRARY ${CMAKE_SOURCE_DIR}/../${C}/$(ConfigurationName)/curl) + set(CURL_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/../${C}) + include_directories( ${CURL_INCLUDE_DIR}) + endif() + + # FIND_PACKAGE(SSH) + if ( NOT SSH_FOUND ) + set(SSH_LIBRARY ${CMAKE_SOURCE_DIR}/../${C}/$(ConfigurationName)/ssh) + set(SSH_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/../${C}) + include_directories( ${SSH_INCLUDE_DIR}) + endif() + + # FIND_PACKAGE(ZLIB QUIET) if ( NOT ZLIB_FOUND ) set(ZLIB_LIBRARY ${CMAKE_SOURCE_DIR}/../${Z}/$(ConfigurationName)/zlib) set(ZLIB_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/../${Z}) @@ -191,10 +216,12 @@ ENDIF( EXIV2_ENABLE_BUILD_PO ) ## # tests -ADD_CUSTOM_TARGET(tests COMMAND make test "EXIV2_BINDIR=${CMAKE_BINARY_DIR}/bin" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test/" ) -ADD_CUSTOM_TARGET(teste COMMAND make teste "EXIV2_BINDIR=${CMAKE_BINARY_DIR}/bin" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test/" ) -ADD_CUSTOM_TARGET(testv COMMAND make testv "EXIV2_BINDIR=${CMAKE_BINARY_DIR}/bin" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test/" ) +ADD_CUSTOM_TARGET(tests COMMAND make test "EXIV2_BINDIR=${CMAKE_BINARY_DIR}/bin" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test/" ) +ADD_CUSTOM_TARGET(teste COMMAND make teste "EXIV2_BINDIR=${CMAKE_BINARY_DIR}/bin" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test/" ) +ADD_CUSTOM_TARGET(testv COMMAND make testv "EXIV2_BINDIR=${CMAKE_BINARY_DIR}/bin" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test/" ) ADD_CUSTOM_TARGET(testvw COMMAND make testvw "EXIV2_BINDIR=${CMAKE_BINARY_DIR}/bin" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test/" ) +ADD_CUSTOM_TARGET(testx COMMAND make testx "EXIV2_BINDIR=${CMAKE_BINARY_DIR}/bin" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test/" ) + ## # http://dev.exiv2.org/boards/3/topics/1364 # effectively does a make doc on the root directory diff --git a/Makefile b/Makefile index 93753d6c..8912e54b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # ***************************************************** -*- Makefile -*- # -# Copyright (C) 2004-2013 Andreas Huggel +# Copyright (C) 2004-2012 Andreas Huggel # # This Makefile is part of the Exiv2 distribution. # @@ -71,36 +71,13 @@ samples: config/config.mk cd samples && $(MAKE) $(MAKECMDGOALS) tests: - @if [ ! -d test ]; then \ - echo "*** directory test not available ***" ; \ - echo "*** see http://dev.exiv2.org/projects/exiv2/wiki/How_do_I_build_Exiv2_on_the_XYZ_platform for more information ***" ; \ - else \ - cd test && $(MAKE) test ; \ - fi + cd test && $(MAKE) test -teste: - @if [ ! -d test ]; then \ - echo "*** directory test not available ***" ; \ - echo "*** see http://dev.exiv2.org/projects/exiv2/wiki/How_do_I_build_Exiv2_on_the_XYZ_platform for more information ***" ; \ - else \ - cd test && $(MAKE) teste ; \ - fi +teste testx testv: + cd test && $(MAKE) $@ -testv: - @if [ ! -d test ]; then \ - echo "*** directory test not available ***" ; \ - echo "*** see http://dev.exiv2.org/projects/exiv2/wiki/How_do_I_build_Exiv2_on_the_XYZ_platform for more information ***" ; \ - else \ - cd test && $(MAKE) testv ; \ - fi - -testvw: - @if [ ! -d test ]; then \ - echo "*** directory test not available ***" ; \ - echo "*** see http://dev.exiv2.org/projects/exiv2/wiki/How_do_I_build_Exiv2_on_the_XYZ_platform for more information ***" ; \ - else \ - cd test && $(MAKE) testvw ; \ - fi +exiv2 conntest exifprint remotetest: + cd src && $(MAKE) $0 MAJOR=$(shell grep "define.*EXIV2_.*_VERSION .*\\d*" src/version.hpp | grep MAJOR | sed -e 's/EXIV2//g' | tr -dC [:digit:]) MINOR=$(shell grep "define.*EXIV2_.*_VERSION .*\\d*" src/version.hpp | grep MINOR | sed -e 's/EXIV2//g' | tr -dC [:digit:]) @@ -126,8 +103,11 @@ configure: config: cd config && $(MAKE) -f config.make $(MAKECMDGOALS) -xmpsdk: config/config.mk +xmpsdk: src/svn_version.h config/config.mk if test "x$(ENABLE_XMP)" = "x1"; then cd xmpsdk/src && $(MAKE) $@; fi; + +src/svn_version.h: + cd src && $(MAKE) svn_version.h mostlyclean clean: config/config.mk cd src && $(MAKE) $(MAKECMDGOALS) @@ -136,6 +116,8 @@ mostlyclean clean: config/config.mk cd xmpsdk/src && $(MAKE) $(MAKECMDGOALS) cd config && $(MAKE) -f config.make $(MAKECMDGOALS) cd po && $(MAKE) $(MAKECMDGOALS) + rm -rf test/tmp include/exiv2/exv_conf.h src/svn_version.h + mkdir test/tmp # `make distclean' also removes files created by configuring # the program. Running `make all distclean' prepares the project @@ -143,7 +125,7 @@ mostlyclean clean: config/config.mk distclean: clean rm -f config.log config.status libtool rm -f *~ *.bak - rm -rf bin + if [ -e bin ]; then rm -rf bin ; fi # This removes almost everything, including the configure script! maintainer-clean: distclean @@ -160,6 +142,6 @@ rebuild: make sudo make install make samples - + # That's all Folks! ## diff --git a/config/CMakeChecks.txt b/config/CMakeChecks.txt index 8e40a43f..4320ec29 100644 --- a/config/CMakeChecks.txt +++ b/config/CMakeChecks.txt @@ -55,6 +55,32 @@ IF( EXIV2_ENABLE_PNG ) SET (HAVE_LIBZ ${ZLIB_FOUND}) ENDIF( EXIV2_ENABLE_PNG ) +IF( EXIV2_ENABLE_CURL ) + FIND_PACKAGE( CURL ) + INCLUDE_DIRECTORIES( ${CURL_INCLUDE_DIR} ) + # FindCURL.cmake doesn't check for REQUIRED flags - so we need to check ourselves + IF( MINGW OR UNIX ) + IF (NOT CURL_FOUND) + MESSAGE(FATAL_ERROR "missing library curl required for HttpIo") + ELSE (NOT CURL_FOUND) + SET ( USE_CURL 1 ) + ENDIF( NOT CURL_FOUND ) + ENDIF( MINGW OR UNIX ) +ENDIF( EXIV2_ENABLE_CURL ) + +IF( EXIV2_ENABLE_SSH ) + FIND_PACKAGE( SSH ) + INCLUDE_DIRECTORIES( ${SSH_INCLUDE_DIR} ) + # FindSSH.cmake doesn't check for REQUIRED flags - so we need to check ourselves + IF( MINGW OR UNIX ) + IF (NOT SSH_FOUND) + MESSAGE(FATAL_ERROR "missing library libssh required for SshIo") + ELSE (NOT SSH_FOUND) + SET ( USE_SSH 1 ) + ENDIF( NOT SSH_FOUND ) + ENDIF( MINGW OR UNIX ) +ENDIF( EXIV2_ENABLE_SSH ) + IF (EXIV2_ENABLE_XMP) FIND_PACKAGE(EXPAT) INCLUDE_DIRECTORIES(${EXPAT_INCLUDE_DIR}) @@ -160,16 +186,12 @@ ENDIF( HAVE_SYS_TIME_H ) ##################################################################################### # strerror_r returns char* -# NOTE : adding #if _POSIX code for #697 +# NOTE : reverting commit #2041, which break compilation under linux and windows + CHECK_C_SOURCE_COMPILES( "#include int main() { char * c; -#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE - int l = strerror_r(0,c,0); - if ( l ) return 0 ; -#else c = strerror_r(0,c,0); -#endif return 0; }" STRERROR_R_CHAR_P ) @@ -230,6 +252,8 @@ SET( EXV_SYMBOLS ENABLE_NLS HAVE_WCHAR_H HAVE_XMP_TOOLKIT HAVE__BOOL + USE_CURL + USE_SSH PACKAGE PACKAGE_BUGREPORT PACKAGE_NAME @@ -245,10 +269,10 @@ FOREACH( entry ${EXV_SYMBOLS} ) # MESSAGE( EXV_${entry} " : " ${${entry}} ) ENDFOREACH( entry ${EXV_SYMBOLS} ) -CONFIGURE_FILE( config/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/exv_conf.h ) +CONFIGURE_FILE( config/config.h.cmake ${CMAKE_SOURCE_DIR}/include/exiv2/exv_conf.h ) CONFIGURE_FILE( config/exv_msvc.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/exv_msvc.h COPYONLY ) -INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/exv_conf.h DESTINATION include/exiv2 ) -INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/exv_msvc.h DESTINATION include/exiv2 ) +INSTALL( FILES ${CMAKE_SOURCE_DIR}/include/exiv2/exv_conf.h DESTINATION include/exiv2 ) +INSTALL( FILES ${CMAKE_SOURCE_DIR}/include/exiv2/exv_msvc.h DESTINATION include/exiv2 ) CONFIGURE_FILE(config/exiv2_uninstall.cmake ${CMAKE_BINARY_DIR}/cmake_uninstall.cmake COPYONLY) ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_BINARY_DIR}/cmake_uninstall.cmake") @@ -283,4 +307,6 @@ OptionOutput( "Nikon lens database: " EXIV2_ENABLE_LENSDATA OptionOutput( "Commercial build: " EXIV2_ENABLE_COMMERCIAL ) OptionOutput( "Build the unit tests: " EXIV2_ENABLE_BUILD_SAMPLES ) OptionOutput( "Building translations files: " EXIV2_ENABLE_BUILD_PO ) +OptionOutput( "USE Libcurl for HttpIo: " EXIV2_ENABLE_CURL ) +OptionOutput( "USE Libssh for SshIo: " EXIV2_ENABLE_SSH ) MESSAGE( STATUS "------------------------------------------------------------------" ) diff --git a/config/Doxyfile b/config/Doxyfile index 60995f63..eec701df 100644 --- a/config/Doxyfile +++ b/config/Doxyfile @@ -668,7 +668,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = ../src/ +INPUT = ../src/ ../include/exiv2/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/config/FindSSH.cmake b/config/FindSSH.cmake new file mode 100644 index 00000000..2a6fa378 --- /dev/null +++ b/config/FindSSH.cmake @@ -0,0 +1,31 @@ +# - Find libssh +# Find the native SSH headers and libraries. +# +# SSH_INCLUDE_DIRS - where to find libssh.h, etc. +# SSH_LIBRARIES - List of libraries when using libssh. +# SSH_FOUND - True if libssh found. +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +# Look for the header file. +FIND_PATH(SSH_INCLUDE_DIR NAMES libssh/libssh.h) + +# Look for the library. +FIND_LIBRARY(SSH_LIBRARY NAMES ssh libssh) + +# handle the QUIETLY and REQUIRED arguments and set SSH_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SSH DEFAULT_MSG SSH_LIBRARY SSH_INCLUDE_DIR) + +# Copy the results to the output variables. +IF(SSH_FOUND) + SET(SSH_LIBRARIES ${SSH_LIBRARY}) + SET(SSH_INCLUDE_DIRS ${SSH_INCLUDE_DIR}) +ELSE(SSH_FOUND) + SET(SSH_LIBRARIES) + SET(SSH_INCLUDE_DIRS) +ENDIF(SSH_FOUND) + +MARK_AS_ADVANCED(SSH_INCLUDE_DIR SSH_LIBRARY) diff --git a/config/Makefile.in b/config/Makefile.in index ec909467..20dfddd6 100644 --- a/config/Makefile.in +++ b/config/Makefile.in @@ -1,6 +1,6 @@ # ***************************************************** -*- Makefile -*- # -# Copyright (C) 2004-2013 Andreas Huggel +# Copyright (C) 2004-2012 Andreas Huggel # # This Makefile is part of the Exiv2 distribution. # @@ -71,36 +71,13 @@ samples: config/config.mk cd samples && $(MAKE) $(MAKECMDGOALS) tests: - @if [ ! -d test ]; then \ - echo "*** directory test not available ***" ; \ - echo "*** see http://dev.exiv2.org/projects/exiv2/wiki/How_do_I_build_Exiv2_on_the_XYZ_platform for more information ***" ; \ - else \ - cd test && $(MAKE) test ; \ - fi + cd test && $(MAKE) test -teste: - @if [ ! -d test ]; then \ - echo "*** directory test not available ***" ; \ - echo "*** see http://dev.exiv2.org/projects/exiv2/wiki/How_do_I_build_Exiv2_on_the_XYZ_platform for more information ***" ; \ - else \ - cd test && $(MAKE) teste ; \ - fi +teste testx testv: + cd test && $(MAKE) $@ -testv: - @if [ ! -d test ]; then \ - echo "*** directory test not available ***" ; \ - echo "*** see http://dev.exiv2.org/projects/exiv2/wiki/How_do_I_build_Exiv2_on_the_XYZ_platform for more information ***" ; \ - else \ - cd test && $(MAKE) testv ; \ - fi - -testvw: - @if [ ! -d test ]; then \ - echo "*** directory test not available ***" ; \ - echo "*** see http://dev.exiv2.org/projects/exiv2/wiki/How_do_I_build_Exiv2_on_the_XYZ_platform for more information ***" ; \ - else \ - cd test && $(MAKE) testvw ; \ - fi +exiv2 conntest exifprint remotetest: + cd src && $(MAKE) $0 MAJOR=$(shell grep "define.*EXIV2_.*_VERSION .*\\d*" src/version.hpp | grep MAJOR | sed -e 's/EXIV2//g' | tr -dC [:digit:]) MINOR=$(shell grep "define.*EXIV2_.*_VERSION .*\\d*" src/version.hpp | grep MINOR | sed -e 's/EXIV2//g' | tr -dC [:digit:]) @@ -126,8 +103,11 @@ configure: config: cd config && $(MAKE) -f config.make $(MAKECMDGOALS) -xmpsdk: config/config.mk +xmpsdk: src/svn_version.h config/config.mk if test "x$(ENABLE_XMP)" = "x1"; then cd xmpsdk/src && $(MAKE) $@; fi; + +src/svn_version.h: + cd src && $(MAKE) svn_version.h mostlyclean clean: config/config.mk cd src && $(MAKE) $(MAKECMDGOALS) @@ -136,6 +116,8 @@ mostlyclean clean: config/config.mk cd xmpsdk/src && $(MAKE) $(MAKECMDGOALS) cd config && $(MAKE) -f config.make $(MAKECMDGOALS) cd po && $(MAKE) $(MAKECMDGOALS) + rm -rf test/tmp include/exiv2/exv_conf.h src/svn_version.h + mkdir test/tmp # `make distclean' also removes files created by configuring # the program. Running `make all distclean' prepares the project @@ -143,7 +125,7 @@ mostlyclean clean: config/config.mk distclean: clean rm -f config.log config.status libtool rm -f *~ *.bak - rm -rf bin + if [ -e bin ]; then rm -rf bin ; fi # This removes almost everything, including the configure script! maintainer-clean: distclean @@ -160,6 +142,6 @@ rebuild: make sudo make install make samples - + # That's all Folks! ## diff --git a/config/config.h.cmake b/config/config.h.cmake index 41a1998b..af372897 100644 --- a/config/config.h.cmake +++ b/config/config.h.cmake @@ -1,6 +1,12 @@ /**/ /* config.h. Generated by cmake from config.h.cmake. */ +/* Define to 1 if you want to use `libssh' for SshIO. */ +#cmakedefine EXV_USE_SSH 1 + +/* Define to 1 if you want to use `libcurl' in httpIO. */ +#cmakedefine EXV_USE_CURL 1 + /* Define to 1 if you have the `alarm' function. */ #cmakedefine EXV_HAVE_ALARM @@ -191,15 +197,16 @@ typedef int pid_t; /* Define to `unsigned' if does not define. */ #cmakedefine size_t -#if defined __CYGWIN32__ && !defined __CYGWIN__ +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) /* For backwards compatibility with Cygwin b19 and earlier, we define __CYGWIN__ here, so that we can rely on checking just for that macro. */ #define __CYGWIN__ __CYGWIN32__ +#define EXV_HAVE_GXXCLASSVISIBILITY #endif /* File path seperator */ -#if defined WIN32 && !defined __CYGWIN__ +#if defined(WIN32) && !defined(__CYGWIN__) #define EXV_SEPERATOR_STR "\\" #define EXV_SEPERATOR_CHR '\\' #else @@ -208,7 +215,7 @@ typedef int pid_t; #endif /* Shared library support, see http://gcc.gnu.org/wiki/Visibility */ -#ifdef WIN32 +#if defined(WIN32) && !defined(__CYGWIN__) # define EXV_IMPORT __declspec(dllimport) # define EXV_EXPORT __declspec(dllexport) # define EXV_DLLLOCAL @@ -248,8 +255,8 @@ typedef int pid_t; #endif /* - If you're using Solaris and the Solaris Studio compiler, then you really - do need to use -library=stdcxx4 along with these inclusions below + If you're using Solaris and the Solaris Studio compiler + you must -library=stdcxx4 along with these inclusions below */ #if defined(OS_SOLARIS) #include @@ -261,5 +268,4 @@ typedef int pid_t; #include #include #endif -#endif - +#endif \ No newline at end of file diff --git a/config/config.h.in b/config/config.h.in index c20c2349..4524dfbf 100644 --- a/config/config.h.in +++ b/config/config.h.in @@ -1,5 +1,18 @@ +#ifndef __CONFIG__H__ +#define __CONFIG__H__ + +#ifdef _MSC_VER +# include "exv_msvc.h" +#else + /* config.h.in. Generated from configure.ac by autoheader. */ +/* Define to 1 if you want to use libssh */ +#undef USE_SSH + +/* Define to 1 if you want to use libcurl in httpIo */ +#undef USE_CURL + /* Define to 1 if you have the `alarm' function. */ #undef HAVE_ALARM @@ -263,3 +276,5 @@ #endif #endif +#endif +#endif \ No newline at end of file diff --git a/config/config.make b/config/config.make index 303f945d..c92eae25 100644 --- a/config/config.make +++ b/config/config.make @@ -1,6 +1,6 @@ # ***************************************************** -*- Makefile -*- # -# Copyright (C) 2004-2013 Andreas Huggel +# Copyright (C) 2004-2012 Andreas Huggel # # This Makefile is part of the Exiv2 distribution. # diff --git a/config/config.mk.in b/config/config.mk.in index 5a697833..2ee02c12 100644 --- a/config/config.mk.in +++ b/config/config.mk.in @@ -1,6 +1,6 @@ # ***************************************************** -*- Makefile -*- # -# Copyright (C) 2004-2013 Andreas Huggel +# Copyright (C) 2004-2012 Andreas Huggel # # This Makefile is part of the Exiv2 distribution. # @@ -58,16 +58,16 @@ GXX = @GXX@ # Common compiler flags (warnings, symbols [-ggdb], optimization [-O2], etc) CXXFLAGS = @CXXFLAGS@ ifeq ($(GXX),yes) - CXXFLAGS += -Wall -Wcast-align -Wpointer-arith -Wformat-security -Wmissing-format-attribute -Woverloaded-virtual -W + CXXFLAGS += -Wall -Wcast-align -Wpointer-arith -Wformat-security -Wmissing-format-attribute -Woverloaded-virtual -W endif # Command to run only the preprocessor CXXCPP = @CXXCPP@ # Preprocessor flags -CPPFLAGS = -I. @CPPFLAGS@ -DEXV_LOCALEDIR=\"$(localedir)\" +CPPFLAGS = -I../src -I../include/ -I../include/exiv2 @CPPFLAGS@ -DEXV_LOCALEDIR=\"$(localedir)\" ifeq ($(COMMERCIAL_VERSION),yes) - CPPFLAGS += -DEXV_COMMERCIAL_VERSION=1 + CPPFLAGS += -DEXV_COMMERCIAL_VERSION=1 endif # Linker flags and libraries @@ -84,7 +84,7 @@ GCC = @GCC@ CFLAGS = @CFLAGS@ ifeq ($(GCC),yes) - CFLAGS += -Wall + CFLAGS += -Wall endif # ********************************************************************** @@ -92,19 +92,29 @@ endif ENABLE_XMP = @ENABLE_XMP@ ifdef ENABLE_XMP - XMPSDK_LIBRARY = xmpsdk - XMPSDK_DIR = $(top_srcdir)/xmpsdk - XMPSDK_CPPFLAGS = -I$(XMPSDK_DIR)/include - XMPSDK_LDFLAGS = -L$(XMPSDK_DIR)/src - XMPSDK_LIBS = -l$(XMPSDK_LIBRARY) + XMPSDK_LIBRARY = xmpsdk + XMPSDK_DIR = $(top_srcdir)/xmpsdk + XMPSDK_CPPFLAGS = -I$(XMPSDK_DIR)/include + XMPSDK_LDFLAGS = -L$(XMPSDK_DIR)/src + XMPSDK_LIBS = -l$(XMPSDK_LIBRARY) else - # Enable additional warnings. XMP Toolkit doesn't compile - # with these. - ifeq ($(GXX),yes) - CXXFLAGS += -Wundef -pedantic - endif + # Enable additional warnings. XMP Toolkit doesn't compile + # with these. + ifeq ($(GXX),yes) + CXXFLAGS += -Wundef -pedantic + endif endif +# Libcurl need for httpIO if it's selected +CURL_CPPFLAGS = @CURL_CPPFLAGS@ +CURL_LDFLAGS = @CURL_LDFLAGS@ +CURL_LIBS = @CURL_LIBS@ + +# Libssh need for SshIO if it's selected +SSH_CPPFLAGS = @SSH_CPPFLAGS@ +SSH_LDFLAGS = @SSH_LDFLAGS@ +SSH_LIBS = @SSH_LIBS@ + # Expat library needed to compile the XMP Toolkit EXPAT_LDFLAGS = @EXPAT_LDFLAGS@ EXPAT_CPPFLAGS = @EXPAT_CPPFLAGS@ @@ -122,29 +132,29 @@ HAVE_TIMEGM = @HAVE_TIMEGM@ DEP_TRACKING = @DEP_TRACKING@ ifdef DEP_TRACKING - # Directory for dependency files - DEPDIR = .deps + # Directory for dependency files + DEPDIR = .deps - # Command to run the compiler or preprocessor to produce - # dependencies. If you're not using gcc, you may need to change - # this to something suitable for your compiler or simply unset - # the variable. See the link above for suggestions. - MAKEDEPEND = $(CXX) -MM $(CPPFLAGS) -o $*.d $< + # Command to run the compiler or preprocessor to produce + # dependencies. If you're not using gcc, you may need to change + # this to something suitable for your compiler or simply unset + # the variable. See the link above for suggestions. + MAKEDEPEND = $(CXX) -MM $(CPPFLAGS) -o $*.d $< - # Dependency files post-process commands - POSTDEPEND = if test ! -d $(DEPDIR); then mkdir $(DEPDIR); fi; \ - if test -e $*.d; then cp $*.d $(DEPDIR)/$*.d; \ - sed -e 's/^\#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + # Dependency files post-process commands + POSTDEPEND = if test ! -d $(DEPDIR); then mkdir $(DEPDIR); fi; \ + if test -e $*.d; then cp $*.d $(DEPDIR)/$*.d; \ + sed -e 's/^\#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ -e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $(DEPDIR)/$*.d; \ - $(RM) $*.d; fi + $(RM) $*.d; fi - # Compiler flags to generate dependency files at the same time - # as object files (for gcc) - ifeq ($(GXX),yes) - CXXFLAGS += -MMD - CFLAGS += -MMD - MAKEDEPEND = - endif + # Compiler flags to generate dependency files at the same time + # as object files (for gcc) + ifeq ($(GXX),yes) + CXXFLAGS += -MMD + CFLAGS += -MMD + MAKEDEPEND = + endif endif # ********************************************************************** @@ -153,7 +163,7 @@ COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) -c # LINK.cc does not need $(LIBS), libtool's dark magic takes care of that # when linking a binary with a libtool library. -LINK.cc = $(CXX) $(LDFLAGS) +LINK.cc = $(CXX) $(LDFLAGS) -ldl # ********************************************************************** # Installation programs diff --git a/config/configure.ac b/config/configure.ac index 2c40af99..8d253fde 100644 --- a/config/configure.ac +++ b/config/configure.ac @@ -151,6 +151,86 @@ AC_ARG_ENABLE(xmp, USE_XMP_TOOLKIT=$enableval, USE_XMP_TOOLKIT=yes) AC_MSG_RESULT($USE_XMP_TOOLKIT) +# libcurl option might change flags, so we save them initially +_cppflags="${CPPFLAGS}" +_ldflags="${LDFLAGS}" + +AC_ARG_WITH(curl, +[ --with-curl[[=DIR]] use libcurl in DIR],[ + if test "$withval" != "no" -a "$withval" != "yes"; then + CURL_DIR=$withval + CPPFLAGS="${CPPFLAGS} -I$withval/include" + LDFLAGS="${LDFLAGS} -L$withval/lib" + fi +]) + +USE_CURL= +if test "$with_curl" != "no"; then + # Check for libcurl library + found_curl=yes + CURL_CPPFLAGS= + CURL_LDFLAGS= + CURL_LIBS= + AC_CHECK_HEADERS(curl/curl.h, + AC_CHECK_LIB(curl, curl_easy_init,[ + USE_CURL=yes + AC_DEFINE([USE_CURL], [1], [Use libcurl library]) + CURL_LIBS="-lcurl" + if test "x${CURL_DIR}" != "x"; then + CURL_CPPFLAGS="-I${CURL_DIR}/include" + CURL_LDFLAGS="-L${CURL_DIR}/lib" + fi],[found_curl=no]),[found_curl=no]) + if test "$found_curl" = "no"; then + AC_MSG_ERROR(either specify a valid curl installation with --with-curl=DIR or disable libcurl support with --disable-curl) + fi + AC_SUBST(CURL_CPPFLAGS) + AC_SUBST(CURL_LDFLAGS) + AC_SUBST(CURL_LIBS) +fi +CPPFLAGS=${_cppflags} +LDFLAGS=${_ldflags} + + +# libssh option might change flags, so we save them initially +_cppflags="${CPPFLAGS}" +_ldflags="${LDFLAGS}" + +AC_ARG_WITH(ssh, +[ --with-ssh[[=DIR]] use libssh in DIR],[ + if test "$withval" != "no" -a "$withval" != "yes"; then + SSH_DIR=$withval + CPPFLAGS="${CPPFLAGS} -I$withval/include" + LDFLAGS="${LDFLAGS} -L$withval/lib" + fi +]) + +USE_SSH= +if test "$with_ssh" != "no"; then + # Check for libssh library + found_ssh=yes + SSH_CPPFLAGS= + SSH_LDFLAGS= + SSH_LIBS= + AC_CHECK_HEADERS(libssh/libssh.h, + AC_CHECK_LIB(ssh, ssh_new,[ + USE_SSH=yes + AC_DEFINE([USE_SSH], [1], [Use libssh library]) + SSH_LIBS="-lssh" + if test "x${SSH_DIR}" != "x"; then + SSH_CPPFLAGS="-I${SSH_DIR}/include" + SSH_LDFLAGS="-L${SSH_DIR}/lib" + fi],[found_ssh=no]),[found_ssh=no]) + if test "$found_ssh" = "no"; then + AC_MSG_ERROR(either specify a valid libssh installation with --with-ssh=DIR or disable libssh support with --disable-ssh) + fi + AC_SUBST(SSH_CPPFLAGS) + AC_SUBST(SSH_LDFLAGS) + AC_SUBST(SSH_LIBS) +fi +CPPFLAGS=${_cppflags} +LDFLAGS=${_ldflags} + + # expat option might change flags, so we save them initially _cppflags="${CPPFLAGS}" _ldflags="${LDFLAGS}" @@ -211,13 +291,10 @@ AC_SUBST(EXV_LIB_STATIC) # version.cpp requires link to psapi/Windows and dl/Unix builds case "$host_os" in *mingw* | *cygwin*) - EXV_LIBPSAPI="-lpsapi" LDFLAGS="$LDFLAGS -no-undefined -lpsapi" ;; *) - EXV_LIBPSAPI= LDFLAGS="$LDFLAGS -ldl" ;; esac -AC_SUBST(EXV_LIBPSAPI) # --------------------------------------------------------------------------- # Create output files. @@ -284,6 +361,28 @@ yes) echo "-- XMP metadata support........... YES" ;; echo "" ;; esac +case "$USE_CURL" in +yes) echo "-- Using Lib Curl................. YES" ;; +*) echo "-- Using Lib Curl................. NO" + echo "" + echo "Libcurl is required for HttpIo in basicIo.cpp. Make sure the Curl header" + echo "files are installed and use --with-curl=DIR if it is in a" + echo "non-standard location. You can get Curl from" + echo "http://curl.haxx.se/libcurl/" + echo "" ;; +esac + +case "$USE_SSH" in +yes) echo "-- Using Lib SSH.................. YES" ;; +*) echo "-- Using Lib SSH.................. NO" + echo "" + echo "Libssh is required for SshIo in basicIo.cpp. Make sure the libssh header" + echo "files are installed and use --with-ssh=DIR if it is in a" + echo "non-standard location. You can get libssh from" + echo "http://www.libssh.org/get-it/" + echo "" ;; +esac + echo "------------------------------------------------------------------" echo "" diff --git a/config/exiv2.pc.in b/config/exiv2.pc.in index a45ad216..e74b18b0 100644 --- a/config/exiv2.pc.in +++ b/config/exiv2.pc.in @@ -7,5 +7,5 @@ Name: exiv2 Description: Image metadata library and tools Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lexiv2 @EXV_LIB_STATIC@ -Libs.private: @EXPAT_LDFLAGS@ @LTLIBINTL@ @LTLIBICONV@ @LIBS@ @EXPAT_LIBS@ @EXV_LIBPSAPI@ +Libs.private: @EXPAT_LDFLAGS@ @SSH_LDFLAGS@ @CURL_LDFLAGS@ @LTLIBINTL@ @LTLIBICONV@ @LIBS@ @EXPAT_LIBS@ @SSH_LIBS@ @CURL_LIBS@ Cflags: -I${includedir} diff --git a/include/exiv2/Jzon.h b/include/exiv2/Jzon.h new file mode 100644 index 00000000..21eb8ca8 --- /dev/null +++ b/include/exiv2/Jzon.h @@ -0,0 +1,474 @@ +/* +Copyright (c) 2013 Johannes Häggqvist + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +#ifndef Jzon_h__ +#define Jzon_h__ + +#ifndef JzonAPI +# ifdef _WINDLL +# define JzonAPI __declspec(dllimport) +# elif defined(__GNUC__) && (__GNUC__ >= 4) +# define JzonAPI __attribute__ ((visibility("default"))) +# else +# define JzonAPI +# endif +#endif + +#include +#include +#include +#include +#include + +namespace Jzon +{ + #ifdef _MSC_VER + # pragma warning(disable : 4251) + #endif + + template + struct Pair + { + Pair(T1 first, T2 second) : first(first), second(second) + {} + + Pair &operator=(const Pair &rhs) + { + if (this != &rhs) + { + this->first = rhs.first; + this->second = rhs.second; + } + return *this; + } + + T1 first; + T2 second; + }; + template + static Pair MakePair(T1 first, T2 second) + { + return Pair(first, second); + } + + class Node; + class Value; + class Object; + class Array; + typedef Pair NamedNode; + typedef Pair NamedNodePtr; + + class TypeException : public std::logic_error + { + public: + TypeException() : std::logic_error("A Node was used as the wrong type") + {} + }; + class NotFoundException : public std::out_of_range + { + public: + NotFoundException() : std::out_of_range("The node could not be found") + {} + }; + + struct Format + { + bool newline; + bool spacing; + bool useTabs; + unsigned int indentSize; + }; + static const Format StandardFormat = { true, true, true, 1 }; + static const Format NoFormat = { false, false, false, 0 }; + + class JzonAPI Node + { + friend class Object; + friend class Array; + + public: + enum Type + { + T_OBJECT, + T_ARRAY, + T_VALUE + }; + + Node(); + virtual ~Node(); + + virtual Type GetType() const = 0; + + inline bool IsObject() const { return (GetType() == T_OBJECT); } + inline bool IsArray() const { return (GetType() == T_ARRAY); } + inline bool IsValue() const { return (GetType() == T_VALUE); } + + Object &AsObject(); + const Object &AsObject() const; + Array &AsArray(); + const Array &AsArray() const; + Value &AsValue(); + const Value &AsValue() const; + + virtual inline bool IsNull() const { return false; } + virtual inline bool IsString() const { return false; } + virtual inline bool IsNumber() const { return false; } + virtual inline bool IsBool() const { return false; } + + virtual std::string ToString() const { throw TypeException(); } + virtual int ToInt() const { throw TypeException(); } + virtual float ToFloat() const { throw TypeException(); } + virtual double ToDouble() const { throw TypeException(); } + virtual bool ToBool() const { throw TypeException(); } + + virtual bool Has(const std::string &/*name*/) const { throw TypeException(); } + virtual size_t GetCount() const { return 0; } + virtual Node &Get(const std::string &/*name*/) const { throw TypeException(); } + virtual Node &Get(size_t /*index*/) const { throw TypeException(); } + + static Type DetermineType(const std::string &json); + + protected: + virtual Node *GetCopy() const = 0; + }; + + class JzonAPI Value : public Node + { + public: + enum ValueType + { + VT_NULL, + VT_STRING, + VT_NUMBER, + VT_BOOL + }; + + Value(); + Value(const Value &rhs); + Value(const Node &rhs); + Value(ValueType type, const std::string &value); + Value(const std::string &value); + Value(const char *value); + Value(const int value); + Value(const float value); + Value(const double value); + Value(const bool value); + virtual ~Value(); + + virtual Type GetType() const; + ValueType GetValueType() const; + + virtual inline bool IsNull() const { return (type == VT_NULL); } + virtual inline bool IsString() const { return (type == VT_STRING); } + virtual inline bool IsNumber() const { return (type == VT_NUMBER); } + virtual inline bool IsBool() const { return (type == VT_BOOL); } + + virtual std::string ToString() const; + virtual int ToInt() const; + virtual float ToFloat() const; + virtual double ToDouble() const; + virtual bool ToBool() const; + + void SetNull(); + void Set(const Value &value); + void Set(ValueType type, const std::string &value); + void Set(const std::string &value); + void Set(const char *value); + void Set(const int value); + void Set(const float value); + void Set(const double value); + void Set(const bool value); + + Value &operator=(const Value &rhs); + Value &operator=(const Node &rhs); + Value &operator=(const std::string &rhs); + Value &operator=(const char *rhs); + Value &operator=(const int rhs); + Value &operator=(const float rhs); + Value &operator=(const double rhs); + Value &operator=(const bool rhs); + + bool operator==(const Value &other) const; + bool operator!=(const Value &other) const; + + static std::string EscapeString(const std::string &value); + static std::string UnescapeString(const std::string &value); + + protected: + virtual Node *GetCopy() const; + + private: + std::string valueStr; + ValueType type; + }; + + static const Value null; + + class JzonAPI Object : public Node + { + public: + class iterator : public std::iterator + { + public: + iterator(NamedNodePtr *o) : p(o) {} + iterator(const iterator &it) : p(it.p) {} + + iterator &operator++() { ++p; return *this; } + iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; } + + bool operator==(const iterator &rhs) { return p == rhs.p; } + bool operator!=(const iterator &rhs) { return p != rhs.p; } + + NamedNode operator*() { return NamedNode(p->first, *p->second); } + + private: + NamedNodePtr *p; + }; + class const_iterator : public std::iterator + { + public: + const_iterator(const NamedNodePtr *o) : p(o) {} + const_iterator(const const_iterator &it) : p(it.p) {} + + const_iterator &operator++() { ++p; return *this; } + const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; } + + bool operator==(const const_iterator &rhs) { return p == rhs.p; } + bool operator!=(const const_iterator &rhs) { return p != rhs.p; } + + const NamedNode operator*() { return NamedNode(p->first, *p->second); } + + private: + const NamedNodePtr *p; + }; + + Object(); + Object(const Object &other); + Object(const Node &other); + virtual ~Object(); + + virtual Type GetType() const; + + void Add(const std::string &name, Node &node); + void Add(const std::string &name, Value node); + void Remove(const std::string &name); + void Clear(); + + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + + virtual bool Has(const std::string &name) const; + virtual size_t GetCount() const; + virtual Node &Get(const std::string &name) const; + using Node::Get; + + protected: + virtual Node *GetCopy() const; + + private: + typedef std::vector ChildList; + ChildList children; + }; + + class JzonAPI Array : public Node + { + public: + class iterator : public std::iterator + { + public: + iterator(Node **o) : p(o) {} + iterator(const iterator &it) : p(it.p) {} + + iterator &operator++() { ++p; return *this; } + iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; } + + bool operator==(const iterator &rhs) { return p == rhs.p; } + bool operator!=(const iterator &rhs) { return p != rhs.p; } + + Node &operator*() { return **p; } + + private: + Node **p; + }; + class const_iterator : public std::iterator + { + public: + const_iterator(const Node *const *o) : p(o) {} + const_iterator(const const_iterator &it) : p(it.p) {} + + const_iterator &operator++() { ++p; return *this; } + const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; } + + bool operator==(const const_iterator &rhs) { return p == rhs.p; } + bool operator!=(const const_iterator &rhs) { return p != rhs.p; } + + const Node &operator*() { return **p; } + + private: + const Node *const *p; + }; + + Array(); + Array(const Array &other); + Array(const Node &other); + virtual ~Array(); + + virtual Type GetType() const; + + void Add(Node &node); + void Add(Value node); + void Remove(size_t index); + void Clear(); + + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + + virtual size_t GetCount() const; + virtual Node &Get(size_t index) const; + using Node::Get; + + protected: + virtual Node *GetCopy() const; + + private: + typedef std::vector ChildList; + ChildList children; + }; + + class JzonAPI FileWriter + { + public: + FileWriter(const std::string &filename); + ~FileWriter(); + + static void WriteFile(const std::string &filename, const Node &root, const Format &format = NoFormat); + + void Write(const Node &root, const Format &format = NoFormat); + + private: + std::string filename; + }; + + class JzonAPI FileReader + { + public: + FileReader(const std::string &filename); + ~FileReader(); + + static bool ReadFile(const std::string &filename, Node &node); + + bool Read(Node &node); + + Node::Type DetermineType(); + + const std::string &GetError() const; + + private: + bool loadFile(const std::string &filename, std::string &json); + std::string json; + std::string error; + }; + + class JzonAPI Writer + { + public: + Writer(const Node &root, const Format &format = NoFormat); + ~Writer(); + + void SetFormat(const Format &format); + const std::string &Write(); + + // Return result from last call to Write() + const std::string &GetResult() const; + + private: + void writeNode(const Node &node, unsigned int level); + void writeObject(const Object &node, unsigned int level); + void writeArray(const Array &node, unsigned int level); + void writeValue(const Value &node); + + std::string result; + + class FormatInterpreter *fi; + + const Node &root; + + // Disable assignment operator + Writer &operator=(const Writer&); + }; + + class JzonAPI Parser + { + public: + Parser(Node &root); + Parser(Node &root, const std::string &json); + ~Parser(); + + void SetJson(const std::string &json); + bool Parse(); + + const std::string &GetError() const; + + private: + enum Token + { + T_UNKNOWN, + T_OBJ_BEGIN, + T_OBJ_END, + T_ARRAY_BEGIN, + T_ARRAY_END, + T_SEPARATOR_NODE, + T_SEPARATOR_NAME, + T_VALUE + }; + + void tokenize(); + bool assemble(); + + char peek(); + void jumpToNext(char c); + void jumpToCommentEnd(); + + void readString(); + bool interpretValue(const std::string &value); + + std::string json; + std::size_t jsonSize; + + std::queue tokens; + std::queue > data; + + std::size_t cursor; + + Node &root; + + std::string error; + + // Disable assignment operator + Parser &operator=(const Parser&); + }; +} + +#endif // Jzon_h__ diff --git a/src/actions.hpp b/include/exiv2/actions.hpp similarity index 99% rename from src/actions.hpp rename to include/exiv2/actions.hpp index bf0c8547..d470d919 100644 --- a/src/actions.hpp +++ b/include/exiv2/actions.hpp @@ -22,7 +22,7 @@ @file actions.hpp @brief Implements base class Task, TaskFactory and the various supported actions (derived from Task). - @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 11-Dec-03, ahu: created diff --git a/src/asfvideo.hpp b/include/exiv2/asfvideo.hpp similarity index 100% rename from src/asfvideo.hpp rename to include/exiv2/asfvideo.hpp diff --git a/src/basicio.hpp b/include/exiv2/basicio.hpp similarity index 58% rename from src/basicio.hpp rename to include/exiv2/basicio.hpp index d22f0de1..cdff8555 100644 --- a/src/basicio.hpp +++ b/include/exiv2/basicio.hpp @@ -21,7 +21,7 @@ /*! @file basicio.hpp @brief Simple binary IO abstraction - @version $Rev$ + @version $Rev: 3091 $ @author Brad Schick (brad) brad@robotbattle.com @date 04-Dec-04, brad: created @@ -29,14 +29,23 @@ #ifndef BASICIO_HPP_ #define BASICIO_HPP_ +// The way to handle data from stdin or data uri path. If XPATH_MEMIO = 1, it uses MemIo. Otherwises, it uses FileIo. +#ifndef XPATH_MEMIO +#define XPATH_MEMIO 0 +#endif + // ***************************************************************************** // included header files #include "types.hpp" +#include "futils.hpp" // + standard includes #include -#include // for std::auto_ptr - +#include // for std::auto_ptr +#include // write the temporary file +#include // _O_BINARY in FileIo::FileIo +#include // timestamp for the name of temporary file +#include // std::memcpy // ***************************************************************************** // namespace extensions namespace Exiv2 { @@ -172,7 +181,7 @@ namespace Exiv2 { #if defined(_MSC_VER) virtual int seek(uint64_t offset, Position pos) = 0; #else - virtual int seek(long offset, Position pos) = 0; + virtual int seek(long offset, Position pos) = 0; #endif /*! @@ -241,6 +250,15 @@ namespace Exiv2 { @throw Error In case of failure */ virtual BasicIo::AutoPtr temporary() const = 0; + + /*! + @brief Mark all the bNone blocks to bKnow. This avoids allocating memory + for parts of the file that contain image-date (non-metadata/pixel data) + + @note This method should be only called after the concerned data (metadata) + are all downloaded from the remote file to memory. + */ + virtual void populateFakeData() {} //@} protected: @@ -264,7 +282,7 @@ namespace Exiv2 { //! Constructor, takes a BasicIo reference IoCloser(BasicIo& bio) : bio_(bio) {} //! Destructor, closes the BasicIo reference - ~IoCloser() { close(); } + virtual ~IoCloser() { close(); } //@} //! @name Manipulators @@ -434,7 +452,7 @@ namespace Exiv2 { #else virtual int seek(long offset, Position pos); #endif - /*! + /*! @brief Map the file into the process's address space. The file must be open before mmap() is called. If the mapped area is writeable, changes may not be written back to the underlying file until @@ -454,8 +472,19 @@ namespace Exiv2 { Nonzero if failure; */ virtual int munmap(); + /*! + @brief close the file source and set a new path. + */ + virtual void setPath(const std::string& path); +#ifdef EXV_UNICODE_PATH + /*! + @brief Like setPath(const std::string& path) but accepts a + unicode path in an std::wstring. + @note This method is only available on Windows. + */ + virtual void setPath(const std::wstring& wpath); +#endif //@} - //! @name Accessors //@{ /*! @@ -496,6 +525,15 @@ namespace Exiv2 { @throw Error If opening the temporary file fails */ virtual BasicIo::AutoPtr temporary() const; + + /*! + @brief Mark all the bNone blocks to bKnow. This avoids allocating memory + for parts of the file that contain image-date (non-metadata/pixel data) + + @note This method should be only called after the concerned data (metadata) + are all downloaded from the remote file to memory. + */ + virtual void populateFakeData(); //@} private: @@ -539,7 +577,7 @@ namespace Exiv2 { */ MemIo(const byte* data, long size); //! Destructor. Releases all managed memory - ~MemIo(); + virtual ~MemIo(); //@} //! @name Manipulators @@ -644,7 +682,7 @@ namespace Exiv2 { #if defined(_MSC_VER) virtual int seek(uint64_t offset, Position pos); #else - virtual int seek(long offset, Position pos); + virtual int seek(long offset, Position pos); #endif /*! @brief Allow direct access to the underlying data buffer. The buffer @@ -693,6 +731,16 @@ namespace Exiv2 { @return An instance of BasicIo */ virtual BasicIo::AutoPtr temporary() const; + + /*! + @brief Mark all the bNone blocks to bKnow. This avoids allocating memory + for parts of the file that contain image-date (non-metadata/pixel data) + + @note This method should be only called after the concerned data (metadata) + are all downloaded from the remote file to memory. + */ + virtual void populateFakeData(); + //@} private: @@ -708,6 +756,492 @@ namespace Exiv2 { }; // class MemIo + /*! + @brief Provides binary IO for the data from stdin and data uri path. + */ +#if XPATH_MEMIO + class EXIV2API XPathIo : public MemIo { + public: + //! @name Creators + //@{ + //! Default constructor + XPathIo(const std::string& path); +#ifdef EXV_UNICODE_PATH + /*! + @brief Like XPathIo(const std::string& path) but accepts a + unicode url in an std::wstring. + @note This constructor is only available on Windows. + */ + XPathIo(const std::wstring& wpath); +#endif + //@} + private: + /*! + @brief Read data from stdin and write the data to memory. + @throw Error if it can't convert stdin to binary. + */ + void ReadStdin(); + /*! + @brief Read the data from data uri path and write the data to memory. + @param path The data uri. + @throw Error if no base64 data in path. + */ + void ReadDataUri(const std::string& path); + }; // class XPathIo +#else + class EXIV2API XPathIo : public FileIo { + public: + /*! + @brief The extention of the temporary file which is created when getting input data + to read metadata. This file will be deleted in destructor. + */ + static const std::string TEMP_FILE_EXT; + /*! + @brief The extention of the generated file which is created when getting input data + to add or modify the metadata. + */ + static const std::string GEN_FILE_EXT; + + //! @name Creators + //@{ + //! Default constructor that reads data from stdin/data uri path and writes them to the temp file. + XPathIo(const std::string& orgPath); +#ifdef EXV_UNICODE_PATH + /*! + @brief Like XPathIo(const std::string& orgPath) but accepts a + unicode url in an std::wstring. + @note This constructor is only available on Windows. + */ + XPathIo(const std::wstring& wOrgPathpath); +#endif + //! Destructor. Releases all managed memory and removes the temp file. + virtual ~XPathIo(); + //@} + + //! @name Manipulators + //@{ + /*! + @brief Change the name of the temp file and make it untemporary before + calling the method of superclass FileIo::transfer. + */ + virtual void transfer(BasicIo& src); + + //@} + + //! @name Static methods + //@{ + /*! + @brief Read the data from stdin/data uri path and write them to the file. + @param orgPath It equals "-" if the input data's from stdin. Otherwise, it's data uri path. + @return the name of the new file. + @throw Error if it fails. + */ + static std::string writeDataToFile(const std::string& orgPath); +#ifdef EXV_UNICODE_PATH + /*! + @brief Like writeDataToFile(const std::string& orgPath) but accepts a + unicode url in an std::wstring. + @note This constructor is only available on Windows. + */ + static std::string writeDataToFile(const std::wstring& wOrgPath); +#endif + //@} + + private: + // True if the file is a temporary file and it should be deleted in destructor. + bool isTemp_; + std::string tempFilePath_; + }; // class XPathIo +#endif + + /*! + @brief Utility class provides the block mapping to the part of data. This avoids allocating + a single contiguous block of memory to the big data. + */ + class EXIV2API BlockMap { + public: + //! the status of the block. + enum blockType_e {bNone, bKnown, bMemory}; + //! @name Creators + //@{ + //! Default constructor. the init status of the block is bNone. + BlockMap():type_(bNone), data_(NULL) {} + //! Destructor. Releases all managed memory. + virtual ~BlockMap() { + if (data_) {std::free(data_); data_ = NULL;} + } + //@} + //! @name Manipulators + //@{ + /*! + @brief Populate the block. + @param source The data populate to the block + @param num The size of data + */ + void populate (byte* source, size_t num) { + size_ = num; + data_ = (byte*) std::malloc(size_); + type_ = bMemory; + std::memcpy(data_, source, size_); + } + /*! + @brief Change the status to bKnow. bKnow blocks do not contain the data, + but they keep the size of data. This avoids allocating memory for parts + of the file that contain image-date (non-metadata/pixel data) which never change in exiv2. + @param num The size of the data + */ + void markKnown(size_t num) { + type_ = bKnown; + size_ = num; + } + //@} + //! @name Accessors + //@{ + bool isNone() {return type_ == bNone;} + bool isInMem () {return type_ == bMemory;} + bool isKnown () {return type_ == bKnown;} + byte* getData () {return data_;} + size_t getSize () {return size_;} + //@} + private: + blockType_e type_; + byte* data_; + size_t size_; + }; // class BlockMap + + /*! + @brief Provides remote binary file IO by implementing the BasicIo interface. This is an + abstract class. The logics for remote access are implemented in HttpIo, CurlIo, SshIo which + are the derived classes of RemoteIo. + */ + class EXIV2API RemoteIo : public BasicIo { + public: + //! Destructor. Releases all managed memory. + virtual ~RemoteIo(); + //@} + + //! @name Manipulators + //@{ + /*! + @brief Connect to the remote server, get the size of the remote file and + allocate the array of blocksMap. + + If the blocksMap is already allocated (this method has been called before), + it just reset IO position to the start and does not flush the old data. + @return 0 if successful;
+ Nonzero if failure. + */ + virtual int open(); + /*! + @brief Reset the IO position to the start. It does not release the data. + @return 0 if successful;
+ Nonzero if failure. + */ + virtual int close(); + /*! + @brief Not support this method. + @return 0 means failure + */ + virtual long write(const byte* data, long wcount); + /*! + @brief Write data that is read from another BasicIo instance to the remote file. + + The write access is done in an efficient way. It only sends the range of different + bytes between the current data and BasicIo instance to the remote machine. + + @param src Reference to another BasicIo instance. Reading start + at the source's current IO position + @return The size of BasicIo instance;
+ 0 if failure; + @throw Error In case of failure + + @note The write access is only supported by http, https, ssh. + */ + virtual long write(BasicIo& src); + + /*! + @brief Not support + @return 0 means failure + */ + virtual int putb(byte data); + /*! + @brief Read data from the memory blocks. Reading starts at the current + IO position and the position is advanced by the number of + bytes read. + If the memory blocks are not populated (False), it will connect to server + and populate the data to memory blocks. + @param rcount Maximum number of bytes to read. Fewer bytes may be + read if \em rcount bytes are not available. + @return DataBuf instance containing the bytes read. Use the + DataBuf::size_ member to find the number of bytes read. + DataBuf::size_ will be 0 on failure. + */ + virtual DataBuf read(long rcount); + /*! + @brief Read data from the the memory blocks. Reading starts at the current + IO position and the position is advanced by the number of + bytes read. + If the memory blocks are not populated (!= bMemory), it will connect to server + and populate the data to memory blocks. + @param buf Pointer to a block of memory into which the read data + is stored. The memory block must be at least \em rcount bytes + long. + @param rcount Maximum number of bytes to read. Fewer bytes may be + read if \em rcount bytes are not available. + @return Number of bytes read from the memory block successfully;
+ 0 if failure; + */ + virtual long read(byte* buf, long rcount); + /*! + @brief Read one byte from the memory blocks. The IO position is + advanced by one byte. + If the memory block is not populated (!= bMemory), it will connect to server + and populate the data to the memory block. + @return The byte read from the memory block if successful;
+ EOF if failure; + */ + virtual int getb(); + /*! + @brief Remove the contents of the file and then transfer data from + the \em src BasicIo object into the empty file. + + The write access is done in an efficient way. It only sends the range of different + bytes between the current data and BasicIo instance to the remote machine. + + @param src Reference to another BasicIo instance. The entire contents + of src are transferred to this object. The \em src object is + invalidated by the method. + @throw Error In case of failure + + @note The write access is only supported by http, https, ssh. + */ + virtual void transfer(BasicIo& src); + /*! + @brief Move the current IO position. + @param offset Number of bytes to move the IO position + relative to the starting position specified by \em pos + @param pos Position from which the seek should start + @return 0 if successful;
+ Nonzero if failure; + */ +#if defined(_MSC_VER) + virtual int seek(uint64_t offset, Position pos); +#else + virtual int seek(long offset, Position pos); +#endif + /*! + @brief Not support + @return NULL + */ + virtual byte* mmap(bool /*isWriteable*/ =false); + /*! + @brief Not support + @return 0 + */ + virtual int munmap(); + //@} + //! @name Accessors + //@{ + /*! + @brief Get the current IO position. + @return Offset from the start of the memory block + */ + virtual long tell() const; + /*! + @brief Get the current memory buffer size in bytes. + @return Size of the in memory data in bytes;
+ -1 if failure; + */ + virtual long size() const; + //!Returns true if the memory area is allocated. + virtual bool isopen() const; + //!Always returns 0 + virtual int error() const; + //!Returns true if the IO position has reach the end, otherwise false. + virtual bool eof() const; + //!Returns the URL of the file. + virtual std::string path() const; +#ifdef EXV_UNICODE_PATH + /* + @brief Like path() but returns a unicode URL path in an std::wstring. + @note This function is only available on Windows. + */ + virtual std::wstring wpath() const; +#endif + /*! + @brief Returns a temporary data storage location. Currently returns + an empty MemIo object, but callers should not rely on this + behavior since it may change. + @return An instance of BasicIo + */ + virtual BasicIo::AutoPtr temporary() const; + + /*! + @brief Mark all the bNone blocks to bKnow. This avoids allocating memory + for parts of the file that contain image-date (non-metadata/pixel data) + + @note This method should be only called after the concerned data (metadata) + are all downloaded from the remote file to memory. + */ + virtual void populateFakeData(); + //@} + + protected: + //! @name Creators + //@{ + //! Default Constructor + RemoteIo() {p_=NULL;} + //@} + + // Pimpl idiom + class Impl; + Impl* p_; + }; // class RemoteIo + + /*! + @brief Provides the http read/write access for the RemoteIo. + */ + class EXIV2API HttpIo : public RemoteIo { + public: + //! @name Creators + //@{ + /*! + @brief Constructor that accepts the http URL on which IO will be + performed. The constructor does not open the file, and + therefore never failes. + @param url The full path of url + @param blockSize the size of the memory block. The file content is + divided into the memory blocks. These blocks are populated + on demand from the server, so it avoids copying the complete file. + */ + HttpIo(const std::string& url, size_t blockSize = 1024); +#ifdef EXV_UNICODE_PATH + /*! + @brief Like HttpIo(const std::string& url, size_t blockSize = 1024) but accepts a + unicode url in an std::wstring. + @note This constructor is only available on Windows. + */ + HttpIo(const std::wstring& wurl, size_t blockSize = 1024); +#endif + //@} + protected: + // NOT IMPLEMENTED + //! Copy constructor + HttpIo(HttpIo& rhs); + //! Assignment operator + HttpIo& operator=(const HttpIo& rhs); + // Pimpl idiom + class HttpImpl; + + //! @name Creators + //@{ + //! Default Destructor + virtual ~HttpIo(){} + //@} + }; + + +#if EXV_USE_CURL == 1 + /*! + @brief Provides the http, https read/write access and ftp read access for the RemoteIo. + This class is based on libcurl. + */ + class EXIV2API CurlIo : public RemoteIo { + public: + //! @name Creators + //@{ + /*! + @brief Constructor that accepts the URL on which IO will be + performed. + @param url The full path of url + @param blockSize the size of the memory block. The file content is + divided into the memory blocks. These blocks are populated + on demand from the server, so it avoids copying the complete file. + @throw Error if it is unable to init curl pointer. + */ + CurlIo(const std::string& url, size_t blockSize = 0); +#ifdef EXV_UNICODE_PATH + /*! + @brief Like CurlIo(const std::string& url, size_t blockSize = 0) but accepts a + unicode url in an std::wstring. + @note This constructor is only available on Windows. + */ + CurlIo(const std::wstring& wurl, size_t blockSize = 0); +#endif + /*! + @brief Write access is only available for some protocols. This method + will call RemoteIo::write(const byte* data, long wcount) if the write + access is available for the protocol. Otherwise, it throws the Error. + */ + long write(const byte* data, long wcount); + /*! + @brief Write access is only available for some protocols. This method + will call RemoteIo::write(BasicIo& src) if the write access is available + for the protocol. Otherwise, it throws the Error. + */ + long write(BasicIo& src); + protected: + // NOT IMPLEMENTED + //! Copy constructor + CurlIo(CurlIo& rhs); + //! Assignment operator + CurlIo& operator=(const CurlIo& rhs); + // Pimpl idiom + class CurlImpl; + + //! @name Creators + //@{ + //! Default Destructor + virtual ~CurlIo(){} + //@} + }; +#endif + +#if EXV_USE_SSH == 1 + /*! + @brief Provides the ssh read/write access and sftp read access for the RemoteIo. + This class is based on libssh. + */ + class EXIV2API SshIo : public RemoteIo { + public: + //! @name Creators + //@{ + /*! + @brief Constructor that accepts the URL on which IO will be + performed. + @param url The full path of url + @param blockSize the size of the memory block. The file content is + divided into the memory blocks. These blocks are populated + on demand from the server, so it avoids copying the complete file. + @throw Error if it is unable to init ssh session. + */ + SshIo(const std::string& url, size_t blockSize = 1024); +#ifdef EXV_UNICODE_PATH + /*! + @brief Like SshIo(const std::string& url, size_t blockSize = 1024) but accepts a + unicode url in an std::wstring. + @note This constructor is only available on Windows. + */ + SshIo(const std::wstring& wurl, size_t blockSize = 1024); +#endif + //@} + protected: + // NOT IMPLEMENTED + //! Copy constructor + SshIo(SshIo& rhs); + //! Assignment operator + SshIo& operator=(const SshIo& rhs); + // Pimpl idiom + class SshImpl; + + //! @name Creators + //@{ + //! Default Destructor + virtual ~SshIo(){} + //@} + }; +#endif + // ***************************************************************************** // template, inline and free functions @@ -736,8 +1270,27 @@ namespace Exiv2 { @note This function is only available on Windows. */ EXIV2API long writeFile(const DataBuf& buf, const std::wstring& wpath); - #endif - + /*! + @brief replace each substring of the subject that matches the given search string with the given replacement. + @return the subject after replacing. + */ + EXIV2API std::string ReplaceStringInPlace(std::string subject, const std::string& search, + const std::string& replace); +#ifdef EXV_UNICODE_PATH + /*! + @brief Like ReplaceStringInPlace() but accepts a unicode path in an std::wstring. + @return the subject after replacing. + @note This function is only available on Windows. + */ + EXIV2API std::wstring ReplaceStringInPlace(std::wstring subject, const std::wstring& search, + const std::wstring& replace); +#endif +#if EXV_USE_CURL == 1 + /*! + @brief The callback function is called by libcurl to write the data + */ + EXIV2API size_t curlWriter(char* data, size_t size, size_t nmemb, std::string* writerData); +#endif } // namespace Exiv2 #endif // #ifndef BASICIO_HPP_ diff --git a/src/bmpimage.hpp b/include/exiv2/bmpimage.hpp similarity index 99% rename from src/bmpimage.hpp rename to include/exiv2/bmpimage.hpp index b6ce3933..ddc96218 100644 --- a/src/bmpimage.hpp +++ b/include/exiv2/bmpimage.hpp @@ -21,7 +21,7 @@ /*! @file bmpimage.hpp @brief Windows Bitmap (BMP) image - @version $Rev$ + @version $Rev: 3091 $ @author Marco Piovanelli, Ovolab (marco) marco.piovanelli@pobox.com @date 05-Mar-2007, marco: created diff --git a/include/exiv2/config.h b/include/exiv2/config.h new file mode 100644 index 00000000..9089cafc --- /dev/null +++ b/include/exiv2/config.h @@ -0,0 +1,12 @@ +#ifdef _MSC_VER +# include "exv_msvc.h" +#else +# include "exv_conf.h" +#endif + +// Linux GCC 4.8 appears to be confused about strerror_r +#ifndef EXV_STRERROR_R_CHAR_P +#ifdef __gnu_linux__ +#define EXV_STRERROR_R_CHAR_P +#endif +#endif diff --git a/src/convert.hpp b/include/exiv2/convert.hpp similarity index 96% rename from src/convert.hpp rename to include/exiv2/convert.hpp index 7806a04f..23a9aa07 100644 --- a/src/convert.hpp +++ b/include/exiv2/convert.hpp @@ -21,7 +21,7 @@ /*! @file convert.hpp @brief Exif and IPTC conversions to and from XMP - @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net
Vladimir Nadvornik (vn) @@ -32,13 +32,8 @@ #ifndef CONVERT_HPP_ #define CONVERT_HPP_ -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" // + standard includes #include diff --git a/src/cr2image.hpp b/include/exiv2/cr2image.hpp similarity index 99% rename from src/cr2image.hpp rename to include/exiv2/cr2image.hpp index 6591042f..77ce1b09 100644 --- a/src/cr2image.hpp +++ b/include/exiv2/cr2image.hpp @@ -21,7 +21,7 @@ /*! @file cr2image.hpp @brief Class Cr2Image - @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 22-Apr-06, ahu: created diff --git a/src/crwimage.hpp b/include/exiv2/crwimage.hpp similarity index 99% rename from src/crwimage.hpp rename to include/exiv2/crwimage.hpp index 78ac781d..0bd71b5f 100644 --- a/src/crwimage.hpp +++ b/include/exiv2/crwimage.hpp @@ -23,7 +23,7 @@ @brief Class CrwImage to access Canon CRW images.
References:
The Canon RAW (CRW) File Format by Phil Harvey - @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 28-Aug-05, ahu: created diff --git a/src/datasets.hpp b/include/exiv2/datasets.hpp similarity index 99% rename from src/datasets.hpp rename to include/exiv2/datasets.hpp index cbc329a7..d4c307e3 100644 --- a/src/datasets.hpp +++ b/include/exiv2/datasets.hpp @@ -21,7 +21,7 @@ /*! @file datasets.hpp @brief IPTC dataset and type information - @version $Rev$ + @version $Rev: 3091 $ @author Brad Schick (brad) @date 24-Jul-04, brad: created */ diff --git a/src/easyaccess.hpp b/include/exiv2/easyaccess.hpp similarity index 99% rename from src/easyaccess.hpp rename to include/exiv2/easyaccess.hpp index 1711368e..5391dbb6 100644 --- a/src/easyaccess.hpp +++ b/include/exiv2/easyaccess.hpp @@ -21,7 +21,7 @@ /*! @file easyaccess.hpp @brief Provides easy (high-level) access to some Exif meta data. - @version $Rev$ + @version $Rev: 3091 $ @author Carsten Pfeiffer @date 28-Feb-09, gis: created */ diff --git a/src/epsimage.hpp b/include/exiv2/epsimage.hpp similarity index 100% rename from src/epsimage.hpp rename to include/exiv2/epsimage.hpp diff --git a/src/error.hpp b/include/exiv2/error.hpp similarity index 99% rename from src/error.hpp rename to include/exiv2/error.hpp index b8df55d2..51613ba6 100644 --- a/src/error.hpp +++ b/include/exiv2/error.hpp @@ -21,7 +21,7 @@ /*! @file error.hpp @brief Error class for exceptions, log message class - @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 15-Jan-04, ahu: created
diff --git a/src/exif.hpp b/include/exiv2/exif.hpp similarity index 99% rename from src/exif.hpp rename to include/exiv2/exif.hpp index afc55f31..f22830b9 100644 --- a/src/exif.hpp +++ b/include/exiv2/exif.hpp @@ -21,7 +21,7 @@ /*! @file exif.hpp @brief Encoding and decoding of Exif data - @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 09-Jan-04, ahu: created diff --git a/src/exiv2.hpp b/include/exiv2/exiv2.hpp similarity index 97% rename from src/exiv2.hpp rename to include/exiv2/exiv2.hpp index c41cb762..f1bc88f6 100644 --- a/src/exiv2.hpp +++ b/include/exiv2/exiv2.hpp @@ -21,7 +21,7 @@ /*! @file exiv2.hpp @brief Include all Exiv2 header files. - @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 21-Jun-10, ahu: created @@ -45,6 +45,7 @@ #include "gifimage.hpp" #include "image.hpp" #include "iptc.hpp" +#include "http.hpp" #include "jp2image.hpp" #include "jpgimage.hpp" #include "metadatum.hpp" diff --git a/src/exiv2app.hpp b/include/exiv2/exiv2app.hpp similarity index 99% rename from src/exiv2app.hpp rename to include/exiv2/exiv2app.hpp index 7339d268..62a88fc6 100644 --- a/src/exiv2app.hpp +++ b/include/exiv2/exiv2app.hpp @@ -21,7 +21,7 @@ /*! @file exiv2app.hpp @brief Defines class Params, used for the command line handling of exiv2 - @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 08-Dec-03, ahu: created diff --git a/include/exiv2/exv_msvc-webready.h b/include/exiv2/exv_msvc-webready.h new file mode 100644 index 00000000..ef2f0c35 --- /dev/null +++ b/include/exiv2/exv_msvc-webready.h @@ -0,0 +1,162 @@ +/* ***************************************************************** -*- C -*- */ +/*! + @file exv_msvc.h + @brief Configuration settings for MSVC + @version $Rev: 2320 $ + @author Andreas Huggel (ahu) + ahuggel@gmx.net + @date 07-Feb-04, ahu: created + 26-Feb-05, ahu: renamed and moved to src directory + */ + +#ifdef _MSC_VER +#ifndef _EXV_MSVC_H_ +#define _EXV_MSVC_H_ + +#if _MSC_VER >= 1600 +// stdint.h was introduced with DevStudio 2010 +#define EXV_HAVE_STDINT_H 1 +#endif +#if _MSC_VER >= 1700 +#define MSDEV_2012 1 +#elif _MSC_VER >= 1600 +#define MSDEV_2010 1 +#elif _MSC_VER >= 1500 +#define MSDEV_2008 1 +#elif _MSC_VER >= 1400 +#define MSDEV_2005 1 +#else +#define MSDEV_2003 1 +#endif + +#if MSDEV_2012 +#define HAVE_NTOHLL 1 +#endif + +/* Define to 1 if you have the header file. */ +#define EXV_HAVE_PROCESS_H 1 + +/* Define to the address where bug reports for this package should be sent. */ +#define EXV_PACKAGE_BUGREPORT "ahuggel@gmx.net" + +/* Define to the full name of this package. */ +#define EXV_PACKAGE_NAME "exiv2" + +/* Define to the full name and version of this package. */ +#define EXV_PACKAGE_STRING "exiv2 0.24" + +/* Define to the one symbol short name of this package. */ +#define EXV_PACKAGE_TARNAME "exiv2" + +/* Define to the version of this package. */ +#define EXV_PACKAGE_VERSION "0.24" + +/* Define to `int' if does not define pid_t. */ +typedef int pid_t; + +#ifndef EXV_COMMERCIAL_VERSION + +/* Define to 1 to enable translation of Nikon lens names. */ +# define EXV_HAVE_LENSDATA 1 + +/* Define to 1 if translation of program messages to the user's + native language is requested. */ +# undef EXV_ENABLE_NLS + +#endif /* !EXV_COMMERCIAL_VERSION */ + +/* Define to 1 if you have the `iconv' function. */ +# undef EXV_HAVE_ICONV + +#ifdef EXV_HAVE_ICONV +#define EXV_ICONV_CONST const +#endif + +/* Define as 1 if you have the `zlib' library. (0 to omit zlib) [png support] */ +#define HAVE_LIBZ 1 + +#if HAVE_LIBZ + #define EXV_HAVE_LIBZ + // assist VC7.1 to compile vsnprintf + #if (_MSC_VER < 1400) && !defined(vsnprintf) + #define vsnprintf _vsnprintf + #endif +#endif + +/* Define to 1 if you have the Adobe XMP Toolkit. */ +#define EXV_HAVE_XMP_TOOLKIT 1 + +/* Define as 1 if you want to use curl to perform http I/O */ +#ifndef EXV_USE_CURL +#define EXV_USE_CURL 1 +#endif + +/* Define as 1 if you want to use libssh (for ssh:// and sftp:// support */ +#ifndef EXV_USE_SSH +#define EXV_USE_SSH 1 +#endif + +/* Help out our buddy curl */ +#ifndef EXV_HAVE_DLL +#define CURL_STATICLIB +#endif + +#pragma comment(lib, "ws2_32.lib") +#pragma comment(lib, "wldap32.lib") + +/* File path seperator */ +#define EXV_SEPERATOR_STR "\\" +#define EXV_SEPERATOR_CHR '\\' + +/* Windows unicode path support */ +// #define EXV_UNICODE_PATH + +/* Define to 1 if you have the `mmap' function. */ +/* #undef EXV_HAVE_MMAP */ + +/* Define to 1 if you have the `munmap' function. */ +/* #undef EXV_HAVE_MUNMAP */ + +/* Shared library support */ +#ifdef EXV_HAVE_DLL +#define EXV_IMPORT __declspec(dllimport) +#define EXV_EXPORT __declspec(dllexport) +#define EXV_DLLLOCAL +#define EXV_DLLPUBLIC +#else +#define EXV_IMPORT +#define EXV_EXPORT +#define EXV_DLLLOCAL +#define EXV_DLLPUBLIC +#define EXIV2API +#endif + +/* Define EXIV2API for DLL builds */ +#ifdef EXV_HAVE_DLL +# ifdef EXV_BUILDING_LIB +# define EXIV2API EXV_EXPORT +# else +# define EXIV2API EXV_IMPORT +# endif /* ! EXV_BUILDING_LIB */ +#else +# define EXIV2API +#endif /* ! EXV_HAVE_DLL */ + + +/* + Disable warning 4251. This is warning from std templates about exporting interfaces +*/ +#ifdef EXV_HAVE_DLL +#pragma warning( disable : 4251 ) +#endif +/* + Visual Studio C++ 2005 (8.0) + Disable warnings about 'deprecated' standard functions + See, eg. http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=259 +*/ +#if _MSC_VER >= 1400 +# pragma warning(disable : 4996) +#endif + +#endif /* _EXV_MSVC_H_ */ +#endif /* _MSC_VER */ diff --git a/include/exiv2/exv_msvc.h b/include/exiv2/exv_msvc.h new file mode 100644 index 00000000..1f1312fb --- /dev/null +++ b/include/exiv2/exv_msvc.h @@ -0,0 +1,162 @@ +/* ***************************************************************** -*- C -*- */ +/*! + @file exv_msvc.h + @brief Configuration settings for MSVC + @version $Rev: 2320 $ + @author Andreas Huggel (ahu) + ahuggel@gmx.net + @date 07-Feb-04, ahu: created + 26-Feb-05, ahu: renamed and moved to src directory + */ + +#ifdef _MSC_VER +#ifndef _EXV_MSVC_H_ +#define _EXV_MSVC_H_ + +#if _MSC_VER >= 1600 +// stdint.h was introduced with DevStudio 2010 +#define EXV_HAVE_STDINT_H 1 +#endif +#if _MSC_VER >= 1700 +#define MSDEV_2012 1 +#elif _MSC_VER >= 1600 +#define MSDEV_2010 1 +#elif _MSC_VER >= 1500 +#define MSDEV_2008 1 +#elif _MSC_VER >= 1400 +#define MSDEV_2005 1 +#else +#define MSDEV_2003 1 +#endif + +#if MSDEV_2012 +#define HAVE_NTOHLL 1 +#endif + +/* Define to 1 if you have the header file. */ +#define EXV_HAVE_PROCESS_H 1 + +/* Define to the address where bug reports for this package should be sent. */ +#define EXV_PACKAGE_BUGREPORT "ahuggel@gmx.net" + +/* Define to the full name of this package. */ +#define EXV_PACKAGE_NAME "exiv2" + +/* Define to the full name and version of this package. */ +#define EXV_PACKAGE_STRING "exiv2 0.24" + +/* Define to the one symbol short name of this package. */ +#define EXV_PACKAGE_TARNAME "exiv2" + +/* Define to the version of this package. */ +#define EXV_PACKAGE_VERSION "0.24" + +/* Define to `int' if does not define pid_t. */ +typedef int pid_t; + +#ifndef EXV_COMMERCIAL_VERSION + +/* Define to 1 to enable translation of Nikon lens names. */ +# define EXV_HAVE_LENSDATA 1 + +/* Define to 1 if translation of program messages to the user's + native language is requested. */ +# undef EXV_ENABLE_NLS + +#endif /* !EXV_COMMERCIAL_VERSION */ + +/* Define to 1 if you have the `iconv' function. */ +# undef EXV_HAVE_ICONV + +#ifdef EXV_HAVE_ICONV +#define EXV_ICONV_CONST const +#endif + +/* Define as 1 if you have the `zlib' library. (0 to omit zlib) [png support] */ +#define HAVE_LIBZ 1 + +#if HAVE_LIBZ + #define EXV_HAVE_LIBZ + // assist VC7.1 to compile vsnprintf + #if (_MSC_VER < 1400) && !defined(vsnprintf) + #define vsnprintf _vsnprintf + #endif +#endif + +/* Define to 1 if you have the Adobe XMP Toolkit. */ +#define EXV_HAVE_XMP_TOOLKIT 1 + +/* Define as 1 if you want to use curl to perform http I/O */ +#ifndef EXV_USE_CURL +#define EXV_USE_CURL 0 +#endif + +/* Define as 1 if you want to use libssh (for ssh:// and sftp:// support */ +#ifndef EXV_USE_SSH +#define EXV_USE_SSH 0 +#endif + +/* Help out our buddy curl */ +#ifndef EXV_HAVE_DLL +#define CURL_STATICLIB +#endif + +#pragma comment(lib, "ws2_32.lib") +#pragma comment(lib, "wldap32.lib") + +/* File path seperator */ +#define EXV_SEPERATOR_STR "\\" +#define EXV_SEPERATOR_CHR '\\' + +/* Windows unicode path support */ +// #define EXV_UNICODE_PATH + +/* Define to 1 if you have the `mmap' function. */ +/* #undef EXV_HAVE_MMAP */ + +/* Define to 1 if you have the `munmap' function. */ +/* #undef EXV_HAVE_MUNMAP */ + +/* Shared library support */ +#ifdef EXV_HAVE_DLL +#define EXV_IMPORT __declspec(dllimport) +#define EXV_EXPORT __declspec(dllexport) +#define EXV_DLLLOCAL +#define EXV_DLLPUBLIC +#else +#define EXV_IMPORT +#define EXV_EXPORT +#define EXV_DLLLOCAL +#define EXV_DLLPUBLIC +#define EXIV2API +#endif + +/* Define EXIV2API for DLL builds */ +#ifdef EXV_HAVE_DLL +# ifdef EXV_BUILDING_LIB +# define EXIV2API EXV_EXPORT +# else +# define EXIV2API EXV_IMPORT +# endif /* ! EXV_BUILDING_LIB */ +#else +# define EXIV2API +#endif /* ! EXV_HAVE_DLL */ + + +/* + Disable warning 4251. This is warning from std templates about exporting interfaces +*/ +#ifdef EXV_HAVE_DLL +#pragma warning( disable : 4251 ) +#endif +/* + Visual Studio C++ 2005 (8.0) + Disable warnings about 'deprecated' standard functions + See, eg. http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=259 +*/ +#if _MSC_VER >= 1400 +# pragma warning(disable : 4996) +#endif + +#endif /* _EXV_MSVC_H_ */ +#endif /* _MSC_VER */ diff --git a/include/exiv2/futils.hpp b/include/exiv2/futils.hpp new file mode 100644 index 00000000..d31687b4 --- /dev/null +++ b/include/exiv2/futils.hpp @@ -0,0 +1,214 @@ +// ********************************************************* -*- C++ -*- +/* + * Copyright (C) 2004-2013 Andreas Huggel + * + * This program is part of the Exiv2 distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. + */ +/*! + @file futils.hpp + @brief Basic file utility functions required by Exiv2 + @version $Rev: 3091 $ + @author Andreas Huggel (ahu) + ahuggel@gmx.net + @date 12-Dec-03, ahu: created
+ 02-Apr-05, ahu: moved to Exiv2 namespace + */ +#ifndef FUTILS_HPP_ +#define FUTILS_HPP_ + +// ********************************************************************* +// included header files +#include "config.h" + +#define UNUSED(x) (void)(x) + +#ifdef EXV_HAVE_STDINT_H +# include // for uint8_t +#endif + +// + standard includes +#include +#include +#include +#include // for UINT_MAX + +// ********************************************************************* +// namespace extensions +namespace Exiv2 { + //! the name of environmental variables. + enum EnVar { envHTTPPOST = 0, envTIMEOUT = 1}; + //! the collection of protocols. + enum Protocol { pFile = 0, pHttp, pFtp, pHttps, pSftp, pSsh, pFileUri, pDataUri, pStdin}; + //! the dictionary type for the protcol identifer strings. + typedef std::map protDict_t; + //! the dictionary iterator for protcol identifer strings. + typedef std::map::iterator protDict_i; +#ifdef EXV_UNICODE_PATH + //! the dictionary type for the protcol identifer strings. + typedef std::map wprotDict_t; + //! the dictionary iterator for protcol identifer strings. + typedef std::map::iterator wprotDict_i; +#endif +// ********************************************************************* +// free functions + /*! + @brief Return the value of environmental variable. + @param var The name of environmental variable. + @return the value of environmental variable. If it's empty, the default value is returned. + */ + EXIV2API std::string getEnv(EnVar var); + /*! + @brief Convert an integer value to its hex character. + @param code The integer value. + @return the input's hex character. + */ + EXIV2API char to_hex(char code); + /*! + @brief Convert a hex character to its integer value. + @param ch The hex character. + @return the input's integer value. + */ + EXIV2API char from_hex(char ch); + /*! + @brief Encode the input url. + @param str The url needs encoding. + @return the url-encoded version of str. + + @note Be sure to free() the returned string after use + Source: http://www.geekhideout.com/urlcode.shtml + */ + EXIV2API char* urlencode(char* str); + /*! + @brief Decode the input url. + @param str The url needs decoding. + @return the url-decoded version of str. + + @note Be sure to free() the returned string after use + Source: http://www.geekhideout.com/urlcode.shtml + */ + EXIV2API char* urldecode(const char* str); + /*! + @brief Like urlencode(char* str) but accept the input url in the std::string and modify it. + */ + EXIV2API void urldecode(std::string& str); + /*! + @brief Encode in base64 the data in data_buf and put the resulting string in result. + @param data_buf The data need to encode + @param dataLength Size in bytes of the in buffer + @param result The container for the result, NULL if it fails + @param resultSize Size in bytes of the out string, it should be at least ((dataLength + 2) / 3) * 4 + 1 + @return 1 indicate success + + @note Source: http://en.wikibooks.org/wiki/Algorithm_Implementation/Miscellaneous/Base64 + */ + EXIV2API int base64encode(const void* data_buf, size_t dataLength, char* result, size_t resultSize); + /*! + @brief Decode base64 data and put the resulting string in out. + @param in The data need to decode. + @param out The container for the result, it should be large enough to contain the result. + @param out_size The size of out in bytes. + @return the size of the resulting string. If it fails, return -1. + + @note Source: https://github.com/davidgaleano/libwebsockets/blob/master/lib/base64-decode.c + */ + EXIV2API long base64decode(const char *in, char *out, size_t out_size); + /*! + @brief Return the protocol of the path. + @param path The path of file to extract the protocol. + @return the protocol of the path. + */ + EXIV2API Protocol fileProtocol(const std::string& path); +#ifdef EXV_UNICODE_PATH + /*! + @brief Like fileProtocol() but accept a unicode path in an std::wstring. + @note This function is only available on Windows. + */ + EXIV2API Protocol fileProtocol(const std::wstring& wpath); +#endif + /*! + @brief Test if a file exists. + + @param path Name of file to verify. + @param ct Flag to check if path is a regular file. + @return true if path exists and, if ct is set, + is a regular file, else false. + + @note The function calls stat() test for path + and its type, see stat(2). errno is left unchanged + in case of an error. + */ + EXIV2API bool fileExists(const std::string& path, bool ct =false); +#ifdef EXV_UNICODE_PATH + /*! + @brief Like fileExists(const std::string& path, bool ct =false) but + accepts a unicode path in an std::wstring. + @note This function is only available on Windows. + */ + EXIV2API bool fileExists(const std::wstring& wpath, bool ct =false); +#endif + /*! + @brief Get the path of file URL. + + @param url The file URL in the format file:/// or file:///. + @return the path of file URL. + */ + EXIV2API std::string pathOfFileUrl(const std::string& url); +#ifdef EXV_UNICODE_PATH + /*! + @brief Like pathOfFileUrl(const std::string& url) but accepts a unicode path in an std::wstring. + @note This function is only available on Windows. + */ + EXIV2API std::wstring pathOfFileUrl(const std::wstring& wurl); +#endif + /*! + @brief Return a system error message and the error code (errno). + See %strerror(3). + */ + EXIV2API std::string strError(); + + /*! + @brief A container for URL components. It also provides the method to parse a + URL to get the protocol, host, path, port, querystring, username, password. + + Source: http://stackoverflow.com/questions/2616011/easy-way-to-parse-a-url-in-c-cross-platform + */ + class Uri + { + public: + // DATA + std::string QueryString; //!< URL query string + std::string Path; //!< URL file path + std::string Protocol; //!< URL protocol + std::string Host; //!< URL host + std::string Port; //!< URL port + std::string Username; //!< URL username + std::string Password; //!< URL password + + /*! + @brief Parse the input URL to the protocol, host, path, username, password + */ + static Uri EXIV2API Parse(const std::string &uri); + + /*! + @brief Decode the url components. + */ + static void EXIV2API Decode(Uri& uri); + }; // class Uri + +} // namespace Exiv2 + +#endif // #ifndef FUTILS_HPP_ diff --git a/include/exiv2/getopt_win32.h b/include/exiv2/getopt_win32.h new file mode 100644 index 00000000..6b6f643b --- /dev/null +++ b/include/exiv2/getopt_win32.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 1987, 1993, 1994, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __GETOPT_H__ +#define __GETOPT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int opterr; /* if error message should be printed */ +extern int optind; /* index into parent argv vector */ +extern int optopt; /* character checked for validity */ +extern int optreset; /* reset getopt */ +extern char *optarg; /* argument associated with option */ + +int getopt (int, char * const *, const char *); + +#ifdef __cplusplus +} +#endif + +#endif /* __GETOPT_H__ */ + +#ifndef __UNISTD_GETOPT__ +#ifndef __GETOPT_LONG_H__ +#define __GETOPT_LONG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct option { + const char *name; + int has_arg; + int *flag; + int val; +}; + +int getopt_long (int, char *const *, const char *, const struct option *, int *); +#ifndef HAVE_DECL_GETOPT +#define HAVE_DECL_GETOPT 1 +#endif + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#ifdef __cplusplus +} +#endif + +#endif /* __GETOPT_LONG_H__ */ +#endif /* __UNISTD_GETOPT__ */ diff --git a/src/gifimage.hpp b/include/exiv2/gifimage.hpp similarity index 99% rename from src/gifimage.hpp rename to include/exiv2/gifimage.hpp index dbb5f4e5..186748ee 100644 --- a/src/gifimage.hpp +++ b/include/exiv2/gifimage.hpp @@ -22,7 +22,7 @@ @file gifimage.hpp @brief GIF image, implemented using the following references: GIF89 specification by W3C
- @version $Rev$ + @version $Rev: 3091 $ @author Marco Piovanelli, Ovolab (marco) marco.piovanelli@pobox.com @date 26-Feb-2007, marco: created diff --git a/include/exiv2/http.hpp b/include/exiv2/http.hpp new file mode 100644 index 00000000..84cf51aa --- /dev/null +++ b/include/exiv2/http.hpp @@ -0,0 +1,19 @@ +#ifndef HTTP_H_ +#define HTTP_H_ + +#include +#include +#include + +#include + +namespace Exiv2 { + typedef std::map dict_t; + typedef dict_t::iterator dict_i; + + EXIV2API int http(dict_t& request,dict_t& response,std::string& errors); + +} +#endif + + diff --git a/include/exiv2/i18n.h b/include/exiv2/i18n.h new file mode 100644 index 00000000..714c0663 --- /dev/null +++ b/include/exiv2/i18n.h @@ -0,0 +1,50 @@ +/* **************************************************************** -*- C -*- */ +/* + * Copyright (C) 2004-2012 Andreas Huggel + * + * This program is part of the Exiv2 distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. + */ +/* + File: i18n.h + Brief: i18n definitions. Do not use. This is an Exiv2 internal header. + Version: $Rev: 2681 $ + Author(s): Gilles Caulier (gc) + History: 01-Nov-06, gc: created + */ +#ifndef I18N_H_ +#define I18N_H_ + +#include "config.h" + +/* NLS can be disabled through the configure --disable-nls option. */ +#ifdef EXV_ENABLE_NLS +# include + +// Definition is in types.cpp +EXIV2API const char* _exvGettext(const char* str); + +# define _(String) _exvGettext(String) +# define N_(String) String + +#else /* NLS is disabled */ + +# define _(String) (String) +# define N_(String) String + +#endif /* EXV_ENABLE_NLS */ + +#endif /* I18N_H_ */ diff --git a/src/image.hpp b/include/exiv2/image.hpp similarity index 93% rename from src/image.hpp rename to include/exiv2/image.hpp index 5f11cd73..c824b6e1 100644 --- a/src/image.hpp +++ b/include/exiv2/image.hpp @@ -21,7 +21,7 @@ /*! @file image.hpp @brief Class Image, defining the interface for all Image subclasses. - @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @author Brad Schick (brad) @@ -102,6 +102,12 @@ namespace Exiv2 { //! @name Manipulators //@{ + /*! + @brief Print out the structure of image file. + @throw Error if reading of the file fails or the image data is + not valid (does not look like data of the specific image type). + */ + virtual void printStructure(); /*! @brief Read all metadata supported by a specific image format from the image. Before this method is called, the image metadata will be @@ -444,24 +450,48 @@ namespace Exiv2 { class EXIV2API ImageFactory { friend bool Image::good() const; public: + /*! + @brief Create the appropriate class type implemented BasicIo based on the protocol of the input. + + "-" path implies the data from stdin and it is handled by StdinIo. + Http path can be handled by either HttpIo or CurlIo. Https, ftp paths + are handled by CurlIo. Ssh, sftp paths are handled by SshIo. Others are handled by FileIo. + + @param path %Image file. + @param useCurl Indicate whether the libcurl is used or not. + If it's true, http is handled by CurlIo. Otherwise it is handled by HttpIo. + @return An auto-pointer that owns an BasicIo instance. + @throw Error If the file is not found or it is unable to connect to the server to + read the remote file. + */ + static BasicIo::AutoPtr createIo(const std::string& path, bool useCurl = true); +#ifdef EXV_UNICODE_PATH + /*! + @brief Like createIo() but accepts a unicode path in an std::wstring. + @note This function is only available on Windows. + */ + static BasicIo::AutoPtr createIo(const std::wstring& wpath, bool useCurl = true); +#endif /*! @brief Create an Image subclass of the appropriate type by reading the specified file. %Image type is derived from the file contents. @param path %Image file. The contents of the file are tested to determine the image type. File extension is ignored. + @param useCurl Indicate whether the libcurl is used or not. + If it's true, http is handled by CurlIo. Otherwise it is handled by HttpIo. @return An auto-pointer that owns an Image instance whose type matches that of the file. @throw Error If opening the file fails or it contains data of an unknown image type. */ - static Image::AutoPtr open(const std::string& path); + static Image::AutoPtr open(const std::string& path, bool useCurl = true); #ifdef EXV_UNICODE_PATH /*! @brief Like open() but accepts a unicode path in an std::wstring. @note This function is only available on Windows. */ - static Image::AutoPtr open(const std::wstring& wpath); + static Image::AutoPtr open(const std::wstring& wpath, bool useCurl = true); #endif /*! @brief Create an Image subclass of the appropriate type by reading diff --git a/src/iptc.hpp b/include/exiv2/iptc.hpp similarity index 99% rename from src/iptc.hpp rename to include/exiv2/iptc.hpp index 131728aa..d5f004f5 100644 --- a/src/iptc.hpp +++ b/include/exiv2/iptc.hpp @@ -21,7 +21,7 @@ /*! @file iptc.hpp @brief Encoding and decoding of IPTC data - @version $Rev$ + @version $Rev: 3091 $ @author Brad Schick (brad) brad@robotbattle.com @date 31-Jul-04, brad: created diff --git a/src/jp2image.hpp b/include/exiv2/jp2image.hpp similarity index 99% rename from src/jp2image.hpp rename to include/exiv2/jp2image.hpp index 7f458c92..13ce4fec 100644 --- a/src/jp2image.hpp +++ b/include/exiv2/jp2image.hpp @@ -22,7 +22,7 @@ @file jp2image.hpp @brief JPEG-2000 image, implemented using the following references: ISO/IEC JTC 1/SC 29/WG1 N2401: JPEG 2000 Part 6 FCD 15444-6
- @version $Rev$ + @version $Rev: 3091 $ @author Gilles Caulier (cgilles) caulier dot gilles at gmail dot com @author Marco Piovanelli, Ovolab (marco) diff --git a/src/jpgimage.hpp b/include/exiv2/jpgimage.hpp similarity index 98% rename from src/jpgimage.hpp rename to include/exiv2/jpgimage.hpp index 2e233e9f..5be3c384 100644 --- a/src/jpgimage.hpp +++ b/include/exiv2/jpgimage.hpp @@ -21,7 +21,7 @@ /*! @file jpgimage.hpp @brief Class JpegImage to access JPEG images - @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @author Brad Schick (brad) @@ -150,6 +150,7 @@ namespace Exiv2 { public: //! @name Manipulators //@{ + void printStructure(); void readMetadata(); void writeMetadata(); //@} @@ -218,6 +219,9 @@ namespace Exiv2 { //@} // Constant Data + static const byte dht_; //!< JPEG DHT marker + static const byte dqt_; //!< JPEG DQT marker + static const byte dri_; //!< JPEG DRI marker static const byte sos_; //!< JPEG SOS marker static const byte eoi_; //!< JPEG EOI marker static const byte app0_; //!< JPEG APP0 marker diff --git a/src/matroskavideo.hpp b/include/exiv2/matroskavideo.hpp similarity index 100% rename from src/matroskavideo.hpp rename to include/exiv2/matroskavideo.hpp diff --git a/src/metadatum.hpp b/include/exiv2/metadatum.hpp similarity index 99% rename from src/metadatum.hpp rename to include/exiv2/metadatum.hpp index 255456a0..e8dd04f9 100644 --- a/src/metadatum.hpp +++ b/include/exiv2/metadatum.hpp @@ -21,7 +21,7 @@ /*! @file metadatum.hpp @brief Provides abstract base classes Metadatum and Key - @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @author Brad Schick (brad) diff --git a/src/mrwimage.hpp b/include/exiv2/mrwimage.hpp similarity index 99% rename from src/mrwimage.hpp rename to include/exiv2/mrwimage.hpp index eee7599b..88c737b3 100644 --- a/src/mrwimage.hpp +++ b/include/exiv2/mrwimage.hpp @@ -22,7 +22,7 @@ @file mrwimage.hpp @brief Minolta RAW image, implemented using the following references: Minolta Raw file format by Dalibor Jelinek - @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 13-May-06, ahu: created diff --git a/src/orfimage.hpp b/include/exiv2/orfimage.hpp similarity index 99% rename from src/orfimage.hpp rename to include/exiv2/orfimage.hpp index 0415c434..b388d460 100644 --- a/src/orfimage.hpp +++ b/include/exiv2/orfimage.hpp @@ -21,7 +21,7 @@ /*! @file orfimage.hpp @brief Olympus RAW image - @version $Rev$ + @version $Rev: 3091 $ @author Jeff Costlow costlow@gmail.com @date 31-Jul-07, costlow: created diff --git a/src/pgfimage.hpp b/include/exiv2/pgfimage.hpp similarity index 99% rename from src/pgfimage.hpp rename to include/exiv2/pgfimage.hpp index 10e7335e..10b8e9dd 100644 --- a/src/pgfimage.hpp +++ b/include/exiv2/pgfimage.hpp @@ -22,7 +22,7 @@ @file pgfimage.hpp @brief PGF image, implemented using the following references: PGF specification from libpgf web site
- @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @author Gilles Caulier (cgilles) diff --git a/src/pngimage.hpp b/include/exiv2/pngimage.hpp similarity index 98% rename from src/pngimage.hpp rename to include/exiv2/pngimage.hpp index 5100e39e..6bfd037a 100644 --- a/src/pngimage.hpp +++ b/include/exiv2/pngimage.hpp @@ -23,7 +23,7 @@ @brief PNG image, implemented using the following references: PNG specification by W3C
PNG tags list by Phil Harvey
- @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @author Gilles Caulier (cgilles) @@ -84,6 +84,7 @@ namespace Exiv2 //! @name Manipulators //@{ + void printStructure(); void readMetadata(); void writeMetadata(); //@} diff --git a/src/preview.hpp b/include/exiv2/preview.hpp similarity index 99% rename from src/preview.hpp rename to include/exiv2/preview.hpp index 25140001..931dffbf 100644 --- a/src/preview.hpp +++ b/include/exiv2/preview.hpp @@ -21,7 +21,7 @@ /*! @file preview.hpp @brief Classes to access all preview images embedded in an image. - @version $Rev$ + @version $Rev: 3091 $ @author Vladimir Nadvornik (vn) nadvornik@suse.cz @date 18-Sep-08, vn: created diff --git a/include/exiv2/private.h b/include/exiv2/private.h new file mode 100644 index 00000000..11078a0e --- /dev/null +++ b/include/exiv2/private.h @@ -0,0 +1,210 @@ +/*! + @file private.h + @brief This file is from the tz distribution at ftp://elsie.nci.nih.gov/pub/ + @version $Rev: 1358 $ +*/ +#ifndef PRIVATE_H + +#define PRIVATE_H + +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +*/ + +/* +** This header is for use ONLY with the time conversion code. +** There is no guarantee that it will remain unchanged, +** or that it will remain at all. +** Do NOT copy it to any system include directory. +** Thank you! +*/ + +/* +** ID +*/ + +#ifndef lint +#ifndef NOID +static char privatehid[] = "@(#)private.h 7.53"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/* ahu: moved required preprocessor symbols to config.h */ + +/* ahu: disable warnings */ +#ifdef _MSC_VER +// disable warning 'uses old-style declarator' C4131 +#pragma warning (disable: 4131) +#endif + +/* +** Nested includes +*/ + +#include "sys/types.h" /* for time_t */ +#include "stdio.h" +#include "errno.h" +#include "string.h" +#include "limits.h" /* for CHAR_BIT */ +#include "time.h" +#include "stdlib.h" + +/* ahu: added io.h for MSVC */ +#ifdef _MSC_VER +# include "io.h" +#endif + +/* ahu: deleted include libintl.h */ + +/* ahu: deleted include sys/wait.h and WIFEXITED, WEXITSTATUS macros */ + +#if EXV_HAVE_UNISTD_H - 0 +#include "unistd.h" /* for F_OK and R_OK */ +#endif /* EXV_HAVE_UNISTD_H - 0 */ + +#if !(EXV_HAVE_UNISTD_H - 0) +#ifndef F_OK +#define F_OK 0 +#endif /* !defined F_OK */ +#ifndef R_OK +#define R_OK 4 +#endif /* !defined R_OK */ +#endif /* !(EXV_HAVE_UNISTD_H - 0) */ + +/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ +#define is_digit(c) ((unsigned)(c) - '0' <= 9) + +/* +** Workarounds for compilers/systems. +*/ + +/* +** SunOS 4.1.1 cc lacks prototypes. +*/ + +#ifndef P +#ifdef __STDC__ +#define P(x) x +#endif /* defined __STDC__ */ +#ifndef __STDC__ +#define P(x) () +#endif /* !defined __STDC__ */ +#endif /* !defined P */ + +/* +** SunOS 4.1.1 headers lack EXIT_SUCCESS. +*/ + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif /* !defined EXIT_SUCCESS */ + +/* +** SunOS 4.1.1 headers lack EXIT_FAILURE. +*/ + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif /* !defined EXIT_FAILURE */ + +/* +** SunOS 4.1.1 headers lack FILENAME_MAX. +*/ + +#ifndef FILENAME_MAX + +#ifndef MAXPATHLEN +#ifdef unix +#include "sys/param.h" +#endif /* defined unix */ +#endif /* !defined MAXPATHLEN */ + +#ifdef MAXPATHLEN +#define FILENAME_MAX MAXPATHLEN +#endif /* defined MAXPATHLEN */ +#ifndef MAXPATHLEN +#define FILENAME_MAX 1024 /* Pure guesswork */ +#endif /* !defined MAXPATHLEN */ + +#endif /* !defined FILENAME_MAX */ + +/* ahu: deleted unlink declaration and remove define */ + +/* ahu: deleted errno declaration */ + +/* ahu: deleted private function declarations */ + +/* +** Finally, some convenience items. +*/ + +#ifndef TRUE +#define TRUE 1 +#endif /* !defined TRUE */ + +#ifndef FALSE +#define FALSE 0 +#endif /* !defined FALSE */ + +#ifndef TYPE_BIT +#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT) +#endif /* !defined TYPE_BIT */ + +#ifndef TYPE_SIGNED +#define TYPE_SIGNED(type) (((type) -1) < 0) +#endif /* !defined TYPE_SIGNED */ + +#ifndef INT_STRLEN_MAXIMUM +/* +** 302 / 1000 is log10(2.0) rounded up. +** Subtract one for the sign bit if the type is signed; +** add one for integer division truncation; +** add one more for a minus sign if the type is signed. +*/ +#define INT_STRLEN_MAXIMUM(type) \ + ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type)) +#endif /* !defined INT_STRLEN_MAXIMUM */ + +/* +** INITIALIZE(x) +*/ + +#ifndef GNUC_or_lint +#ifdef lint +#define GNUC_or_lint +#endif /* defined lint */ +#ifndef lint +#ifdef __GNUC__ +#define GNUC_or_lint +#endif /* defined __GNUC__ */ +#endif /* !defined lint */ +#endif /* !defined GNUC_or_lint */ + +#ifndef INITIALIZE +#ifdef GNUC_or_lint +#define INITIALIZE(x) ((x) = 0) +#endif /* defined GNUC_or_lint */ +#ifndef GNUC_or_lint +#define INITIALIZE(x) +#endif /* !defined GNUC_or_lint */ +#endif /* !defined INITIALIZE */ + +/* ahu: deleted definition of _(msgid) macro */ + +#ifndef TZ_DOMAIN +#define TZ_DOMAIN "tz" +#endif /* !defined TZ_DOMAIN */ + +#if HAVE_INCOMPATIBLE_CTIME_R +#undef asctime_r +#undef ctime_r +char *asctime_r P((struct tm const *, char *)); +char *ctime_r P((time_t const *, char *)); +#endif /* HAVE_INCOMPATIBLE_CTIME_R */ + +/* +** UNIX was a registered trademark of The Open Group in 2003. +*/ + +#endif /* !defined PRIVATE_H */ diff --git a/src/properties.hpp b/include/exiv2/properties.hpp similarity index 99% rename from src/properties.hpp rename to include/exiv2/properties.hpp index b56a65dc..dbe549a0 100644 --- a/src/properties.hpp +++ b/include/exiv2/properties.hpp @@ -23,7 +23,7 @@ @brief XMP property and type information.
References:
XMP Specification from Adobe (Property descriptions copied from the XMP specification with the permission of Adobe) - @version $Rev$ + @version $Rev: 3091 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @author Gilles Caulier (cgilles) diff --git a/src/psdimage.hpp b/include/exiv2/psdimage.hpp similarity index 99% rename from src/psdimage.hpp rename to include/exiv2/psdimage.hpp index b592af65..c611fa73 100644 --- a/src/psdimage.hpp +++ b/include/exiv2/psdimage.hpp @@ -22,7 +22,7 @@ @file psdimage.hpp @brief Photoshop image, implemented using the following references: Adobe Photoshop 6.0 File Format Specification by Adobe
- @version $Rev$ + @version $Rev: 3091 $ @author Marco Piovanelli, Ovolab (marco) marco.piovanelli@pobox.com @author Michael Ulbrich diff --git a/src/quicktimevideo.hpp b/include/exiv2/quicktimevideo.hpp similarity index 100% rename from src/quicktimevideo.hpp rename to include/exiv2/quicktimevideo.hpp diff --git a/src/rafimage.hpp b/include/exiv2/rafimage.hpp similarity index 99% rename from src/rafimage.hpp rename to include/exiv2/rafimage.hpp index da100c28..16f290c3 100644 --- a/src/rafimage.hpp +++ b/include/exiv2/rafimage.hpp @@ -21,7 +21,7 @@ /*! @file rafimage.hpp @brief Fujifilm RAW image - @version $Rev$ + @version $Rev: 3090 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 05-Feb-07, ahu: created diff --git a/src/riffvideo.hpp b/include/exiv2/riffvideo.hpp similarity index 100% rename from src/riffvideo.hpp rename to include/exiv2/riffvideo.hpp diff --git a/src/rw2image.hpp b/include/exiv2/rw2image.hpp similarity index 99% rename from src/rw2image.hpp rename to include/exiv2/rw2image.hpp index 790c98c5..a3b012d5 100644 --- a/src/rw2image.hpp +++ b/include/exiv2/rw2image.hpp @@ -21,7 +21,7 @@ /*! @file rw2image.hpp @brief Class Rw2Image - @version $Rev$ + @version $Rev: 3090 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 06-Jan-09, ahu: created diff --git a/include/exiv2/ssh.hpp b/include/exiv2/ssh.hpp new file mode 100644 index 00000000..1adf1cf4 --- /dev/null +++ b/include/exiv2/ssh.hpp @@ -0,0 +1,109 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (C) 2004-2013 Andreas Huggel + * + * This program is part of the Exiv2 distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. + */ +#ifndef SSH_HPP_ +#define SSH_HPP_ + +// included header files +#include "config.h" + +#if EXV_USE_SSH == 1 +#include +#include +#include +#include +#include "error.hpp" +#include "types.hpp" +#include "futils.hpp" + +namespace Exiv2 { + /*! + @brief The class provides the high-level functions related to libssh. + It makes the libssh transparent. The functions in this class can + be used without the requirement of understanding libssh. + */ + class EXIV2API SSH { + public: + //! @name Creators + //@{ + /*! + @brief Constructor to set up the connection to ssh server. + @param host The host name of ssh server. + @param user The username used to connect to ssh server. + @param pass The password used to connect to ssh server. + @param port The port to connect to ssh server. Set empty string to use the default port. + @throw Error if it fails to connect the server. + */ + SSH (const std::string& host, const std::string& user, const std::string& pass, const std::string port = ""); + //! Destructor + ~SSH(); + //@} + + //! @name Manipulators + //@{ + /*! + @brief Run the command on the remote machine. + @param cmd The command + @param output The container for the command's output + @return 0 (SSH_OK) if there is no error. + */ + int runCommand(const std::string& cmd, std::string* output); + /*! + @brief SCP data to the remote machine. + @param filePath The path of the new file on the remote machine where the data is saved. + @param data The data copied to the remote machine. + @param size The size of the data. + @return 0 (SSH_OK) if there is no error. + @throw Error if it is unable to copy the data. + */ + int scp(const std::string& filePath, const byte* data, size_t size); + /*! + @brief Return the sftp file handle of the file on the remote machine to read the data. + @param filePath The path of the file on the remote machine. + @param handle The container for the file handle. + @throw Error if it is unable to get the sftp file handle. + + @note Be sure to close() the file handle after use. + */ + void getFileSftp(const std::string& filePath, sftp_file& handle); + //@} + private: + /*! + @brief Open the sftp session. + */ + void openSftp(); + // DATA + //! The number of seconds to wait while trying to connect. + long timeout_; + //! the ssh server host + std::string host_; + //! the username + std::string user_; + //! the password + std::string pass_; + //! the ssh session + ssh_session session_; + //! the sftp session + sftp_session sftp_; + }; // class SSH +} // namespace Exiv2 +#endif + +#endif // #ifdef EXIV2_HPP_ diff --git a/include/exiv2/svn_version.h b/include/exiv2/svn_version.h new file mode 100644 index 00000000..359f6e8a --- /dev/null +++ b/include/exiv2/svn_version.h @@ -0,0 +1,3 @@ +#ifndef SVN_VERSION +#define SVN_VERSION 0 +#endif diff --git a/src/tags.hpp b/include/exiv2/tags.hpp similarity index 99% rename from src/tags.hpp rename to include/exiv2/tags.hpp index 61c9989e..46a58725 100644 --- a/src/tags.hpp +++ b/include/exiv2/tags.hpp @@ -21,7 +21,7 @@ /*! @file tags.hpp @brief Exif tag and type information - @version $Rev$ + @version $Rev: 3090 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 15-Jan-04, ahu: created
diff --git a/src/tgaimage.hpp b/include/exiv2/tgaimage.hpp similarity index 99% rename from src/tgaimage.hpp rename to include/exiv2/tgaimage.hpp index 4b1b4faf..c96e6065 100644 --- a/src/tgaimage.hpp +++ b/include/exiv2/tgaimage.hpp @@ -23,7 +23,7 @@ @brief Truevision TARGA v2 image, implemented using the following references: Truevision TGA page on Wikipedia
TGA(tm) File Format Specification - @version $Rev$ + @version $Rev: 3090 $ @author Marco Piovanelli, Ovolab (marco) marco.piovanelli@pobox.com @date 05-Mar-2007, marco: created diff --git a/src/tiffimage.hpp b/include/exiv2/tiffimage.hpp similarity index 99% rename from src/tiffimage.hpp rename to include/exiv2/tiffimage.hpp index fce0cea3..85339dde 100644 --- a/src/tiffimage.hpp +++ b/include/exiv2/tiffimage.hpp @@ -21,7 +21,7 @@ /*! @file tiffimage.hpp @brief Class TiffImage - @version $Rev$ + @version $Rev: 3090 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 15-Mar-06, ahu: created diff --git a/include/exiv2/timegm.h b/include/exiv2/timegm.h new file mode 100644 index 00000000..f36f1868 --- /dev/null +++ b/include/exiv2/timegm.h @@ -0,0 +1,94 @@ +/*! + @file timegm.h + @brief Declaration of timegm(). The implementation is in localtime.c + @version $Rev: 1800 $ +*/ +#ifndef TIMEGM_H_ +#define TIMEGM_H_ + +#include + +/* + The following comments are copied from the Makefile of the tz distribution, + available at ftp://elsie.nci.nih.gov/pub/: + + NIST-PCTS:151-2, Version 1.4, (1993-12-03) is a test suite put + out by the National Institute of Standards and Technology + which claims to test C and Posix conformance. If you want to pass PCTS, add + -DPCTS + to the end of the "CFLAGS=" line. + + If your system has a "zone abbreviation" field in its "struct tm"s + (or if you decide to add such a field in your system's "time.h" file), + add the name to a define such as + -DTM_ZONE=tm_zone + or + -DTM_ZONE=_tm_zone + to the end of the "CFLAGS=" line. + + If you want functions that were inspired by early versions of X3J11's work, + add + -DSTD_INSPIRED + to the end of the "CFLAGS=" line. + + If you want to allocate state structures in localtime, add + -DALL_STATE + to the end of the "CFLAGS=" line. Storage is obtained by calling malloc. + + If you want Source Code Control System ID's left out of object modules, add + -DNOID + + Add the following to the end of the "CFLAGS=" line as needed. + -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified + DST transitions if the time zone files cannot be accessed + + If you want to use System V compatibility code, add + -DUSG_COMPAT + to the end of the "CFLAGS=" line. This arrange for "timezone" and "daylight" + variables to be kept up-to-date by the time conversion functions. Neither + "timezone" nor "daylight" is described in X3J11's work. + + If you want an "altzone" variable (a la System V Release 3.1), add + -DALTZONE + to the end of the "CFLAGS=" line. + This variable is not described in X3J11's work. + + If your system has a "GMT offset" field in its "struct tm"s + (or if you decide to add such a field in your system's "time.h" file), + add the name to a define such as + -DTM_GMTOFF=tm_gmtoff + or + -DTM_GMTOFF=_tm_gmtoff + to the end of the "CFLAGS=" line. + Neither tm_gmtoff nor _tm_gmtoff is described in X3J11's work; + in its work, use of "tm_gmtoff" is described as non-conforming. + Both Linux and BSD have done the equivalent of defining TM_GMTOFF in + their recent releases. + + If you want a "gtime" function (a la MACH), add + -DCMUCS + to the end of the "CFLAGS=" line + This function is not described in X3J11's work. +*/ + +#define STD_INSPIRED +#define NOID + +#ifdef __cplusplus +extern "C" { +#endif + +// The UTC version of mktime +/* rmills - timegm is replaced with _mkgmtime on VC 2005 and up */ +/* - see localtime.c */ +#if !defined(_MSC_VER) || (_MSC_VER < 1400) +time_t timegm(struct tm * const tmp); +#else +#define timegm _mkgmtime +#endif + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef TIMEGM_H_ diff --git a/src/types.hpp b/include/exiv2/types.hpp similarity index 97% rename from src/types.hpp rename to include/exiv2/types.hpp index 8bf258b3..45d22a16 100644 --- a/src/types.hpp +++ b/include/exiv2/types.hpp @@ -21,7 +21,7 @@ /*! @file types.hpp @brief Type definitions for %Exiv2 and related functionality - @version $Rev$ + @version $Rev: 3090 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 09-Jan-04, ahu: created
@@ -31,19 +31,8 @@ #ifndef TYPES_HPP_ #define TYPES_HPP_ -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif - -#if defined(__MINGW32__) || defined(__MINGW64__) -# ifndef __MINGW__ -# define __MINGW__ -# endif -#endif +#include "config.h" #include "version.hpp" @@ -74,13 +63,6 @@ typedef __int64 int64_t; # define EXV_WIDEN(t) L ## t #endif -#if defined(__MINGW__) || defined(_MSC_VER) -typedef unsigned char u_int8_t; -typedef unsigned short u_int16_t; -typedef unsigned int u_int32_t; -typedef unsigned long long u_int64_t; -#endif - /*! @brief Macro to make calls to member functions through a pointer more readable. See the C++ FAQ LITE, item @@ -114,7 +96,7 @@ namespace Exiv2 { typedef std::pair Rational; //! Type to express the byte order (little or big endian) - enum ByteOrder { invalidByteOrder, littleEndian, bigEndian }; + enum ByteOrder { invalidByteOrder, littleEndian, bigEndian,asciiBytes }; //! Type to indicate write method used by TIFF parsers enum WriteMethod { wmIntrusive, wmNonIntrusive }; diff --git a/include/exiv2/tzfile.h b/include/exiv2/tzfile.h new file mode 100644 index 00000000..d9c22105 --- /dev/null +++ b/include/exiv2/tzfile.h @@ -0,0 +1,193 @@ +/*! + @file tzfile.h + @brief This file is from the tz distribution at ftp://elsie.nci.nih.gov/pub/ + @version $Rev: 392 $ +*/ +#ifndef TZFILE_H + +#define TZFILE_H + +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +*/ + +/* +** This header is for use ONLY with the time conversion code. +** There is no guarantee that it will remain unchanged, +** or that it will remain at all. +** Do NOT copy it to any system include directory. +** Thank you! +*/ + +/* +** ID +*/ + +#ifndef lint +#ifndef NOID +static char tzfilehid[] = "@(#)tzfile.h 7.14"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/* +** Information about time zone files. +*/ + +#ifndef TZDIR +#define TZDIR "/usr/local/etc/zoneinfo" /* Time zone object file directory */ +#endif /* !defined TZDIR */ + +#ifndef TZDEFAULT +#define TZDEFAULT "localtime" +#endif /* !defined TZDEFAULT */ + +#ifndef TZDEFRULES +#define TZDEFRULES "posixrules" +#endif /* !defined TZDEFRULES */ + +/* +** Each file begins with. . . +*/ + +#define TZ_MAGIC "TZif" + +struct tzhead { + char tzh_magic[4]; /* TZ_MAGIC */ + char tzh_reserved[16]; /* reserved for future use */ + char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ + char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ + char tzh_leapcnt[4]; /* coded number of leap seconds */ + char tzh_timecnt[4]; /* coded number of transition times */ + char tzh_typecnt[4]; /* coded number of local time types */ + char tzh_charcnt[4]; /* coded number of abbr. chars */ +}; + +/* +** . . .followed by. . . +** +** tzh_timecnt (char [4])s coded transition times a la time(2) +** tzh_timecnt (unsigned char)s types of local time starting at above +** tzh_typecnt repetitions of +** one (char [4]) coded UTC offset in seconds +** one (unsigned char) used to set tm_isdst +** one (unsigned char) that's an abbreviation list index +** tzh_charcnt (char)s '\0'-terminated zone abbreviations +** tzh_leapcnt repetitions of +** one (char [4]) coded leap second transition times +** one (char [4]) total correction after above +** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition +** time is standard time, if FALSE, +** transition time is wall clock time +** if absent, transition times are +** assumed to be wall clock time +** tzh_ttisgmtcnt (char)s indexed by type; if TRUE, transition +** time is UTC, if FALSE, +** transition time is local time +** if absent, transition times are +** assumed to be local time +*/ + +/* +** In the current implementation, "tzset()" refuses to deal with files that +** exceed any of the limits below. +*/ + +#ifndef TZ_MAX_TIMES +/* +** The TZ_MAX_TIMES value below is enough to handle a bit more than a +** year's worth of solar time (corrected daily to the nearest second) or +** 138 years of Pacific Presidential Election time +** (where there are three time zone transitions every fourth year). +*/ +#define TZ_MAX_TIMES 370 +#endif /* !defined TZ_MAX_TIMES */ + +#ifndef TZ_MAX_TYPES +#ifndef NOSOLAR +#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ +#endif /* !defined NOSOLAR */ +#ifdef NOSOLAR +/* +** Must be at least 14 for Europe/Riga as of Jan 12 1995, +** as noted by Earl Chew . +*/ +#define TZ_MAX_TYPES 20 /* Maximum number of local time types */ +#endif /* !defined NOSOLAR */ +#endif /* !defined TZ_MAX_TYPES */ + +#ifndef TZ_MAX_CHARS +#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ + /* (limited by what unsigned chars can hold) */ +#endif /* !defined TZ_MAX_CHARS */ + +#ifndef TZ_MAX_LEAPS +#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ +#endif /* !defined TZ_MAX_LEAPS */ + +#define SECSPERMIN 60 +#define MINSPERHOUR 60 +#define HOURSPERDAY 24 +#define DAYSPERWEEK 7 +#define DAYSPERNYEAR 365 +#define DAYSPERLYEAR 366 +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY) +#define MONSPERYEAR 12 + +#define TM_SUNDAY 0 +#define TM_MONDAY 1 +#define TM_TUESDAY 2 +#define TM_WEDNESDAY 3 +#define TM_THURSDAY 4 +#define TM_FRIDAY 5 +#define TM_SATURDAY 6 + +#define TM_JANUARY 0 +#define TM_FEBRUARY 1 +#define TM_MARCH 2 +#define TM_APRIL 3 +#define TM_MAY 4 +#define TM_JUNE 5 +#define TM_JULY 6 +#define TM_AUGUST 7 +#define TM_SEPTEMBER 8 +#define TM_OCTOBER 9 +#define TM_NOVEMBER 10 +#define TM_DECEMBER 11 + +#define TM_YEAR_BASE 1900 + +#define EPOCH_YEAR 1970 +#define EPOCH_WDAY TM_THURSDAY + +/* +** Accurate only for the past couple of centuries; +** that will probably do. +*/ + +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) + +#ifndef USG + +/* +** Use of the underscored variants may cause problems if you move your code to +** certain System-V-based systems; for maximum portability, use the +** underscore-free variants. The underscored variants are provided for +** backward compatibility only; they may disappear from future versions of +** this file. +*/ + +#define SECS_PER_MIN SECSPERMIN +#define MINS_PER_HOUR MINSPERHOUR +#define HOURS_PER_DAY HOURSPERDAY +#define DAYS_PER_WEEK DAYSPERWEEK +#define DAYS_PER_NYEAR DAYSPERNYEAR +#define DAYS_PER_LYEAR DAYSPERLYEAR +#define SECS_PER_HOUR SECSPERHOUR +#define SECS_PER_DAY SECSPERDAY +#define MONS_PER_YEAR MONSPERYEAR + +#endif /* !defined USG */ + +#endif /* !defined TZFILE_H */ diff --git a/src/utils.hpp b/include/exiv2/utils.hpp similarity index 99% rename from src/utils.hpp rename to include/exiv2/utils.hpp index 5b2765ef..146d5333 100644 --- a/src/utils.hpp +++ b/include/exiv2/utils.hpp @@ -21,7 +21,7 @@ /*! @file utils.hpp @brief A collection of utility functions - @version $Rev$ + @version $Rev: 3090 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 12-Dec-03, ahu: created @@ -33,7 +33,7 @@ // included header files // + standard includes #include - +#include // ********************************************************************* // namespace extensions /*! diff --git a/src/utilsvideo.hpp b/include/exiv2/utilsvideo.hpp similarity index 100% rename from src/utilsvideo.hpp rename to include/exiv2/utilsvideo.hpp diff --git a/src/value.hpp b/include/exiv2/value.hpp similarity index 99% rename from src/value.hpp rename to include/exiv2/value.hpp index c3eb459f..65fef873 100644 --- a/src/value.hpp +++ b/include/exiv2/value.hpp @@ -21,7 +21,7 @@ /*! @file value.hpp @brief Value interface and concrete subclasses - @version $Rev$ + @version $Rev: 3090 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 09-Jan-04, ahu: created @@ -1062,8 +1062,8 @@ namespace Exiv2 { @brief %Value for simple ISO 8601 times. This class is limited to handling simple time strings in the ISO 8601 - format HHMMSS±HHMM where HHMMSS refers to local hour, minute and - seconds and ±HHMM refers to hours and minutes ahead or behind + format HHMMSS�HHMM where HHMMSS refers to local hour, minute and + seconds and �HHMM refers to hours and minutes ahead or behind Universal Coordinated Time. */ class EXIV2API TimeValue : public Value { diff --git a/src/version.hpp b/include/exiv2/version.hpp similarity index 97% rename from src/version.hpp rename to include/exiv2/version.hpp index ff2535cc..8b5b716e 100644 --- a/src/version.hpp +++ b/include/exiv2/version.hpp @@ -24,7 +24,7 @@ References: Similar versioning defines are used in KDE, GTK and other libraries. See http://apr.apache.org/versioning.html for accompanying guidelines. - @version $Rev$ + @version $Rev: 3371 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 31-May-06, ahu: created @@ -37,13 +37,6 @@ // + standard includes #include -// svn version has not been implemented yet for DevStudio -#if defined(_MSC_VER) && !defined(CMAKE_BUILD_SVN) -#define SVN_VERSION 0 -#else -#include "svn_version.h" -#endif - /*! @brief %Exiv2 MAJOR version number of the library used at compile-time. */ diff --git a/src/xmp.hpp b/include/exiv2/xmp.hpp similarity index 99% rename from src/xmp.hpp rename to include/exiv2/xmp.hpp index bb86b94e..1ab7cea6 100644 --- a/src/xmp.hpp +++ b/include/exiv2/xmp.hpp @@ -21,7 +21,7 @@ /*! @file xmp.hpp @brief Encoding and decoding of XMP data - @version $Rev$ + @version $Rev: 3090 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 13-Jul-07, ahu: created diff --git a/src/xmpsidecar.hpp b/include/exiv2/xmpsidecar.hpp similarity index 99% rename from src/xmpsidecar.hpp rename to include/exiv2/xmpsidecar.hpp index b54c3a6f..6a34cb3b 100644 --- a/src/xmpsidecar.hpp +++ b/include/exiv2/xmpsidecar.hpp @@ -21,7 +21,7 @@ /*! @file xmpsidecar.hpp @brief An Image subclass to support XMP sidecar files - @version $Rev$ + @version $Rev: 3090 $ @author Andreas Huggel ahuggel@gmx.net @date 07-Mar-08, ahu: created diff --git a/jenkins_build.bat b/jenkins_build.bat index c26d4fc1..13fe5ed0 100644 --- a/jenkins_build.bat +++ b/jenkins_build.bat @@ -26,6 +26,7 @@ if NOT DEFINED zlib set zlib=true if NOT DEFINED curl set curl=false if NOT DEFINED libssh set libssh=false if NOT DEFINED openssl set openssl=false +if %openssl%==true set curl=true if %ACTION%==/clean set tests=false if %ACTION%==/upgrade set tests=false @@ -35,26 +36,43 @@ if NOT DEFINED LIB set "LIB=C:\Program Files (x86)\Microsoft Visual St if NOT DEFINED LIBPATH set "LIBPATH=C:\Windows\Microsoft.NET\Framework\v2.0.50727;C:\Program Files (x86)\Microsoft Visual Studio 8\VC\ATLMFC\LIB" if NOT DEFINED VS80COMNTOOLS set "VS80COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\Tools\" -rem -- +rem ---------------------------------------------- rem set the build environment call "%VS80COMNTOOLS%\..\..\Vc\bin\vcvars32.bat" -rem -- -rem Pull in support libraries -if NOT EXIST ..\expat-2.1.0 xcopy/yesihq c:\exiv2libs\expat-2.1.0 ..\expat-2.1.0 -if NOT EXIST ..\zlib-1.2.7 xcopy/yesihq c:\exiv2libs\zlib-1.2.7 ..\zlib-1.2.7 +rem ---------------------------------------------- +rem copy the support libraries +xcopy/yesihq c:\exiv2libs\expat-2.1.0 ..\expat +xcopy/yesihq c:\exiv2libs\zlib-1.2.7 ..\zlib +xcopy/yesihq c:\exiv2libs\openssl-1.0.1j ..\openssl +xcopy/yesihq c:\exiv2libs\libssh-0.5.5 ..\libssh +xcopy/yesihq c:\exiv2libs\curl-7.39.0 ..\curl -rem -- -rem build and test +rem ---------------------------------------------- pushd msvc2005 +rem -- +rem FOO is the current directory in cygwin (/cygdrive/c/users/shared/workspace/exiv2-trunk/label/msvc) +rem we need this to set the correct directory when we run the test suite from Cygwin for /f "tokens=*" %%a in ('cygpath -au ..') do set FOO=%%a +copy exiv2.sln e.sln + +set webready=false +if %curl% == true if %libssh% == true if %openssl% == true set webready=true +if %webready% == true ( + copy/y exiv2-webready.sln e.sln + copy/y ..\include\exiv2\exv-msvc-webready.h ..\..\include\exiv2\exv-msvc.h +) + +rem -- +rem Now build and test + if %Win32%==true ( if %debug%==true ( if %static%==true ( - devenv exiv2.sln %ACTION% "Debug|Win32" + devenv e.sln %ACTION% "Debug|Win32" if %tests%==true ( call bash -c 'cd %FOO%;cd test;./testMSVC.sh ../msvc2005/bin/Win32/Debug' ) ) ) ) @@ -62,7 +80,7 @@ if %Win32%==true ( if %Win32%==true ( if %release%==true ( if %static%==true ( - devenv exiv2.sln %ACTION% "Release|Win32" + devenv e.sln %ACTION% "Release|Win32" if %tests%==true ( call bash -c 'cd %FOO%;cd test;./testMSVC.sh ../msvc2005/bin/Win32/Release' ) ) ) ) @@ -70,7 +88,7 @@ if %Win32%==true ( if %Win32%==true ( if %debug%==true ( if %dll%==true ( - devenv exiv2.sln %ACTION% "DebugDLL|Win32" + devenv e.sln %ACTION% "DebugDLL|Win32" if %tests%==true ( call bash -c 'cd %FOO%;cd test;./testMSVC.sh ../msvc2005/bin/Win32/DebugDLL' ) ) ) ) @@ -78,7 +96,7 @@ if %Win32%==true ( if %Win32%==true ( if %release%==true ( if %dll%==true ( - devenv exiv2.sln %ACTION% "ReleaseDLL|Win32" + devenv e.sln %ACTION% "ReleaseDLL|Win32" if %tests%==true ( call bash -c 'cd %FOO%;cd test;./testMSVC.sh ../msvc2005/bin/Win32/ReleaseDLL' ) ) ) ) @@ -86,7 +104,7 @@ if %Win32%==true ( if %x64%==true ( if %debug%==true ( if %static%==true ( - devenv exiv2.sln %ACTION% "Debug|x64" + devenv e.sln %ACTION% "Debug|x64" if %tests%==true ( call bash -c 'cd %FOO%;cd test;./testMSVC.sh ../msvc2005/bin/x64/Debug' ) ) ) ) @@ -94,7 +112,7 @@ if %x64%==true ( if %x64%==true ( if %release%==true ( if %static%==true ( - devenv exiv2.sln %ACTION% "Release|x64" + devenv e.sln %ACTION% "Release|x64" if %tests%==true ( call bash -c 'cd %FOO%;cd test;./testMSVC.sh ../msvc2005/bin/x64/Release' ) ) ) ) @@ -102,7 +120,7 @@ if %x64%==true ( if %x64%==true ( if %debug%==true ( if %dll%==true ( - devenv exiv2.sln %ACTION% "DebugDLL|x64" + devenv e.sln %ACTION% "DebugDLL|x64" if %tests%==true ( call bash -c 'cd %FOO%;cd test;./testMSVC.sh ../msvc2005/bin/x64/DebugDLL' ) ) ) ) @@ -110,15 +128,16 @@ if %x64%==true ( if %x64%==true ( if %release%==true ( if %dll%==true ( - devenv exiv2.sln %ACTION% "ReleaseDLL|x64" + devenv e.sln %ACTION% "ReleaseDLL|x64" if %tests%==true ( call bash -c 'cd %FOO%;cd test;./testMSVC.sh ../msvc2005/bin/x64/ReleaseDLL' ) ) ) ) +del e.sln popd rem delete the support libraries (with mozilla's native rm utility) -msvc2005\tools\bin\rm.exe -rf ..\expat-2.1.0 ..\zlib-1.2.7 +msvc2005\tools\bin\rm.exe -rf ..\expat ..\zlib ..\openssl ..\libssh ..\curl rem That's all Folks! rem ----------------- diff --git a/jenkins_build.sh b/jenkins_build.sh index 08fda5fe..e6b9b7cc 100755 --- a/jenkins_build.sh +++ b/jenkins_build.sh @@ -153,7 +153,7 @@ if [ $PLATFORM == "macosx" -a "$target" == "macosx" -a "$macosx" == "true" ]; t if [ $PLATFORM == "cygwin" -a "$target" == "cygwin" -a "$cygwin" == "true" ]; then build=CYGW ; fi if [ $PLATFORM == "cygwin" -a "$target" == "mingw" -a "$mingw" == "true" ]; then build=MING ; fi if [ $PLATFORM == "cygwin" -a "$target" == "msvc" -a "$msvc" == "true" ]; then build=MSVC ; fi -if [ $PLATFORM == "mingw" -a "$target" == "mingw" ]; then build=MING ; fi +if [ $PLATFORM == "mingw" -a "$target" == "mingw" ]; then build=MING ; fi echo "3 target = $target platform = $PLATFORM build = $build" @@ -162,14 +162,13 @@ case "$build" in echo ------------- echo ./configure --prefix=$PWD/usr $withcurl $withssh echo ------------- - ./configure --prefix=$PWD/usr $withcurl $withssh - (cd src ; make svn_version.h) + ./configure "--prefix=$PWD/usr" $withcurl $withssh make -j4 "LDFLAGS=-L${PWD}/usr/lib -L${PWD}/xmpsdk/src/.libs" make install make -j4 samples "CXXFLAGS=-I${PWD}/usr/include -I${PWD}/src" "LDFLAGS=-L${PWD}/usr/lib -L${PWD}/xmpsdk/src/.libs -lexiv2" result=$? run_tests - exiv2 -v -V + "$PWD/usr/bin/exiv2" -v -V ;; CYGW) @@ -178,7 +177,6 @@ case "$build" in # 1. trying to get Cygwin to build with gettext and friends # 2. trying to get Cygwin to install into a local directory ./configure --disable-nls $withcurl $withssh - (cd src ; make svn_version.h) make -j4 # result=$? make install @@ -215,7 +213,6 @@ case "$build" in fi ./configure $withcurl $withssh - (cd src ; make svn_version.h) make # DO NOT USE -j4. It seems to hang the build! make install make samples diff --git a/msvc2003/addmoddel/addmoddel.vcproj b/msvc2003/addmoddel/addmoddel.vcproj index 032b2c4c..ba91db87 100644 --- a/msvc2003/addmoddel/addmoddel.vcproj +++ b/msvc2003/addmoddel/addmoddel.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/convert-test/convert-test.vcproj b/msvc2003/convert-test/convert-test.vcproj index 36886c63..6acc09f7 100644 --- a/msvc2003/convert-test/convert-test.vcproj +++ b/msvc2003/convert-test/convert-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/easyaccess-test/easyaccess-test.vcproj b/msvc2003/easyaccess-test/easyaccess-test.vcproj index bac5fa66..4328e067 100644 --- a/msvc2003/easyaccess-test/easyaccess-test.vcproj +++ b/msvc2003/easyaccess-test/easyaccess-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/exifcomment/exifcomment.vcproj b/msvc2003/exifcomment/exifcomment.vcproj index ea8edac9..8af2a4d8 100644 --- a/msvc2003/exifcomment/exifcomment.vcproj +++ b/msvc2003/exifcomment/exifcomment.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/exifdata-test/exifdata-test.vcproj b/msvc2003/exifdata-test/exifdata-test.vcproj index 4ec3d0fc..5a875e15 100644 --- a/msvc2003/exifdata-test/exifdata-test.vcproj +++ b/msvc2003/exifdata-test/exifdata-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/exifprint/exifprint.vcproj b/msvc2003/exifprint/exifprint.vcproj index f8be92ce..016ebd50 100644 --- a/msvc2003/exifprint/exifprint.vcproj +++ b/msvc2003/exifprint/exifprint.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/exiv2/exiv2.vcproj b/msvc2003/exiv2/exiv2.vcproj index 802f0dac..9770ee50 100644 --- a/msvc2003/exiv2/exiv2.vcproj +++ b/msvc2003/exiv2/exiv2.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/exiv2lib/exiv2lib.vcproj b/msvc2003/exiv2lib/exiv2lib.vcproj index 0b98a778..55f0ce4f 100644 --- a/msvc2003/exiv2lib/exiv2lib.vcproj +++ b/msvc2003/exiv2lib/exiv2lib.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/exivsimple/exivsimple.vcproj b/msvc2003/exivsimple/exivsimple.vcproj index 26f5d9f7..ec87fa48 100644 --- a/msvc2003/exivsimple/exivsimple.vcproj +++ b/msvc2003/exivsimple/exivsimple.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/geotag/geotag.vcproj b/msvc2003/geotag/geotag.vcproj index e4f35290..691e04b4 100644 --- a/msvc2003/geotag/geotag.vcproj +++ b/msvc2003/geotag/geotag.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/iotest/iotest.vcproj b/msvc2003/iotest/iotest.vcproj index 57394358..e0ae0bba 100644 --- a/msvc2003/iotest/iotest.vcproj +++ b/msvc2003/iotest/iotest.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/iptceasy/iptceasy.vcproj b/msvc2003/iptceasy/iptceasy.vcproj index 23e5ca64..84693bad 100644 --- a/msvc2003/iptceasy/iptceasy.vcproj +++ b/msvc2003/iptceasy/iptceasy.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/iptcprint/iptcprint.vcproj b/msvc2003/iptcprint/iptcprint.vcproj index bfcb8425..a31a97db 100644 --- a/msvc2003/iptcprint/iptcprint.vcproj +++ b/msvc2003/iptcprint/iptcprint.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/iptctest/iptctest.vcproj b/msvc2003/iptctest/iptctest.vcproj index 5969afaf..68083450 100644 --- a/msvc2003/iptctest/iptctest.vcproj +++ b/msvc2003/iptctest/iptctest.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/key-test/key-test.vcproj b/msvc2003/key-test/key-test.vcproj index ce54691a..da4b0be3 100644 --- a/msvc2003/key-test/key-test.vcproj +++ b/msvc2003/key-test/key-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/largeiptc-test/largeiptc-test.vcproj b/msvc2003/largeiptc-test/largeiptc-test.vcproj index 8078c770..d6e5c15c 100644 --- a/msvc2003/largeiptc-test/largeiptc-test.vcproj +++ b/msvc2003/largeiptc-test/largeiptc-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/metacopy/metacopy.vcproj b/msvc2003/metacopy/metacopy.vcproj index fe51c61c..bb9f5957 100644 --- a/msvc2003/metacopy/metacopy.vcproj +++ b/msvc2003/metacopy/metacopy.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/mmap-test/mmap-test.vcproj b/msvc2003/mmap-test/mmap-test.vcproj index 99096d37..8fee61b5 100644 --- a/msvc2003/mmap-test/mmap-test.vcproj +++ b/msvc2003/mmap-test/mmap-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/organize/organize.vcproj b/msvc2003/organize/organize.vcproj index 59ba525b..0290034b 100644 --- a/msvc2003/organize/organize.vcproj +++ b/msvc2003/organize/organize.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/path-test/path-test.vcproj b/msvc2003/path-test/path-test.vcproj index 7adcc863..55b4cf66 100644 --- a/msvc2003/path-test/path-test.vcproj +++ b/msvc2003/path-test/path-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/prevtest/prevtest.vcproj b/msvc2003/prevtest/prevtest.vcproj index edc9fd3d..ea42ce1e 100644 --- a/msvc2003/prevtest/prevtest.vcproj +++ b/msvc2003/prevtest/prevtest.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/stringto-test/stringto-test.vcproj b/msvc2003/stringto-test/stringto-test.vcproj index a152523b..e046e10c 100644 --- a/msvc2003/stringto-test/stringto-test.vcproj +++ b/msvc2003/stringto-test/stringto-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/taglist/taglist.vcproj b/msvc2003/taglist/taglist.vcproj index c8854a38..4640b48b 100644 --- a/msvc2003/taglist/taglist.vcproj +++ b/msvc2003/taglist/taglist.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/tiff-test/tiff-test.vcproj b/msvc2003/tiff-test/tiff-test.vcproj index 3adbcc58..1c9abe65 100644 --- a/msvc2003/tiff-test/tiff-test.vcproj +++ b/msvc2003/tiff-test/tiff-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/utiltest/utiltest.vcproj b/msvc2003/utiltest/utiltest.vcproj index 7b7b8b31..1d1433ce 100644 --- a/msvc2003/utiltest/utiltest.vcproj +++ b/msvc2003/utiltest/utiltest.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/werror-test/werror-test.vcproj b/msvc2003/werror-test/werror-test.vcproj index 2b573906..d5e40c1e 100644 --- a/msvc2003/werror-test/werror-test.vcproj +++ b/msvc2003/werror-test/werror-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/write-test/write-test.vcproj b/msvc2003/write-test/write-test.vcproj index df4e935a..0c153ecd 100644 --- a/msvc2003/write-test/write-test.vcproj +++ b/msvc2003/write-test/write-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/write2-test/write2-test.vcproj b/msvc2003/write2-test/write2-test.vcproj index b53f47ce..8e76a0ab 100644 --- a/msvc2003/write2-test/write2-test.vcproj +++ b/msvc2003/write2-test/write2-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/xmpparse/xmpparse.vcproj b/msvc2003/xmpparse/xmpparse.vcproj index 7a2f7264..59623f5b 100644 --- a/msvc2003/xmpparse/xmpparse.vcproj +++ b/msvc2003/xmpparse/xmpparse.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/xmpparser-test/xmpparser-test.vcproj b/msvc2003/xmpparser-test/xmpparser-test.vcproj index de55b64c..e0924b7e 100644 --- a/msvc2003/xmpparser-test/xmpparser-test.vcproj +++ b/msvc2003/xmpparser-test/xmpparser-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/xmpsample/xmpsample.vcproj b/msvc2003/xmpsample/xmpsample.vcproj index dab3f5b6..c07ebe24 100644 --- a/msvc2003/xmpsample/xmpsample.vcproj +++ b/msvc2003/xmpsample/xmpsample.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2003/xmpsdk/xmpsdk.vcproj b/msvc2003/xmpsdk/xmpsdk.vcproj index 73671f96..feac1a32 100644 --- a/msvc2003/xmpsdk/xmpsdk.vcproj +++ b/msvc2003/xmpsdk/xmpsdk.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/ReadMe.txt b/msvc2005/ReadMe.txt index c6672a57..a17f9c90 100644 --- a/msvc2005/ReadMe.txt +++ b/msvc2005/ReadMe.txt @@ -2,15 +2,13 @@ exiv2\msvc2005\ReadMe.txt ------------------------- +-----------------------------------------------------------+ -| msvc2012 builds 32bit and 64bit binaries | -| with Visual Studio 2012 | | msvc2005 builds 32bit and 64bit binaries | -| with Visual Studio 2005/8/10 | +| with Visual Studio 2005/8/10/12 | | msvc2003 builds 32bit binaries | | with Visual Studio 2003/5/8 | +-----------------------------------------------------------+ -Updated: 2013-07-22 +Updated: 2013-12-25 Robin Mills http://clanmills.com @@ -23,10 +21,10 @@ T A B L E o f C O N T E N T S 1.1 Tools 1.2 Install zlib and expat sources. 1.3 Open exiv2\msvc2005\exiv2.sln -1.4 What is build -1.5 Building with zlib1.2.3 (or 1.2.5) and expat 2.0.1 -1.6 Express editions of DevStudio (or 32 bit only builds, or 64 bit only builds) -1.7 Support for DevStudio 11 +1.4 Building with and without webready +1.5 What is build +1.6 Building with zlib1.2.3 (or 1.2.5) and expat 2.0.1 +1.7 Express editions of DevStudio (or 32 bit only builds, or 64 bit only builds) 2 Design 2.1 Architecture @@ -37,8 +35,7 @@ T A B L E o f C O N T E N T S 4 Batch builds and tests 4.1 buildall.bat -4.2 runner.py -4.3 Running the test suite +4.2 Running the test suite ## End Table of Contents End ## #### @@ -46,9 +43,9 @@ T A B L E o f C O N T E N T S 1 Build Instructions 1.1 Tools - This has been tested with the "Pro" versions of VS 2005/08/10 - Express editions don't support 64 bit builds, however it is - possible to build 32 bit libraries with "Express". + This has been tested with the "Pro" versions of VS 2005/08/10/12 + Some Express editions don't support 64 bit builds + however it is possible to build 32 bit libraries with "Express". See notes below about DevStudio Express and building only Win32 or x64 builds 1.2 Install zlib and expat sources. @@ -57,24 +54,37 @@ T A B L E o f C O N T E N T S c:\gnu>dir Directory of c:\gnu 2010-12-05 10:05 exiv2 <--- this tree - 2012-05-04 23:35 expat-2.1.0 <--- "vanilla" expat 2.1.0 source tree - 2012-05-04 23:35 zlib-1.2.7 <--- "vanilla" zlib 1.2.7 source tree - 2010-12-02 21:06 expat-2.0.1 OPTIONAL <--- "vanilla" expat 2.0.1 source tree - 2010-12-02 20:58 zlib-1.2.5 OPTIONAL <--- "vanilla" zlib 1.2.5 source tree - 2010-12-02 20:58 zlib-1.2.3 OPTIONAL <--- "vanilla" zlib 1.2.3 source tree + 2012-05-04 23:35 expat <--- "vanilla" expat 2.1.0 source tree + 2012-05-04 23:35 zlib <--- "vanilla" zlib 1.2.7 source tree + 2012-05-04 23:35 curl <--- "vanilla" curl 7.39.0 source tree + 2012-05-04 23:35 openssl <--- "vanilla" openssl 1.0.1j source tree + 2012-05-04 23:35 libssh <--- "vanilla" libssh 0.5.5 source tree c:\gnu> + + You can obtain the libraries from http://clanmills.com/files/exiv2libs.zip (6.9mb) + I copy those to the directory c:\exiv2libs + The script msvc2005/copylibs.bat will copy them from c:\exiv2libs to the correct location + + 11/05/2014 07:26 AM curl-7.39.0 + 12/07/2014 09:18 AM expat-2.1.0 + 12/17/2014 09:40 AM libssh-0.5.5 + 12/17/2014 09:38 AM openssl-1.0.1j + 12/07/2014 09:18 AM zlib-1.2.7 The URLs from which to obtain zlib and expat are documented in exiv2\msvc2003\ReadMe.txt expat-2.1.0 is available from http://voxel.dl.sourceforge.net/sourceforge/expat/expat-2.1.0.tar.gz zlib-1.2.7 is available from http://zlib.net/zlib-1.2.7.tar.gz + curl is available from http://curl.haxx.se/download.html + openssh is available from https://www.openssl.org/source/ + libssh is available from https://www.libssh.org/get-it/ 1.3 Open exiv2\msvc2005\exiv2.sln Projects are zlib, expat, xmpsdk, exiv2lib, exiv2, addmoddel etc... Build/Batch build... Select All, Build - - 29 projects (zlib, expat, xmpsdk, exiv2lib, exiv2, addmoddel etc) + - 41 projects (zlib, expat, xmpsdk, exiv2lib, exiv2, addmoddel etc) x 2 Platforms (x64|Win32) x 4 Configurations (Debug|Release|DebugDLL|ReleaseDLL) - = 29x2x4 = 232 builds. + = 41x2x4 = 328 builds. If you haven't installed the x64 compiler, don't select the 64 bit configurations! You may have to hand-edit the vcproj and sln files to hide the 64 bit information. @@ -82,12 +92,23 @@ T A B L E o f C O N T E N T S Build time is 20 minutes on a 2.2GHz Duo Core and consumes 3.0 gBytes of disk space. -1.4 What is built +1.4 Building with and without webready + Building the complete library with webready support requires building + openssl, libssh and curl. This is time consuming. The build time + increases from 5 to 20 minutes. + + By default, you will not build with webready. + + To build with webready: + 1 copy include\exiv2\exv_msvc-webready.h include\exiv2\exv_msvc.h + 2 open open msvc2005\exiv2-webready.vcproj + +1.5 What is built The DLL builds use the DLL version of the C runtime libraries The Debug|Release builds use static C runtime libraries This is discussed in exiv2\msvc2003\ReadMe.txt -1.5 Building with zlib1.2.5 (or 1.2.3) and/or expat 2.0.1 +1.6 Building with zlib1.2.5 (or 1.2.3) and/or expat 2.0.1 By default, msvc2005 builds with zlib-1.2.7 and expat 2.1.0 You can build with zlib1.2.3. To do this: @@ -116,7 +137,7 @@ T A B L E o f C O N T E N T S 4) Alter "AdditionalIncludeDirectories" for expat 2.0.1 -1.6 Express editions of DevStudio (or 32 bit only builds, or 64 bit only builds) +1.7 Express editions of DevStudio (or 32 bit only builds, or 64 bit only builds) Express does not provide a 64 bit compiler. You can build 32 bit libraries with DevStudio Express (with a little effort) @@ -147,16 +168,6 @@ T A B L E o f C O N T E N T S To remove the "memory" of old configurations: setbuild.py reset - -1.7 Support for DevStudio 11 - I have successfully built and tested a sub-set of exiv2/msvc2005 with DevStudio 11 beta. - - I have no plan to support beta versions of DevStudio. - - I will need to purchase DevStudio 11 when it's available to support exiv2. - This is a private purchase and will only be used to support exiv2. - I would appreciate a donation of a legal copy of DevStudio 11. - (Any Microsoft employees/contractors with staff software purchase privileges?) 2 Design @@ -178,10 +189,10 @@ T A B L E o f C O N T E N T S zlib and expat exiv2\msvc2005\zlib\zlib.vcproj DevStudio files - ..\..\..\zlib-1.2.7\ Source code + ..\..\..\zlib Source code exiv2\msvc2005\expat\expat.vcproj DevStudio files - ..\..\..\expat-2.1.0\ Source code + ..\..\..\expat Source code 2.1 Architecture There are directories for every component: @@ -195,19 +206,18 @@ T A B L E o f C O N T E N T S exiv2lib\x64\{Debug|Release|DebugDLL|ReleaseDLL} 64 bit builds Final builds and include directories (for export to "foreign" projects) - bin\{win32|x84}\Win32\{Debug|Release|DebugDLL|ReleaseDLL} - include + bin\{win32|x64}\Win32\{Debug|Release|DebugDLL|ReleaseDLL} 2.2 Relationship with msvc2003 build environment msvc2005 is similar to msvc2003. However there are significant differences: 1) msvc2005 supports 64 bit and 32 bit builds - 2) msvc2005 provides projects to build expat and zlib + 2) msvc2005 provides projects to build expat, zlib, curl, libssh and openssl 3) msvc2005 is designed to accomodate new versions of expat and zlib when they become available. - 4) msvc2005 supports DevStudio 2005, 2008 and 2010 (no support for 2003) + 4) msvc2005 supports DevStudio 2005 and later (no support for 2003) 5) msvc2005 does not require you to build 'vanilla' expat and zlib projects in advance 6) msvc2005 does not support the organize application - 7) msvc2005 supports building with zlib1.2.7 (default) or zlib1.2.3/5 + 7) msvc2005 supports building with zlib1.2.7 (default) or zlib1.2.3/5 7) msvc2005 supports building with expat2.1.0 (default) or expa2.0.1 msvc2003 will continue to be supported for 32 bit builds using DevStudio 2003/05/08, @@ -241,20 +251,7 @@ T A B L E o f C O N T E N T S It doesn't know anything about building only x64 or only Win32. Change the script if you want something special. -4.2 runner.py - runner.py [Win32|x64|all] - - This script runs some basic "sanity" checks on the build. You should compare the - output of runner.py with the reference output runner.txt. - diff/windiff/winmergeu - or whatever your favorite diff tool. - - python runner.py all > new.txt - winmergeu.exe new.txt runner.txt - - If you have only build Win32 (or x64), you'll have to remove the output from - runner.txt for the target that isn't of interest. - -4.3 Running the test suite +4.2 Running the test suite You will need to install cygwin to run the test suite. This is a two stage process: diff --git a/msvc2005/addmoddel/addmoddel.vcproj b/msvc2005/addmoddel/addmoddel.vcproj index 10675965..067245eb 100644 --- a/msvc2005/addmoddel/addmoddel.vcproj +++ b/msvc2005/addmoddel/addmoddel.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/convert-test/convert-test.vcproj b/msvc2005/convert-test/convert-test.vcproj index 4c60360b..17f8f443 100644 --- a/msvc2005/convert-test/convert-test.vcproj +++ b/msvc2005/convert-test/convert-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/copylibs.bat b/msvc2005/copylibs.bat new file mode 100644 index 00000000..0140012f --- /dev/null +++ b/msvc2005/copylibs.bat @@ -0,0 +1,16 @@ +@echo off +rem copylibs.bat +rem get the support libraries +rem +setlocal +set EXIV2LIBS=c:\exiv2libs + +xcopy/yesihq %EXIV2LIBS%\expat-2.1.0 ..\..\expat +xcopy/yesihq %EXIV2LIBS%\zlib-1.2.7 ..\..\zlib +xcopy/yesihq %EXIV2LIBS%\openssl-1.0.1j ..\..\openssl +xcopy/yesihq %EXIV2LIBS%\libssh-0.5.5 ..\..\libssh +xcopy/yesihq %EXIV2LIBS%\curl-7.39.0 ..\..\curl + + +rem That's all Folks! +rem ----------------- \ No newline at end of file diff --git a/msvc2005/easyaccess-test/easyaccess-test.vcproj b/msvc2005/easyaccess-test/easyaccess-test.vcproj index 9695e0d0..aa0c262b 100644 --- a/msvc2005/easyaccess-test/easyaccess-test.vcproj +++ b/msvc2005/easyaccess-test/easyaccess-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/exifcomment/exifcomment.vcproj b/msvc2005/exifcomment/exifcomment.vcproj index 1ac759ef..3e7a2b7f 100644 --- a/msvc2005/exifcomment/exifcomment.vcproj +++ b/msvc2005/exifcomment/exifcomment.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/exifdata-test/exifdata-test.vcproj b/msvc2005/exifdata-test/exifdata-test.vcproj index 71b0f616..c48d8b3c 100644 --- a/msvc2005/exifdata-test/exifdata-test.vcproj +++ b/msvc2005/exifdata-test/exifdata-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/exifprint/exifprint.vcproj b/msvc2005/exifprint/exifprint.vcproj index da2f0772..3592dd02 100644 --- a/msvc2005/exifprint/exifprint.vcproj +++ b/msvc2005/exifprint/exifprint.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/exiv2-webready.sln b/msvc2005/exiv2-webready.sln new file mode 100644 index 00000000..149ee796 --- /dev/null +++ b/msvc2005/exiv2-webready.sln @@ -0,0 +1,1029 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libexiv2", "libexiv2\libexiv2.vcproj", "{831EF580-92C8-4CA8-B0CE-3D906280A54D}" + ProjectSection(ProjectDependencies) = postProject + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7} = {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA} = {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exiv2", "exiv2\exiv2.vcproj", "{07293CAC-00DA-493E-90C9-5D010C2B1B53}" + ProjectSection(ProjectDependencies) = postProject + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA} = {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA} + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7} = {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmpsdk", "xmpsdk\xmpsdk.vcproj", "{09877CF4-83B6-44FE-A2E2-629AA5C8093E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libexpat", "libexpat\libexpat.vcproj", "{6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib1", "zlib\zlib.vcproj", "{8308C68D-E12B-4C71-96F4-7137F6BEB654}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "addmoddel", "addmoddel\addmoddel.vcproj", "{83914D93-57B3-4718-8A50-662C17C4AE8F}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iptctest", "iptctest\iptctest.vcproj", "{AD41F87C-242B-4B61-B767-A9879F0D5C04}" + ProjectSection(ProjectDependencies) = postProject + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "easyaccess-test", "easyaccess-test\easyaccess-test.vcproj", "{30E18D87-0147-4601-9ED2-4D5291645DB3}" + ProjectSection(ProjectDependencies) = postProject + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "largeiptc-test", "largeiptc-test\largeiptc-test.vcproj", "{953404C9-B20A-4D17-8262-9D9AD1CDC5C1}" + ProjectSection(ProjectDependencies) = postProject + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "convert-test", "convert-test\convert-test.vcproj", "{D802FE1E-7868-4034-92B8-00865E1CABAB}" + ProjectSection(ProjectDependencies) = postProject + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iotest", "iotest\iotest.vcproj", "{21F0CEB1-D850-4C29-88BF-1CE4171824E6}" + ProjectSection(ProjectDependencies) = postProject + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iptcprint", "iptcprint\iptcprint.vcproj", "{A7D22798-1262-4194-94A5-C636BCB68329}" + ProjectSection(ProjectDependencies) = postProject + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "key-test", "key-test\key-test.vcproj", "{F11358FA-AA36-46E1-BA80-A17B8042BF9B}" + ProjectSection(ProjectDependencies) = postProject + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mmap-test", "mmap-test\mmap-test.vcproj", "{556CB4FC-33BB-4E67-AB0E-1865E67176A5}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "prevtest", "prevtest\prevtest.vcproj", "{FC7120EC-BEB2-4CC3-9B90-B022F560E584}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stringto-test", "stringto-test\stringto-test.vcproj", "{9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tiff-test", "tiff-test\tiff-test.vcproj", "{C34B11A1-B707-46B2-8053-2FA236B369CF}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "werror-test", "werror-test\werror-test.vcproj", "{430C4512-CC73-4943-8CDF-71DEA573BD47}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "write-test", "write-test\write-test.vcproj", "{98A9F59D-FDFE-4B27-88FE-2625F1E7597F}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "write2-test", "write2-test\write2-test.vcproj", "{E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exifdata-test", "exifdata-test\exifdata-test.vcproj", "{FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exifprint", "exifprint\exifprint.vcproj", "{BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmpsample", "xmpsample\xmpsample.vcproj", "{45CA5427-4260-4F4A-86B0-FB7AE233D76B}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmpparser-test", "xmpparser-test\xmpparser-test.vcproj", "{85121FD0-01A1-49BA-B168-CC8D90F91A6F}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmpparse", "xmpparse\xmpparse.vcproj", "{1708EFC1-414E-4712-80A5-813A6F38814C}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exifcomment", "exifcomment\exifcomment.vcproj", "{D291B6EF-986B-4222-ADA6-38A2EC2A56CE}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "metacopy", "metacopy\metacopy.vcproj", "{AD231915-942F-4083-9671-85E26A5798B0}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "path-test", "path-test\path-test.vcproj", "{E04D48BF-F529-4267-9311-908E94DF5A49}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iptceasy", "iptceasy\iptceasy.vcproj", "{6860BB9B-2053-46CD-9E2D-EEC199D68982}" + ProjectSection(ProjectDependencies) = postProject + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "taglist", "taglist\taglist.vcproj", "{DBD630FC-0DA9-41EB-925D-70654D01F6FA}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "utiltest", "utiltest\utiltest.vcproj", "{495BC686-DF50-4250-B469-9C6B7B33A4B8}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "geotag", "geotag\geotag.vcproj", "{E3073076-4837-4DDB-89E5-5AC297C7481D}" + ProjectSection(ProjectDependencies) = postProject + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httptest", "httptest\httptest.vcproj", "{4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}" + ProjectSection(ProjectDependencies) = postProject + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exiv2json", "exiv2json\exiv2json.vcproj", "{4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcurl", "libcurl\libcurl.vcproj", "{F36F075A-880D-47BA-805F-C47850062121}" + ProjectSection(ProjectDependencies) = postProject + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7} = {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7} + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA} = {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "remotetest", "remotetest\remotetest.vcproj", "{B25A3F96-68E8-4FD4-860E-2C33E539B892}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "conntest", "conntest\conntest.vcproj", "{E015DB8C-C463-4A6B-88EA-AFC671D84B5B}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {729E4E11-3BBA-4306-B53C-8AEC45E70E10} = {729E4E11-3BBA-4306-B53C-8AEC45E70E10} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {F36F075A-880D-47BA-805F-C47850062121} = {F36F075A-880D-47BA-805F-C47850062121} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libssh", "libssh\libssh.vcproj", "{729E4E11-3BBA-4306-B53C-8AEC45E70E10}" + ProjectSection(ProjectDependencies) = postProject + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA} = {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7} = {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openssl", "openssl\openssl.vcproj", "{3D77E4F8-02EE-491F-B01C-EE8012CABA18}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libeay32", "libeay32\libeay32.vcproj", "{2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}" + ProjectSection(ProjectDependencies) = postProject + {3D77E4F8-02EE-491F-B01C-EE8012CABA18} = {3D77E4F8-02EE-491F-B01C-EE8012CABA18} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssleay32", "ssleay32\ssleay32.vcproj", "{6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA}" + ProjectSection(ProjectDependencies) = postProject + {3D77E4F8-02EE-491F-B01C-EE8012CABA18} = {3D77E4F8-02EE-491F-B01C-EE8012CABA18} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + DebugDLL|Win32 = DebugDLL|Win32 + DebugDLL|x64 = DebugDLL|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseDLL|Win32 = ReleaseDLL|Win32 + ReleaseDLL|x64 = ReleaseDLL|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.Debug|Win32.ActiveCfg = Debug|Win32 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.Debug|Win32.Build.0 = Debug|Win32 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.Debug|x64.ActiveCfg = Debug|x64 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.Debug|x64.Build.0 = Debug|x64 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.Release|Win32.ActiveCfg = Release|Win32 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.Release|Win32.Build.0 = Release|Win32 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.Release|x64.ActiveCfg = Release|x64 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.Release|x64.Build.0 = Release|x64 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {831EF580-92C8-4CA8-B0CE-3D906280A54D}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.Debug|Win32.ActiveCfg = Debug|Win32 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.Debug|Win32.Build.0 = Debug|Win32 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.Debug|x64.ActiveCfg = Debug|x64 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.Debug|x64.Build.0 = Debug|x64 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.Release|Win32.ActiveCfg = Release|Win32 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.Release|Win32.Build.0 = Release|Win32 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.Release|x64.ActiveCfg = Release|x64 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.Release|x64.Build.0 = Release|x64 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {07293CAC-00DA-493E-90C9-5D010C2B1B53}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.Debug|Win32.ActiveCfg = Debug|Win32 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.Debug|Win32.Build.0 = Debug|Win32 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.Debug|x64.ActiveCfg = Debug|x64 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.Debug|x64.Build.0 = Debug|x64 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.Release|Win32.ActiveCfg = Release|Win32 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.Release|Win32.Build.0 = Release|Win32 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.Release|x64.ActiveCfg = Release|x64 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.Release|x64.Build.0 = Release|x64 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {09877CF4-83B6-44FE-A2E2-629AA5C8093E}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.Debug|Win32.ActiveCfg = Debug|Win32 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.Debug|Win32.Build.0 = Debug|Win32 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.Debug|x64.ActiveCfg = Debug|x64 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.Debug|x64.Build.0 = Debug|x64 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.Release|Win32.ActiveCfg = Release|Win32 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.Release|Win32.Build.0 = Release|Win32 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.Release|x64.ActiveCfg = Release|x64 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.Release|x64.Build.0 = Release|x64 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.Debug|Win32.ActiveCfg = Debug|Win32 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.Debug|Win32.Build.0 = Debug|Win32 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.Debug|x64.ActiveCfg = Debug|x64 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.Debug|x64.Build.0 = Debug|x64 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.Release|Win32.ActiveCfg = Release|Win32 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.Release|Win32.Build.0 = Release|Win32 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.Release|x64.ActiveCfg = Release|x64 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.Release|x64.Build.0 = Release|x64 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {8308C68D-E12B-4C71-96F4-7137F6BEB654}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.Debug|Win32.ActiveCfg = Debug|Win32 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.Debug|Win32.Build.0 = Debug|Win32 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.Debug|x64.ActiveCfg = Debug|x64 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.Debug|x64.Build.0 = Debug|x64 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.Release|Win32.ActiveCfg = Release|Win32 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.Release|Win32.Build.0 = Release|Win32 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.Release|x64.ActiveCfg = Release|x64 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.Release|x64.Build.0 = Release|x64 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {83914D93-57B3-4718-8A50-662C17C4AE8F}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.Debug|Win32.ActiveCfg = Debug|Win32 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.Debug|Win32.Build.0 = Debug|Win32 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.Debug|x64.ActiveCfg = Debug|x64 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.Debug|x64.Build.0 = Debug|x64 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.Release|Win32.ActiveCfg = Release|Win32 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.Release|Win32.Build.0 = Release|Win32 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.Release|x64.ActiveCfg = Release|x64 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.Release|x64.Build.0 = Release|x64 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {AD41F87C-242B-4B61-B767-A9879F0D5C04}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.Debug|Win32.ActiveCfg = Debug|Win32 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.Debug|Win32.Build.0 = Debug|Win32 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.Debug|x64.ActiveCfg = Debug|x64 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.Debug|x64.Build.0 = Debug|x64 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.Release|Win32.ActiveCfg = Release|Win32 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.Release|Win32.Build.0 = Release|Win32 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.Release|x64.ActiveCfg = Release|x64 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.Release|x64.Build.0 = Release|x64 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {30E18D87-0147-4601-9ED2-4D5291645DB3}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.Debug|Win32.ActiveCfg = Debug|Win32 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.Debug|Win32.Build.0 = Debug|Win32 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.Debug|x64.ActiveCfg = Debug|x64 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.Debug|x64.Build.0 = Debug|x64 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.Release|Win32.ActiveCfg = Release|Win32 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.Release|Win32.Build.0 = Release|Win32 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.Release|x64.ActiveCfg = Release|x64 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.Release|x64.Build.0 = Release|x64 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {953404C9-B20A-4D17-8262-9D9AD1CDC5C1}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.Debug|Win32.ActiveCfg = Debug|Win32 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.Debug|Win32.Build.0 = Debug|Win32 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.Debug|x64.ActiveCfg = Debug|x64 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.Debug|x64.Build.0 = Debug|x64 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.Release|Win32.ActiveCfg = Release|Win32 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.Release|Win32.Build.0 = Release|Win32 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.Release|x64.ActiveCfg = Release|x64 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.Release|x64.Build.0 = Release|x64 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {D802FE1E-7868-4034-92B8-00865E1CABAB}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.Debug|Win32.ActiveCfg = Debug|Win32 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.Debug|Win32.Build.0 = Debug|Win32 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.Debug|x64.ActiveCfg = Debug|x64 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.Debug|x64.Build.0 = Debug|x64 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.Release|Win32.ActiveCfg = Release|Win32 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.Release|Win32.Build.0 = Release|Win32 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.Release|x64.ActiveCfg = Release|x64 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.Release|x64.Build.0 = Release|x64 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {21F0CEB1-D850-4C29-88BF-1CE4171824E6}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {A7D22798-1262-4194-94A5-C636BCB68329}.Debug|Win32.ActiveCfg = Debug|Win32 + {A7D22798-1262-4194-94A5-C636BCB68329}.Debug|Win32.Build.0 = Debug|Win32 + {A7D22798-1262-4194-94A5-C636BCB68329}.Debug|x64.ActiveCfg = Debug|x64 + {A7D22798-1262-4194-94A5-C636BCB68329}.Debug|x64.Build.0 = Debug|x64 + {A7D22798-1262-4194-94A5-C636BCB68329}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {A7D22798-1262-4194-94A5-C636BCB68329}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {A7D22798-1262-4194-94A5-C636BCB68329}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {A7D22798-1262-4194-94A5-C636BCB68329}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {A7D22798-1262-4194-94A5-C636BCB68329}.Release|Win32.ActiveCfg = Release|Win32 + {A7D22798-1262-4194-94A5-C636BCB68329}.Release|Win32.Build.0 = Release|Win32 + {A7D22798-1262-4194-94A5-C636BCB68329}.Release|x64.ActiveCfg = Release|x64 + {A7D22798-1262-4194-94A5-C636BCB68329}.Release|x64.Build.0 = Release|x64 + {A7D22798-1262-4194-94A5-C636BCB68329}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {A7D22798-1262-4194-94A5-C636BCB68329}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {A7D22798-1262-4194-94A5-C636BCB68329}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {A7D22798-1262-4194-94A5-C636BCB68329}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.Debug|Win32.ActiveCfg = Debug|Win32 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.Debug|Win32.Build.0 = Debug|Win32 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.Debug|x64.ActiveCfg = Debug|x64 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.Debug|x64.Build.0 = Debug|x64 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.Release|Win32.ActiveCfg = Release|Win32 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.Release|Win32.Build.0 = Release|Win32 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.Release|x64.ActiveCfg = Release|x64 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.Release|x64.Build.0 = Release|x64 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {F11358FA-AA36-46E1-BA80-A17B8042BF9B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.Debug|Win32.ActiveCfg = Debug|Win32 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.Debug|Win32.Build.0 = Debug|Win32 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.Debug|x64.ActiveCfg = Debug|x64 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.Debug|x64.Build.0 = Debug|x64 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.Release|Win32.ActiveCfg = Release|Win32 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.Release|Win32.Build.0 = Release|Win32 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.Release|x64.ActiveCfg = Release|x64 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.Release|x64.Build.0 = Release|x64 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {556CB4FC-33BB-4E67-AB0E-1865E67176A5}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.Debug|Win32.ActiveCfg = Debug|Win32 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.Debug|Win32.Build.0 = Debug|Win32 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.Debug|x64.ActiveCfg = Debug|x64 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.Debug|x64.Build.0 = Debug|x64 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.Release|Win32.ActiveCfg = Release|Win32 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.Release|Win32.Build.0 = Release|Win32 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.Release|x64.ActiveCfg = Release|x64 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.Release|x64.Build.0 = Release|x64 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {FC7120EC-BEB2-4CC3-9B90-B022F560E584}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.Debug|Win32.ActiveCfg = Debug|Win32 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.Debug|Win32.Build.0 = Debug|Win32 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.Debug|x64.ActiveCfg = Debug|x64 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.Debug|x64.Build.0 = Debug|x64 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.Release|Win32.ActiveCfg = Release|Win32 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.Release|Win32.Build.0 = Release|Win32 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.Release|x64.ActiveCfg = Release|x64 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.Release|x64.Build.0 = Release|x64 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.Debug|Win32.ActiveCfg = Debug|Win32 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.Debug|Win32.Build.0 = Debug|Win32 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.Debug|x64.ActiveCfg = Debug|x64 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.Debug|x64.Build.0 = Debug|x64 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.Release|Win32.ActiveCfg = Release|Win32 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.Release|Win32.Build.0 = Release|Win32 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.Release|x64.ActiveCfg = Release|x64 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.Release|x64.Build.0 = Release|x64 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {C34B11A1-B707-46B2-8053-2FA236B369CF}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.Debug|Win32.ActiveCfg = Debug|Win32 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.Debug|Win32.Build.0 = Debug|Win32 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.Debug|x64.ActiveCfg = Debug|x64 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.Debug|x64.Build.0 = Debug|x64 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.Release|Win32.ActiveCfg = Release|Win32 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.Release|Win32.Build.0 = Release|Win32 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.Release|x64.ActiveCfg = Release|x64 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.Release|x64.Build.0 = Release|x64 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {430C4512-CC73-4943-8CDF-71DEA573BD47}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.Debug|Win32.ActiveCfg = Debug|Win32 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.Debug|Win32.Build.0 = Debug|Win32 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.Debug|x64.ActiveCfg = Debug|x64 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.Debug|x64.Build.0 = Debug|x64 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.Release|Win32.ActiveCfg = Release|Win32 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.Release|Win32.Build.0 = Release|Win32 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.Release|x64.ActiveCfg = Release|x64 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.Release|x64.Build.0 = Release|x64 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {98A9F59D-FDFE-4B27-88FE-2625F1E7597F}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.Debug|Win32.Build.0 = Debug|Win32 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.Debug|x64.ActiveCfg = Debug|x64 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.Debug|x64.Build.0 = Debug|x64 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.Release|Win32.ActiveCfg = Release|Win32 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.Release|Win32.Build.0 = Release|Win32 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.Release|x64.ActiveCfg = Release|x64 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.Release|x64.Build.0 = Release|x64 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.Debug|Win32.ActiveCfg = Debug|Win32 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.Debug|Win32.Build.0 = Debug|Win32 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.Debug|x64.ActiveCfg = Debug|x64 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.Debug|x64.Build.0 = Debug|x64 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.Release|Win32.ActiveCfg = Release|Win32 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.Release|Win32.Build.0 = Release|Win32 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.Release|x64.ActiveCfg = Release|x64 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.Release|x64.Build.0 = Release|x64 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.Debug|Win32.ActiveCfg = Debug|Win32 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.Debug|Win32.Build.0 = Debug|Win32 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.Debug|x64.ActiveCfg = Debug|x64 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.Debug|x64.Build.0 = Debug|x64 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.Release|Win32.ActiveCfg = Release|Win32 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.Release|Win32.Build.0 = Release|Win32 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.Release|x64.ActiveCfg = Release|x64 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.Release|x64.Build.0 = Release|x64 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.Debug|Win32.ActiveCfg = Debug|Win32 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.Debug|Win32.Build.0 = Debug|Win32 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.Debug|x64.ActiveCfg = Debug|x64 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.Debug|x64.Build.0 = Debug|x64 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.Release|Win32.ActiveCfg = Release|Win32 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.Release|Win32.Build.0 = Release|Win32 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.Release|x64.ActiveCfg = Release|x64 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.Release|x64.Build.0 = Release|x64 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {45CA5427-4260-4F4A-86B0-FB7AE233D76B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.Debug|Win32.ActiveCfg = Debug|Win32 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.Debug|Win32.Build.0 = Debug|Win32 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.Debug|x64.ActiveCfg = Debug|x64 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.Debug|x64.Build.0 = Debug|x64 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.Release|Win32.ActiveCfg = Release|Win32 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.Release|Win32.Build.0 = Release|Win32 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.Release|x64.ActiveCfg = Release|x64 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.Release|x64.Build.0 = Release|x64 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {85121FD0-01A1-49BA-B168-CC8D90F91A6F}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {1708EFC1-414E-4712-80A5-813A6F38814C}.Debug|Win32.ActiveCfg = Debug|Win32 + {1708EFC1-414E-4712-80A5-813A6F38814C}.Debug|Win32.Build.0 = Debug|Win32 + {1708EFC1-414E-4712-80A5-813A6F38814C}.Debug|x64.ActiveCfg = Debug|x64 + {1708EFC1-414E-4712-80A5-813A6F38814C}.Debug|x64.Build.0 = Debug|x64 + {1708EFC1-414E-4712-80A5-813A6F38814C}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {1708EFC1-414E-4712-80A5-813A6F38814C}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {1708EFC1-414E-4712-80A5-813A6F38814C}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {1708EFC1-414E-4712-80A5-813A6F38814C}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {1708EFC1-414E-4712-80A5-813A6F38814C}.Release|Win32.ActiveCfg = Release|Win32 + {1708EFC1-414E-4712-80A5-813A6F38814C}.Release|Win32.Build.0 = Release|Win32 + {1708EFC1-414E-4712-80A5-813A6F38814C}.Release|x64.ActiveCfg = Release|x64 + {1708EFC1-414E-4712-80A5-813A6F38814C}.Release|x64.Build.0 = Release|x64 + {1708EFC1-414E-4712-80A5-813A6F38814C}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {1708EFC1-414E-4712-80A5-813A6F38814C}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {1708EFC1-414E-4712-80A5-813A6F38814C}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {1708EFC1-414E-4712-80A5-813A6F38814C}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.Debug|Win32.ActiveCfg = Debug|Win32 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.Debug|Win32.Build.0 = Debug|Win32 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.Debug|x64.ActiveCfg = Debug|x64 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.Debug|x64.Build.0 = Debug|x64 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.Release|Win32.ActiveCfg = Release|Win32 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.Release|Win32.Build.0 = Release|Win32 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.Release|x64.ActiveCfg = Release|x64 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.Release|x64.Build.0 = Release|x64 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {D291B6EF-986B-4222-ADA6-38A2EC2A56CE}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {AD231915-942F-4083-9671-85E26A5798B0}.Debug|Win32.ActiveCfg = Debug|Win32 + {AD231915-942F-4083-9671-85E26A5798B0}.Debug|Win32.Build.0 = Debug|Win32 + {AD231915-942F-4083-9671-85E26A5798B0}.Debug|x64.ActiveCfg = Debug|x64 + {AD231915-942F-4083-9671-85E26A5798B0}.Debug|x64.Build.0 = Debug|x64 + {AD231915-942F-4083-9671-85E26A5798B0}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {AD231915-942F-4083-9671-85E26A5798B0}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {AD231915-942F-4083-9671-85E26A5798B0}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {AD231915-942F-4083-9671-85E26A5798B0}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {AD231915-942F-4083-9671-85E26A5798B0}.Release|Win32.ActiveCfg = Release|Win32 + {AD231915-942F-4083-9671-85E26A5798B0}.Release|Win32.Build.0 = Release|Win32 + {AD231915-942F-4083-9671-85E26A5798B0}.Release|x64.ActiveCfg = Release|x64 + {AD231915-942F-4083-9671-85E26A5798B0}.Release|x64.Build.0 = Release|x64 + {AD231915-942F-4083-9671-85E26A5798B0}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {AD231915-942F-4083-9671-85E26A5798B0}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {AD231915-942F-4083-9671-85E26A5798B0}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {AD231915-942F-4083-9671-85E26A5798B0}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {E04D48BF-F529-4267-9311-908E94DF5A49}.Debug|Win32.ActiveCfg = Debug|Win32 + {E04D48BF-F529-4267-9311-908E94DF5A49}.Debug|Win32.Build.0 = Debug|Win32 + {E04D48BF-F529-4267-9311-908E94DF5A49}.Debug|x64.ActiveCfg = Debug|x64 + {E04D48BF-F529-4267-9311-908E94DF5A49}.Debug|x64.Build.0 = Debug|x64 + {E04D48BF-F529-4267-9311-908E94DF5A49}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {E04D48BF-F529-4267-9311-908E94DF5A49}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {E04D48BF-F529-4267-9311-908E94DF5A49}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {E04D48BF-F529-4267-9311-908E94DF5A49}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {E04D48BF-F529-4267-9311-908E94DF5A49}.Release|Win32.ActiveCfg = Release|Win32 + {E04D48BF-F529-4267-9311-908E94DF5A49}.Release|Win32.Build.0 = Release|Win32 + {E04D48BF-F529-4267-9311-908E94DF5A49}.Release|x64.ActiveCfg = Release|x64 + {E04D48BF-F529-4267-9311-908E94DF5A49}.Release|x64.Build.0 = Release|x64 + {E04D48BF-F529-4267-9311-908E94DF5A49}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {E04D48BF-F529-4267-9311-908E94DF5A49}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {E04D48BF-F529-4267-9311-908E94DF5A49}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {E04D48BF-F529-4267-9311-908E94DF5A49}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.Debug|Win32.ActiveCfg = Debug|Win32 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.Debug|Win32.Build.0 = Debug|Win32 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.Debug|x64.ActiveCfg = Debug|x64 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.Debug|x64.Build.0 = Debug|x64 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.Release|Win32.ActiveCfg = Release|Win32 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.Release|Win32.Build.0 = Release|Win32 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.Release|x64.ActiveCfg = Release|x64 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.Release|x64.Build.0 = Release|x64 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {6860BB9B-2053-46CD-9E2D-EEC199D68982}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.Debug|Win32.ActiveCfg = Debug|Win32 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.Debug|Win32.Build.0 = Debug|Win32 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.Debug|x64.ActiveCfg = Debug|x64 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.Debug|x64.Build.0 = Debug|x64 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.Release|Win32.ActiveCfg = Release|Win32 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.Release|Win32.Build.0 = Release|Win32 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.Release|x64.ActiveCfg = Release|x64 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.Release|x64.Build.0 = Release|x64 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {DBD630FC-0DA9-41EB-925D-70654D01F6FA}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.Debug|Win32.ActiveCfg = Debug|Win32 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.Debug|Win32.Build.0 = Debug|Win32 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.Debug|x64.ActiveCfg = Debug|x64 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.Debug|x64.Build.0 = Debug|x64 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.Release|Win32.ActiveCfg = Release|Win32 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.Release|Win32.Build.0 = Release|Win32 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.Release|x64.ActiveCfg = Release|x64 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.Release|x64.Build.0 = Release|x64 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {495BC686-DF50-4250-B469-9C6B7B33A4B8}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.Debug|Win32.ActiveCfg = Debug|Win32 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.Debug|Win32.Build.0 = Debug|Win32 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.Debug|x64.ActiveCfg = Debug|x64 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.Debug|x64.Build.0 = Debug|x64 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.Release|Win32.ActiveCfg = Release|Win32 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.Release|Win32.Build.0 = Release|Win32 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.Release|x64.ActiveCfg = Release|x64 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.Release|x64.Build.0 = Release|x64 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {E3073076-4837-4DDB-89E5-5AC297C7481D}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Debug|Win32.ActiveCfg = Debug|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Debug|Win32.Build.0 = Debug|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Debug|x64.ActiveCfg = Debug|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Debug|x64.Build.0 = Debug|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Release|Win32.ActiveCfg = Release|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Release|Win32.Build.0 = Release|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Release|x64.ActiveCfg = Release|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Release|x64.Build.0 = Release|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Debug|Win32.ActiveCfg = Debug|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Debug|Win32.Build.0 = Debug|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Debug|x64.ActiveCfg = Debug|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Debug|x64.Build.0 = Debug|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Release|Win32.ActiveCfg = Release|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Release|Win32.Build.0 = Release|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Release|x64.ActiveCfg = Release|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Release|x64.Build.0 = Release|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {F36F075A-880D-47BA-805F-C47850062121}.Debug|Win32.ActiveCfg = Debug|Win32 + {F36F075A-880D-47BA-805F-C47850062121}.Debug|Win32.Build.0 = Debug|Win32 + {F36F075A-880D-47BA-805F-C47850062121}.Debug|x64.ActiveCfg = Debug|x64 + {F36F075A-880D-47BA-805F-C47850062121}.Debug|x64.Build.0 = Debug|x64 + {F36F075A-880D-47BA-805F-C47850062121}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {F36F075A-880D-47BA-805F-C47850062121}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {F36F075A-880D-47BA-805F-C47850062121}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {F36F075A-880D-47BA-805F-C47850062121}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {F36F075A-880D-47BA-805F-C47850062121}.Release|Win32.ActiveCfg = Release|Win32 + {F36F075A-880D-47BA-805F-C47850062121}.Release|Win32.Build.0 = Release|Win32 + {F36F075A-880D-47BA-805F-C47850062121}.Release|x64.ActiveCfg = Release|x64 + {F36F075A-880D-47BA-805F-C47850062121}.Release|x64.Build.0 = Release|x64 + {F36F075A-880D-47BA-805F-C47850062121}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {F36F075A-880D-47BA-805F-C47850062121}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {F36F075A-880D-47BA-805F-C47850062121}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {F36F075A-880D-47BA-805F-C47850062121}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Debug|Win32.ActiveCfg = Debug|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Debug|Win32.Build.0 = Debug|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Debug|x64.ActiveCfg = Debug|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Debug|x64.Build.0 = Debug|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Release|Win32.ActiveCfg = Release|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Release|Win32.Build.0 = Release|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Release|x64.ActiveCfg = Release|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Release|x64.Build.0 = Release|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Debug|Win32.ActiveCfg = Debug|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Debug|Win32.Build.0 = Debug|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Debug|x64.ActiveCfg = Debug|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Debug|x64.Build.0 = Debug|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Release|Win32.ActiveCfg = Release|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Release|Win32.Build.0 = Release|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Release|x64.ActiveCfg = Release|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Release|x64.Build.0 = Release|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.Debug|Win32.ActiveCfg = Debug|Win32 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.Debug|Win32.Build.0 = Debug|Win32 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.Debug|x64.ActiveCfg = Debug|x64 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.Debug|x64.Build.0 = Debug|x64 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.Release|Win32.ActiveCfg = Release|Win32 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.Release|Win32.Build.0 = Release|Win32 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.Release|x64.ActiveCfg = Release|x64 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.Release|x64.Build.0 = Release|x64 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {729E4E11-3BBA-4306-B53C-8AEC45E70E10}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.Debug|Win32.ActiveCfg = Debug|Win32 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.Debug|Win32.Build.0 = Debug|Win32 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.Debug|x64.ActiveCfg = Debug|x64 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.Debug|x64.Build.0 = Debug|x64 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.Release|Win32.ActiveCfg = Release|Win32 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.Release|Win32.Build.0 = Release|Win32 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.Release|x64.ActiveCfg = Release|x64 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.Release|x64.Build.0 = Release|x64 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {3D77E4F8-02EE-491F-B01C-EE8012CABA18}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.Debug|Win32.ActiveCfg = Debug|Win32 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.Debug|Win32.Build.0 = Debug|Win32 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.Debug|x64.ActiveCfg = Debug|x64 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.Debug|x64.Build.0 = Debug|x64 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.Release|Win32.ActiveCfg = Release|Win32 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.Release|Win32.Build.0 = Release|Win32 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.Release|x64.ActiveCfg = Release|x64 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.Release|x64.Build.0 = Release|x64 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {2C117585-9BA4-4BFE-8335-E3E9D51D4DA7}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA}.Debug|Win32.ActiveCfg = Debug|Win32 + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA}.Debug|Win32.Build.0 = Debug|Win32 + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA}.Debug|x64.ActiveCfg = Debug|x64 + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA}.Release|Win32.ActiveCfg = Release|Win32 + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA}.Release|Win32.Build.0 = Release|Win32 + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA}.Release|x64.ActiveCfg = Release|x64 + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {6ABBF8BA-0A23-4C5C-8AEB-1B2577625DFA}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/msvc2005/exiv2.sln b/msvc2005/exiv2.sln index 27fd0073..cfba8f28 100644 --- a/msvc2005/exiv2.sln +++ b/msvc2005/exiv2.sln @@ -1,186 +1,271 @@ Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exiv2lib", "exiv2lib\exiv2lib.vcproj", "{831EF580-92C8-4CA8-B0CE-3D906280A54D}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libexiv2", "libexiv2\libexiv2.vcproj", "{831EF580-92C8-4CA8-B0CE-3D906280A54D}" ProjectSection(ProjectDependencies) = postProject - {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} - {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exiv2", "exiv2\exiv2.vcproj", "{07293CAC-00DA-493E-90C9-5D010C2B1B53}" ProjectSection(ProjectDependencies) = postProject + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmpsdk", "xmpsdk\xmpsdk.vcproj", "{09877CF4-83B6-44FE-A2E2-629AA5C8093E}" - ProjectSection(ProjectDependencies) = postProject - {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} - {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} - EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "expat", "expat\expat.vcproj", "{6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libexpat", "libexpat\libexpat.vcproj", "{6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib1", "zlib\zlib.vcproj", "{8308C68D-E12B-4C71-96F4-7137F6BEB654}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "addmoddel", "addmoddel\addmoddel.vcproj", "{83914D93-57B3-4718-8A50-662C17C4AE8F}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iptctest", "iptctest\iptctest.vcproj", "{AD41F87C-242B-4B61-B767-A9879F0D5C04}" ProjectSection(ProjectDependencies) = postProject {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "easyaccess-test", "easyaccess-test\easyaccess-test.vcproj", "{30E18D87-0147-4601-9ED2-4D5291645DB3}" ProjectSection(ProjectDependencies) = postProject + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "largeiptc-test", "largeiptc-test\largeiptc-test.vcproj", "{953404C9-B20A-4D17-8262-9D9AD1CDC5C1}" ProjectSection(ProjectDependencies) = postProject {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "convert-test", "convert-test\convert-test.vcproj", "{D802FE1E-7868-4034-92B8-00865E1CABAB}" ProjectSection(ProjectDependencies) = postProject + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iotest", "iotest\iotest.vcproj", "{21F0CEB1-D850-4C29-88BF-1CE4171824E6}" ProjectSection(ProjectDependencies) = postProject {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iptcprint", "iptcprint\iptcprint.vcproj", "{A7D22798-1262-4194-94A5-C636BCB68329}" ProjectSection(ProjectDependencies) = postProject {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "key-test", "key-test\key-test.vcproj", "{F11358FA-AA36-46E1-BA80-A17B8042BF9B}" ProjectSection(ProjectDependencies) = postProject {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mmap-test", "mmap-test\mmap-test.vcproj", "{556CB4FC-33BB-4E67-AB0E-1865E67176A5}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "prevtest", "prevtest\prevtest.vcproj", "{FC7120EC-BEB2-4CC3-9B90-B022F560E584}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stringto-test", "stringto-test\stringto-test.vcproj", "{9DCEE051-A07B-4C6B-B2BC-0814F0C323AA}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tiff-test", "tiff-test\tiff-test.vcproj", "{C34B11A1-B707-46B2-8053-2FA236B369CF}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "werror-test", "werror-test\werror-test.vcproj", "{430C4512-CC73-4943-8CDF-71DEA573BD47}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "write-test", "write-test\write-test.vcproj", "{98A9F59D-FDFE-4B27-88FE-2625F1E7597F}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "write2-test", "write2-test\write2-test.vcproj", "{E796088F-0EE6-4EC7-ABA0-8A18F54A4DD7}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exifdata-test", "exifdata-test\exifdata-test.vcproj", "{FEF9C19E-F774-4D8A-991C-A566C1B2E8B6}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exifprint", "exifprint\exifprint.vcproj", "{BFB98A96-7ABD-4F78-BA8B-2C2C257D74D8}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmpsample", "xmpsample\xmpsample.vcproj", "{45CA5427-4260-4F4A-86B0-FB7AE233D76B}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmpparser-test", "xmpparser-test\xmpparser-test.vcproj", "{85121FD0-01A1-49BA-B168-CC8D90F91A6F}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmpparse", "xmpparse\xmpparse.vcproj", "{1708EFC1-414E-4712-80A5-813A6F38814C}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exifcomment", "exifcomment\exifcomment.vcproj", "{D291B6EF-986B-4222-ADA6-38A2EC2A56CE}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "metacopy", "metacopy\metacopy.vcproj", "{AD231915-942F-4083-9671-85E26A5798B0}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "path-test", "path-test\path-test.vcproj", "{E04D48BF-F529-4267-9311-908E94DF5A49}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iptceasy", "iptceasy\iptceasy.vcproj", "{6860BB9B-2053-46CD-9E2D-EEC199D68982}" ProjectSection(ProjectDependencies) = postProject {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "taglist", "taglist\taglist.vcproj", "{DBD630FC-0DA9-41EB-925D-70654D01F6FA}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "utiltest", "utiltest\utiltest.vcproj", "{495BC686-DF50-4250-B469-9C6B7B33A4B8}" ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "geotag", "geotag\geotag.vcproj", "{E3073076-4837-4DDB-89E5-5AC297C7481D}" ProjectSection(ProjectDependencies) = postProject + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} - {07293CAC-00DA-493E-90C9-5D010C2B1B53} = {07293CAC-00DA-493E-90C9-5D010C2B1B53} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httptest", "httptest\httptest.vcproj", "{4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}" + ProjectSection(ProjectDependencies) = postProject + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exiv2json", "exiv2json\exiv2json.vcproj", "{4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "remotetest", "remotetest\remotetest.vcproj", "{B25A3F96-68E8-4FD4-860E-2C33E539B892}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} + {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "conntest", "conntest\conntest.vcproj", "{E015DB8C-C463-4A6B-88EA-AFC671D84B5B}" + ProjectSection(ProjectDependencies) = postProject + {8308C68D-E12B-4C71-96F4-7137F6BEB654} = {8308C68D-E12B-4C71-96F4-7137F6BEB654} + {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} = {6C4C06A3-6F8F-4067-AA4C-D5F41E1FFF9A} + {09877CF4-83B6-44FE-A2E2-629AA5C8093E} = {09877CF4-83B6-44FE-A2E2-629AA5C8093E} {831EF580-92C8-4CA8-B0CE-3D906280A54D} = {831EF580-92C8-4CA8-B0CE-3D906280A54D} EndProjectSection EndProject @@ -708,6 +793,70 @@ Global {E3073076-4837-4DDB-89E5-5AC297C7481D}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 {E3073076-4837-4DDB-89E5-5AC297C7481D}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 {E3073076-4837-4DDB-89E5-5AC297C7481D}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Debug|Win32.ActiveCfg = Debug|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Debug|Win32.Build.0 = Debug|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Debug|x64.ActiveCfg = Debug|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Debug|x64.Build.0 = Debug|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Release|Win32.ActiveCfg = Release|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Release|Win32.Build.0 = Release|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Release|x64.ActiveCfg = Release|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.Release|x64.Build.0 = Release|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {4AC6B957-1506-4EDB-BF6A-CF7CCE86EC1F}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Debug|Win32.ActiveCfg = Debug|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Debug|Win32.Build.0 = Debug|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Debug|x64.ActiveCfg = Debug|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Debug|x64.Build.0 = Debug|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Release|Win32.ActiveCfg = Release|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Release|Win32.Build.0 = Release|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Release|x64.ActiveCfg = Release|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.Release|x64.Build.0 = Release|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {4171BC51-2FDD-4BF5-BB80-1D9B2ACB03B9}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Debug|Win32.ActiveCfg = Debug|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Debug|Win32.Build.0 = Debug|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Debug|x64.ActiveCfg = Debug|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Debug|x64.Build.0 = Debug|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Release|Win32.ActiveCfg = Release|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Release|Win32.Build.0 = Release|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Release|x64.ActiveCfg = Release|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.Release|x64.Build.0 = Release|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {B25A3F96-68E8-4FD4-860E-2C33E539B892}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Debug|Win32.ActiveCfg = Debug|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Debug|Win32.Build.0 = Debug|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Debug|x64.ActiveCfg = Debug|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Debug|x64.Build.0 = Debug|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Release|Win32.ActiveCfg = Release|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Release|Win32.Build.0 = Release|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Release|x64.ActiveCfg = Release|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.Release|x64.Build.0 = Release|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {E015DB8C-C463-4A6B-88EA-AFC671D84B5B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/msvc2005/exiv2.vsprops b/msvc2005/exiv2.vsprops new file mode 100644 index 00000000..a7ad2eab --- /dev/null +++ b/msvc2005/exiv2.vsprops @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/msvc2005/exiv2/exiv2.vcproj b/msvc2005/exiv2/exiv2.vcproj index f4fa6243..be670acc 100644 --- a/msvc2005/exiv2/exiv2.vcproj +++ b/msvc2005/exiv2/exiv2.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/geotag/geotag.vcproj b/msvc2005/geotag/geotag.vcproj index 694dcace..c18ff731 100644 --- a/msvc2005/geotag/geotag.vcproj +++ b/msvc2005/geotag/geotag.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/iotest/iotest.vcproj b/msvc2005/iotest/iotest.vcproj index 17c670fb..0a8ab79d 100644 --- a/msvc2005/iotest/iotest.vcproj +++ b/msvc2005/iotest/iotest.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/iptceasy/iptceasy.vcproj b/msvc2005/iptceasy/iptceasy.vcproj index 4a123a38..99b35097 100644 --- a/msvc2005/iptceasy/iptceasy.vcproj +++ b/msvc2005/iptceasy/iptceasy.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/iptcprint/iptcprint.vcproj b/msvc2005/iptcprint/iptcprint.vcproj index 23eb12cb..4a846768 100644 --- a/msvc2005/iptcprint/iptcprint.vcproj +++ b/msvc2005/iptcprint/iptcprint.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/iptctest/iptctest.vcproj b/msvc2005/iptctest/iptctest.vcproj index 0f30f1ca..5b2d4676 100644 --- a/msvc2005/iptctest/iptctest.vcproj +++ b/msvc2005/iptctest/iptctest.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/key-test/key-test.vcproj b/msvc2005/key-test/key-test.vcproj index 8071f08f..7e91e6ef 100644 --- a/msvc2005/key-test/key-test.vcproj +++ b/msvc2005/key-test/key-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/largeiptc-test/largeiptc-test.vcproj b/msvc2005/largeiptc-test/largeiptc-test.vcproj index 9c05537f..beda93f4 100644 --- a/msvc2005/largeiptc-test/largeiptc-test.vcproj +++ b/msvc2005/largeiptc-test/largeiptc-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/metacopy/metacopy.vcproj b/msvc2005/metacopy/metacopy.vcproj index 5dcecdc5..95b68903 100644 --- a/msvc2005/metacopy/metacopy.vcproj +++ b/msvc2005/metacopy/metacopy.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/mmap-test/mmap-test.vcproj b/msvc2005/mmap-test/mmap-test.vcproj index 1afddcef..8895cba4 100644 --- a/msvc2005/mmap-test/mmap-test.vcproj +++ b/msvc2005/mmap-test/mmap-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/path-test/path-test.vcproj b/msvc2005/path-test/path-test.vcproj index bf00047f..77721fe3 100644 --- a/msvc2005/path-test/path-test.vcproj +++ b/msvc2005/path-test/path-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/prevtest/prevtest.vcproj b/msvc2005/prevtest/prevtest.vcproj index 65371694..cfc3b4b7 100644 --- a/msvc2005/prevtest/prevtest.vcproj +++ b/msvc2005/prevtest/prevtest.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/stringto-test/stringto-test.vcproj b/msvc2005/stringto-test/stringto-test.vcproj index 97a87154..b5218b14 100644 --- a/msvc2005/stringto-test/stringto-test.vcproj +++ b/msvc2005/stringto-test/stringto-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/taglist/taglist.vcproj b/msvc2005/taglist/taglist.vcproj index a5a235af..7ebdfb22 100644 --- a/msvc2005/taglist/taglist.vcproj +++ b/msvc2005/taglist/taglist.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/tiff-test/tiff-test.vcproj b/msvc2005/tiff-test/tiff-test.vcproj index 2a61ab9f..e9e603a0 100644 --- a/msvc2005/tiff-test/tiff-test.vcproj +++ b/msvc2005/tiff-test/tiff-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/tools/bin/sed.exe b/msvc2005/tools/bin/sed.exe new file mode 100755 index 00000000..0390cb85 Binary files /dev/null and b/msvc2005/tools/bin/sed.exe differ diff --git a/msvc2005/tools/depends/depends.vcproj b/msvc2005/tools/depends/depends.vcproj index d92f5c03..7afc763a 100644 --- a/msvc2005/tools/depends/depends.vcproj +++ b/msvc2005/tools/depends/depends.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/utiltest/utiltest.vcproj b/msvc2005/utiltest/utiltest.vcproj index f6b6d2c6..82576199 100644 --- a/msvc2005/utiltest/utiltest.vcproj +++ b/msvc2005/utiltest/utiltest.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/werror-test/werror-test.vcproj b/msvc2005/werror-test/werror-test.vcproj index a4a18583..2cac6e47 100644 --- a/msvc2005/werror-test/werror-test.vcproj +++ b/msvc2005/werror-test/werror-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/write-test/write-test.vcproj b/msvc2005/write-test/write-test.vcproj index 7a927163..6dfff346 100644 --- a/msvc2005/write-test/write-test.vcproj +++ b/msvc2005/write-test/write-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/write2-test/write2-test.vcproj b/msvc2005/write2-test/write2-test.vcproj index 28069a28..8c5f929d 100644 --- a/msvc2005/write2-test/write2-test.vcproj +++ b/msvc2005/write2-test/write2-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/xmpparse/xmpparse.vcproj b/msvc2005/xmpparse/xmpparse.vcproj index 512aecaf..c143c612 100644 --- a/msvc2005/xmpparse/xmpparse.vcproj +++ b/msvc2005/xmpparse/xmpparse.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/xmpparser-test/xmpparser-test.vcproj b/msvc2005/xmpparser-test/xmpparser-test.vcproj index d14b0c5c..d1af2df5 100644 --- a/msvc2005/xmpparser-test/xmpparser-test.vcproj +++ b/msvc2005/xmpparser-test/xmpparser-test.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/xmpsample/xmpsample.vcproj b/msvc2005/xmpsample/xmpsample.vcproj index f0ba0b3e..7b14313c 100644 --- a/msvc2005/xmpsample/xmpsample.vcproj +++ b/msvc2005/xmpsample/xmpsample.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/xmpsdk/xmpsdk.vcproj b/msvc2005/xmpsdk/xmpsdk.vcproj index 1ce3ce45..b142f590 100644 --- a/msvc2005/xmpsdk/xmpsdk.vcproj +++ b/msvc2005/xmpsdk/xmpsdk.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/msvc2005/zlib/zlib.vcproj b/msvc2005/zlib/zlib.vcproj index b84ea4dc..0a70d6df 100644 --- a/msvc2005/zlib/zlib.vcproj +++ b/msvc2005/zlib/zlib.vcproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/po/Makefile.in.in b/po/Makefile.in.in index 6c646a88..acefa5fe 100644 --- a/po/Makefile.in.in +++ b/po/Makefile.in.in @@ -286,8 +286,8 @@ info dvi ps pdf html tags TAGS ctags CTAGS ID: mostlyclean: rm -f remove-potcdate.sed - rm -f stamp-poT - rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po + rm -f stamp-poT stamp-po + rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po *.gmo rm -fr *.o clean: mostlyclean diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index c463f6a2..524f0713 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -26,6 +26,7 @@ SET( SAMPLES addmoddel.cpp exifcomment.cpp exifdata-test.cpp exifprint.cpp + exiv2json.cpp geotag.cpp iotest.cpp iptceasy.cpp diff --git a/samples/Makefile b/samples/Makefile index 0cc5b584..53c7c271 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -60,6 +60,8 @@ BINSRC = addmoddel.cpp \ exifcomment.cpp \ exifdata-test.cpp \ exifprint.cpp \ + exiv2json.cpp \ + httptest.cpp \ iotest.cpp \ iptceasy.cpp \ iptcprint.cpp \ @@ -112,6 +114,7 @@ endif PREFIX = /usr/local/lib LINK.cc += -rpath $(PREFIX) -L$(PREFIX) +COMPILE.cc += -I$(top_srcdir)/include/exiv2 # ****************************************************************************** # Rules @@ -158,7 +161,6 @@ metacopy path-test: %: %.cpp ../src/utils.o # Remove binaries, e.g., to relink them binclean: - cd ../bin $(RM) $(EXECUTABLE) mostlyclean: diff --git a/samples/conntest.cpp b/samples/conntest.cpp new file mode 100644 index 00000000..3a1282d7 --- /dev/null +++ b/samples/conntest.cpp @@ -0,0 +1,167 @@ +// ***************************************************************** -*- C++ -*- +// con-test.cpp +// Tester application for testing the http/https/ftp/ssh/sftp connection + +#include "config.h" + +#include "exiv2/futils.hpp" +#include "http.hpp" +#if EXV_USE_CURL == 1 +#include +#endif +#if EXV_USE_SSH == 1 +#include "ssh.hpp" +#endif + +#include +#include +using namespace std; + +void httpcon(const std::string& url, bool useHttp1_0 = false) { + Exiv2::dict_t response; + Exiv2::dict_t request; + string errors; + + Exiv2::Uri uri = Exiv2::Uri::Parse(url); + Exiv2::Uri::Decode(uri); + + request["server"] = uri.Host; + request["page"] = uri.Path; + request["port"] = uri.Port; + if (!useHttp1_0) request["version"] = "1.1"; + + int serverCode = Exiv2::http(request,response,errors); + if (serverCode < 0 || serverCode >= 400 || errors.compare("") != 0) { + throw Exiv2::Error(55, "Server", serverCode); + } +} + +#if EXV_USE_CURL == 1 +void curlcon(const std::string& url, bool useHttp1_0 = false) { + CURL* curl = curl_easy_init(); + if(!curl) { + throw Exiv2::Error(1, "Uable to init libcurl."); + } + + // get the timeout value + std::string timeoutStr = Exiv2::getEnv(Exiv2::envTIMEOUT); + long timeout = atol(timeoutStr.c_str()); + if (timeout == 0) { + throw Exiv2::Error(1, "Timeout Environmental Variable must be a positive integer."); + } + + string response; + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Exiv2::curlWriter); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout); + //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); // debug + if (useHttp1_0) curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + else curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); + + /* Perform the request, res will get the return code */ + CURLcode res = curl_easy_perform(curl); + if(res != CURLE_OK) { // error happends + throw Exiv2::Error(1, curl_easy_strerror(res)); + } + + // get return code + long returnCode; + curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &returnCode); // get code + curl_easy_cleanup(curl); + + if (returnCode >= 400 || returnCode < 0) { + throw Exiv2::Error(55, "Server", returnCode); + } +} +#endif + +#if EXV_USE_SSH == 1 +void sshcon(const std::string& url) { + Exiv2::Uri uri = Exiv2::Uri::Parse(url); + Exiv2::Uri::Decode(uri); + + string page = uri.Path; + // remove / at the beginning of the path + if (page[0] == '/') { + page = page.substr(1); + } + Exiv2::SSH ssh(uri.Host, uri.Username, uri.Password, uri.Port); + string response = ""; + string cmd = "declare -a x=($(ls -alt " + page + ")); echo ${x[4]}"; + if (ssh.runCommand(cmd, &response) != 0) { + throw Exiv2::Error(1, "Unable to get file length."); + } else { + long length = atol(response.c_str()); + if (length == 0) { + throw Exiv2::Error(1, "File is empty or not found."); + } + } +} + +void sftpcon(const std::string& url) { + Exiv2::Uri uri = Exiv2::Uri::Parse(url); + Exiv2::Uri::Decode(uri); + + string page = uri.Path; + // remove / at the beginning of the path + if (page[0] == '/') { + page = page.substr(1); + } + Exiv2::SSH ssh(uri.Host, uri.Username, uri.Password, uri.Port); + sftp_file handle; + ssh.getFileSftp(page, handle); + if (handle == NULL) throw Exiv2::Error(1, "Unable to open the file"); + else sftp_close(handle); +} +#endif + +int main(int argc,const char** argv) +{ + if (argc < 2) { + cout << "Usage: " << argv[0] << " url {-http1_0}\n"; + return 1; + } + std::string url(argv[1]); + Exiv2::Protocol prot = Exiv2::fileProtocol(url); + + bool useHttp1_0 = false; + for ( int a = 1 ; a < argc ; a++ ) { + std::string arg(argv[a]); + if (arg == "-http1_0") useHttp1_0 = true; + } + + bool isOk = false; + try { + #if EXV_USE_SSH == 1 + if (prot == Exiv2::pSsh) { + sshcon(url); + isOk = true; + } else if (prot == Exiv2::pSftp){ + sftpcon(url); + isOk = true; + } + #endif + #if EXV_USE_CURL == 1 + if (prot == Exiv2::pHttp || prot == Exiv2::pHttps || prot == Exiv2::pFtp) { + curlcon(url, useHttp1_0); + isOk = true; + } + #endif + if (!isOk && prot == Exiv2::pHttp) { + httpcon(url, useHttp1_0); + isOk = true; + } + } catch (Exiv2::AnyError& e) { + std::cout << "Error: '" << e << "'\n"; + return -1; + } + + if (!isOk) cout << "The protocol is unsupported.\n"; + else cout << "OK.\n"; + return 0; +} + +// That's all Folks! diff --git a/samples/exiv2json.cpp b/samples/exiv2json.cpp new file mode 100644 index 00000000..6d6991e5 --- /dev/null +++ b/samples/exiv2json.cpp @@ -0,0 +1,246 @@ +// ***************************************************************** -*- C++ -*- +// exif2json.cpp, $Id: exif2json.cpp 518 2013-05-10 23:53:00Z robinwmills@gmail.com $ +// Sample program to print the Exif metadata in JSON format + +#include +#include + +#include +#include +#include +#include + +#if defined(__MINGW32__) || defined(__MINGW64__) +# ifndef __MINGW__ +# define __MINGW__ +# endif +#endif + +#include +#include +#include +#include + +#if defined(_MSC_VER) || defined(__MINGW__) +#include +#ifndef PATH_MAX +# define PATH_MAX 512 +#endif +const char* realpath(const char* file,char* path) +{ + GetFullPathName(file,PATH_MAX,path,NULL); + return path; +} +#else +#include +#endif + +using namespace std; +using namespace Jzon; +using namespace Exiv2; + +// http://stackoverflow.com/questions/236129/splitting-a-string-in-c +static size_t split(const std::string& s, char delim, std::vector& elems) +{ + std::stringstream ss(s); + std::string item; + while (std::getline(ss, item, delim)) { + elems.push_back(item); + } + return elems.size(); +} + +Jzon::Object& objectForKey(std::string Key,std::string& name,Jzon::Object& root) +{ + static Jzon::Object object; + + std::vector keys ; + size_t l = split(Key,'.',keys); + if ( l < 3 || l > 7 ) return object; // maybe we should throw + + name = keys[l-1]; + size_t k = 0; + Jzon::Object& r1 = root; + + // this is horrible References are pointers that don't work properly! + if ( !r1.Has(keys[k]) ) r1.Add(keys[k],object); + Jzon::Object& r2 = (Jzon::Object&) r1.Get(keys[k]); + if ( l == 2 ) return r2; + + if ( !r2.Has(keys[++k])) r2.Add(keys[k],object); + Jzon::Object& r3 = (Jzon::Object&) r2.Get(keys[k]); + if ( l == 3 ) return r3; + + if ( !r3.Has(keys[++k])) r3.Add(keys[k],object); + Jzon::Object& r4 = (Jzon::Object&) r3.Get(keys[k]); + if ( l == 4 ) return r4; + + if ( !r4.Has(keys[++k])) r4.Add(keys[k],object); + Jzon::Object& r5 = (Jzon::Object&) r4.Get(keys[k]); + if ( l == 5 ) return r5; + + if ( !r5.Has(keys[++k])) r5.Add(keys[k],object); + Jzon::Object& r6 = (Jzon::Object&) r5.Get(keys[k]); + if ( l == 6 ) return r6; + + if ( !r6.Has(keys[++k])) r6.Add(keys[k],object); + Jzon::Object& r7 = (Jzon::Object&) r6.Get(keys[k]); + if ( l == 7 ) return r7; + + return object; +} + +// ExifData::const_iterator i +template +void push(Jzon::Object& json,const std::string& key,T i) +{ + std::string value = i->value().toString(); + + switch ( i->typeId() ) { + case Exiv2::xmpText: + case Exiv2::asciiString : + case Exiv2::string: + case Exiv2::comment: + json.Add(key,value); + break; + + case Exiv2::unsignedByte: + case Exiv2::unsignedShort: + case Exiv2::unsignedLong: + case Exiv2::signedByte: + case Exiv2::signedShort: + case Exiv2::signedLong: + json.Add(key,(int)i->value().toLong()); + break; + + case Exiv2::tiffFloat: + case Exiv2::tiffDouble: + json.Add(key,i->value().toFloat()); + break; + + case Exiv2::unsignedRational: + case Exiv2::signedRational: { + Jzon::Array arr; + Rational rat = i->value().toRational(); + arr.Add (rat.first ); + arr.Add (rat.second); + json.Add(key,arr); + } break; + + case Exiv2::date: + case Exiv2::time: + json.Add(key,i->value().toString()); + break; + + default: + case Exiv2::undefined: + case Exiv2::tiffIfd: + case Exiv2::directory: + case Exiv2::xmpAlt: + case Exiv2::xmpBag: + case Exiv2::xmpSeq: + case Exiv2::langAlt: + // http://dev.exiv2.org/boards/3/topics/1367#message-1373 + if ( key == "UserComment" ) { + size_t pos = value.find('\0') ; + if ( pos != string::npos ) + value = value.substr(0,pos); + } + + if ( key != "MakerNote") json.Add(key,value); + break; + } +} + +void fileSystemPush(const char* path,Jzon::Node& nfs) +{ + Jzon::Object& fs = (Jzon::Object&) nfs; + fs.Add("path",path); + char resolved_path[PATH_MAX]; + fs.Add("realpath",realpath(path,resolved_path)); + + struct stat buf; + memset(&buf,0,sizeof(buf)); + stat(path,&buf); + + fs.Add("st_dev" ,(int) buf.st_dev ); /* ID of device containing file */ + fs.Add("st_ino" ,(int) buf.st_ino ); /* inode number */ + fs.Add("st_mode" ,(int) buf.st_mode ); /* protection */ + fs.Add("st_nlink" ,(int) buf.st_nlink ); /* number of hard links */ + fs.Add("st_uid" ,(int) buf.st_uid ); /* user ID of owner */ + fs.Add("st_gid" ,(int) buf.st_gid ); /* group ID of owner */ + fs.Add("st_rdev" ,(int) buf.st_rdev ); /* device ID (if special file) */ + fs.Add("st_size" ,(int) buf.st_size ); /* total size, in bytes */ + fs.Add("st_atime" ,(int) buf.st_atime ); /* time of last access */ + fs.Add("st_mtime" ,(int) buf.st_mtime ); /* time of last modification */ + fs.Add("st_ctime" ,(int) buf.st_ctime ); /* time of last status change */ + +#if defined(_MSC_VER) || defined(__MINGW__) + size_t blksize = 1024; + size_t blocks = (buf.st_size+blksize-1)/blksize; +#else + size_t blksize = buf.st_blksize; + size_t blocks = buf.st_blocks ; +#endif + fs.Add("st_blksize",(int) blksize ); /* blocksize for file system I/O */ + fs.Add("st_blocks" ,(int) blocks ); /* number of 512B blocks allocated */ +} + +int main(int argc, char* const argv[]) +try { + + if (argc != 2) { + std::cout << "Usage: " << argv[0] << " file\n"; + return 1; + } + + const char* path=argv[1]; + + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path); + assert(image.get() != 0); + image->readMetadata(); + + Jzon::Object root; + + const char* FS="FS"; + Jzon::Object fs ; + root.Add (FS,fs) ; + fileSystemPush(path,root.Get(FS)); + + Exiv2::ExifData &exifData = image->exifData(); + for ( ExifData::const_iterator i = exifData.begin(); i != exifData.end() ; ++i ) { + std::string key ; + push(objectForKey(i->key(),key,root),key,i); + } + + Exiv2::IptcData &iptcData = image->iptcData(); + for (Exiv2::IptcData::const_iterator i = iptcData.begin(); i != iptcData.end(); ++i) { + std::string key ; + push(objectForKey(i->key(),key,root),key,i); + } + + Exiv2::XmpData &xmpData = image->xmpData(); + for (Exiv2::XmpData::const_iterator i = xmpData.begin(); i != xmpData.end(); ++i) { + std::string key ; + push(objectForKey(i->key(),key,root),key,i); + } +/* + This is only for testing long paths + { + ExifData::const_iterator i = exifData.begin(); + std::string key; + push(objectForKey("This.Is.A.Rather.Long.Path.Key",key,root),key,i); + } +*/ + Jzon::Writer writer(root,Jzon::StandardFormat); + writer.Write(); + std::cout << writer.GetResult() << std::endl; + return 0; +} + +//catch (std::exception& e) { +//catch (Exiv2::AnyError& e) { +catch (Exiv2::Error& e) { + std::cout << "Caught Exiv2 exception '" << e.what() << "'\n"; + return -1; +} diff --git a/samples/geotag.cpp b/samples/geotag.cpp index c60286d6..0d50347d 100644 --- a/samples/geotag.cpp +++ b/samples/geotag.cpp @@ -1,7 +1,6 @@ // ***************************************************************** -*- C++ -*- - // geotag.cpp, $Rev: 2286 $ -// Sample program to read gpx files and update the images with GPS tags +// Sample program to read gpx files and update images with GPS tags #include @@ -28,14 +27,6 @@ # endif #endif -#ifdef __MINGW__ -// rmills: dummy off for MinGW. I don't have time to fix this for 0.24 -int main(int,const char**) -{ - return 0; -} -#else - using namespace std; #ifndef lengthof @@ -44,11 +35,8 @@ using namespace std; #ifndef nil #define nil NULL #endif -#ifndef _MAX_PATH -#define _MAX_PATH 1024 -#endif -#ifdef _MSC_VER +#if defined(_MSC_VER) || defined(__MINGW__) #include char* realpath(const char* file,char* path); #define lstat _stat @@ -57,14 +45,19 @@ char* realpath(const char* file,char* path); #define strcpy_s(d,l,s) strcpy(d,s) #define strcat_s(d,l,s) strcat(d,s) #endif +#endif -#else +#if ! defined(_MSC_VER) #include #include #include #define stricmp strcasecmp #endif +#ifndef _MAX_PATH +#define _MAX_PATH 1024 +#endif + // prototypes class Options; int getFileType(const char* path ,Options& options); @@ -75,12 +68,13 @@ time_t parseTime(const char* ,bool bAdjust=false); int timeZoneAdjust(); // platform specific code -#ifdef _MSC_VER +#if defined(_MSC_VER) || defined(__MINGW__) char* realpath(const char* file,char* path) { char* result = (char*) malloc(_MAX_PATH); if (result) GetFullPathName(file,_MAX_PATH,result,NULL); return result ; + UNUSED(path); } #endif @@ -419,10 +413,11 @@ int timeZoneAdjust() time_t now = time(NULL); int offset; -#if defined(_MSC_VER) +#if defined(_MSC_VER) || defined(__MINGW__) TIME_ZONE_INFORMATION TimeZoneInfo; GetTimeZoneInformation( &TimeZoneInfo ); offset = - (((int)TimeZoneInfo.Bias + (int)TimeZoneInfo.DaylightBias) * 60); + UNUSED(now); #elif defined(__CYGWIN__) struct tm lcopy = *localtime(&now); time_t gmt = timegm(&lcopy) ; // timegm modifies lcopy @@ -958,4 +953,6 @@ int main(int argc,const char* argv[]) return result ; } -#endif + +// That's all Folks! +//// diff --git a/samples/httptest.cpp b/samples/httptest.cpp new file mode 100644 index 00000000..deae7d51 --- /dev/null +++ b/samples/httptest.cpp @@ -0,0 +1,99 @@ +// ***************************************************************** -*- C++ -*- +/* + httptest.cpp + This application is to test http.cpp. It provides the function to GET|HEAD|PUT the file via http protocol. + */ + +#include "http.hpp" +#include +#include +using namespace std; + +static int testSyntax(const char* arg) +{ + if ( !arg ) { + cout << "insufficient input" << endl; + exit(0); + } + return 0; +} + +int main(int argc,const char** argv) +{ + if ( argc < 2 ) { + cout << "usage : " << argv[0] << " [key value]+" << endl; + cout << "example: " << argv[0] << " [[-url] url | -server clanmills.com -page /LargsPanorama.jpg] -header \"Range: bytes=0-200\"" << endl; + cout << "or : " << argv[0] << " http://clanmills.com/LargsPanorama.jpg" << endl; + cout << "useful keys: -verb {GET|HEAD|PUT} -page str -server str -port number -version [-header something]+ " << endl; + cout << "default keys: -verb GET -server clanmills.com -page robin.shtml -port 80 -version 1.0" << endl; + cout << "export http_proxy=url eg export http_proxy=http://64.62.247.244:80" << endl; + return 0; + } + + Exiv2::dict_t response; + Exiv2::dict_t request; + string errors; + + // convert the command-line arguments into the request dictionary + for ( int i = 1 ; i < argc ; i +=2 ) { + const char* arg = argv[i]; + // skip past the -'s on the key + while ( arg[0] == '-' ) arg++; + + if ( string(arg) == "header" ) { + testSyntax(argv[i+1]); + string header = argv[i+1]; + if ( ! strchr(argv[i+1],'\n') ) { + header += "\r\n"; + } + request[arg] += header; + } else if ( string(arg) == "uri" || string(arg) == "url" ) { + testSyntax(argv[i+1]); + Exiv2::Uri uri = Exiv2::Uri::Parse(argv[i+1]); + if ( uri.Protocol == "http" ) { + request["server"] = uri.Host; + request["page"] = uri.Path; + request["port"] = uri.Port; + } + } else if ( string(arg).substr(0,7) == "http://" ) { + Exiv2::Uri uri = Exiv2::Uri::Parse(argv[i--]); + if ( uri.Protocol == "http" ) { + request["server"] = uri.Host; + request["page"] = uri.Path; + request["port"] = uri.Port; + } + } else { + testSyntax(argv[i+1]); + request[arg]=argv[i+1]; + } + } + if ( !request.count("page" ) ) request["page" ] = "robin.shtml"; + if ( !request.count("server") ) request["server"] = "clanmills.com"; + + int result = Exiv2::http(request,response,errors); + cout << "result = " << result << endl; + cout << "errors = " << errors << endl; + cout << endl; + + for ( Exiv2::dict_i it = response.begin() ; it != response.end() ; it++ ) { + // don't show request header + if (it->first == "requestheaders") continue; + + cout << it->first << " -> "; + + if ( it->first == "body") { + string& value = it->second; + cout << "# " << value.length(); + if ( value.length() < 1000 ) cout << " = " << value ; + } else { + cout << it->second; + } + + cout << endl; + } + + return 0; +} + +// That's all Folks! +//// diff --git a/samples/remotetest.cpp b/samples/remotetest.cpp new file mode 100644 index 00000000..d3ee44b1 --- /dev/null +++ b/samples/remotetest.cpp @@ -0,0 +1,104 @@ +// ***************************************************************** -*- C++ -*- +// remotetest.cpp +// Tester application for testing remote i/o. +// It makes some modifications on the metadata of remote file, reads new metadata from that file +// and reset the metadata back to the original status. + +#include +#include +#include +#include + +int main(int argc, char* const argv[]) +try { + if (argc < 2) { + std::cout << "Usage: " << argv[0] << " file {--nocurl | --curl}\n\n"; + return 1; + } + + bool useCurlFromExiv2TestApps = true; + for ( int a = 1 ; a < argc ; a++ ) { + std::string arg(argv[a]); + if (arg == "--nocurl") useCurlFromExiv2TestApps = false; + else if (arg == "--curl") useCurlFromExiv2TestApps = true; + } + + std::string file(argv[1]); + + // set/add metadata + std::cout << "Modify the metadata ...\n"; + Exiv2::ExifData exifData; + exifData["Exif.Photo.UserComment"] = "Hello World"; // AsciiValue + exifData["Exif.Image.Software"] = "Exiv2"; // AsciiValue + exifData["Exif.Image.Copyright"] = "Exiv2"; // AsciiValue + exifData["Exif.Image.Make"] = "Canon"; // AsciiValue + exifData["Exif.Canon.OwnerName"] = "Tuan"; // UShortValue + exifData["Exif.CanonCs.LensType"] = uint16_t(65535); // LongValue + Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::asciiString); + v->read("2013:06:09 14:30:30"); + Exiv2::ExifKey key("Exif.Image.DateTime"); + exifData.add(key, v.get()); + + Exiv2::Image::AutoPtr writeTest = Exiv2::ImageFactory::open(file, useCurlFromExiv2TestApps); + assert(writeTest.get() != 0); + writeTest->setExifData(exifData); + writeTest->writeMetadata(); + + // read the result to make sure everything fine + std::cout << "Print out the new metadata ...\n"; + Exiv2::Image::AutoPtr readTest = Exiv2::ImageFactory::open(file, useCurlFromExiv2TestApps); + assert(readTest.get() != 0); + readTest->readMetadata(); + Exiv2::ExifData &exifReadData = readTest->exifData(); + if (exifReadData.empty()) { + std::string error(argv[1]); + error += ": No Exif data found in the file"; + throw Exiv2::Error(1, error); + } + Exiv2::ExifData::const_iterator end = exifReadData.end(); + for (Exiv2::ExifData::const_iterator i = exifReadData.begin(); i != end; ++i) { + const char* tn = i->typeName(); + std::cout << std::setw(44) << std::setfill(' ') << std::left + << i->key() << " " + << "0x" << std::setw(4) << std::setfill('0') << std::right + << std::hex << i->tag() << " " + << std::setw(9) << std::setfill(' ') << std::left + << (tn ? tn : "Unknown") << " " + << std::dec << std::setw(3) + << std::setfill(' ') << std::right + << i->count() << " " + << std::dec << i->value() + << "\n"; + } + + + // del, reset the metadata + std::cout << "Reset ...\n"; + exifReadData["Exif.Photo.UserComment"] = "Have a nice day"; // AsciiValue + exifReadData["Exif.Image.Software"] = "Exiv2.org"; // AsciiValue + exifReadData["Exif.Image.Copyright"] = "Exiv2.org"; // AsciiValue + key = Exiv2::ExifKey("Exif.Image.Make"); + Exiv2::ExifData::iterator pos = exifReadData.findKey(key); + if (pos == exifReadData.end()) throw Exiv2::Error(1, "Exif.Image.Make not found"); + exifReadData.erase(pos); + key = Exiv2::ExifKey("Exif.Image.DateTime"); + pos = exifReadData.findKey(key); + if (pos == exifReadData.end()) throw Exiv2::Error(1, "Exif.Image.DateTime not found"); + exifReadData.erase(pos); + key = Exiv2::ExifKey("Exif.Canon.OwnerName"); + pos = exifReadData.findKey(key); + if (pos == exifReadData.end()) throw Exiv2::Error(1, "Exif.Canon.OwnerName not found"); + exifReadData.erase(pos); + key = Exiv2::ExifKey("Exif.CanonCs.LensType"); + pos = exifReadData.findKey(key); + if (pos == exifReadData.end()) throw Exiv2::Error(1, "Exif.CanonCs.LensType not found"); + exifReadData.erase(pos); + readTest->setExifData(exifReadData); + readTest->writeMetadata(); + + return 0; +} +catch (Exiv2::AnyError& e) { + std::cout << "Caught Exiv2 exception '" << e << "'\n"; + return -1; +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index de85e0e8..6c4fd036 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,46 +37,49 @@ SET( LIBEXIV2_PRIVATE_HDR canonmn_int.hpp ) # Add standalone C++ header files to this list -SET( LIBEXIV2_HDR asfvideo.hpp - basicio.hpp - bmpimage.hpp - convert.hpp - cr2image.hpp - crwimage.hpp - datasets.hpp - easyaccess.hpp - epsimage.hpp - error.hpp - exif.hpp - exiv2.hpp - futils.hpp - gifimage.hpp - image.hpp - iptc.hpp - jp2image.hpp - jpgimage.hpp - matroskavideo.hpp - metadatum.hpp - mrwimage.hpp - orfimage.hpp - pgfimage.hpp - preview.hpp - properties.hpp - psdimage.hpp - quicktimevideo.hpp - rafimage.hpp - riffvideo.hpp - rw2image.hpp - tags.hpp - tgaimage.hpp - tiffimage.hpp - types.hpp - utilsvideo.hpp - value.hpp - version.hpp - xmp.hpp - xmpsidecar.hpp - utilsvideo.hpp +SET( LIBEXIV2_HDR ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/asfvideo.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/basicio.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/bmpimage.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/config.h + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/convert.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/cr2image.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/crwimage.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/datasets.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/easyaccess.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/epsimage.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/error.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/exif.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/exiv2.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/futils.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/gifimage.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/http.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/image.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/iptc.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/jp2image.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/jpgimage.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/Jzon.h + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/matroskavideo.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/metadatum.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/mrwimage.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/orfimage.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/pgfimage.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/preview.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/properties.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/psdimage.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/quicktimevideo.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/rafimage.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/riffvideo.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/rw2image.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/tags.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/tgaimage.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/tiffimage.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/types.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/utilsvideo.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/value.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/version.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/xmp.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/xmpsidecar.hpp + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/utilsvideo.hpp ) # Add library C++ source files to this list @@ -97,10 +100,12 @@ SET( LIBEXIV2_SRC asfvideo.cpp futils.cpp fujimn.cpp gifimage.cpp + http.cpp image.cpp iptc.cpp jp2image.cpp jpgimage.cpp + Jzon.cpp makernote.cpp matroskavideo.cpp metadatum.cpp @@ -136,6 +141,32 @@ SET( LIBEXIV2_SRC asfvideo.cpp utilsvideo.cpp ) +## +# add curl support +IF( EXIV2_ENABLE_CURL ) + IF( CURL_FOUND ) + SET( LIBEXIV2_SRC ${LIBEXIV2_SRC} + easyaccess.cpp + ) + set( LIBEXIV2_HDR ${LIBEXIV2_HDR} + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/easyaccess.hpp + ) + ENDIF() +ENDIF() + +## +# add ssh support +IF( EXIV2_ENABLE_SSH ) + IF( SSH_FOUND ) + SET( LIBEXIV2_SRC ${LIBEXIV2_SRC} + ssh.cpp + ) + set( LIBEXIV2_HDR ${LIBEXIV2_HDR} + ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/ssh.hpp + ) + ENDIF() +ENDIF() + ## # add png*.cpp files if PNG support requested IF( EXIV2_ENABLE_PNG ) @@ -144,22 +175,17 @@ IF( EXIV2_ENABLE_PNG ) pngchunk.cpp pngimage.cpp ) - set( LIBEXIV2_HDR ${LIBEXIV2_HDR} pngimage.hpp ) + set( LIBEXIV2_HDR ${LIBEXIV2_HDR} ${CMAKE_CURRENT_LIST_DIR}/../include/exiv2/pngimage.hpp ) ENDIF( ZLIB_FOUND ) ENDIF( EXIV2_ENABLE_PNG ) -CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/svn_version.h.in - ${CMAKE_CURRENT_SOURCE_DIR}/svn_version.h @ONLY) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) IF( MSVC ) # to support the old VS solution builds ADD_DEFINITIONS("-DCMAKE_BUILD_SVN") ENDIF() -SET( LIBEXIV2_HDR ${LIBEXIV2_HDR} - svn_version.h -) +SET( LIBEXIV2_HDR ${LIBEXIV2_HDR} ) ## # add xmp source if xmp is requested and xmp library not built @@ -177,6 +203,13 @@ SET( EXIV2_SRC exiv2.cpp utils.cpp ) +# connection test application +SET( CONNTEST ../samples/conntest.cpp) +# exifprint application +SET( EXIFPRINT ../samples/exifprint.cpp) +# cmdfiletest application +SET( REMOTETEST ../samples/remotetest.cpp) + ## # modify source lists to suit environment IF(NOT HAVE_TIMEGM ) @@ -212,17 +245,27 @@ SET_TARGET_PROPERTIES( exiv2lib PROPERTIES if ( MSVC ) source_group("Header Files" FILES ${LIBEXIV2_HDR} ) TARGET_LINK_LIBRARIES( exiv2lib ${EXPAT_LIBRARIES} ) + source_group("Header Files" FILES ${LIBCURL_HDR} ) + TARGET_LINK_LIBRARIES( exiv2lib ${CURL_LIBRARIES} ) + source_group("Header Files" FILES ${SSH_HDR} ) + TARGET_LINK_LIBRARIES( exiv2lib ${SSH_LIBRARIES} ) else() if ( NOT MINGW ) TARGET_LINK_LIBRARIES( exiv2lib dl ${EXPAT_LIBRARIES} ) + TARGET_LINK_LIBRARIES( exiv2lib dl ${CURL_LIBRARIES} ) + TARGET_LINK_LIBRARIES( exiv2lib dl ${SSH_LIBRARIES} ) else() TARGET_LINK_LIBRARIES( exiv2lib ${EXPAT_LIBRARIES} ) + TARGET_LINK_LIBRARIES( exiv2lib ${CURL_LIBRARIES} ) + TARGET_LINK_LIBRARIES( exiv2lib ${SSH_LIBRARIES} ) endif() endif() if( EXIV2_ENABLE_LIBXMP ) ADD_DEPENDENCIES( exiv2lib xmp ) - LINK_DIRECTORIES(${LIBRARY_OUTPUT_PATH}/$(ConfigurationName)) + if ( MSVC ) + LINK_DIRECTORIES(${LIBRARY_OUTPUT_PATH}/$(ConfigurationName)) + endif(MSVC) TARGET_LINK_LIBRARIES( exiv2lib xmp ) ENDIF() @@ -254,22 +297,30 @@ ENDIF(CYGWIN OR MINGW) ## -# copy header files (TODO: rewrite for NMake) -IF (MSVC ) - if (OUT_OF_SOURCE) - ADD_CUSTOM_COMMAND( - TARGET exiv2lib - PRE_BUILD - COMMAND set S=$(SolutionDir)..\\src\nset I=$(SolutionDir)include\nset E=%I%\\exiv2\nif NOT exist %I% mkdir %I%\nif NOT exist %E% mkdir %E%\ncopy /y %S%\\*.h %E%\ncopy /y %S%\\*.hpp %E% - ) - else() - ADD_CUSTOM_COMMAND( - TARGET exiv2lib - PRE_BUILD - COMMAND set S=$(SolutionDir)src\nset I=$(SolutionDir)include\nset E=%I%\\exiv2\nif NOT exist %I% mkdir %I%\nif NOT exist %E% mkdir %E%\ncopy /y %S%\\*.h %E%\ncopy /y %S%\\*.hpp %E% - ) - endif() +# copy curl dlls to output directory (TODO: rewrite for NMake) +IF ( MSVC AND EXIV2_ENABLE_CURL ) + get_filename_component(CURL_LIBRARY_DIR ${CURL_LIBRARY} PATH) + string(REGEX REPLACE "/" "\\\\" CURL_LIBRARY_DIR ${CURL_LIBRARY_DIR}) + ADD_CUSTOM_COMMAND( + TARGET exiv2lib + POST_BUILD + COMMAND copy /y ${CURL_LIBRARY_DIR}\\*.dll $(SolutionDir)\\bin\\${P_DIR}\\${T_DIR}\\$(ConfigurationName) + ) ENDIF() +INSTALL( TARGETS exiv2lib ${INSTALL_TARGET_STANDARD_ARGS} ) + +## +# copy libssh dlls to output directory (TODO: rewrite for NMake) +IF ( MSVC AND EXIV2_ENABLE_SSH ) + get_filename_component(SSH_LIBRARY_DIR ${SSH_LIBRARY} PATH) + string(REGEX REPLACE "/" "\\\\" SSH_LIBRARY_DIR ${SSH_LIBRARY_DIR}) + ADD_CUSTOM_COMMAND( + TARGET exiv2lib + POST_BUILD + COMMAND copy /y ${SSH_LIBRARY_DIR}\\*.dll $(SolutionDir)\\bin\\${P_DIR}\\${T_DIR}\\$(ConfigurationName) + ) +ENDIF() +INSTALL( TARGETS exiv2lib ${INSTALL_TARGET_STANDARD_ARGS} ) ## # copy zlib and expat dlls to output directory (TODO: rewrite for NMake) @@ -297,6 +348,21 @@ ADD_EXECUTABLE( exiv2 ${EXIV2_SRC} ) TARGET_LINK_LIBRARIES( exiv2 exiv2lib ) INSTALL( TARGETS exiv2 ${INSTALL_TARGET_STANDARD_ARGS} ) +# ****************************************************************************** +# connection test application +ADD_EXECUTABLE( conntest ${CONNTEST} ) +TARGET_LINK_LIBRARIES( conntest exiv2lib ) + +# ****************************************************************************** +# exifprint application +# ADD_EXECUTABLE( exifprint ${EXIFPRINT} ) +# TARGET_LINK_LIBRARIES( exifprint exiv2lib ) + +# ****************************************************************************** +# remotetest application +ADD_EXECUTABLE( remotetest ${REMOTETEST} ) +TARGET_LINK_LIBRARIES( remotetest exiv2lib ) + # ****************************************************************************** # Headers INSTALL( FILES ${LIBEXIV2_HDR} DESTINATION include/exiv2 ) diff --git a/src/Jzon.cpp b/src/Jzon.cpp new file mode 100644 index 00000000..50729e09 --- /dev/null +++ b/src/Jzon.cpp @@ -0,0 +1,1301 @@ +/* +Copyright (c) 2013 Johannes Häggqvist + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifdef _WINDLL +#define JzonAPI __declspec(dllexport) +#endif + +#include "Jzon.h" + +#include +#include +#include +#include + +namespace Jzon +{ + class FormatInterpreter + { + public: + FormatInterpreter() + { + SetFormat(NoFormat); + } + FormatInterpreter(const Format &format) + { + SetFormat(format); + } + + void SetFormat(const Format &format) + { + this->format = format; + indentationChar = (format.useTabs ? '\t' : ' '); + spacing = (format.spacing ? " " : ""); + newline = (format.newline ? "\n" : spacing); + } + + std::string GetIndentation(unsigned int level) const + { + if (!format.newline) + { + return ""; + } + else + { + return std::string(format.indentSize * level, indentationChar); + } + } + + inline const std::string &GetNewline() const + { + return newline; + } + inline const std::string &GetSpacing() const + { + return spacing; + } + + private: + Format format; + char indentationChar; + std::string newline; + std::string spacing; + }; + + inline bool IsWhitespace(char c) + { + return (c == '\n' || c == ' ' || c == '\t' || c == '\r' || c == '\f'); + } + inline bool IsNumber(char c) + { + return ((c >= '0' && c <= '9') || c == '.' || c == '-'); + } + + Node::Node() + { + } + Node::~Node() + { + } + + Object &Node::AsObject() + { + if (IsObject()) + return static_cast(*this); + else + throw TypeException(); + } + const Object &Node::AsObject() const + { + if (IsObject()) + return static_cast(*this); + else + throw TypeException(); + } + Array &Node::AsArray() + { + if (IsArray()) + return static_cast(*this); + else + throw TypeException(); + } + const Array &Node::AsArray() const + { + if (IsArray()) + return static_cast(*this); + else + throw TypeException(); + } + Value &Node::AsValue() + { + if (IsValue()) + return static_cast(*this); + else + throw TypeException(); + } + const Value &Node::AsValue() const + { + if (IsValue()) + return static_cast(*this); + else + throw TypeException(); + } + + Node::Type Node::DetermineType(const std::string &json) + { + std::string::const_iterator jsonIt = json.begin(); + + while (jsonIt != json.end() && IsWhitespace(*jsonIt)) + ++jsonIt; + + if (jsonIt == json.end()) + return T_VALUE; + + switch (*jsonIt) + { + case '{' : return T_OBJECT; + case '[' : return T_ARRAY; + default : return T_VALUE; + } + } + + + Value::Value() : Node() + { + SetNull(); + } + Value::Value(const Value &rhs) : Node() + { + Set(rhs); + } + Value::Value(const Node &rhs) : Node() + { + const Value &value = rhs.AsValue(); + Set(value); + } + Value::Value(ValueType type, const std::string &value) + { + Set(type, value); + } + Value::Value(const std::string &value) + { + Set(value); + } + Value::Value(const char *value) + { + Set(value); + } + Value::Value(const int value) + { + Set(value); + } + Value::Value(const float value) + { + Set(value); + } + Value::Value(const double value) + { + Set(value); + } + Value::Value(const bool value) + { + Set(value); + } + Value::~Value() + { + } + + Node::Type Value::GetType() const + { + return T_VALUE; + } + Value::ValueType Value::GetValueType() const + { + return type; + } + + std::string Value::ToString() const + { + if (IsNull()) + { + return "null"; + } + else + { + return valueStr; + } + } + int Value::ToInt() const + { + if (IsNumber()) + { + std::stringstream sstr(valueStr); + int val; + sstr >> val; + return val; + } + else + { + return 0; + } + } + float Value::ToFloat() const + { + if (IsNumber()) + { + std::stringstream sstr(valueStr); + float val; + sstr >> val; + return val; + } + else + { + return 0.f; + } + } + double Value::ToDouble() const + { + if (IsNumber()) + { + std::stringstream sstr(valueStr); + double val; + sstr >> val; + return val; + } + else + { + return 0.0; + } + } + bool Value::ToBool() const + { + if (IsBool()) + { + return (valueStr == "true"); + } + else + { + return false; + } + } + + void Value::SetNull() + { + valueStr = ""; + type = VT_NULL; + } + void Value::Set(const Value &value) + { + if (this != &value) + { + valueStr = value.valueStr; + type = value.type; + } + } + void Value::Set(ValueType type, const std::string &value) + { + valueStr = value; + this->type = type; + } + void Value::Set(const std::string &value) + { + valueStr = UnescapeString(value); + type = VT_STRING; + } + void Value::Set(const char *value) + { + valueStr = UnescapeString(std::string(value)); + type = VT_STRING; + } + void Value::Set(const int value) + { + std::stringstream sstr; + sstr << value; + valueStr = sstr.str(); + type = VT_NUMBER; + } + void Value::Set(const float value) + { + std::stringstream sstr; + sstr << value; + valueStr = sstr.str(); + type = VT_NUMBER; + } + void Value::Set(const double value) + { + std::stringstream sstr; + sstr << value; + valueStr = sstr.str(); + type = VT_NUMBER; + } + void Value::Set(const bool value) + { + if (value) + valueStr = "true"; + else + valueStr = "false"; + type = VT_BOOL; + } + + Value &Value::operator=(const Value &rhs) + { + if (this != &rhs) + Set(rhs); + return *this; + } + Value &Value::operator=(const Node &rhs) + { + if (this != &rhs) + Set(rhs.AsValue()); + return *this; + } + Value &Value::operator=(const std::string &rhs) + { + Set(rhs); + return *this; + } + Value &Value::operator=(const char *rhs) + { + Set(rhs); + return *this; + } + Value &Value::operator=(const int rhs) + { + Set(rhs); + return *this; + } + Value &Value::operator=(const float rhs) + { + Set(rhs); + return *this; + } + Value &Value::operator=(const double rhs) + { + Set(rhs); + return *this; + } + Value &Value::operator=(const bool rhs) + { + Set(rhs); + return *this; + } + + bool Value::operator==(const Value &other) const + { + return ((type == other.type)&&(valueStr == other.valueStr)); + } + bool Value::operator!=(const Value &other) const + { + return !(*this == other); + } + + Node *Value::GetCopy() const + { + return new Value(*this); + } + + // This is not the most beautiful place for these, but it'll do + static const char charsUnescaped[] = { '\\' , '/' , '\"' , '\n' , '\t' , '\b' , '\f' , '\r' }; + static const char *charsEscaped[] = { "\\\\", "\\/", "\\\"", "\\n", "\\t", "\\b", "\\f", "\\r" }; + static const unsigned int numEscapeChars = 8; + static const char nullUnescaped = '\0'; + static const char *nullEscaped = "\0\0"; + const char *&getEscaped(const char &c) + { + for (unsigned int i = 0; i < numEscapeChars; ++i) + { + const char &ue = charsUnescaped[i]; + + if (c == ue) + { + const char *&e = charsEscaped[i]; + return e; + } + } + return nullEscaped; + } + const char &getUnescaped(const char &c1, const char &c2) + { + for (unsigned int i = 0; i < numEscapeChars; ++i) + { + const char *&e = charsEscaped[i]; + + if (c1 == e[0] && c2 == e[1]) + { + const char &ue = charsUnescaped[i]; + return ue; + } + } + return nullUnescaped; + } + + std::string Value::EscapeString(const std::string &value) + { + std::string escaped; + + for (std::string::const_iterator it = value.begin(); it != value.end(); ++it) + { + const char &c = (*it); + + const char *&a = getEscaped(c); + if (a[0] != '\0') + { + escaped += a[0]; + escaped += a[1]; + } + else + { + escaped += c; + } + } + + return escaped; + } + std::string Value::UnescapeString(const std::string &value) + { + std::string unescaped; + + for (std::string::const_iterator it = value.begin(); it != value.end(); ++it) + { + const char &c = (*it); + char c2 = '\0'; + if (it+1 != value.end()) + c2 = *(it+1); + + const char &a = getUnescaped(c, c2); + if (a != '\0') + { + unescaped += a; + if (it+1 != value.end()) + ++it; + } + else + { + unescaped += c; + } + } + + return unescaped; + } + + + Object::Object() : Node() + { + } + Object::Object(const Object &other) : Node() + { + for (ChildList::const_iterator it = other.children.begin(); it != other.children.end(); ++it) + { + const std::string &name = (*it).first; + Node &value = *(*it).second; + + children.push_back(NamedNodePtr(name, value.GetCopy())); + } + } + Object::Object(const Node &other) : Node() + { + const Object &object = other.AsObject(); + + for (ChildList::const_iterator it = object.children.begin(); it != object.children.end(); ++it) + { + const std::string &name = (*it).first; + Node &value = *(*it).second; + + children.push_back(NamedNodePtr(name, value.GetCopy())); + } + } + Object::~Object() + { + Clear(); + } + + Node::Type Object::GetType() const + { + return T_OBJECT; + } + + void Object::Add(const std::string &name, Node &node) + { + children.push_back(NamedNodePtr(name, node.GetCopy())); + } + void Object::Add(const std::string &name, Value node) + { + children.push_back(NamedNodePtr(name, new Value(node))); + } + void Object::Remove(const std::string &name) + { + for (ChildList::iterator it = children.begin(); it != children.end(); ++it) + { + if ((*it).first == name) + { + delete (*it).second; + children.erase(it); + break; + } + } + } + void Object::Clear() + { + for (ChildList::iterator it = children.begin(); it != children.end(); ++it) + { + delete (*it).second; + (*it).second = NULL; + } + children.clear(); + } + + Object::iterator Object::begin() + { + if (!children.empty()) + return Object::iterator(&children.front()); + else + return Object::iterator(NULL); + } + Object::const_iterator Object::begin() const + { + if (!children.empty()) + return Object::const_iterator(&children.front()); + else + return Object::const_iterator(NULL); + } + Object::iterator Object::end() + { + if (!children.empty()) + return Object::iterator(&children.back()+1); + else + return Object::iterator(NULL); + } + Object::const_iterator Object::end() const + { + if (!children.empty()) + return Object::const_iterator(&children.back()+1); + else + return Object::const_iterator(NULL); + } + + bool Object::Has(const std::string &name) const + { + for (ChildList::const_iterator it = children.begin(); it != children.end(); ++it) + { + if ((*it).first == name) + { + return true; + } + } + return false; + } + size_t Object::GetCount() const + { + return children.size(); + } + Node &Object::Get(const std::string &name) const + { + for (ChildList::const_iterator it = children.begin(); it != children.end(); ++it) + { + if ((*it).first == name) + { + return *(*it).second; + } + } + + throw NotFoundException(); + } + + Node *Object::GetCopy() const + { + return new Object(*this); + } + + + Array::Array() : Node() + { + } + Array::Array(const Array &other) : Node() + { + for (ChildList::const_iterator it = other.children.begin(); it != other.children.end(); ++it) + { + const Node &value = *(*it); + + children.push_back(value.GetCopy()); + } + } + Array::Array(const Node &other) : Node() + { + const Array &array = other.AsArray(); + + for (ChildList::const_iterator it = array.children.begin(); it != array.children.end(); ++it) + { + const Node &value = *(*it); + + children.push_back(value.GetCopy()); + } + } + Array::~Array() + { + Clear(); + } + + Node::Type Array::GetType() const + { + return T_ARRAY; + } + + void Array::Add(Node &node) + { + children.push_back(node.GetCopy()); + } + void Array::Add(Value node) + { + children.push_back(new Value(node)); + } + void Array::Remove(size_t index) + { + if (index < children.size()) + { + ChildList::iterator it = children.begin()+index; + delete (*it); + children.erase(it); + } + } + void Array::Clear() + { + for (ChildList::iterator it = children.begin(); it != children.end(); ++it) + { + delete (*it); + (*it) = NULL; + } + children.clear(); + } + + Array::iterator Array::begin() + { + if (!children.empty()) + return Array::iterator(&children.front()); + else + return Array::iterator(NULL); + } + Array::const_iterator Array::begin() const + { + if (!children.empty()) + return Array::const_iterator(&children.front()); + else + return Array::const_iterator(NULL); + } + Array::iterator Array::end() + { + if (!children.empty()) + return Array::iterator(&children.back()+1); + else + return Array::iterator(NULL); + } + Array::const_iterator Array::end() const + { + if (!children.empty()) + return Array::const_iterator(&children.back()+1); + else + return Array::const_iterator(NULL); + } + + size_t Array::GetCount() const + { + return children.size(); + } + Node &Array::Get(size_t index) const + { + if (index < children.size()) + { + return *children.at(index); + } + + throw NotFoundException(); + } + + Node *Array::GetCopy() const + { + return new Array(*this); + } + + + FileWriter::FileWriter(const std::string &filename) : filename(filename) + { + } + FileWriter::~FileWriter() + { + } + + void FileWriter::WriteFile(const std::string &filename, const Node &root, const Format &format) + { + FileWriter writer(filename); + writer.Write(root, format); + } + + void FileWriter::Write(const Node &root, const Format &format) + { + Writer writer(root, format); + writer.Write(); + + std::fstream file(filename.c_str(), std::ios::out | std::ios::trunc); + file << writer.GetResult(); + file.close(); + } + + + FileReader::FileReader(const std::string &filename) + { + if (!loadFile(filename, json)) + { + error = "Failed to load file"; + } + } + FileReader::~FileReader() + { + } + + bool FileReader::ReadFile(const std::string &filename, Node &node) + { + FileReader reader(filename); + return reader.Read(node); + } + + bool FileReader::Read(Node &node) + { + if (!error.empty()) + return false; + + Parser parser(node, json); + if (!parser.Parse()) + { + error = parser.GetError(); + return false; + } + else + { + return true; + } + } + + Node::Type FileReader::DetermineType() + { + return Node::DetermineType(json); + } + + const std::string &FileReader::GetError() const + { + return error; + } + + bool FileReader::loadFile(const std::string &filename, std::string &json) + { + std::fstream file(filename.c_str(), std::ios::in | std::ios::binary); + + if (!file.is_open()) + { + return false; + } + + file.seekg(0, std::ios::end); + std::ios::pos_type size = file.tellg(); + file.seekg(0, std::ios::beg); + + json.resize(static_cast(size), '\0'); + file.read(&json[0], size); + + return true; + } + + + Writer::Writer(const Node &root, const Format &format) : fi(new FormatInterpreter), root(root) + { + SetFormat(format); + } + Writer::~Writer() + { + delete fi; + fi = NULL; + } + + void Writer::SetFormat(const Format &format) + { + fi->SetFormat(format); + } + const std::string &Writer::Write() + { + result.clear(); + writeNode(root, 0); + return result; + } + + const std::string &Writer::GetResult() const + { + return result; + } + + void Writer::writeNode(const Node &node, unsigned int level) + { + switch (node.GetType()) + { + case Node::T_OBJECT : writeObject(node.AsObject(), level); break; + case Node::T_ARRAY : writeArray(node.AsArray(), level); break; + case Node::T_VALUE : writeValue(node.AsValue()); break; + } + } + void Writer::writeObject(const Object &node, unsigned int level) + { + result += "{" + fi->GetNewline(); + + for (Object::const_iterator it = node.begin(); it != node.end(); ++it) + { + const std::string &name = (*it).first; + const Node &value = (*it).second; + + if (it != node.begin()) + result += "," + fi->GetNewline(); + result += fi->GetIndentation(level+1) + "\""+name+"\"" + ":" + fi->GetSpacing(); + writeNode(value, level+1); + } + + result += fi->GetNewline() + fi->GetIndentation(level) + "}"; + } + void Writer::writeArray(const Array &node, unsigned int level) + { + result += "[" + fi->GetNewline(); + + for (Array::const_iterator it = node.begin(); it != node.end(); ++it) + { + const Node &value = (*it); + + if (it != node.begin()) + result += "," + fi->GetNewline(); + result += fi->GetIndentation(level+1); + writeNode(value, level+1); + } + + result += fi->GetNewline() + fi->GetIndentation(level) + "]"; + } + void Writer::writeValue(const Value &node) + { + if (node.IsString()) + { + result += "\""+Value::EscapeString(node.ToString())+"\""; + } + else + { + result += node.ToString(); + } + } + + + Parser::Parser(Node &root) : root(root) + { + } + Parser::Parser(Node &root, const std::string &json) : root(root) + { + SetJson(json); + } + Parser::~Parser() + { + } + + void Parser::SetJson(const std::string &json) + { + this->json = json; + jsonSize = json.size(); + } + bool Parser::Parse() + { + cursor = 0; + + tokenize(); + bool success = assemble(); + + return success; + } + + const std::string &Parser::GetError() const + { + return error; + } + + void Parser::tokenize() + { + Token token; + std::string valueBuffer; + bool saveBuffer; + + char c = '\0'; + for (; cursor < jsonSize; ++cursor) + { + c = json.at(cursor); + + if (IsWhitespace(c)) + continue; + + saveBuffer = true; + + switch (c) + { + case '{' : + { + token = T_OBJ_BEGIN; + break; + } + case '}' : + { + token = T_OBJ_END; + break; + } + case '[' : + { + token = T_ARRAY_BEGIN; + break; + } + case ']' : + { + token = T_ARRAY_END; + break; + } + case ',' : + { + token = T_SEPARATOR_NODE; + break; + } + case ':' : + { + token = T_SEPARATOR_NAME; + break; + } + case '"' : + { + token = T_VALUE; + readString(); + break; + } + case '/' : + { + char p = peek(); + if (p == '*') + { + jumpToCommentEnd(); + } + else if (p == '/') + { + jumpToNext('\n'); + } + break; + } + default : + { + valueBuffer += c; + saveBuffer = false; + break; + } + } + + if ((saveBuffer || cursor == jsonSize-1) && (!valueBuffer.empty())) // Always save buffer on the last character + { + if (interpretValue(valueBuffer)) + { + tokens.push(T_VALUE); + } + else + { + // Store the unknown token, so we can show it to the user + data.push(MakePair(Value::VT_STRING, valueBuffer)); + tokens.push(T_UNKNOWN); + } + + valueBuffer.clear(); + } + + // Push the token last so that any + // value token will get pushed first + // from above. + // If saveBuffer is false, it means that + // we are in the middle of a value, so we + // don't want to push any tokens now. + if (saveBuffer) + { + tokens.push(token); + } + } + } + bool Parser::assemble() + { + std::stack > nodeStack; + + std::string name = ""; + + Token token; + while (!tokens.empty()) + { + token = tokens.front(); + tokens.pop(); + + switch (token) + { + case T_UNKNOWN : + { + const std::string &unknownToken = data.front().second; + error = "Unknown token: "+unknownToken; + data.pop(); + return false; + } + case T_OBJ_BEGIN : + { + Node *node = NULL; + if (nodeStack.empty()) + { + if (!root.IsObject()) + { + error = "The given root node is not an object"; + return false; + } + + node = &root; + } + else + { + node = new Object; + } + + nodeStack.push(MakePair(name, node)); + name.clear(); + break; + } + case T_ARRAY_BEGIN : + { + Node *node = NULL; + if (nodeStack.empty()) + { + if (!root.IsArray()) + { + error = "The given root node is not an array"; + return false; + } + + node = &root; + } + else + { + node = new Array; + } + + nodeStack.push(MakePair(name, node)); + name.clear(); + break; + } + case T_OBJ_END : + case T_ARRAY_END : + { + if (nodeStack.empty()) + { + error = "Found end of object or array without beginning"; + return false; + } + if (token == T_OBJ_END && !nodeStack.top().second->IsObject()) + { + error = "Mismatched end and beginning of object"; + return false; + } + if (token == T_ARRAY_END && !nodeStack.top().second->IsArray()) + { + error = "Mismatched end and beginning of array"; + return false; + } + + std::string name = nodeStack.top().first; + Node *node = nodeStack.top().second; + nodeStack.pop(); + + if (!nodeStack.empty()) + { + if (nodeStack.top().second->IsObject()) + { + nodeStack.top().second->AsObject().Add(name, *node); + } + else if (nodeStack.top().second->IsArray()) + { + nodeStack.top().second->AsArray().Add(*node); + } + else + { + error = "Can only add elements to objects and arrays"; + return false; + } + + delete node; + node = NULL; + } + break; + } + case T_VALUE : + { + if (!tokens.empty() && tokens.front() == T_SEPARATOR_NAME) + { + tokens.pop(); + if (data.front().first != Value::VT_STRING) + { + error = "A name has to be a string"; + return false; + } + else + { + name = data.front().second; + data.pop(); + } + } + else + { + Node *node = NULL; + if (nodeStack.empty()) + { + if (!root.IsValue()) + { + error = "The given root node is not a value"; + return false; + } + + node = &root; + } + else + { + node = new Value; + } + + if (data.front().first == Value::VT_STRING) + { + static_cast(node)->Set(data.front().second); // This method calls UnescapeString() + } + else + { + static_cast(node)->Set(data.front().first, data.front().second); + } + data.pop(); + + if (!nodeStack.empty()) + { + if (nodeStack.top().second->IsObject()) + nodeStack.top().second->AsObject().Add(name, *node); + else if (nodeStack.top().second->IsArray()) + nodeStack.top().second->AsArray().Add(*node); + + delete node; + node = NULL; + name.clear(); + } + else + { + nodeStack.push(MakePair(name, node)); + name.clear(); + } + } + break; + } + case T_SEPARATOR_NAME : + case T_SEPARATOR_NODE : break; + } + } + + return true; + } + + char Parser::peek() + { + if (cursor < jsonSize-1) + { + return json.at(cursor+1); + } + else + { + return '\0'; + } + } + void Parser::jumpToNext(char c) + { + ++cursor; + while (cursor < jsonSize && json.at(cursor) != c) + ++cursor; + } + void Parser::jumpToCommentEnd() + { + ++cursor; + char c1 = '\0', c2 = '\0'; + for (; cursor < jsonSize; ++cursor) + { + c2 = json.at(cursor); + + if (c1 == '*' && c2 == '/') + break; + + c1 = c2; + } + } + + void Parser::readString() + { + if (json.at(cursor) != '"') + return; + + std::string str; + + ++cursor; + + char c1 = '\0', c2 = '\0'; + for (; cursor < jsonSize; ++cursor) + { + c2 = json.at(cursor); + + if (c1 != '\\' && c2 == '"') + { + break; + } + + str += c2; + + c1 = c2; + } + + data.push(MakePair(Value::VT_STRING, str)); + } + bool Parser::interpretValue(const std::string &value) + { + std::string upperValue(value.size(), '\0'); + + std::transform(value.begin(), value.end(), upperValue.begin(), toupper); + + if (upperValue == "NULL") + { + data.push(MakePair(Value::VT_NULL, std::string(""))); + } + else if (upperValue == "TRUE") + { + data.push(MakePair(Value::VT_BOOL, std::string("true"))); + } + else if (upperValue == "FALSE") + { + data.push(MakePair(Value::VT_BOOL, std::string("false"))); + } + else + { + bool number = true; + for (std::string::const_iterator it = value.begin(); it != value.end(); ++it) + { + if (!IsNumber(*it)) + { + number = false; + break; + } + } + + if (number) + { + data.push(MakePair(Value::VT_NUMBER, value)); + } + else + { + return false; + } + } + + return true; + } +} diff --git a/src/Makefile b/src/Makefile index 99ff9750..1e2f57e5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,6 +1,6 @@ # ************************************************************* -*- Makefile -*- # -# Copyright (C) 2004-2013 Andreas Huggel +# Copyright (C) 2004-2012 Andreas Huggel # # This Makefile is part of the Exiv2 distribution. # @@ -62,6 +62,7 @@ include $(top_srcdir)/config/config.mk CCHDR = exiv2.hpp \ exv_conf.h \ exv_msvc.h \ + Jzon.h \ svn_version.h \ version.hpp @@ -82,10 +83,13 @@ CCSRC = asfvideo.cpp \ futils.cpp \ fujimn.cpp \ gifimage.cpp \ + http.cpp \ + ssh.cpp \ image.cpp \ iptc.cpp \ jp2image.cpp \ jpgimage.cpp \ + Jzon.cpp \ makernote.cpp \ matroskavideo.cpp \ metadatum.cpp \ @@ -95,6 +99,7 @@ CCSRC = asfvideo.cpp \ olympusmn.cpp \ orfimage.cpp \ panasonicmn.cpp \ + pentaxmn.cpp \ pgfimage.cpp ifdef HAVE_LIBZ CCSRC += pngimage.cpp \ @@ -109,7 +114,6 @@ CCSRC += preview.cpp \ rw2image.cpp \ samsungmn.cpp \ sigmamn.cpp \ - pentaxmn.cpp \ sonymn.cpp \ tags.cpp \ tgaimage.cpp \ @@ -117,7 +121,6 @@ CCSRC += preview.cpp \ tiffimage.cpp \ tiffvisitor.cpp \ types.cpp \ - utilsvideo.cpp \ value.cpp \ version.cpp \ xmp.cpp \ @@ -130,8 +133,8 @@ endif # Source files for the Exiv2 application EXIV2MAIN = exiv2.cpp -EXIV2SRC = actions.cpp \ - utils.cpp +EXIV2SRC = actions.cpp \ + utils.cpp # C source files for the Exiv2 application ifndef HAVE_TIMEGM EXIVCSRC = localtime.c @@ -143,38 +146,64 @@ LIBRARY = libexiv2.la # ****************************************************************************** # Initialisations -SHELL = /bin/sh +SHELL = /bin/bash .SUFFIXES: .SUFFIXES: .c .cpp .o .so .PRECIOUS: %.cpp -CPPFLAGS += $(XMPSDK_CPPFLAGS) -LDFLAGS += $(EXPAT_LDFLAGS) $(XMPSDK_LDFLAGS) -LIBS += $(EXPAT_LIBS) $(XMPSDK_LIBS) +CPPFLAGS += $(SSH_CPPFLAGS) $(CURL_CPPFLAGS) $(XMPSDK_CPPFLAGS) +LDFLAGS += $(SSH_LDFLAGS) $(CURL_LDFLAGS) $(EXPAT_LDFLAGS) $(XMPSDK_LDFLAGS) +LIBS += $(SSH_LIBS) $(CURL_LIBS) $(EXPAT_LIBS) $(XMPSDK_LIBS) # Generic variables CCHDR := $(CCHDR) $(CCSRC:.cpp=.hpp) -CCOBJ = $(CCSRC:.cpp=.o) +CCOBJ = $(CCSRC:.cpp=.o) CCLOBJ = $(CCSRC:.cpp=.lo) -COBJ = $(CSRC:.c=.o) -CLOBJ = $(CSRC:.c=.lo) +COBJ = $(CSRC:.c=.o) +CLOBJ = $(CSRC:.c=.lo) -SRC = $(CCSRC) $(CSRC) -HDR = $(CCHDR) -OBJ = $(CCOBJ) $(COBJ) -LOBJ = $(CCLOBJ) $(CLOBJ) +SRC = $(CCSRC) $(CSRC) +HDR = $(CCHDR) +OBJ = $(CCOBJ) $(COBJ) +LOBJ = $(CCLOBJ) $(CLOBJ) -EXIV2OBJ = $(EXIV2MAIN:.cpp=.o) $(EXIV2SRC:.cpp=.o) +EXIV2OBJ = $(EXIV2MAIN:.cpp=.o) $(EXIV2SRC:.cpp=.o) EXIV2COBJ = $(EXIVCSRC:.c=.o) -EXIV2BIN = ../bin/$(EXIV2MAIN:.cpp=) -EXIV2EXE = $(EXIV2MAIN:.cpp=$(EXEEXT)) +EXIV2BIN = $(EXIV2MAIN:.cpp=) +EXIV2EXE = $(EXIV2MAIN:.cpp=$(EXEEXT)) + +SAMPLEDIR = ../samples/ + +# connection test application +CONNTEST = conntest.cpp +CONNTOBJ = $(SAMPLEDIR)$(CONNTEST:.cpp=.o) +CONNTBIN = $(CONNTEST:.cpp=) +CONNTEXE = $(CONNTEST:.cpp=$(EXEEXT)) + +# exifprint application +EXIFPRINT = exifprint.cpp +EXIFPOBJ = $(SAMPLEDIR)$(EXIFPRINT:.cpp=.o) +EXIFPBIN = $(EXIFPRINT:.cpp=) +EXIFPEXE = $(EXIFPRINT:.cpp=$(EXEEXT)) + +# cmdfiletest application +REMOTETEST = remotetest.cpp +REMOTETOBJ = $(SAMPLEDIR)$(REMOTETEST:.cpp=.o) +REMOTETBIN = $(REMOTETEST:.cpp=) +REMOTETEXE = $(REMOTETEST:.cpp=$(EXEEXT)) ifdef DEP_TRACKING -DEP = $(CCSRC:%.cpp=$(DEPDIR)/%.d) $(CSRC:%.c=$(DEPDIR)/%.d) \ - $(EXIV2MAIN:%.cpp=$(DEPDIR)/%.d) $(EXIV2SRC:%.cpp=$(DEPDIR)/%.d) \ +DEP = $(CCSRC:%.cpp=$(DEPDIR)/%.d) \ + $(CSRC:%.c=$(DEPDIR)/%.d) \ + $(BINSRC:%.cpp=$(DEPDIR)/%.d) \ + $(EXIV2MAIN:%.cpp=$(DEPDIR)/%.d) \ + $(EXIV2SRC:%.cpp=$(DEPDIR)/%.d) \ + $(CONNTEST:%.cpp=$(DEPDIR)/%.d) \ + $(EXIFPRINT:%.cpp=$(DEPDIR)/%.d) \ + $(REMOTETEST:%.cpp=$(DEPDIR)/%.d) \ $(EXIVCSRC:%.c=$(DEPDIR)/%.d) endif @@ -196,6 +225,21 @@ $(EXIV2OBJ): %.o: %.cpp @$(MAKEDEPEND) @$(POSTDEPEND) +$(CONNTOBJ): %.o: %.cpp + $(COMPILE.cc) -o $@ $< + @$(MAKEDEPEND) + @$(POSTDEPEND) + +$(EXIFPOBJ): %.o: %.cpp + $(COMPILE.cc) -o $@ $< + @$(MAKEDEPEND) + @$(POSTDEPEND) + +$(REMOTETOBJ): %.o: %.cpp + $(COMPILE.cc) -o $@ $< + @$(MAKEDEPEND) + @$(POSTDEPEND) + %.o: %.c $(COMPILE.c) -o $@ $< @$(MAKEDEPEND) @@ -218,36 +262,51 @@ ifdef DEP_TRACKING endif # Be sure to rewrite exv_conf.h and svn_version.h before compiling anything -$(SRC): exv_conf.h svn_version.h +$(SRC): ../include/exiv2/exv_conf.h svn_version.h -exv_conf.h: $(top_srcdir)/config/config.h +../include/exiv2/exv_conf.h: $(top_srcdir)/config/config.h LC_ALL=C sed 's/#define \([A-Z]\)/#define EXV_\1/; s/#undef \([A-Z]\)/#undef EXV_\1/' < $< > $@ # svn_version.h is only rewritten when the svn info | grep Revision has changed svn_version.h: - $(SHELL) ./svn_version.sh - + ./svn_version.sh + version.hpp : svn_version.h $(LIBTOOL): $(LIBTOOL_DEPS) $(SHELL) $(top_srcdir)/config.status --recheck -bin: lib $(EXIV2BIN) +bin: lib $(EXIV2BIN) $(CONNTBIN) $(EXIFPBIN) $(REMOTETBIN) lib: $(OBJ) $(LIBTOOL) --mode=link $(LINK.cc) -o $(LIBRARY) $(LOBJ) -rpath $(libdir) -version-info $(EXIV2_LTVERSION) $(LIBS) @touch lib -$(EXIV2BIN): lib $(EXIV2OBJ) $(EXIV2COBJ) svn_version.h - -mkdir -p ../bin >/dev/null 2>&1 - @$(LIBTOOL) --mode=link $(LINK.cc) -o $@ $(LIBRARY) $(EXIV2OBJ) $(EXIV2COBJ) -rpath $(libdir) +$(BINARY): %: %.o lib + @$(LIBTOOL) --mode=link $(LINK.cc) -o $@ $(LIBRARY) $@.o -rpath $(libdir) + +$(EXIV2BIN): lib $(EXIV2OBJ) $(EXIV2COBJ) + mkdir -pv ../bin 2>&1 > /dev/null + @$(LIBTOOL) --mode=link $(LINK.cc) -o ../bin/$@ $(LIBRARY) $(EXIV2OBJ) $(EXIV2COBJ) -rpath $(libdir) + +$(CONNTBIN): lib $(CONNTOBJ) + mkdir -pv ../bin 2>&1 > /dev/null + @$(LIBTOOL) --mode=link $(LINK.cc) -o ../bin/$@ $(LIBRARY) $(CONNTOBJ) -rpath $(libdir) $(LIBS) + +$(EXIFPBIN): lib $(EXIFPOBJ) + mkdir -pv ../bin 2>&1 > /dev/null + @$(LIBTOOL) --mode=link $(LINK.cc) -o ../bin/$@ $(LIBRARY) $(EXIFPOBJ) -rpath $(libdir) + +$(REMOTETBIN): lib $(REMOTETOBJ) + mkdir -pv ../bin 2>&1 > /dev/null + @$(LIBTOOL) --mode=link $(LINK.cc) -o ../bin/$@ $(LIBRARY) $(REMOTETOBJ) -rpath $(libdir) install-header: $(INSTALL_DIRS) $(DESTDIR)$(incdir) @list='$(HDR)'; for p in $$list; do \ - if test -f $$p; then \ - echo "$(INSTALL_DATA) $$p $(DESTDIR)$(incdir)/$$p"; \ - $(INSTALL_DATA) $$p $(DESTDIR)$(incdir)/$$p; \ + if test -f ../include/exiv2/$$p; then \ + echo "$(INSTALL_DATA) ../include/exiv2/$$p $(DESTDIR)$(incdir)/$$p"; \ + $(INSTALL_DATA) ../include/exiv2/$$p $(DESTDIR)$(incdir)/$$p; \ else :; fi; \ done @@ -291,19 +350,18 @@ ctags: # ctags-exuberant --extra=+q * check: - @echo "No checks available for this library." + @echo "No checks available for this library - or $ make tests" mostlyclean: $(RM) core $(RM) $(CCSRC:.cpp=.ii) $(RM) lib - $(RM) exv_conf.h svn_version.h - $(RM) $(CCSRC:%.cpp=.libs/%.d) $(CSRC:%.c=.libs/%.d) - @$(LIBTOOL) --mode=clean $(RM) $(LOBJ) $(sort $(EXIV2OBJ) $(EXIV2COBJ) ) + $(RM) -rf $(CCSRC:%.cpp=.libs/%.d) $(CSRC:%.c=.libs/%.d) .libs/*.dSYM + @$(LIBTOOL) --mode=clean $(RM) $(LOBJ) $(sort $(EXIV2OBJ) $(EXIV2COBJ) $(CONNTOBJ) $(EXIFPOBJ) $(REMOTETOBJ) ) clean: mostlyclean @$(LIBTOOL) --mode=clean $(RM) $(LIBRARY) - @$(LIBTOOL) --mode=clean $(RM) ../bin/$(EXIV2EXE) + @$(LIBTOOL) --mode=clean $(RM) $(EXECUTABLE) $(EXIV2EXE) # Run `make distclean' from the top source directory to also remove # files created by configuring the program. diff --git a/src/actions.cpp b/src/actions.cpp index af46b815..35660545 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -29,13 +29,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #ifndef EXV_HAVE_TIMEGM # include "timegm.h" diff --git a/src/basicio.cpp b/src/basicio.cpp index 44b50a9d..df4b7c3d 100644 --- a/src/basicio.cpp +++ b/src/basicio.cpp @@ -28,18 +28,14 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "basicio.hpp" #include "futils.hpp" #include "types.hpp" #include "error.hpp" +#include "http.hpp" // + standard includes #include @@ -60,6 +56,12 @@ EXIV2_RCSID("@(#) $Id$") #ifdef EXV_HAVE_UNISTD_H # include // for getpid, stat #endif +#if EXV_USE_CURL == 1 +#include +#endif +#if EXV_USE_SSH == 1 +#include "ssh.hpp" +#endif // Platform specific headers for handling extended attributes (xattr) #if defined(__APPLE__) @@ -68,7 +70,9 @@ EXIV2_RCSID("@(#) $Id$") #if defined WIN32 && !defined __CYGWIN__ // Windows doesn't provide mode_t, nlink_t +#ifndef EXV_USE_SSH typedef unsigned short mode_t; +#endif typedef short nlink_t; # include @@ -113,19 +117,23 @@ namespace Exiv2 { HANDLE hFile_; //!< Duplicated fd HANDLE hMap_; //!< Handle from CreateFileMapping #endif - byte* pMappedArea_; //!< Pointer to the memory-mapped area + byte* pMappedArea_; //!< Pointer to the memory-mapped area size_t mappedLength_; //!< Size of the memory-mapped area - bool isMalloced_; //!< Is the mapped area allocated? - bool isWriteable_; //!< Can the mapped area be written to? + bool isMalloced_; //!< Is the mapped area allocated? + bool isWriteable_; //!< Can the mapped area be written to? // TYPES //! Simple struct stat wrapper for internal use struct StructStat { +#if EXV_USE_SSH == 1 StructStat() : st_mode(0), st_size(0), st_nlink(0) {} mode_t st_mode; //!< Permissions - off_t st_size; //!< Size +#else + StructStat() : st_size(0), st_nlink(0) {} +#endif + off_t st_size; //!< Size nlink_t st_nlink; //!< Number of hard links (broken on Windows, see winNumberOfLinks()) }; - +// #endif // METHODS /*! @brief Switch to a new access mode, reopening the file if needed. @@ -151,15 +159,15 @@ namespace Exiv2 { }; // class FileIo::Impl FileIo::Impl::Impl(const std::string& path) - : path_(path), + : path_(path) + , fp_(0), opMode_(opSeek) + , pMappedArea_(0), mappedLength_(0), isMalloced_(false), isWriteable_(false) #ifdef EXV_UNICODE_PATH - wpMode_(wpStandard), + , wpMode_(wpStandard) #endif - fp_(0), opMode_(opSeek), #if defined WIN32 && !defined __CYGWIN__ - hFile_(0), hMap_(0), + , hFile_(0), hMap_(0) #endif - pMappedArea_(0), mappedLength_(0), isMalloced_(false), isWriteable_(false) { } @@ -252,8 +260,10 @@ namespace Exiv2 { ret = ::stat(path_.c_str(), &st); if (0 == ret) { buf.st_size = st.st_size; - buf.st_mode = st.st_mode; buf.st_nlink = st.st_nlink; +#if EXV_USE_SSH == 1 + buf.st_mode = st.st_mode; +#endif } } return ret; @@ -319,7 +329,7 @@ namespace Exiv2 { if (hKernel) { GetFileInformationByHandle_t pfcn_GetFileInformationByHandle = (GetFileInformationByHandle_t)GetProcAddress(hKernel, "GetFileInformationByHandle"); if (pfcn_GetFileInformationByHandle) { - BY_HANDLE_FILE_INFORMATION fi; + BY_HANDLE_FILE_INFORMATION fi = {0}; if (pfcn_GetFileInformationByHandle(hFd, &fi)) { nlink = fi.nNumberOfLinks; } @@ -344,6 +354,7 @@ namespace Exiv2 { } // FileIo::Impl::winNumberOfLinks #endif // defined WIN32 && !defined __CYGWIN__ + FileIo::FileIo(const std::string& path) : p_(new Impl(path)) { @@ -536,6 +547,33 @@ namespace Exiv2 { return p_->pMappedArea_; } + void FileIo::setPath(const std::string& path) { + close(); +#ifdef EXV_UNICODE_PATH + if (p_->wpMode_ == Impl::wpUnicode) { + std::wstring wpath; + wpath.assign(path.begin(), path.end()); + p_->wpath_ = wpath; + } + p_->path_ = path; +#else + p_->path_ = path; +#endif + } + +#ifdef EXV_UNICODE_PATH + void FileIo::setPath(const std::wstring& wpath) { + close(); + if (p_->wpMode_ == Impl::wpStandard) { + std::string path; + path.assign(wpath.begin(), wpath.end()); + p_->path_ = path; + } else { + p_->wpath_ = wpath; + } + } +#endif + BasicIo::AutoPtr FileIo::temporary() const { BasicIo::AutoPtr basicIo; @@ -650,8 +688,10 @@ namespace Exiv2 { close(); bool statOk = true; - mode_t origStMode = 0; - std::string spf; +#if EXV_USE_SSH == 1 + mode_t origStMode = 0; +#endif + std::string spf; char* pf = 0; #ifdef EXV_UNICODE_PATH std::wstring wspf; @@ -680,7 +720,9 @@ namespace Exiv2 { EXV_WARNING << Error(2, pf, strError(), "::lstat") << "\n"; #endif } +#if EXV_USE_SSH == 1 origStMode = buf1.st_mode; +#endif DataBuf lbuf; // So that the allocated memory is freed. Must have same scope as pf // In case path() is a symlink, get the path of the linked-to file if (statOk && S_ISLNK(buf1.st_mode)) { @@ -697,14 +739,18 @@ namespace Exiv2 { EXV_WARNING << Error(2, pf, strError(), "::stat") << "\n"; #endif } +#if EXV_USE_SSH == 1 origStMode = buf1.st_mode; +#endif } #else // EXV_HAVE_LSTAT Impl::StructStat buf1; if (p_->stat(buf1) == -1) { statOk = false; } - origStMode = buf1.st_mode; +#if EXV_USE_SSH == 1 + origStMode = buf1.st_mode; +#endif #endif // !EXV_HAVE_LSTAT // MSVCRT rename that does not overwrite existing files @@ -828,7 +874,8 @@ namespace Exiv2 { EXV_WARNING << Error(2, pf, strError(), "::stat") << "\n"; #endif } - if (statOk && origStMode != buf2.st_mode) { +#if EXV_USE_SSH == 1 + if (statOk && origStMode != buf2.st_mode) { // Set original file permissions if (::chmod(pf, origStMode) == -1) { #ifndef SUPPRESS_WARNINGS @@ -836,7 +883,8 @@ namespace Exiv2 { #endif } } - } +#endif + } } // if (fileIo) else { // Generic handling, reopen both to reset to start @@ -1055,6 +1103,11 @@ namespace Exiv2 { } #endif + + void FileIo::populateFakeData() { + + } + //! Internal Pimpl structure of class MemIo. class MemIo::Impl { public: @@ -1330,6 +1383,1213 @@ namespace Exiv2 { } #endif + void MemIo::populateFakeData() { + + } + +#if XPATH_MEMIO + XPathIo::XPathIo(const std::string& path) { + Protocol prot = fileProtocol(path); + + if (prot == pStdin) ReadStdin(); + else if (prot == pDataUri) ReadDataUri(path); + } +#ifdef EXV_UNICODE_PATH + XPathIo::XPathIo(const std::wstring& wpath) { + std::string path; + path.assign(wpath.begin(), wpath.end()); + Protocol prot = fileProtocol(path); + if (prot == pStdin) ReadStdin(); + else if (prot == pDataUri) ReadDataUri(path); + } +#endif + + void XPathIo::ReadStdin() { + if (isatty(fileno(stdin))) + throw Error(53); + +#ifdef _O_BINARY + // convert stdin to binary + if (_setmode(_fileno(stdin), _O_BINARY) == -1) + throw Error(54); +#endif + + char readBuf[100*1024]; + std::streamsize readBufSize = 0; + do { + std::cin.read(readBuf, sizeof(readBuf)); + readBufSize = std::cin.gcount(); + if (readBufSize > 0) { + write((byte*)readBuf, (long)readBufSize); + } + } while(readBufSize); + } + + void XPathIo::ReadDataUri(const std::string& path) { + size_t base64Pos = path.find("base64,"); + if (base64Pos == std::string::npos) + throw Error(1, "No base64 data"); + + std::string data = path.substr(base64Pos+7); + char* decodeData = new char[data.length()]; + long size = base64decode(data.c_str(), decodeData, data.length()); + if (size > 0) + write((byte*)decodeData, size); + else + throw Error(1, "Unable to decode base 64."); + delete[] decodeData; + } + +#else + const std::string XPathIo::TEMP_FILE_EXT = ".exiv2_temp"; + const std::string XPathIo::GEN_FILE_EXT = ".exiv2"; + + XPathIo::XPathIo(const std::string& orgPath) : FileIo(XPathIo::writeDataToFile(orgPath)) { + isTemp_ = true; + tempFilePath_ = path(); + } + +#ifdef EXV_UNICODE_PATH + XPathIo::XPathIo(const std::wstring& wOrgPathpath) : FileIo(XPathIo::writeDataToFile(wOrgPathpath)) { + isTemp_ = true; + tempFilePath_ = path(); + } +#endif + + XPathIo::~XPathIo() { + if (isTemp_ && remove(tempFilePath_.c_str()) != 0) { + // error when removing file + // printf ("Warning: Unable to remove the temp file %s.\n", tempFilePath_.c_str()); + } + } + + void XPathIo::transfer(BasicIo& src) { + if (isTemp_) { + // replace temp path to gent path. + std::string currentPath = path(); + setPath(ReplaceStringInPlace(currentPath, XPathIo::TEMP_FILE_EXT, XPathIo::GEN_FILE_EXT)); + // rename the file + tempFilePath_ = path(); + if (rename(currentPath.c_str(), tempFilePath_.c_str()) != 0) { + // printf("Warning: Failed to rename the temp file. \n"); + } + isTemp_ = false; + // call super class method + FileIo::transfer(src); + } + } + + std::string XPathIo::writeDataToFile(const std::string& orgPath) { + Protocol prot = fileProtocol(orgPath); + + // generating the name for temp file. + std::time_t timestamp = std::time(NULL); + std::stringstream ss; + ss << timestamp << XPathIo::TEMP_FILE_EXT; + std::string path = ss.str(); + std::ofstream fs(path.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + + if (prot == pStdin) { + if (isatty(fileno(stdin))) + throw Error(53); +#ifdef _MSC_VER + // convert stdin to binary + if (_setmode(_fileno(stdin), _O_BINARY) == -1) + throw Error(54); +#endif + // read stdin and write to the temp file. + char readBuf[100*1024]; + std::streamsize readBufSize = 0; + do { + std::cin.read(readBuf, sizeof(readBuf)); + readBufSize = std::cin.gcount(); + if (readBufSize > 0) { + fs.write (readBuf, readBufSize); + } + } while(readBufSize); + } else if (prot == pDataUri) { + // read data uri and write to the temp file. + size_t base64Pos = orgPath.find("base64,"); + if (base64Pos == std::string::npos) + throw Error(1, "No base64 data"); + + std::string data = orgPath.substr(base64Pos+7); + char* decodeData = new char[data.length()]; + long size = base64decode(data.c_str(), decodeData, data.length()); + if (size > 0) + fs.write(decodeData, size); + else + throw Error(1, "Unable to decode base 64."); + delete[] decodeData; + } + + fs.close(); + return path; + } + +#ifdef EXV_UNICODE_PATH + std::string XPathIo::writeDataToFile(const std::wstring& wOrgPath) { + std::string orgPath; + orgPath.assign(wOrgPath.begin(), wOrgPath.end()); + return XPathIo::writeDataToFile(orgPath); + } +#endif + +#endif + + //! Internal Pimpl abstract structure of class RemoteIo. + class RemoteIo::Impl { + public: + //! Constructor + Impl(const std::string& path, size_t blockSize); +#ifdef EXV_UNICODE_PATH + //! Constructor accepting a unicode path in an std::wstring + Impl(const std::wstring& wpath, size_t blockSize); +#endif + //! Destructor. Releases all managed memory. + virtual ~Impl(); + + // DATA + std::string path_; //!< (Standard) path +#ifdef EXV_UNICODE_PATH + std::wstring wpath_; //!< Unicode path +#endif + size_t blockSize_; //!< Size of the block memory. + BlockMap* blocksMap_; //!< An array contains all blocksMap + size_t size_; //!< The file size + long idx_; //!< Index into the memory area + bool isMalloced_; //!< Was the blocksMap_ allocated? + bool eof_; //!< EOF indicator + Protocol protocol_; //!< the protocol of url + + // METHODS + /*! + @brief Get the length (in bytes) of the remote file. + @return Return -1 if the size is unknown. Otherwise it returns the length of remote file (in bytes). + @throw Error if the server returns the error code. + */ + virtual long getFileLength() = 0; + /*! + @brief Get the data by range. + @param lowBlock The start block index. + @param highBlock The end block index. + @param response The data from the server. + @throw Error if the server returns the error code. + @note Set lowBlock = -1 and highBlock = -1 to get the whole file content. + */ + virtual void getDataByRange(long lowBlock, long highBlock, std::string& response) = 0; + /*! + @brief Submit the data to the remote machine. The data replace a part of the remote file. + The replaced part of remote file is indicated by from and to parameters. + @param data The data are submitted to the remote machine. + @param size The size of data. + @param from The start position in the remote file where the data replace. + @param to The end position in the remote file where the data replace. + @note The write access is available on some protocols. HTTP and HTTPS require the script file + on the remote machine to handle the data. SSH requires the permission to edit the file. + @throw Error if it fails. + */ + virtual void writeRemote(const byte* data, size_t size, long from, long to) = 0; + /*! + @brief Get the data from the remote machine and write them to the memory blocks. + @param lowBlock The start block index. + @param highBlock The end block index. + @return Number of bytes written to the memory block successfully + @throw Error if it fails. + */ + virtual size_t populateBlocks(size_t lowBlock, size_t highBlock); + + }; // class RemoteIo::Impl + + RemoteIo::Impl::Impl(const std::string& url, size_t blockSize) + : path_(url), blockSize_(blockSize), blocksMap_(0), size_(0), + idx_(0), isMalloced_(false), eof_(false), protocol_(fileProtocol(url)) + { + } +#ifdef EXV_UNICODE_PATH + RemoteIo::Impl::Impl(const std::wstring& wurl, size_t blockSize) + : wpath_(wurl), blockSize_(blockSize), blocksMap_(0), size_(0), + idx_(0), isMalloced_(false), eof_(false), protocol_(fileProtocol(wurl)) + { + } +#endif + + size_t RemoteIo::Impl::populateBlocks(size_t lowBlock, size_t highBlock) + { + assert(isMalloced_); + + // optimize: ignore all true blocks on left & right sides. + while(!blocksMap_[lowBlock].isNone() && lowBlock < highBlock) lowBlock++; + while(!blocksMap_[highBlock].isNone() && highBlock > lowBlock) highBlock--; + + size_t rcount = 0; + if (blocksMap_[highBlock].isNone()) + { + std::string data; + getDataByRange( (long) lowBlock, (long) highBlock, data); + rcount = (size_t)data.length(); + if (rcount == 0) { + throw Error(1, "Data By Range is empty. Please check the permission."); + } + byte* source = (byte*)data.c_str(); + size_t remain = rcount, totalRead = 0; + size_t iBlock = (rcount == size_) ? 0 : lowBlock; + + while (remain) { + size_t allow = EXV_MIN(remain, blockSize_); + blocksMap_[iBlock].populate(&source[totalRead], allow); + remain -= allow; + totalRead += allow; + iBlock++; + } + } + + return rcount; + } + + RemoteIo::Impl::~Impl() { + if (blocksMap_) delete[] blocksMap_; + } + + RemoteIo::~RemoteIo() + { + if (p_) { + close(); + delete p_; + } + } + + int RemoteIo::open() + { + close(); // reset the IO position + if (p_->isMalloced_ == false) { + long length = p_->getFileLength(); + if (length < 0) { // unable to get the length of remote file, get the whole file content. + std::string data; + p_->getDataByRange(-1, -1, data); + p_->size_ = (size_t) data.length(); + size_t nBlocks = (p_->size_ + p_->blockSize_ - 1) / p_->blockSize_; + p_->blocksMap_ = new BlockMap[nBlocks]; + p_->isMalloced_ = true; + byte* source = (byte*)data.c_str(); + size_t remain = p_->size_, iBlock = 0, totalRead = 0; + while (remain) { + size_t allow = EXV_MIN(remain, p_->blockSize_); + p_->blocksMap_[iBlock].populate(&source[totalRead], allow); + remain -= allow; + totalRead += allow; + iBlock++; + } + } else if (length == 0) { // file is empty + throw Error(1, "the file length is 0"); + } else { + p_->size_ = (size_t) length; + size_t nBlocks = (p_->size_ + p_->blockSize_ - 1) / p_->blockSize_; + p_->blocksMap_ = new BlockMap[nBlocks]; + p_->isMalloced_ = true; + } + } + return 0; // means OK + } + + int RemoteIo::close() + { + if (p_->isMalloced_) { + p_->eof_ = false; + p_->idx_ = 0; + } + return 0; + } + + long RemoteIo::write(const byte* /* unused data*/, long /* unused wcount*/) + { + return 0; // means failure + } + + long RemoteIo::write(BasicIo& src) + { + assert(p_->isMalloced_); + if (!src.isopen()) return 0; + + /* + * The idea is to compare the file content, find the different bytes and submit them to the remote machine. + * To simplify it, it: + * + goes from the left, find the first different position -> $left + * + goes from the right, find the first different position -> $right + * The different bytes are [$left-$right] part. + */ + long left = 0; + long right = 0; + long blockIndex = 0; + long i = 0; + long readCount = 0; + long blockSize = 0; + byte* buf = (byte*) std::malloc(p_->blockSize_); + long nBlocks = (long)((p_->size_ + p_->blockSize_ - 1) / p_->blockSize_); + + // find $left + src.seek(0, BasicIo::beg); + bool findDiff = false; + while (blockIndex < nBlocks && !src.eof() && !findDiff) { + blockSize = (long)p_->blocksMap_[blockIndex].getSize(); + bool isFakeData = p_->blocksMap_[blockIndex].isKnown(); // fake data + readCount = src.read(buf, blockSize); + byte* blockData = p_->blocksMap_[blockIndex].getData(); + for (i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) { + if ((!isFakeData && buf[i] != blockData[i]) || (isFakeData && buf[i] != 0)) { + findDiff = true; + } else { + left++; + } + } + blockIndex++; + } + + + // find $right + findDiff = false; + blockIndex = nBlocks - 1; + blockSize = (long)p_->blocksMap_[blockIndex].getSize(); + while ((blockIndex + 1 > 0) && right < src.size() && !findDiff) { + if(src.seek(-1 * (blockSize + right), BasicIo::end)) { + findDiff = true; + } else { + bool isFakeData = p_->blocksMap_[blockIndex].isKnown(); // fake data + readCount = src.read(buf, blockSize); + byte* blockData = p_->blocksMap_[blockIndex].getData(); + for (i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) { + if ((!isFakeData && buf[readCount - i - 1] != blockData[blockSize - i - 1]) || (isFakeData && buf[readCount - i - 1] != 0)) { + findDiff = true; + } else { + right++; + } + } + } + blockIndex--; + blockSize = (long)p_->blocksMap_[blockIndex].getSize(); + } + + // free buf + if (buf) std::free(buf); + + // submit to the remote machine. + long dataSize = src.size() - left - right; + if (dataSize > 0) { + byte* data = (byte*) std::malloc(dataSize); + src.seek(left, BasicIo::beg); + src.read(data, dataSize); + p_->writeRemote(data, (size_t)dataSize, left, (long) p_->size_ - right); + if (data) std::free(data); + } + return src.size(); + } + + int RemoteIo::putb(byte /*unused data*/) + { + return 0; + } + + DataBuf RemoteIo::read(long rcount) + { + DataBuf buf(rcount); + long readCount = read(buf.pData_, buf.size_); + buf.size_ = readCount; + return buf; + } + + long RemoteIo::read(byte* buf, long rcount) + { + assert(p_->isMalloced_); + if (p_->eof_) return 0; + + size_t allow = EXV_MIN(rcount, (long)( p_->size_ - p_->idx_)); + size_t lowBlock = p_->idx_ /p_->blockSize_; + size_t highBlock = (p_->idx_ + allow)/p_->blockSize_; + + // connect to the remote machine & populate the blocks just in time. + p_->populateBlocks(lowBlock, highBlock); + byte* fakeData = (byte*) std::calloc(p_->blockSize_, sizeof(byte)); + if (!fakeData) { + throw Error(1, "Unable to allocate data"); + } + + size_t iBlock = lowBlock; + size_t startPos = p_->idx_ - lowBlock*p_->blockSize_; + size_t totalRead = 0; + do { + byte* data = p_->blocksMap_[iBlock++].getData(); + if (data == NULL) data = fakeData; + size_t blockR = EXV_MIN(allow, p_->blockSize_ - startPos); + std::memcpy(&buf[totalRead], &data[startPos], blockR); + totalRead += blockR; + startPos = 0; + allow -= blockR; + } while(allow); + + if (fakeData) std::free(fakeData); + + p_->idx_ += (long) totalRead; + p_->eof_ = (p_->idx_ == (long) p_->size_); + + return (long) totalRead; + } + + int RemoteIo::getb() + { + assert(p_->isMalloced_); + if (p_->idx_ == (long)p_->size_) { + p_->eof_ = true; + return EOF; + } + + size_t expectedBlock = (p_->idx_ + 1)/p_->blockSize_; + // connect to the remote machine & populate the blocks just in time. + p_->populateBlocks(expectedBlock, expectedBlock); + + byte* data = p_->blocksMap_[expectedBlock].getData(); + return data[p_->idx_++ - expectedBlock*p_->blockSize_]; + } + + void RemoteIo::transfer(BasicIo& src) + { + if (src.open() != 0) { + throw Error(1, "unable to open src when transferring"); + } + write(src); + src.close(); + } + +#if defined(_MSC_VER) + int RemoteIo::seek( uint64_t offset, Position pos ) + { + assert(p_->isMalloced_); + uint64_t newIdx = 0; + + switch (pos) { + case BasicIo::cur: newIdx = p_->idx_ + offset; break; + case BasicIo::beg: newIdx = offset; break; + case BasicIo::end: newIdx = p_->size_ + offset; break; + } + + if ( /*newIdx < 0 || */ newIdx > static_cast(p_->size_) ) return 1; + p_->idx_ = static_cast(newIdx); //not very sure about this. need more test!! - note by Shawn fly2xj@gmail.com //TODO + p_->eof_ = false; + return 0; + } +#else + int RemoteIo::seek(long offset, Position pos) + { + assert(p_->isMalloced_); + long newIdx = 0; + + switch (pos) { + case BasicIo::cur: newIdx = p_->idx_ + offset; break; + case BasicIo::beg: newIdx = offset; break; + case BasicIo::end: newIdx = p_->size_ + offset; break; + } + + if (newIdx < 0 || newIdx > (long) p_->size_) return 1; + p_->idx_ = newIdx; + p_->eof_ = false; + return 0; + } +#endif + + byte* RemoteIo::mmap(bool /*isWriteable*/) + { + return NULL; + } + + int RemoteIo::munmap() + { + return 0; + } + + long RemoteIo::tell() const + { + return p_->idx_; + } + + long RemoteIo::size() const + { + return (long) p_->size_; + } + + bool RemoteIo::isopen() const + { + return p_->isMalloced_; + } + + int RemoteIo::error() const + { + return 0; + } + + bool RemoteIo::eof() const + { + return p_->eof_; + } + + std::string RemoteIo::path() const + { + return p_->path_; + } + +#ifdef EXV_UNICODE_PATH + std::wstring RemoteIo::wpath() const + { + return p_->wpath_; + } +#endif + + BasicIo::AutoPtr RemoteIo::temporary() const + { + return BasicIo::AutoPtr(new MemIo); + } + + void RemoteIo::populateFakeData() + { + assert(p_->isMalloced_); + size_t nBlocks = (p_->size_ + p_->blockSize_ - 1) / p_->blockSize_; + for (size_t i = 0; i < nBlocks; i++) { + if (p_->blocksMap_[i].isNone()) + p_->blocksMap_[i].markKnown(p_->blockSize_); + } + } + + + //! Internal Pimpl structure of class HttpIo. + class HttpIo::HttpImpl : public Impl { + public: + //! Constructor + HttpImpl(const std::string& path, size_t blockSize); +#ifdef EXV_UNICODE_PATH + //! Constructor accepting a unicode path in an std::wstring + HttpImpl(const std::wstring& wpath, size_t blockSize); +#endif + Exiv2::Uri hostInfo_; //!< the host information extracted from the path + + // METHODS + /*! + @brief Get the length (in bytes) of the remote file. + @return Return -1 if the size is unknown. Otherwise it returns the length of remote file (in bytes). + @throw Error if the server returns the error code. + */ + long getFileLength(); + /*! + @brief Get the data by range. + @param lowBlock The start block index. + @param highBlock The end block index. + @param response The data from the server. + @throw Error if the server returns the error code. + @note Set lowBlock = -1 and highBlock = -1 to get the whole file content. + */ + void getDataByRange(long lowBlock, long highBlock, std::string& response); + /*! + @brief Submit the data to the remote machine. The data replace a part of the remote file. + The replaced part of remote file is indicated by from and to parameters. + @param data The data are submitted to the remote machine. + @param size The size of data. + @param from The start position in the remote file where the data replace. + @param to The end position in the remote file where the data replace. + @note The data are submitted to the remote machine via POST. This requires the script file + on the remote machine to receive the data and edit the remote file. The server-side + script may be specified with the environment string EXIV2_HTTP_POST. The default value is + "/exiv2.php". More info is available at http://dev.exiv2.org/wiki/exiv2 + @throw Error if it fails. + */ + void writeRemote(const byte* data, size_t size, long from, long to); + protected: + // NOT IMPLEMENTED + HttpImpl(const HttpImpl& rhs); //!< Copy constructor + HttpImpl& operator=(const HttpImpl& rhs); //!< Assignment + }; // class HttpIo::HttpImpl + + HttpIo::HttpImpl::HttpImpl(const std::string& url, size_t blockSize):Impl(url, blockSize) + { + hostInfo_ = Exiv2::Uri::Parse(url); + Exiv2::Uri::Decode(hostInfo_); + } +#ifdef EXV_UNICODE_PATH + HttpIo::HttpImpl::HttpImpl(const std::wstring& wurl, size_t blockSize):Impl(wurl, blockSize) + { + std::string url; + url.assign(wurl.begin(), wurl.end()); + path_ = url; + + hostInfo_ = Exiv2::Uri::Parse(url); + Exiv2::Uri::Decode(hostInfo_); + } +#endif + + long HttpIo::HttpImpl::getFileLength() + { + dict_t response; + dict_t request; + std::string errors; + request["server"] = hostInfo_.Host; + request["page" ] = hostInfo_.Path; + if (hostInfo_.Port != "") request["port"] = hostInfo_.Port; + request["verb"] = "HEAD"; + long serverCode = (long)http(request, response, errors); + if (serverCode < 0 || serverCode >= 400 || errors.compare("") != 0) { + throw Error(55, "Server", serverCode); + } + + dict_i lengthIter = response.find("Content-Length"); + return (lengthIter == response.end()) ? -1 : atol((lengthIter->second).c_str()); + } + + void HttpIo::HttpImpl::getDataByRange(long lowBlock, long highBlock, std::string& response) + { + dict_t responseDic; + dict_t request; + request["server"] = hostInfo_.Host; + request["page" ] = hostInfo_.Path; + if (hostInfo_.Port != "") request["port"] = hostInfo_.Port; + request["verb"] = "GET"; + std::string errors; + if (lowBlock > -1 && highBlock > -1) { + std::stringstream ss; + ss << "Range: bytes=" << lowBlock * blockSize_ << "-" << ((highBlock + 1) * blockSize_ - 1) << "\r\n"; + request["header"] = ss.str(); + } + + long serverCode = (long)http(request, responseDic, errors); + if (serverCode < 0 || serverCode >= 400 || errors.compare("") != 0) { + throw Error(55, "Server", serverCode); + } + response = responseDic["body"]; + } + + void HttpIo::HttpImpl::writeRemote(const byte* data, size_t size, long from, long to) + { + std::string scriptPath(getEnv(envHTTPPOST)); + if (scriptPath == "") { + throw Error(1, "Please set the path of the server script to handle http post data to EXIV2_HTTP_POST environmental variable."); + } + + // standadize the path without "/" at the beginning. + std::size_t protocolIndex = scriptPath.find("://"); + if (protocolIndex == std::string::npos && scriptPath[0] != '/') { + scriptPath = "/" + scriptPath; + } + + dict_t response; + dict_t request; + std::string errors; + + Uri scriptUri = Exiv2::Uri::Parse(scriptPath); + request["server"] = scriptUri.Host == "" ? hostInfo_.Host : scriptUri.Host; + if (scriptUri.Port != "") request["port"] = scriptUri.Port; + request["page"] = scriptUri.Path; + request["verb"] = "POST"; + + // encode base64 + size_t encodeLength = ((size + 2) / 3) * 4 + 1; + char* encodeData = new char[encodeLength]; + base64encode(data, size, encodeData, encodeLength); + // url encode + char* urlencodeData = urlencode(encodeData); + delete[] encodeData; + + std::stringstream ss; + ss << "path=" << hostInfo_.Path << "&" + << "from=" << from << "&" + << "to=" << to << "&" + << "data=" << urlencodeData; + std::string postData = ss.str(); + delete[] urlencodeData; + + // create the header + ss.str(""); + ss << "Content-Length: " << postData.length() << "\n" + << "Content-Type: application/x-www-form-urlencoded\n" + << "\n" << postData << "\r\n"; + request["header"] = ss.str(); + + int serverCode = http(request, response, errors); + if (serverCode < 0 || serverCode >= 400 || errors.compare("") != 0) { + throw Error(55, "Server", serverCode); + } + } + HttpIo::HttpIo(const std::string& url, size_t blockSize) + { + p_ = new HttpImpl(url, blockSize); + } +#ifdef EXV_UNICODE_PATH + HttpIo::HttpIo(const std::wstring& wurl, size_t blockSize) + { + p_ = new HttpImpl(wurl, blockSize); + } +#endif + +#if EXV_USE_CURL == 1 + //! Internal Pimpl structure of class RemoteIo. + class CurlIo::CurlImpl : public Impl { + public: + //! Constructor + CurlImpl(const std::string& path, size_t blockSize); +#ifdef EXV_UNICODE_PATH + //! Constructor accepting a unicode path in an std::wstring + CurlImpl(const std::wstring& wpath, size_t blockSize); +#endif + //! Destructor. Cleans up the curl pointer and releases all managed memory. + ~CurlImpl(); + + CURL* curl_; //!< libcurl pointer + + // METHODS + /*! + @brief Get the length (in bytes) of the remote file. + @return Return -1 if the size is unknown. Otherwise it returns the length of remote file (in bytes). + @throw Error if the server returns the error code. + */ + long getFileLength(); + /*! + @brief Get the data by range. + @param lowBlock The start block index. + @param highBlock The end block index. + @param response The data from the server. + @throw Error if the server returns the error code. + @note Set lowBlock = -1 and highBlock = -1 to get the whole file content. + */ + void getDataByRange(long lowBlock, long highBlock, std::string& response); + /*! + @brief Submit the data to the remote machine. The data replace a part of the remote file. + The replaced part of remote file is indicated by from and to parameters. + @param data The data are submitted to the remote machine. + @param size The size of data. + @param from The start position in the remote file where the data replace. + @param to The end position in the remote file where the data replace. + @throw Error if it fails. + @note The write access is only available on HTTP & HTTPS protocols. The data are submitted to server + via POST method. It requires the script file on the remote machine to receive the data + and edit the remote file. The server-side script may be specified with the environment + string EXIV2_HTTP_POST. The default value is "/exiv2.php". More info is available at + http://dev.exiv2.org/wiki/exiv2 + */ + void writeRemote(const byte* data, size_t size, long from, long to); + protected: + // NOT IMPLEMENTED + CurlImpl(const CurlImpl& rhs); //!< Copy constructor + CurlImpl& operator=(const CurlImpl& rhs); //!< Assignment + private: + long timeout_; //!< The number of seconds to wait while trying to connect. + }; // class RemoteIo::Impl + + CurlIo::CurlImpl::CurlImpl(const std::string& url, size_t blockSize):Impl(url, blockSize) + { + // init curl pointer + curl_ = curl_easy_init(); + if(!curl_) { + throw Error(1, "Uable to init libcurl."); + } + + // The default block size for FTP is much larger than other protocols + // the reason is that getDataByRange() in FTP always creates the new connection, + // so we need the large block size to reduce the overhead of creating the connection. + if (blockSize_ == 0) { + blockSize_ = protocol_ == pFtp ? 102400 : 1024; + } + + std::string timeout = getEnv(envTIMEOUT); + timeout_ = atol(timeout.c_str()); + if (timeout_ == 0) { + throw Error(1, "Timeout Environmental Variable must be a positive integer."); + } + } +#ifdef EXV_UNICODE_PATH + CurlIo::CurlImpl::CurlImpl(const std::wstring& wurl, size_t blockSize):Impl(wurl, blockSize) + { + std::string url; + url.assign(wurl.begin(), wurl.end()); + path_ = url; + + // init curl pointer + curl_ = curl_easy_init(); + if(!curl_) { + throw Error(1, "Uable to init libcurl."); + } + + // The default block size for FTP is much larger than other protocols + // the reason is that getDataByRange() in FTP always creates the new connection, + // so we need the large block size to reduce the overhead of creating the connection. + if (blockSize_ == 0) { + blockSize_ = protocol_ == pFtp ? 102400 : 1024; + } + } +#endif + + long CurlIo::CurlImpl::getFileLength() + { + curl_easy_reset(curl_); // reset all options + std::string response; + curl_easy_setopt(curl_, CURLOPT_URL, path_.c_str()); + curl_easy_setopt(curl_, CURLOPT_NOBODY, 1); // HEAD + curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, curlWriter); + curl_easy_setopt(curl_, CURLOPT_WRITEDATA, &response); + curl_easy_setopt(curl_, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl_, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl_, CURLOPT_CONNECTTIMEOUT, timeout_); + //curl_easy_setopt(curl_, CURLOPT_VERBOSE, 1); // debugging mode + + /* Perform the request, res will get the return code */ + CURLcode res = curl_easy_perform(curl_); + if(res != CURLE_OK) { // error happends + throw Error(1, curl_easy_strerror(res)); + } + // get return code + long returnCode; + curl_easy_getinfo (curl_, CURLINFO_RESPONSE_CODE, &returnCode); // get code + if (returnCode >= 400 || returnCode < 0) { + throw Error(55, "Server", returnCode); + } + // get length + double temp; + curl_easy_getinfo(curl_, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &temp); // return -1 if unknown + return (long) temp; + } + + void CurlIo::CurlImpl::getDataByRange(long lowBlock, long highBlock, std::string& response) + { + curl_easy_reset(curl_); // reset all options + curl_easy_setopt(curl_, CURLOPT_URL, path_.c_str()); + curl_easy_setopt(curl_, CURLOPT_NOPROGRESS, 1L); // no progress meter please + curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, curlWriter); + curl_easy_setopt(curl_, CURLOPT_WRITEDATA, &response); + curl_easy_setopt(curl_, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl_, CURLOPT_CONNECTTIMEOUT, timeout_); + //curl_easy_setopt(curl_, CURLOPT_VERBOSE, 1); // debugging mode + + if (lowBlock > -1 && highBlock> -1) { + std::stringstream ss; + ss << lowBlock * blockSize_ << "-" << ((highBlock + 1) * blockSize_ - 1); + std::string range = ss.str(); + curl_easy_setopt(curl_, CURLOPT_RANGE, range.c_str()); + } + + /* Perform the request, res will get the return code */ + CURLcode res = curl_easy_perform(curl_); + + if(res != CURLE_OK) { + throw Error(1, curl_easy_strerror(res)); + } else { + long serverCode; + curl_easy_getinfo (curl_, CURLINFO_RESPONSE_CODE, &serverCode); // get code + if (serverCode >= 400 || serverCode < 0) { + throw Error(55, "Server", serverCode); + } + } + } + + void CurlIo::CurlImpl::writeRemote(const byte* data, size_t size, long from, long to) + { + std::string scriptPath(getEnv(envHTTPPOST)); + if (scriptPath == "") { + throw Error(1, "Please set the path of the server script to handle http post data to EXIV2_HTTP_POST environmental variable."); + } + + Exiv2::Uri hostInfo = Exiv2::Uri::Parse(path_); + + // add the protocol and host to the path + std::size_t protocolIndex = scriptPath.find("://"); + if (protocolIndex == std::string::npos) { + if (scriptPath[0] != '/') scriptPath = "/" + scriptPath; + scriptPath = hostInfo.Protocol + "://" + hostInfo.Host + scriptPath; + } + + curl_easy_reset(curl_); // reset all options + curl_easy_setopt(curl_, CURLOPT_NOPROGRESS, 1L); // no progress meter please + //curl_easy_setopt(curl_, CURLOPT_VERBOSE, 1); // debugging mode + curl_easy_setopt(curl_, CURLOPT_URL, scriptPath.c_str()); + curl_easy_setopt(curl_, CURLOPT_SSL_VERIFYPEER, 0L); + + + // encode base64 + size_t encodeLength = ((size + 2) / 3) * 4 + 1; + char* encodeData = new char[encodeLength]; + base64encode(data, size, encodeData, encodeLength); + // url encode + char* urlencodeData = urlencode(encodeData); + delete[] encodeData; + std::stringstream ss; + ss << "path=" << hostInfo.Path << "&" + << "from=" << from << "&" + << "to=" << to << "&" + << "data=" << urlencodeData; + std::string postData = ss.str(); + delete[] urlencodeData; + + curl_easy_setopt(curl_, CURLOPT_POSTFIELDS, postData.c_str()); + // Perform the request, res will get the return code. + CURLcode res = curl_easy_perform(curl_); + + if(res != CURLE_OK) { + throw Error(1, curl_easy_strerror(res)); + } else { + long serverCode; + curl_easy_getinfo (curl_, CURLINFO_RESPONSE_CODE, &serverCode); + if (serverCode >= 400 || serverCode < 0) { + throw Error(55, "Server", serverCode); + } + } + } + + CurlIo::CurlImpl::~CurlImpl() { + curl_easy_cleanup(curl_); + } + + long CurlIo::write(const byte* data, long wcount) + { + if (p_->protocol_ == pHttp || p_->protocol_ == pHttps) { + return RemoteIo::write(data, wcount); + } else { + throw Error(1, "doesnt support write for this protocol."); + } + } + + long CurlIo::write(BasicIo& src) + { + if (p_->protocol_ == pHttp || p_->protocol_ == pHttps) { + return RemoteIo::write(src); + } else { + throw Error(1, "doesnt support write for this protocol."); + } + } + + CurlIo::CurlIo(const std::string& url, size_t blockSize) + { + p_ = new CurlImpl(url, blockSize); + } +#ifdef EXV_UNICODE_PATH + CurlIo::CurlIo(const std::wstring& wurl, size_t blockSize) + { + p_ = new CurlImpl(wurl, blockSize); + } +#endif + +#endif + + +#if EXV_USE_SSH == 1 + //! Internal Pimpl structure of class RemoteIo. + class SshIo::SshImpl : public Impl { + public: + //! Constructor + SshImpl(const std::string& path, size_t blockSize); +#ifdef EXV_UNICODE_PATH + //! Constructor accepting a unicode path in an std::wstring + SshImpl(const std::wstring& wpath, size_t blockSize); +#endif + //! Destructor. Closes ssh session and releases all managed memory. + ~SshImpl(); + + Exiv2::Uri hostInfo_; //!< host information extracted from path + SSH* ssh_; //!< SSH pointer + sftp_file fileHandler_; //!< sftp file handler + + // METHODS + /*! + @brief Get the length (in bytes) of the remote file. + @return Return -1 if the size is unknown. Otherwise it returns the length of remote file (in bytes). + @throw Error if the server returns the error code. + */ + long getFileLength(); + /*! + @brief Get the data by range. + @param lowBlock The start block index. + @param highBlock The end block index. + @param response The data from the server. + @throw Error if the server returns the error code. + @note Set lowBlock = -1 and highBlock = -1 to get the whole file content. + */ + void getDataByRange(long lowBlock, long highBlock, std::string& response); + /*! + @brief Submit the data to the remote machine. The data replace a part of the remote file. + The replaced part of remote file is indicated by from and to parameters. + @param data The data are submitted to the remote machine. + @param size The size of data. + @param from The start position in the remote file where the data replace. + @param to The end position in the remote file where the data replace. + @note The write access is only available on the SSH protocol. It requires the write permission + to edit the remote file. + @throw Error if it fails. + */ + void writeRemote(const byte* data, size_t size, long from, long to); + + protected: + // NOT IMPLEMENTED + SshImpl(const SshImpl& rhs); //!< Copy constructor + SshImpl& operator=(const SshImpl& rhs); //!< Assignment + }; // class RemoteIo::Impl + + SshIo::SshImpl::SshImpl(const std::string& url, size_t blockSize):Impl(url, blockSize) + { + hostInfo_ = Exiv2::Uri::Parse(url); + Exiv2::Uri::Decode(hostInfo_); + + // remove / at the beginning of the path + if (hostInfo_.Path[0] == '/') { + hostInfo_.Path = hostInfo_.Path.substr(1); + } + ssh_ = new SSH(hostInfo_.Host, hostInfo_.Username, hostInfo_.Password, hostInfo_.Port); + + if (protocol_ == pSftp) { + ssh_->getFileSftp(hostInfo_.Path, fileHandler_); + if (fileHandler_ == NULL) throw Error(1, "Unable to open the file"); + } else { + fileHandler_ = NULL; + } + } +#ifdef EXV_UNICODE_PATH + SshIo::SshImpl::SshImpl(const std::wstring& wurl, size_t blockSize):Impl(wurl, blockSize) + { + std::string url; + url.assign(wurl.begin(), wurl.end()); + path_ = url; + + hostInfo_ = Exiv2::Uri::Parse(url); + Exiv2::Uri::Decode(hostInfo_); + + // remove / at the beginning of the path + if (hostInfo_.Path[0] == '/') { + hostInfo_.Path = hostInfo_.Path.substr(1); + } + ssh_ = new SSH(hostInfo_.Host, hostInfo_.Username, hostInfo_.Password, hostInfo_.Port); + + if (protocol_ == pSftp) { + ssh_->getFileSftp(hostInfo_.Path, fileHandler_); + if (fileHandler_ == NULL) throw Error(1, "Unable to open the file"); + } else { + fileHandler_ = NULL; + } + } +#endif + + long SshIo::SshImpl::getFileLength() + { + long length = 0; + if (protocol_ == pSftp) { // sftp + sftp_attributes attributes = sftp_fstat(fileHandler_); + length = (long)attributes->size; + } else { // ssh + std::string response; + //std::string cmd = "stat -c %s " + hostInfo_.Path; + std::string cmd = "declare -a x=($(ls -alt " + hostInfo_.Path + ")); echo ${x[4]}"; + if (ssh_->runCommand(cmd, &response) != 0) { + throw Error(1, "Unable to get file length."); + } else { + length = atol(response.c_str()); + if (length == 0) { + throw Error(1, "File is empty or not found."); + } + } + } + return length; + } + + void SshIo::SshImpl::getDataByRange(long lowBlock, long highBlock, std::string& response) + { + if (protocol_ == pSftp) { + if (sftp_seek(fileHandler_, (uint32_t) (lowBlock * blockSize_)) < 0) throw Error(1, "SFTP: unable to sftp_seek"); + size_t buffSize = (highBlock - lowBlock + 1) * blockSize_; + char* buffer = new char[buffSize]; + long nBytes = (long) sftp_read(fileHandler_, buffer, buffSize); + if (nBytes < 0) throw Error(1, "SFTP: unable to sftp_read"); + response.assign(buffer, buffSize); + delete[] buffer; + } else { + std::stringstream ss; + if (lowBlock > -1 && highBlock > -1) { + ss << "dd if=" << hostInfo_.Path + << " ibs=" << blockSize_ + << " skip=" << lowBlock + << " count=" << (highBlock - lowBlock) + 1<< " 2>/dev/null"; + } else { + ss << "dd if=" << hostInfo_.Path + << " ibs=" << blockSize_ + << " 2>/dev/null"; + } + std::string cmd = ss.str(); + if (ssh_->runCommand(cmd, &response) != 0) { + throw Error(1, "Unable to get data by range."); + } + } + } + + void SshIo::SshImpl::writeRemote(const byte* data, size_t size, long from, long to) + { + if (protocol_ == pSftp) throw Error(1, "not support SFTP write access."); + + //printf("ssh update size=%ld from=%ld to=%ld\n", (long)size, from, to); + assert(isMalloced_); + + std::string tempFile = hostInfo_.Path + ".exiv2tmp"; + std::string response; + std::stringstream ss; + // copy the head (byte 0 to byte fromByte) of original file to filepath.exiv2tmp + ss << "head -c " << from + << " " << hostInfo_.Path + << " > " << tempFile; + std::string cmd = ss.str(); + if (ssh_->runCommand(cmd, &response) != 0) { + throw Error(1, "SSH: Unable to cope the head of file to temp"); + } + + // upload the data (the byte ranges which are different between the original + // file and the new file) to filepath.exiv2datatemp + if (ssh_->scp(hostInfo_.Path + ".exiv2datatemp", data, size) != 0) { + throw Error(1, "SSH: Unable to copy file"); + } + + // concatenate the filepath.exiv2datatemp to filepath.exiv2tmp + cmd = "cat " + hostInfo_.Path + ".exiv2datatemp >> " + tempFile; + if (ssh_->runCommand(cmd, &response) != 0) { + throw Error(1, "SSH: Unable to copy the rest"); + } + + // copy the tail (from byte toByte to the end of file) of original file to filepath.exiv2tmp + ss.str(""); + ss << "tail -c+" << (to + 1) + << " " << hostInfo_.Path + << " >> " << tempFile; + cmd = ss.str(); + if (ssh_->runCommand(cmd, &response) != 0) { + throw Error(1, "SSH: Unable to copy the rest"); + } + + // replace the original file with filepath.exiv2tmp + cmd = "mv " + tempFile + " " + hostInfo_.Path; + if (ssh_->runCommand(cmd, &response) != 0) { + throw Error(1, "SSH: Unable to copy the rest"); + } + + // remove filepath.exiv2datatemp + cmd = "rm " + hostInfo_.Path + ".exiv2datatemp"; + if (ssh_->runCommand(cmd, &response) != 0) { + throw Error(1, "SSH: Unable to copy the rest"); + } + } + + SshIo::SshImpl::~SshImpl() { + if (fileHandler_) sftp_close(fileHandler_); + if (ssh_) delete ssh_; + } + + SshIo::SshIo(const std::string& url, size_t blockSize) + { + p_ = new SshImpl(url, blockSize); + } +#ifdef EXV_UNICODE_PATH + SshIo::SshIo(const std::wstring& wurl, size_t blockSize) + { + p_ = new SshImpl(wurl, blockSize); + } +#endif + +#endif + // ************************************************************************* // free functions @@ -1390,5 +2650,34 @@ namespace Exiv2 { return file.write(buf.pData_, buf.size_); } +#endif + std::string ReplaceStringInPlace(std::string subject, const std::string& search, + const std::string& replace) { + size_t pos = 0; + while((pos = subject.find(search, pos)) != std::string::npos) { + subject.replace(pos, search.length(), replace); + pos += replace.length(); + } + return subject; + } +#ifdef EXV_UNICODE_PATH + std::wstring ReplaceStringInPlace(std::wstring subject, const std::wstring& search, + const std::wstring& replace) { + std::wstring::size_type pos = 0; + while((pos = subject.find(search, pos)) != std::wstring::npos) { + subject.replace(pos, search.length(), replace); + pos += replace.length(); + } + return subject; + } +#endif +#if EXV_USE_CURL == 1 + size_t curlWriter(char* data, size_t size, size_t nmemb, + std::string* writerData) + { + if (writerData == NULL) return 0; + writerData->append(data, size*nmemb); + return size * nmemb; + } #endif } // namespace Exiv2 diff --git a/src/bmpimage.cpp b/src/bmpimage.cpp index 4b183780..aeb86a05 100644 --- a/src/bmpimage.cpp +++ b/src/bmpimage.cpp @@ -28,15 +28,9 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -//#define DEBUG 1 - -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" + #include "bmpimage.hpp" #include "image.hpp" #include "basicio.hpp" diff --git a/src/cr2image.cpp b/src/cr2image.cpp index b90ea095..e974cb85 100644 --- a/src/cr2image.cpp +++ b/src/cr2image.cpp @@ -29,13 +29,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "cr2image.hpp" #include "cr2image_int.hpp" @@ -280,6 +275,7 @@ namespace Exiv2 { buf.pData_[0] = 0x4d; buf.pData_[1] = 0x4d; break; + case asciiBytes: case invalidByteOrder: assert(false); break; diff --git a/src/crwimage.cpp b/src/crwimage.cpp index f6bc554f..008c751d 100644 --- a/src/crwimage.cpp +++ b/src/crwimage.cpp @@ -29,17 +29,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// Define DEBUG to output debug information to std::cerr, e.g, by calling make -// like this: make DEFS=-DDEBUG crwimage.o -//#define DEBUG 1 - -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "crwimage.hpp" #include "crwimage_int.hpp" diff --git a/src/epsimage.cpp b/src/epsimage.cpp index 8840f70d..87291774 100644 --- a/src/epsimage.cpp +++ b/src/epsimage.cpp @@ -29,17 +29,9 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id: epsimage.cpp $") -// ***************************************************************************** - -//#define DEBUG 1 - -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" + #include "epsimage.hpp" #include "image.hpp" #include "basicio.hpp" diff --git a/src/exif.cpp b/src/exif.cpp index 99338ae6..09cfe618 100644 --- a/src/exif.cpp +++ b/src/exif.cpp @@ -29,13 +29,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "exif.hpp" #include "metadatum.hpp" diff --git a/src/exiv2.cpp b/src/exiv2.cpp index 7ac6810a..97ceaeb5 100644 --- a/src/exiv2.cpp +++ b/src/exiv2.cpp @@ -30,13 +30,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "exiv2app.hpp" #include "actions.hpp" @@ -53,6 +48,13 @@ EXIV2_RCSID("@(#) $Id$") #include #include +#if defined(__MINGW32__) || defined(__MINGW64__) +# ifndef __MINGW__ +# define __MINGW__ +# endif +#endif + + // ***************************************************************************** // local declarations namespace { @@ -225,7 +227,7 @@ void Params::version(bool verbose,std::ostream& os) const "License along with this program; if not, write to the Free\n" "Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\n" "Boston, MA 02110-1301 USA\n"); - + if ( verbose ) dumpLibraryInfo(os); } @@ -1037,6 +1039,28 @@ namespace { } } // parseCmdLines +#if defined(_MSC_VER) || defined(__MINGW__) + static std::string formatArg(const char* arg) + { + std::string result = ""; + char b = ' ' ; + char e = '\\'; std::string E = std::string("\\"); + char q = '\''; std::string Q = std::string("'" ); + bool qt = false; + char* a = (char*) arg; + while ( *a ) { + if ( *a == b || *a == e || *a == q ) qt = true; + if ( *a == q ) result += E; + if ( *a == e ) result += E; + result += std::string(a,1); + a++ ; + } + if (qt) result = Q + result + Q; + + return result; + } +#endif + bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) { const std::string delim = " \t"; @@ -1052,8 +1076,12 @@ namespace { if ( cmdStart == std::string::npos || cmdEnd == std::string::npos || keyStart == std::string::npos) { + std::string cmdLine ; +#if defined(_MSC_VER) || defined(__MINGW__) + for ( int i = 1 ; i < __argc ; i++ ) { cmdLine += std::string(" ") + formatArg(__argv[i]) ; } +#endif throw Exiv2::Error(1, Exiv2::toString(num) - + ": " + _("Invalid command line")); + + ": " + _("Invalid command line:") + cmdLine); } std::string cmd(line.substr(cmdStart, cmdEnd-cmdStart)); @@ -1165,7 +1193,7 @@ namespace { return cmdIdAndString[i].cmdId_; } - std::string parseEscapes(const std::string& input) + std::string parseEscapes(const std::string& input) { std::string result = ""; for (unsigned int i = 0; i < input.length(); ++i) { @@ -1242,4 +1270,4 @@ namespace { } } - + diff --git a/src/futils.cpp b/src/futils.cpp index 95da9ccc..bc30cba0 100644 --- a/src/futils.cpp +++ b/src/futils.cpp @@ -29,13 +29,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "futils.hpp" @@ -52,6 +47,7 @@ EXIV2_RCSID("@(#) $Id$") #include #include #include +#include #if defined EXV_HAVE_STRERROR_R && !defined EXV_HAVE_DECL_STRERROR_R # ifdef EXV_STRERROR_R_CHAR_P @@ -62,14 +58,237 @@ extern int strerror_r(int errnum, char *buf, size_t n); #endif namespace Exiv2 { - + const char* ENVARDEF[] = {"/exiv2.php", "40"}; + const char* ENVARKEY[] = {"EXIV2_HTTP_POST", "EXIV2_TIMEOUT"}; // ***************************************************************************** // free functions + std::string getEnv(EnVar var) { + return getenv(ENVARKEY[var]) ? getenv(ENVARKEY[var]) : ENVARDEF[var]; + } // getEnv + char to_hex(char code) { + static char hex[] = "0123456789abcdef"; + return hex[code & 15]; + } // to_hex + + char from_hex(char ch) { + return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10; + } // from_hex + + char* urlencode(char* str) { + char* pstr = str; + char* buf = (char*)malloc(strlen(str) * 3 + 1); + char* pbuf = buf; + while (*pstr) { + if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') + *pbuf++ = *pstr; + else if (*pstr == ' ') + *pbuf++ = '+'; + else + *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15); + pstr++; + } + *pbuf = '\0'; + return buf; + } // urlencode + + char* urldecode(const char* str) { + const char* pstr = str; + char* buf = (char*)malloc(strlen(str) + 1); + char* pbuf = buf; + while (*pstr) { + if (*pstr == '%') { + if (pstr[1] && pstr[2]) { + *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]); + pstr += 2; + } + } else if (*pstr == '+') { + *pbuf++ = ' '; + } else { + *pbuf++ = *pstr; + } + pstr++; + } + *pbuf = '\0'; + return buf; + } // urldecode + + void urldecode(std::string& str) { + char* decodeStr = Exiv2::urldecode(str.c_str()); + str = std::string(decodeStr); + free(decodeStr); + } // urldecode(const std::string& str) + + int base64encode(const void* data_buf, size_t dataLength, char* result, size_t resultSize) { + const char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + const uint8_t* data = (const uint8_t*)data_buf; + size_t resultIndex = 0; + size_t x; + uint32_t n = 0; + size_t padCount = dataLength % 3; + uint8_t n0, n1, n2, n3; + + /* increment over the length of the string, three characters at a time */ + for (x = 0; x < dataLength; x += 3) + { + /* these three 8-bit (ASCII) characters become one 24-bit number */ + n = data[x] << 16; + + if((x+1) < dataLength) + n += data[x+1] << 8; + + if((x+2) < dataLength) + n += data[x+2]; + + /* this 24-bit number gets separated into four 6-bit numbers */ + n0 = (uint8_t)(n >> 18) & 63; + n1 = (uint8_t)(n >> 12) & 63; + n2 = (uint8_t)(n >> 6) & 63; + n3 = (uint8_t)n & 63; + + /* + * if we have one byte available, then its encoding is spread + * out over two characters + */ + if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */ + result[resultIndex++] = base64chars[n0]; + if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */ + result[resultIndex++] = base64chars[n1]; + + /* + * if we have only two bytes available, then their encoding is + * spread out over three chars + */ + if((x+1) < dataLength) + { + if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */ + result[resultIndex++] = base64chars[n2]; + } + + /* + * if we have all three bytes available, then their encoding is spread + * out over four characters + */ + if((x+2) < dataLength) + { + if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */ + result[resultIndex++] = base64chars[n3]; + } + } + + /* + * create and add padding that is required if we did not have a multiple of 3 + * number of characters available + */ + if (padCount > 0) + { + for (; padCount < 3; padCount++) + { + if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */ + result[resultIndex++] = '='; + } + } + if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */ + result[resultIndex] = 0; + return 1; /* indicate success */ + } // base64encode + + long base64decode(const char *in, char *out, size_t out_size) { + static const char decode[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW" + "$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; + long len; + long i; + long done = 0; + unsigned char v; + unsigned char quad[4]; + + while (*in) { + len = 0; + for (i = 0; i < 4 && *in; i++) { + v = 0; + while (*in && !v) { + v = *in++; + v = (v < 43 || v > 122) ? 0 : decode[v - 43]; + if (v) + v = (v == '$') ? 0 : v - 61; + if (*in) { + len++; + if (v) + quad[i] = v - 1; + } else + quad[i] = 0; + } + } + if (!len) + continue; + if (out_size < (size_t) (done + len - 1)) + /* out buffer is too small */ + return -1; + if (len >= 2) + *out++ = quad[0] << 2 | quad[1] >> 4; + if (len >= 3) + *out++ = quad[1] << 4 | quad[2] >> 2; + if (len >= 4) + *out++ = ((quad[2] << 6) & 0xc0) | quad[3]; + done += len - 1; + } + if ((size_t)(done + 1) >= out_size) + return -1; + *out++ = '\0'; + return done; + } // base64decode + + Protocol fileProtocol(const std::string& path) { + Protocol result = pFile ; + static Exiv2::protDict_t protDict; + if (!protDict.size()) { + protDict["http://" ] = pHttp; + protDict["ftp://" ] = pFtp; + protDict["https://"] = pHttps; + protDict["sftp://" ] = pSftp; + protDict["ssh://" ] = pSsh; + protDict["file://" ] = pFileUri; + protDict["data:" ] = pDataUri; + protDict["-" ] = pStdin; + } + for (Exiv2::protDict_i it = protDict.begin(); it != protDict.end(); it++) { + if (path.find(it->first) == 0) + result = it->second; + } + return result; + } // fileProtocol +#ifdef EXV_UNICODE_PATH + Protocol fileProtocol(const std::wstring& wpath) { + Protocol result = pFile ; + static wprotDict_t protDict; + if (!protDict.size()) { + protDict[L"http://" ] = pHttp; + protDict[L"ftp://" ] = pFtp; + protDict[L"https://" ] = pHttps; + protDict[L"sftp://" ] = pSftp; + protDict[L"ssh://" ] = pSsh; + protDict[L"file:///" ] = pFileUri; + protDict[L"data:" ] = pDataUri; + protDict[L"-" ] = pStdin; + } + for (wprotDict_i it = protDict.begin(); it != protDict.end(); it++) { + if (wpath.find(it->first) == 0) { + result = it->second; + break; + } + } + return result; + } // fileProtocol +#endif bool fileExists(const std::string& path, bool ct) { + // special case: accept "-" (means stdin) + if (path.compare("-") == 0 || fileProtocol(path)) { + return true; + } + struct stat buf; - int ret = ::stat(path.c_str(), &buf); + int ret = ::stat(path.c_str(), &buf); if (0 != ret) return false; if (ct && !S_ISREG(buf.st_mode)) return false; return true; @@ -78,6 +297,11 @@ namespace Exiv2 { #ifdef EXV_UNICODE_PATH bool fileExists(const std::wstring& wpath, bool ct) { + // special case: accept "-" (means stdin) + if (wpath.compare(L"-") == 0 || fileProtocol(wpath)) { + return true; + } + struct _stat buf; int ret = _wstat(wpath.c_str(), &buf); if (0 != ret) return false; @@ -86,32 +310,37 @@ namespace Exiv2 { } // fileExists #endif - -#define UNUSED(x) (void)(x) - -// Linux GCC 4.8 appears to be confused about strerror_r -#ifndef EXV_STRERROR_R_CHAR_P -#ifdef __gnu_linux__ -#define EXV_STRERROR_R_CHAR_P + std::string pathOfFileUrl(const std::string& url) { + std::string path = url.substr(7); + size_t found = path.find('/'); + if (found == std::string::npos) return path; + else return path.substr(found); + } +#ifdef EXV_UNICODE_PATH + std::wstring pathOfFileUrl(const std::wstring& wurl) { + std::wstring path = wurl.substr(7); + int found = path.find('/'); + if (found == std::wstring::npos) return path; + else return path.substr(found); + } #endif -#endif - std::string strError() { - int error = errno; + int error = errno; std::ostringstream os; -#ifdef EXV_HAVE_STRERROR_R +#ifdef EXV_HAVE_STRERROR_R const size_t n = 1024; - char buff[n]; - std::memset(buff, 0x0, n); - // _GNU_SOURCE: See Debian bug #485135 -#ifdef EXV_STRERROR_R_CHAR_P - char* buf = strerror_r(error, buff, n); -#else - char* buf = buff; - int dummy = strerror_r(error, buff, n); - UNUSED(dummy); -#endif +// _GNU_SOURCE: See Debian bug #485135 +# if defined EXV_STRERROR_R_CHAR_P && defined _GNU_SOURCE + char *buf = 0; + char buf2[n]; + std::memset(buf2, 0x0, n); + buf = strerror_r(error, buf2, n); +# else + char buf[n]; + std::memset(buf, 0x0, n); + strerror_r(error, buf, n); +# endif os << buf; // Issue# 908. // report strerror() if strerror_r() returns empty @@ -123,4 +352,91 @@ namespace Exiv2 { return os.str(); } // strError + void Uri::Decode(Uri& uri) + { + urldecode(uri.QueryString); + urldecode(uri.Path); + urldecode(uri.Host); + urldecode(uri.Username); + urldecode(uri.Password); + } + + Uri Uri::Parse(const std::string &uri) + { + Uri result; + + typedef std::string::const_iterator iterator_t; + + if ( !uri.length() ) return result; + + iterator_t uriEnd = uri.end(); + + // get query start + iterator_t queryStart = std::find(uri.begin(), uriEnd, '?'); + + // protocol + iterator_t protocolStart = uri.begin(); + iterator_t protocolEnd = std::find(protocolStart, uriEnd, ':'); //"://"); + + if (protocolEnd != uriEnd) + { + std::string prot = &*(protocolEnd); + if ((prot.length() > 3) && (prot.substr(0, 3) == "://")) + { + result.Protocol = std::string(protocolStart, protocolEnd); + protocolEnd += 3; // :// + } + else + protocolEnd = uri.begin(); // no protocol + } + else + protocolEnd = uri.begin(); // no protocol + + //username & password + iterator_t authStart = protocolEnd; + iterator_t authEnd = std::find(protocolEnd, uriEnd, '@'); + if (authEnd != uriEnd) { + iterator_t userStart = authStart; + iterator_t userEnd = std::find(authStart, authEnd, ':'); + if (userEnd != authEnd) { + result.Username = std::string(userStart, userEnd); + userEnd++; + result.Password = std::string(userEnd, authEnd); + } else { + result.Username = std::string(authStart, authEnd); + } + authEnd++; + } else { + authEnd = protocolEnd; + } + + // host + iterator_t hostStart = authEnd; + iterator_t pathStart = std::find(hostStart, uriEnd, '/'); // get pathStart + + iterator_t hostEnd = std::find(authEnd, + (pathStart != uriEnd) ? pathStart : queryStart, + ':'); // check for port + + result.Host = std::string(hostStart, hostEnd); + + // port + if ((hostEnd != uriEnd) && ((&*(hostEnd))[0] == ':')) // we have a port + { + hostEnd++; + iterator_t portEnd = (pathStart != uriEnd) ? pathStart : queryStart; + result.Port = std::string(hostEnd, portEnd); + } + if ( !result.Port.length() && result.Protocol == "http" ) result.Port = "80"; + + // path + if (pathStart != uriEnd) + result.Path = std::string(pathStart, queryStart); + + // query + if (queryStart != uriEnd) + result.QueryString = std::string(queryStart, uri.end()); + + return result; + } // Uri::Parse } // namespace Exiv2 diff --git a/src/futils.hpp b/src/futils.hpp deleted file mode 100644 index 84ac9bd1..00000000 --- a/src/futils.hpp +++ /dev/null @@ -1,79 +0,0 @@ -// ********************************************************* -*- C++ -*- -/* - * Copyright (C) 2004-2013 Andreas Huggel - * - * This program is part of the Exiv2 distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. - */ -/*! - @file futils.hpp - @brief Basic file utility functions required by Exiv2 - @version $Rev$ - @author Andreas Huggel (ahu) - ahuggel@gmx.net - @date 12-Dec-03, ahu: created
- 02-Apr-05, ahu: moved to Exiv2 namespace - */ -#ifndef FUTILS_HPP_ -#define FUTILS_HPP_ - -// ********************************************************************* -// included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif - -// + standard includes -#include - -// ********************************************************************* -// namespace extensions -namespace Exiv2 { - -// ********************************************************************* -// free functions - - /*! - @brief Test if a file exists. - - @param path Name of file to verify. - @param ct Flag to check if path is a regular file. - @return true if path exists and, if ct is set, - is a regular file, else false. - - @note The function calls stat() test for path - and its type, see stat(2). errno is left unchanged - in case of an error. - */ - EXIV2API bool fileExists(const std::string& path, bool ct =false); -#ifdef EXV_UNICODE_PATH - /*! - @brief Like fileExists() but accepts a unicode path in an std::wstring. - @note This function is only available on Windows. - */ - EXIV2API bool fileExists(const std::wstring& wpath, bool ct =false); -#endif - /*! - @brief Return a system error message and the error code (errno). - See %strerror(3). - */ - EXIV2API std::string strError(); - -} // namespace Exiv2 - -#endif // #ifndef FUTILS_HPP_ diff --git a/src/gifimage.cpp b/src/gifimage.cpp index 3a165971..32695afe 100644 --- a/src/gifimage.cpp +++ b/src/gifimage.cpp @@ -28,15 +28,10 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -//#define DEBUG 1 - // ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" + #include "gifimage.hpp" #include "image.hpp" #include "basicio.hpp" diff --git a/src/http.cpp b/src/http.cpp new file mode 100644 index 00000000..08478544 --- /dev/null +++ b/src/http.cpp @@ -0,0 +1,424 @@ +// ********************************************************* -*- C++ -*- +/* + * Copyright (C) 2004-2013 Andreas Huggel + * + * This program is part of the Exiv2 distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. + */ + +/* + * http.cpp + */ + +// included header files +#include "config.h" + +#include "exiv2.hpp" + +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#pragma message("Using exiv2 http support") +#endif + +#define SLEEP 1000 +#define SNOOZE 0 + +#if defined(__MINGW32__) || defined(__MINGW64__) +#define __MINGW__ +#define fopen_S(f,n,a) f=fopen(n,a) +#endif + +//////////////////////////////////////// +// platform specific code +#if defined(WIN32) || defined(_MSC_VER) +#include +#include +#include +#ifndef __MINGW__ +#define snprintf sprintf_s +#define write _write +#define read _read +#define close _close +#define strdup _strdup +#define stat _stat +#define fopen_S(f,n,a) fopen_s(&f,n,a) +#endif +#else +//////////////////////////////////////// +// Unix or Mac + +#define closesocket close + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define fopen_S(f,n,o) f=fopen(n,o) +#define WINAPI +typedef unsigned long DWORD ; + +#define SOCKET_ERROR -1 +#define WSAEWOULDBLOCK EINPROGRESS +#define WSAENOTCONN EAGAIN + +static int WSAGetLastError() +{ + return errno ; +} + +static void Sleep(int millisecs) +{ + const struct timespec rqtp = { 0 , millisecs*1000000 } ; + struct timespec rmtp ; + nanosleep(&rqtp,&rmtp); +} + +#endif + +//////////////////////////////////////// +// code +const char* httpTemplate = +"%s %s HTTP/%s\r\n" // $verb $page $version +"User-Agent: exiv2http/1.0.0\r\n" +"Accept: */*\r\n" +"Host: %s\r\n" // $servername +"%s" // $header +"\r\n" +; + +#ifndef lengthof +#define lengthof(x) (sizeof(x)/sizeof((x)[0])) +#endif + +#define white(c) ((c == ' ') || (c == '\t')) + +#define FINISH -999 +#define OK(s) (200 <= s && s < 300) + +const char* blankLines[] = +{ "\r\n\r\n" // this is the standard +, "\n\n" // this is commonly sent by CGI scripts +} ; + +int snooze = SNOOZE ; +int sleep_ = SLEEP ; + +static void report(const char* msg,std::string& errors) +{ + errors += std::string(msg) + '\n'; +} + +static int forgive(int n,int& err) +{ + err = WSAGetLastError() ; + if ( !n && !err ) return FINISH ; +#ifndef WIN32 + if ( n == 0 ) return FINISH ; // server hungup +#endif + bool bForgive = err == WSAEWOULDBLOCK || err == WSAENOTCONN ; + bool bError = n == SOCKET_ERROR ; + if ( bError && bForgive ) return 0 ; + return n ; +} + +static int error(std::string errors,const char* msg,const char* x=NULL,const char* y=NULL,int z=0); +static int error(std::string errors,const char* msg,const char* x ,const char* y ,int z ) +{ + char buffer[512] ; +#ifdef MSDEV_2003 + sprintf(buffer,msg,x,y,z); +#else + snprintf(buffer,sizeof buffer,msg,x,y,z) ; +#endif + if ( errno ) { + perror(buffer) ; + } else { + fprintf(stderr,"%s\n",buffer); + } + report(buffer,errors) ; + return -1 ; +} + +static void flushBuffer(const char* buffer,size_t start,int& end,std::string& file) +{ + file += std::string(buffer+start,end-start) ; + end = 0 ; +} + +static Exiv2::dict_t stringToDict(const std::string& s) +{ + Exiv2::dict_t result; + std::string token; + + size_t i = 0; + while (i < s.length() ) + { + if ( s[i] != ',' ) { + if ( s[i] != ' ' ) + token += s[i]; + } else { + result[token]=token; + token=""; + } + i++; + } + result[token]=token; + return result; +} + +static int makeNonBlocking(int sockfd) +{ +#ifdef WIN32 + ULONG ioctl_opt = 1; + return ioctlsocket(sockfd, FIONBIO, &ioctl_opt); +#else + int result = fcntl(sockfd, F_SETFL, O_NONBLOCK); + return result >= 0 ? result : SOCKET_ERROR ; +#endif +} + +int Exiv2::http(dict_t& request,dict_t& response,std::string& errors) +{ + if ( !request.count("verb") ) request["verb" ] = "GET"; + if ( !request.count("header") ) request["header" ] = "" ; + if ( !request.count("version")) request["version"] = "1.0"; + if ( !request.count("port") ) request["port" ] = "" ; + + std::string file; + errors = ""; + int result = 0; + + //////////////////////////////////// + // Windows specific code +#ifdef WIN32 + WSADATA wsaData; + WSAStartup(MAKEWORD(2,2), &wsaData); +#endif + + const char* servername = request["server" ].c_str(); + const char* page = request["page" ].c_str(); + const char* verb = request["verb" ].c_str(); + const char* header = request["header" ].c_str(); + const char* version = request["version"].c_str(); + const char* port = request["port" ].c_str(); + + const char* servername_p = servername; + const char* port_p = port ; + std::string url = std::string("http://") + request["server"] + request["page"]; + + // parse and change server if using a proxy + const char* PROXI = "HTTP_PROXY"; + const char* proxi = "http_proxy"; + const char* PROXY = getenv(PROXI); + const char* proxy = getenv(proxi); + bool bProx = PROXY || proxy; + const char* prox = bProx ? (proxy?proxy:PROXY):""; + Exiv2::Uri Proxy = Exiv2::Uri::Parse(prox); + + // find the dictionary of no_proxy servers + const char* NO_PROXI = "NO_PROXY"; + const char* no_proxi = "no_proxy"; + const char* NO_PROXY = getenv(NO_PROXI); + const char* no_proxy = getenv(no_proxi); + bool bNoProxy = NO_PROXY||no_proxy; + std::string no_prox = std::string(bNoProxy?(no_proxy?no_proxy:NO_PROXY):""); + Exiv2::dict_t noProxy= stringToDict(no_prox + ",localhost,127.0.0.1"); + + // if the server is on the no_proxy list ... ignore the proxy! + if ( noProxy.count(servername) ) bProx = false; + + if ( bProx ) { + servername_p = Proxy.Host.c_str(); + port_p = Proxy.Port.c_str(); + page = url.c_str(); + std::string p(proxy?proxi:PROXI); + // std::cerr << p << '=' << prox << " page = " << page << std::endl; + } + if ( !port [0] ) port = "80"; + if ( !port_p[0] ) port_p = "80"; + + //////////////////////////////////// + // open the socket + int sockfd = (int) socket(AF_INET , SOCK_STREAM,IPPROTO_TCP) ; + if ( sockfd < 0 ) return error("unable to create socket\n",NULL,NULL,0) ; + + // connect the socket to the server + int server = -1 ; + + // fill in the address + struct sockaddr_in serv_addr ; + int serv_len = sizeof(serv_addr); + memset((char *)&serv_addr,0,serv_len); + + serv_addr.sin_addr.s_addr = inet_addr(servername_p); + serv_addr.sin_family = AF_INET ; + serv_addr.sin_port = htons(atoi(port_p)); + + // convert unknown servername into IP address + // http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/rzab6/rzab6uafinet.htm + if (serv_addr.sin_addr.s_addr == (unsigned long)INADDR_NONE) + { + struct hostent* host = gethostbyname(servername_p); + if ( !host ) return error("no such host",servername_p,NULL,0); + memcpy(&serv_addr.sin_addr,host->h_addr,sizeof(serv_addr.sin_addr)); + } + + makeNonBlocking(sockfd) ; + + //////////////////////////////////// + // and connect + server = connect(sockfd, (const struct sockaddr *) &serv_addr, serv_len) ; + if ( server == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK ) + return error(errors,"error - unable to connect to server = %s port = %s wsa_error = %d",servername_p,port_p,WSAGetLastError()); + + char buffer[32*1024+1]; + size_t buff_l= sizeof buffer - 1 ; + + //////////////////////////////////// + // format the request +#ifdef MSDEV_2003 + int n = sprintf(buffer,httpTemplate,verb,page,version,servername,header) ; +#else + int n = snprintf(buffer,buff_l,httpTemplate,verb,page,version,servername,header) ; +#endif + buffer[n] = 0 ; + response["requestheaders"]=std::string(buffer,n); + + + //////////////////////////////////// + // send the header (we'll have to wait for the connection by the non-blocking socket) + while ( sleep_ >= 0 && send(sockfd,buffer,n,0) == SOCKET_ERROR /* && WSAGetLastError() == WSAENOTCONN */ ) { + Sleep(snooze) ; + sleep_ -= snooze ; + } + + if ( sleep_ < 0 ) + return error(errors,"error - timeout connecting to server = %s port = %s wsa_error = %d",servername,port,WSAGetLastError()); + + int end = 0 ; // write position in buffer + bool bSearching = true ; // looking for headers in the response + int status= 200 ; // assume happiness + + //////////////////////////////////// + // read and process the response + int err ; + n=forgive(recv(sockfd,buffer,(int)buff_l,0),err) ; + while ( n >= 0 && OK(status) ) { + if ( n ) { + end += n ; + buffer[end] = 0 ; + + size_t body = 0 ; // start of body + if ( bSearching ) { + + // search for the body + for ( size_t b = 0 ; bSearching && b < lengthof(blankLines) ; b++ ) { + if ( strstr(buffer,blankLines[b]) ) { + bSearching = false ; + body = (int) ( strstr(buffer,blankLines[b]) - buffer ) + strlen(blankLines[b]) ; + status = atoi(strchr(buffer,' ')) ; + } + } + + // parse response headers + char* h = buffer; + char C = ':' ; + char N = '\n'; + int i = 0 ; // initial byte in buffer + while(buffer[i] == N ) i++; + h = strchr(h+i,N)+1; + response[""]=std::string(buffer+i).substr(0,h-buffer-2); + result = atoi(strchr(buffer,' ')); + char* c = strchr(h,C); + char* n = strchr(h,N); + while ( c && n && c < n && h < buffer+body ) { + std::string key(h); + std::string value(c+1); + key = key.substr(0,c-h); + value = value.substr(0,n-c-1); + response[key]=value; + h = n+1; + c = strchr(h,C); + n = strchr(h,N); + } + } + + // if the bufffer's full and we're still searching - give up! + // this handles the possibility that there are no headers + if ( bSearching && buff_l-end < 10 ) { + bSearching = false ; + body = 0 ; + } + if ( !bSearching && OK(status) ) { + flushBuffer(buffer,body,end,file); + } + } + n=forgive(recv(sockfd,buffer+end,(int)(buff_l-end),0),err) ; + if ( !n ) { + Sleep(snooze) ; + sleep_ -= snooze ; + if ( sleep_ < 0 ) n = FINISH ; + } + } + + if ( n != FINISH || !OK(status) ) { +#ifdef MSDEV_2003 + sprintf(buffer,"wsa_error = %d,n = %d,sleep_ = %d status = %d" + , WSAGetLastError() + , n + , sleep_ + , status + ) ; +#else + snprintf(buffer,sizeof buffer,"wsa_error = %d,n = %d,sleep_ = %d status = %d" + , WSAGetLastError() + , n + , sleep_ + , status + ) ; +#endif + error(errors,buffer,NULL,NULL,0) ; + } else if ( bSearching && OK(status) ) { + if ( end ) { + // we finished OK without finding headers, flush the buffer + flushBuffer(buffer,0,end,file) ; + } else { + return error(errors,"error - no response from server = %s port = %s wsa_error = %d",servername,port,WSAGetLastError()); + } + } + + //////////////////////////////////// + // close sockets + closesocket(server) ; + closesocket(sockfd) ; + response["body"]=file; + return result; +} + +// That's all Folks diff --git a/src/image.cpp b/src/image.cpp index bedad72a..d13b8ec5 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -32,13 +32,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "image.hpp" #include "error.hpp" @@ -165,6 +160,9 @@ namespace Exiv2 { Image::~Image() { } + void Image::printStructure() + { + } void Image::clearMetadata() { @@ -416,19 +414,65 @@ namespace Exiv2 { return ImageType::none; } // ImageFactory::getType - Image::AutoPtr ImageFactory::open(const std::string& path) + BasicIo::AutoPtr ImageFactory::createIo(const std::string& path, bool useCurl) { - BasicIo::AutoPtr io(new FileIo(path)); - Image::AutoPtr image = open(io); // may throw + Protocol fProt = fileProtocol(path); +#if EXV_USE_SSH == 1 + if (fProt == pSsh || fProt == pSftp) { + return BasicIo::AutoPtr(new SshIo(path)); // may throw + } +#endif +#if EXV_USE_CURL == 1 + if (useCurl && (fProt == pHttp || fProt == pHttps || fProt == pFtp)) { + return BasicIo::AutoPtr(new CurlIo(path)); // may throw + } +#endif + if (fProt == pHttp) + return BasicIo::AutoPtr(new HttpIo(path)); // may throw + if (fProt == pFileUri) + return BasicIo::AutoPtr(new FileIo(pathOfFileUrl(path))); + if (fProt == pStdin || fProt == pDataUri) + return BasicIo::AutoPtr(new XPathIo(path)); // may throw + + return BasicIo::AutoPtr(new FileIo(path)); + + UNUSED(useCurl); + } // ImageFactory::createIo + +#ifdef EXV_UNICODE_PATH + BasicIo::AutoPtr ImageFactory::createIo(const std::wstring& wpath, bool useCurl) + { + Protocol fProt = fileProtocol(wpath); +#if EXV_USE_SSH == 1 + if (fProt == pSsh || fProt == pSftp) { + return BasicIo::AutoPtr(new SshIo(wpath)); + } +#endif +#if EXV_USE_CURL == 1 + if (useCurl && (fProt == pHttp || fProt == pHttps || fProt == pFtp)) { + return BasicIo::AutoPtr(new CurlIo(wpath)); + } +#endif + if (fProt == pHttp) + return BasicIo::AutoPtr(new HttpIo(wpath)); + if (fProt == pFileUri) + return BasicIo::AutoPtr(new FileIo(pathOfFileUrl(wpath))); + if (fProt == pStdin || fProt == pDataUri) + return BasicIo::AutoPtr(new XPathIo(wpath)); // may throw + return BasicIo::AutoPtr(new FileIo(wpath)); + } // ImageFactory::createIo +#endif + Image::AutoPtr ImageFactory::open(const std::string& path, bool useCurl) + { + Image::AutoPtr image = open(ImageFactory::createIo(path, useCurl)); // may throw if (image.get() == 0) throw Error(11, path); return image; } #ifdef EXV_UNICODE_PATH - Image::AutoPtr ImageFactory::open(const std::wstring& wpath) + Image::AutoPtr ImageFactory::open(const std::wstring& wpath, bool useCurl) { - BasicIo::AutoPtr io(new FileIo(wpath)); - Image::AutoPtr image = open(io); // may throw + Image::AutoPtr image = open(ImageFactory::createIo(wpath, useCurl)); // may throw if (image.get() == 0) throw WError(11, wpath); return image; } diff --git a/src/jp2image.cpp b/src/jp2image.cpp index da2128a3..bc0ea748 100644 --- a/src/jp2image.cpp +++ b/src/jp2image.cpp @@ -29,17 +29,9 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** - -//#define DEBUG 1 - -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" + #include "jp2image.hpp" #include "tiffimage.hpp" #include "image.hpp" @@ -317,7 +309,7 @@ namespace Exiv2 std::cout << "Exiv2::Jp2Image::readMetadata: Xmp data found\n"; #endif - rawData.alloc(box.boxLength - (u_int32_t)(sizeof(box) + sizeof(uuid))); + rawData.alloc(box.boxLength - (uint32_t)(sizeof(box) + sizeof(uuid))); bufRead = io_->read(rawData.pData_, rawData.size_); if (io_->error()) throw Error(14); if (bufRead != rawData.size_) throw Error(20); diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index e91aef63..f7b997c7 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -31,13 +31,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "jpgimage.hpp" #include "error.hpp" @@ -53,6 +48,9 @@ EXIV2_RCSID("@(#) $Id$") namespace Exiv2 { + const byte JpegBase::dht_ = 0xc4; + const byte JpegBase::dqt_ = 0xdb; + const byte JpegBase::dri_ = 0xdd; const byte JpegBase::sos_ = 0xda; const byte JpegBase::eoi_ = 0xd9; const byte JpegBase::app0_ = 0xe0; @@ -509,6 +507,100 @@ namespace Exiv2 { } } // JpegBase::readMetadata + void JpegBase::printStructure() + { + if (io_->open() != 0) throw Error(9, io_->path(), strError()); + // Ensure that this is the correct image type + if (!isThisType(*io_, false)) { + if (io_->error() || io_->eof()) throw Error(14); + throw Error(15); + } + + // nemonic for markers + std::string nm[256] ; + nm[0xd8]="SOI" ; + nm[0xd9]="EOI" ; + nm[0xda]="SOS" ; + nm[0xdb]="DQT" ; + nm[0xdd]="DRI" ; + nm[0xfe]="COM" ; + + // 0xe0 .. 0xef are APPn + // 0xc0 .. 0xcf are SOFn (except 4) + nm[0xc4]="DHT" ; + for ( int i = 0 ; i <= 15 ; i++ ) { + char MN[10]; + sprintf(MN,"APP%d",i); + nm[0xe0+i] = MN; + if ( i != 4 ) { + sprintf(MN,"SOF%d",i); + nm[0xc0+i] = MN; + } + } + + // Container for the signature + const long bufMinSize = 36; + long bufRead = 0, startSig = 0; + DataBuf buf(bufMinSize); + + // Read section marker + int marker = advanceToMarker(); + if (marker < 0) throw Error(15); + + printf("STRUCTURE OF FILE:\n"); + printf(" offset | marker | size | signature\n"); + while (1) { + // print marker bytes + printf("%8ld %#02x %-5s",io_->tell(), marker,nm[marker].c_str()); + if ( marker == eoi_ ) break ; + + // Read size and signature + std::memset(buf.pData_, 0x0, buf.size_); + bufRead = io_->read(buf.pData_, bufMinSize); + if (io_->error()) throw Error(14); + if (bufRead < 2) throw Error(15); + uint16_t size = 0; + + // not all markers have size field. + if( ( marker >= sof0_ && marker <= sof15_) + || ( marker >= app0_ && marker <= (app0_ | 0x0F)) + || marker == dht_ + || marker == dqt_ + || marker == dri_ + || marker == com_ + || marker == sos_ + ){ + size = getUShort(buf.pData_, bigEndian); + printf("%7d ", size); + } else { + printf(" "); + } + + // only print the signature for appn + if (marker >= app0_ && marker <= (app0_ | 0x0F)) { + startSig = size>0?2:0; + int endSig = size?size:bufRead; + if (endSig > 32) endSig = 32 ; + while (startSig++ < endSig ) { + int c = buf.pData_[startSig-1] ; + printf("%c", (' '<=c && c<128) ? c : '.' ); + // else endSig = startSig; + } + } + + // Skip the segment if the size is known + if (io_->seek(size - bufRead, BasicIo::cur)) throw Error(14); + + printf("\n"); + // sos_ is immediately followed by entropy-coded data & eoi_ + if (marker == sos_) break; + + // Read the beginning of the next segment + marker = advanceToMarker(); + } + printf("-----------------\n"); + } + void JpegBase::writeMetadata() { if (io_->open() != 0) { @@ -825,6 +917,10 @@ namespace Exiv2 { ++count; } + // Populate the fake data, only make sense for remoteio, httpio and sshio. + // it avoids allocating memory for parts of the file that contain image-date. + io_->populateFakeData(); + // Copy rest of the Io io_->seek(-2, BasicIo::cur); buf.alloc(4096); diff --git a/src/localtime.c b/src/localtime.c index 771e6335..959ec2b7 100644 --- a/src/localtime.c +++ b/src/localtime.c @@ -4,12 +4,8 @@ @version $Rev$ */ -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "timegm.h" /* diff --git a/src/makernote.cpp b/src/makernote.cpp index 846cd006..6c7c9473 100644 --- a/src/makernote.cpp +++ b/src/makernote.cpp @@ -28,13 +28,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "makernote_int.hpp" #include "tiffcomposite_int.hpp" diff --git a/src/mrwimage.cpp b/src/mrwimage.cpp index 2d7b6067..11e27635 100644 --- a/src/mrwimage.cpp +++ b/src/mrwimage.cpp @@ -29,13 +29,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "mrwimage.hpp" #include "tiffimage.hpp" diff --git a/src/orfimage.cpp b/src/orfimage.cpp index 80d4628a..c24996e9 100644 --- a/src/orfimage.cpp +++ b/src/orfimage.cpp @@ -29,13 +29,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "orfimage.hpp" #include "orfimage_int.hpp" @@ -277,6 +272,7 @@ namespace Exiv2 { buf.pData_[0] = 0x4d; buf.pData_[1] = 0x4d; break; + case asciiBytes: case invalidByteOrder: assert(false); break; diff --git a/src/pgfimage.cpp b/src/pgfimage.cpp index 47d31478..e672d307 100644 --- a/src/pgfimage.cpp +++ b/src/pgfimage.cpp @@ -29,17 +29,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** - -//#define DEBUG 1 - -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "pgfimage.hpp" #include "image.hpp" diff --git a/src/pngchunk.cpp b/src/pngchunk.cpp index c382f739..89823633 100644 --- a/src/pngchunk.cpp +++ b/src/pngchunk.cpp @@ -29,21 +29,10 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" -//#define DEBUG 1 #ifdef EXV_HAVE_LIBZ - -extern "C" { -#include // To uncompress or compress text chunk -} - #include "pngchunk_int.hpp" #include "tiffimage.hpp" #include "jpgimage.hpp" @@ -61,6 +50,8 @@ extern "C" { #include #include +#include // To uncompress or compress text chunk + /* URLs to find informations about PNG chunks : @@ -690,3 +681,4 @@ namespace Exiv2 { }} // namespace Internal, Exiv2 #endif // ifdef EXV_HAVE_LIBZ + diff --git a/src/pngimage.cpp b/src/pngimage.cpp index 3dc437e4..ef57991f 100644 --- a/src/pngimage.cpp +++ b/src/pngimage.cpp @@ -29,19 +29,10 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** - -//#define DEBUG 1 - -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" -#ifdef EXV_HAVE_LIBZ +#ifdef EXV_HAVE_LIBZ #include "pngchunk_int.hpp" #include "pngimage.hpp" #include "jpgimage.hpp" @@ -100,6 +91,48 @@ namespace Exiv2 { return "image/png"; } + void PngImage::printStructure() + { + if (io_->open() != 0) { + throw Error(9, io_->path(), strError()); + } + IoCloser closer(*io_); + // Ensure that this is the correct image type + if (!isPngType(*io_, true)) { + if (io_->error() || io_->eof()) throw Error(14); + throw Error(3, "PNG"); + } + + printf("index | chunk_type | chunk_size\n"); + long index = 0, i = 0; + const long imgSize = io_->size(); + DataBuf cheaderBuf(8); + + while(!io_->eof()) { + std::memset(cheaderBuf.pData_, 0x0, cheaderBuf.size_); + long bufRead = io_->read(cheaderBuf.pData_, cheaderBuf.size_); + if (io_->error()) throw Error(14); + if (bufRead != cheaderBuf.size_) throw Error(20); + + // Decode chunk data length. + uint32_t dataOffset = Exiv2::getULong(cheaderBuf.pData_, Exiv2::bigEndian); + long pos = io_->tell(); + if ( pos == -1 + || dataOffset > uint32_t(0x7FFFFFFF) + || static_cast(dataOffset) > imgSize - pos) throw Exiv2::Error(14); + + printf("%5ld ", index); + for (i = 4; i < 8; i++) + printf("%c", cheaderBuf.pData_[i]); + printf(" %u\n", dataOffset); + + index++; + io_->seek(dataOffset + 4 , BasicIo::cur); + if (io_->error() || io_->eof()) throw Error(14); + } + + } + void PngImage::readMetadata() { #ifdef DEBUG diff --git a/src/preview.cpp b/src/preview.cpp index 625e95be..e1740230 100644 --- a/src/preview.cpp +++ b/src/preview.cpp @@ -28,13 +28,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include #include diff --git a/src/psdimage.cpp b/src/psdimage.cpp index d92d3869..2d849862 100644 --- a/src/psdimage.cpp +++ b/src/psdimage.cpp @@ -29,15 +29,9 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -//#define DEBUG 1 - -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" + #include "psdimage.hpp" #include "jpgimage.hpp" #include "image.hpp" @@ -546,6 +540,10 @@ namespace Exiv2 { xmpDone = true; } + // Populate the fake data, only make sense for remoteio, httpio and sshio. + // it avoids allocating memory for parts of the file that contain image-date. + io_->populateFakeData(); + // Copy remaining data long readSize = 0; while ((readSize=io_->read(lbuf.pData_, lbuf.size_))) { diff --git a/src/rafimage.cpp b/src/rafimage.cpp index 959d9624..1e52a8f0 100644 --- a/src/rafimage.cpp +++ b/src/rafimage.cpp @@ -29,13 +29,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "rafimage.hpp" #include "tiffimage.hpp" diff --git a/src/rcsid_int.hpp b/src/rcsid_int.hpp index e42ac563..549efc6d 100644 --- a/src/rcsid_int.hpp +++ b/src/rcsid_int.hpp @@ -53,7 +53,7 @@ */ -#if (defined(__GNUG__) || defined(__GNUC__) || defined (_MSC_VER)) && ! defined(__clang__) +#if (defined(__GNUG__) || defined(__GNUC__) || defined (_MSC_VER)) && ! defined(__clang__) #define EXIV2_RCSID(id) \ namespace { \ inline const char* getRcsId(const char*) { return id ; } \ diff --git a/src/rw2image.cpp b/src/rw2image.cpp index ccc4cacb..97829eb0 100644 --- a/src/rw2image.cpp +++ b/src/rw2image.cpp @@ -29,13 +29,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "rw2image.hpp" #include "rw2image_int.hpp" diff --git a/src/ssh.cpp b/src/ssh.cpp new file mode 100644 index 00000000..e8ea9deb --- /dev/null +++ b/src/ssh.cpp @@ -0,0 +1,156 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (C) 2004-2013 Andreas Huggel + * + * This program is part of the Exiv2 distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. + */ +/* + File: rw2image.cpp + Version: $Rev: 3201 $ + Author(s): Andreas Huggel (ahu) + History: 06-Jan-09, ahu: created + + */ +// ***************************************************************************** +#include "rcsid_int.hpp" +EXIV2_RCSID("@(#) $Id: rw2image.cpp 3201 2013-12-01 12:13:42Z ahuggel $") + +#include "ssh.hpp" +#if EXV_USE_SSH == 1 + +// class member definitions +namespace Exiv2 { + + SSH::SSH(const std::string& host, const std::string& user, const std::string& pass, const std::string port): + host_(host),user_(user),pass_(pass),sftp_(0) { + + std::string timeout = getEnv(envTIMEOUT); + timeout_ = atol(timeout.c_str()); + if (timeout_ == 0) { + throw Error(1, "Timeout Environmental Variable must be a positive integer."); + } + + session_ = ssh_new(); + if (session_ == NULL) { + throw Error(1, "Unable to create the the ssh session"); + } + + // try to connect + ssh_options_set(session_, SSH_OPTIONS_HOST, host_.c_str()); + ssh_options_set(session_, SSH_OPTIONS_USER, user_.c_str()); + ssh_options_set(session_, SSH_OPTIONS_TIMEOUT, &timeout_); + if (port != "") ssh_options_set(session_, SSH_OPTIONS_PORT_STR, port.c_str()); + + if (ssh_connect(session_) != SSH_OK) { + throw Error(1, ssh_get_error(session_)); + } + // Authentication + if (ssh_userauth_password(session_, NULL, pass_.c_str()) != SSH_AUTH_SUCCESS) { + throw Error(1, ssh_get_error(session_)); + } + } + + int SSH::runCommand(const std::string& cmd, std::string* output) { + int rc; + ssh_channel channel; + channel = ssh_channel_new(session_); + if (channel == NULL) { + rc = SSH_ERROR; + } else { + rc = ssh_channel_open_session(channel); + if (rc != SSH_OK) { + ssh_channel_free(channel); + } else { + char buffer[256]; + rc = ssh_channel_request_exec(channel, cmd.c_str()); + if (rc == SSH_OK) { + while ((rc = ssh_channel_read(channel, buffer, sizeof(buffer), 0)) > 0) { + output->append(buffer, rc); + } + } + ssh_channel_send_eof(channel); + ssh_channel_close(channel); + ssh_channel_free(channel); + } + } + return rc; + } + + int SSH::scp(const std::string& filePath, const byte* data, size_t size) { + ssh_scp scp; + int rc; + + size_t found = filePath.find_last_of("/\\"); + std::string filename = filePath.substr(found+1); + std::string path = filePath.substr(0, found+1); + + scp = ssh_scp_new(session_, SSH_SCP_WRITE, path.c_str()); + if (scp == NULL) { + throw Error(1, ssh_get_error(session_)); + rc = SSH_ERROR; + } else { + rc = ssh_scp_init(scp); + if (rc != SSH_OK) { + throw Error(1, ssh_get_error(session_)); + } else { +#ifdef _MSC_VER +// S_IRUSR & S_IWUSR not in MSVC (0000400 & 0000200 in /usr/include/sys/stat.h on MacOS-X 10.8) +#define S_IRUSR S_IREAD +#define S_IWUSR S_IWRITE +#endif + rc = ssh_scp_push_file (scp, filename.c_str(), size, S_IRUSR | S_IWUSR); + if (rc != SSH_OK) { + throw Error(1, ssh_get_error(session_)); + } else { + rc = ssh_scp_write(scp, data, size); + if (rc != SSH_OK) { + throw Error(1, ssh_get_error(session_)); + } + } + ssh_scp_close(scp); + } + ssh_scp_free(scp); + } + + return rc; + } + + void SSH::openSftp() { + if (sftp_) return; + + sftp_ = sftp_new(session_); + if (sftp_ == NULL) { + throw Error(1, "Unable to create the the sftp session"); + } + if (sftp_init(sftp_) != SSH_OK) { + sftp_free(sftp_); + throw Error(1, "Error initializing SFTP session"); + } + } + + void SSH::getFileSftp(const std::string& filePath, sftp_file& handle) { + if (!sftp_) openSftp(); + handle = sftp_open(sftp_, ("/"+filePath).c_str(), 0x0000, 0); // read only + } + + SSH::~SSH() { + if (sftp_) sftp_free(sftp_); + ssh_disconnect(session_); + ssh_free(session_); + } +} +#endif diff --git a/src/svn_version.sh b/src/svn_version.sh index 1ed25116..d6c0a946 100755 --- a/src/svn_version.sh +++ b/src/svn_version.sh @@ -1,17 +1,32 @@ #!/bin/bash ## -# update svn_version.h when the revision has changed +# update svn_version_h when revision changes +## + +svn_version_h=svn_version.h svn_version=$(svn info .. 2>/dev/null | grep ^Revision | cut -f 2 -d' ') -if [ -z "$svn_version" ]; then svn_version=0 ; fi -if [ -e svn_version.h ]; then - old=$(cut -f 3 -d' ' svn_version.h) +if [ -z "$svn_version" ]; then svn_version=0 ; fi + +## +# report svn_version to output +set | grep svn_version + +## +# sniff svn_version in svn_version.h and delete the file if incorrect +if [ -e "$svn_version_h" ]; then + old=$(cut -f 3 -d' ' "$svn_version_h") if [ "$old" != "$svn_version" ]; then - rm -rf svn_version.h + rm -rf "$svn_version_h" fi fi -if [ ! -e svn_version.h ]; then - echo "#define SVN_VERSION $svn_version" > svn_version.h + +## +# write svn_version to file if necessary +if [ ! -e "$svn_version_h" ]; then + echo "#ifndef SVN_VERSION" > "$svn_version_h" + echo "#define SVN_VERSION $svn_version" >> "$svn_version_h" + echo "#endif" >> "$svn_version_h" fi # That's all Folks! diff --git a/src/tgaimage.cpp b/src/tgaimage.cpp index 99108b00..96c83e60 100644 --- a/src/tgaimage.cpp +++ b/src/tgaimage.cpp @@ -28,15 +28,9 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -//#define DEBUG 1 - -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" + #include "tgaimage.hpp" #include "image.hpp" #include "basicio.hpp" diff --git a/src/tiffcomposite.cpp b/src/tiffcomposite.cpp index 386bb219..5cf2a6e4 100644 --- a/src/tiffcomposite.cpp +++ b/src/tiffcomposite.cpp @@ -28,13 +28,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "tiffimage_int.hpp" #include "tiffcomposite_int.hpp" diff --git a/src/tiffimage.cpp b/src/tiffimage.cpp index 39126783..962c74cf 100644 --- a/src/tiffimage.cpp +++ b/src/tiffimage.cpp @@ -29,13 +29,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "tiffimage.hpp" #include "tiffimage_int.hpp" @@ -2039,6 +2034,7 @@ namespace Exiv2 { buf.pData_[0] = 0x4d; buf.pData_[1] = 0x4d; break; + case asciiBytes: case invalidByteOrder: assert(false); break; @@ -2059,6 +2055,7 @@ namespace Exiv2 { switch (byteOrder_) { case littleEndian: os << ", " << _("little endian encoded"); break; case bigEndian: os << ", " << _("big endian encoded"); break; + case asciiBytes: os << ", " << _("ascii bytes"); break; case invalidByteOrder: break; } os << "\n"; diff --git a/src/tiffvisitor.cpp b/src/tiffvisitor.cpp index 43ef0e77..e93cef1e 100644 --- a/src/tiffvisitor.cpp +++ b/src/tiffvisitor.cpp @@ -28,13 +28,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "tiffcomposite_int.hpp" // Do not change the order of these 2 includes, #include "tiffvisitor_int.hpp" // see bug #487 @@ -363,6 +358,7 @@ namespace Exiv2 { case bigEndian: exifData_["Exif.MakerNote.ByteOrder"] = "MM"; break; + case asciiBytes: case invalidByteOrder: assert(object->byteOrder() != invalidByteOrder); break; diff --git a/src/utils.cpp b/src/utils.cpp index 7c8a87cb..4945b237 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -28,23 +28,19 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "utils.hpp" // + standard includes #include #include -#ifdef _MSC_VER +#if defined(_MSC_VER) # include "getopt_win32.h" # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #endif + #ifdef EXV_HAVE_UNISTD_H # include // for getopt(), stat() #endif diff --git a/src/version.cpp b/src/version.cpp index d5e5cc30..d1f0fdc0 100644 --- a/src/version.cpp +++ b/src/version.cpp @@ -29,30 +29,42 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -#if defined(__MINGW32__) || defined(__MINGW64__) -#ifndef __MINGW__ -#define __MINGW__ -#endif +// ***************************************************************************** + +#include "config.h" + +#ifndef EXV_USE_SSH +#define EXV_USE_SSH 0 #endif -// ***************************************************************************** -// included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" +#ifndef EXV_USE_CURL +#define EXV_USE_CURL 0 +#endif + +#if EXV_USE_CURL == 1 +#include +#endif + +#if defined(__MINGW32__) || defined(__MINGW64__) +# ifndef __MINGW__ +# define __MINGW__ +# endif #endif #if defined(__CYGWIN__) || defined(__MINGW__) #include #endif +#include "http.hpp" +#include "svn_version.h" #include "version.hpp" // + standard includes #include #include + + namespace Exiv2 { int versionNumber() { @@ -99,7 +111,6 @@ typedef string_v::iterator string_i; #define _MAX_PATH 512 #endif - // platform specific support for dumpLibraryInfo #if defined(WIN32) # include @@ -129,6 +140,10 @@ typedef string_v::iterator string_i; void* not_needed1; /* Pointer to the dynamic section of the shared object */ struct lmap *next, *prev;/* chain of loaded objects */ }; +#elif defined(__MINGW32__) || defined(__MINGW64__) +#ifndef __MINGW__ +#define __MINGW__ +#endif #endif EXIV2API void dumpLibraryInfo(std::ostream& os) @@ -176,7 +191,6 @@ EXIV2API void dumpLibraryInfo(std::ostream& os) #define __oracle__ #endif - #ifndef __VERSION__ #ifdef __clang__version__ #define __VERSION__ __clang__version__ @@ -258,7 +272,18 @@ EXIV2API void dumpLibraryInfo(std::ostream& os) os << "date=" << __DATE__ << endl; os << "time=" << __TIME__ << endl; os << "svn=" << SVN_VERSION << endl; - + os << "ssh=" << EXV_USE_SSH << endl; +#if EXV_USE_CURL == 1 + curl_version_info_data* vinfo = curl_version_info(CURLVERSION_NOW); + os << "curlversion=" << vinfo->version << endl; + os << "curlprotocols="; + for (int i = 0; vinfo->protocols[i]; i++) + os << vinfo->protocols[i] << " "; + os << endl; +#else + os << "curl=" << EXV_USE_CURL << endl; +#endif + os << "id=" << "$Id$" << endl; if ( libs.begin() != libs.end() ) { os << "executable=" << *libs.begin() << endl; for ( string_i lib = libs.begin()+1 ; lib != libs.end() ; lib++ ) diff --git a/src/xmpsidecar.cpp b/src/xmpsidecar.cpp index e51b82f4..da349b6f 100644 --- a/src/xmpsidecar.cpp +++ b/src/xmpsidecar.cpp @@ -29,13 +29,8 @@ #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") -// ***************************************************************************** // included header files -#ifdef _MSC_VER -# include "exv_msvc.h" -#else -# include "exv_conf.h" -#endif +#include "config.h" #include "xmpsidecar.hpp" #include "image.hpp" diff --git a/test/Makefile b/test/Makefile index 2b935217..c5a4e0c2 100644 --- a/test/Makefile +++ b/test/Makefile @@ -58,10 +58,7 @@ SHELL = /bin/sh ## # to save download time for simple build/test, we download video and eps data on demand -# TODO: remove data/eps from depot for the 0.24 release. -# If we remove it now, it'll break the test instructions on the web: -# http://www.exiv2.org/download.html -SVN = svn://dev.exiv2.org/svn/testdata/trunk +SVN = svn://dev.exiv2.org/svn/testdata/trunk ## # Add test drivers to this list @@ -84,6 +81,9 @@ TESTS = addmoddel.sh \ TESTV = video-test.sh TESTE = eps-test.sh TESTVW = write-video-test.sh +TESTX = httpiotest.sh \ + curliotest.sh \ + sshiotest.sh tests: cd .. ; make tests @@ -120,13 +120,27 @@ testvw: done ## +## # TODO: download eps data on demand for 0.24 (similar to testv) teste: + @for t in /eps ; do \ + if [ ! -e data/$$t ]; then \ + echo svn export '$(SVN)'$$t data$$t ; \ + svn export '$(SVN)'$$t data$$t ; \ + fi ; done @list='$(TESTE)'; for p in $$list; do \ echo Running $$p ...; \ ./$$p; \ done +## +# TODO: test httpIo and remoteIo +testx: + @list='$(TESTX)'; for p in $$list; do \ + echo Running $$p ...; \ + ./$$p; \ + done + clean: rm -rf $(top_srcdir)/test/tmp/* data/video data/eps diff --git a/test/bugfixes-test.sh b/test/bugfixes-test.sh index b8dd32bf..dc87bacd 100755 --- a/test/bugfixes-test.sh +++ b/test/bugfixes-test.sh @@ -262,11 +262,11 @@ source ./functions.source copyTestFile $filename copyTestFile $dataname copyTestFile $diffname - runTest exiv2 -pa $filename | sort > $num-before.txt + runTest exiv2 -pa $filename | sort > $num-before.txt runTest exiv2 -m $dataname $filename - runTest exiv2 -pa $filename | sort > $num-after.txt - diff $num-before.txt $num-after.txt > $num.txt - diff $num.txt $diffname + runTest exiv2 -pa $filename | sort > $num-after.txt + diff $diffargs $num-before.txt $num-after.txt > $num.txt + diff $diffargs $num.txt $diffname ) 3>&1 > $results 2>&1 diff --git a/test/curliotest.sh b/test/curliotest.sh new file mode 100755 index 00000000..96d37c08 --- /dev/null +++ b/test/curliotest.sh @@ -0,0 +1,156 @@ +#!/bin/bash +# Test driver for CurlIO + +source ./functions.source + + +## +#function to test remote read access in basicio.cpp +RemoteReadTest() +{ + arg=$1 + scheme=${arg:0:4} + + src=$(basename "$arg") + filename=${src%.*} + test=${filename}.txt + good=$datapath/${filename}.txt + dot=. + # run tests + runTest exifprint $1 "--curl" > $test + #check results + diffCheckAscii $test $good + + printf $dot +} + +## +#function to test remoteio read/write access in basicio.cpp +RemoteIOTest() +{ + arg=$1 + scheme=${arg:0:4} + + src=$(basename "$arg") + filename=${src%.*} + test=${filename}.txt + good=$datapath/remoteio.txt + dot=. + + # print out the metadata + runTest remotetest $1 "--curl" > $test + + #check results + diffCheckAscii $test $good + + printf $dot +} + +( cd "$testdir" + + # check environmental variable + if [ -z $EXIV2_AWSUBUNTU_HOST ]; then + echo "***" please set the environmental variable EXIV2_AWSUBUNTU_HOST "***" + exit 1 + fi + if [ -z $EXIV2_AWSUBUNTU_USERNAME ]; then + echo "***" please set the environmental variable EXIV2_AWSUBUNTU_USERNAME "***" + exit 1 + fi + if [ -z $EXIV2_AWSUBUNTU_PASSWORD ]; then + echo "***" please set the environmental variable EXIV2_AWSUBUNTU_PASSWORD "***" + exit 1 + fi + + errors=0 + tesfile="conntest.jpg" + files+=(remoteImg{0..9}.jpg) + iopngfiles+=(remoteio{1..5}.png) + iojpgfiles+=(remoteio{6..10}.jpg) + USE_CURL=$("$bin"/exiv2 -v -V | grep ^curlprotocols= | sed s/curlprotocols=//) + if [ "$USE_CURL" == "" ]; then + #Skip remoteIo test cases + echo 'Curl is not used. Skip remoteio test cases.' + else + # HTTP protocol + if [[ "$USE_CURL" == *http* ]]; then + # test connection + printf 'http test connection ' + TEST_CON=$("$bin"/conntest http://$EXIV2_AWSUBUNTU_HOST/$testfile) + if [[ "$TEST_CON" == OK* ]]; then + errors=0 + printf 'OK\nHTTP IO ' + for name in ${iopngfiles[@]}; do + RemoteIOTest "http://$EXIV2_AWSUBUNTU_HOST/$name" + done + for name in ${iojpgfiles[@]}; do + RemoteIOTest "http://$EXIV2_AWSUBUNTU_HOST/$name" + done + if [ $errors -eq 0 ]; then + printf '\nAll test cases passed\n' + else + echo $errors ' test cases failed!' + fi + else + echo $TEST_CON + printf "FAIL\nnot run httpIo\n" + fi + else + echo 'Curl doesnt support HTTP' + fi + + # HTTPS protocol + if [[ "$USE_CURL" == *https* ]]; then + # test connection + printf 'https test connection ' + TEST_CON=$("$bin"/conntest https://$EXIV2_AWSUBUNTU_HOST/$testfile) + if [[ "$TEST_CON" == OK* ]]; then + errors=0 + printf 'OK\nHTTPS IO ' + for name in ${iopngfiles[@]}; do + RemoteIOTest "https://$EXIV2_AWSUBUNTU_HOST/$name" + done + for name in ${iojpgfiles[@]}; do + RemoteIOTest "https://$EXIV2_AWSUBUNTU_HOST/$name" + done + if [ $errors -eq 0 ]; then + printf '\nAll test cases passed\n' + else + echo $errors ' test cases failed!' + fi + else + echo $TEST_CON + printf "FAIL\nnot run httpsIo\n" + fi + else + echo 'Curl doesnt support HTTPS' + fi + + # FTP protocol + if [[ "$USE_CURL" == *ftp* ]]; then + # test connection + printf 'ftp test connection ' + TEST_CON=$("$bin"/conntest ftp://"$EXIV2_AWSUBUNTU_USERNAME"_ftp:$EXIV2_AWSUBUNTU_PASSWORD@$EXIV2_AWSUBUNTU_HOST/$testfile) + if [[ "$TEST_CON" == OK* ]]; then + errors=0 + printf 'OK\nFTP READ ' + for name in ${files[@]}; do + RemoteReadTest "ftp://"$EXIV2_AWSUBUNTU_USERNAME"_ftp:$EXIV2_AWSUBUNTU_PASSWORD@$EXIV2_AWSUBUNTU_HOST/$name" + done + if [ $errors -eq 0 ]; then + printf '\nAll test cases passed\n' + else + echo $errors ' test cases failed!' + fi + else + echo $TEST_CON + printf "FAIL\nnot run FTP read\n" + fi + else + echo 'Curl doesnt support FTP' + fi + fi +) + +# That's all Folks! +## \ No newline at end of file diff --git a/test/functions.source b/test/functions.source index cf6e1047..ce696738 100644 --- a/test/functions.source +++ b/test/functions.source @@ -9,10 +9,10 @@ runTest() ( cd $here/tmp if [ ! -z $EXIV2_ECHO ]; then - echoTest $VALGRIND $bin/$prog "$@" - fi - $VALGRIND $bin/$prog "$@" - ) + echoTest $VALGRIND $bin$prog "$@" + fi + $VALGRIND $bin$prog "$@" + ) } ## @@ -32,8 +32,14 @@ existsTest() { local prog=$1 result=0 - if [ -e $bin/$prog -o -e $bin/$prog.exe ]; then - result=1 + if [ -z "$bin" ]; then + if [ ! -z $(which $prog) ]; then + result=1 + fi + else + if [ -e $bin$prog -o -e $bin$prog.exe ]; then + result=1 + fi fi echo $result } @@ -46,7 +52,7 @@ copy() } ## -# copy file from data to tmp (copyTestFile from to +# copy file from data to tmp (copyTestFile from to) copyTestFile() { if [ $# == 2 ]; then @@ -76,7 +82,7 @@ reportTest() cat $results | tr '\\' '/' > ${results}-new mv -f ${results}-new $results if [ ! -z `which dos2unix` ]; then - unix2dos $results >/dev/null 2>&1 + dos2unix $results >/dev/null 2>&1 fi if [ $# -eq 0 ]; then @@ -166,7 +172,7 @@ eraseTest() cp $datapath/$src $test #run tests - $bin/metacopy $test $test + ${bin}metacopy $test $test #check results diffCheck $test $good @@ -185,7 +191,7 @@ copyTest() cp $datapath/$dst $test #run tests - $bin/metacopy -a $datapath/$src $test + ${bin}metacopy -a $datapath/$src $test #check results diffCheck $test $good @@ -414,14 +420,17 @@ prepareTest() datadir="../data" if [ -z "$EXIV2_BINDIR" ] ; then - bin="$here/../bin" + bin="$here/../bin/" else - bin="$EXIV2_BINDIR" + bin="$EXIV2_BINDIR/" fi os=$(uname) if [ "${os:0:4}" == "CYGW" ]; then export PLATFORM=cygwin + elif [ "${os:0:4}" == "MING" ]; then + export PLATFORM=mingw + # bin=$(dirname $(which exiv2)) else export PLATFORM=$os fi @@ -430,7 +439,7 @@ prepareTest() exe=.exe fi - if [ "$PLATFORM" == cygwin -o "$PLATFORM" == mingw ]; then + if [ "$PLATFORM" == cygwin ]; then # We need a private version of diff for linux compatibility diff() { @@ -469,20 +478,36 @@ prepareTest() fi da2="--ignore-matching-lines=^Usage:.*exiv2" diff -q $da2 $tmpfile $tmpfile 2>/dev/null - if [ $? -ne 0 ] ; then - da2="" - fi + #if [ $? -ne 0 -o "$PLATFORM" == mingw ] ; then + # da2="" + #fi diffargs="$da1 $da2" + if [ $PLATFORM == mingw ]; then + # export "PATH=${bin}/:$PATH" + export "PATH=$PATH:${bin}" + bin='' + # echo ---- PATH $PATH ---- ; (IFS=:;for i in $PATH; do echo $i; done) ; echo -------------------- + fi + ## # test that exiv2 and some sample apps are in the bin! - for e in exiv2 exifprint; do - e="${bin}/${e}${exe}" - if [ ! -e "$e" ]; then - echo '******************************************' - echo '***' $(real_path "$e") does not exist - echo '******************************************' - exit 42 + for e in exiv2 exifprint easyaccess-test metacopy ; do + if [ $PLATFORM == mingw ]; then + if [ -z $(which $e) ]; then + echo '******************************************' + echo '***' $e is not on path + echo '******************************************' + exit 37 + fi + else + e="${bin}${e}${exe}" + if [ ! -e "$e" ]; then + echo '******************************************' + echo '***' $(real_path "$e") does not exist + echo '******************************************' + exit 42 + fi fi done } diff --git a/test/httpiotest.sh b/test/httpiotest.sh new file mode 100755 index 00000000..4ef6ee88 --- /dev/null +++ b/test/httpiotest.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# Test driver for httptest and httpIo + +source ./functions.source + +## +#function to test httpio class in basicio.cpp +httpIoTest() +{ + arg=$1 + scheme=${arg:0:4} + + src=$(basename "$arg") + filename=${src%.*} + test=${filename}.txt + good=$datapath/remoteio.txt + dot=. + + # print out the metadata + runTest remotetest $1 "--nocurl" > $test + + #check results + diffCheckAscii $test $good + printf $dot +} + +( cd "$testdir" + + # check environmental variable + if [ -z $EXIV2_AWSUBUNTU_HOST ]; then + echo "***" please set the environmental variable EXIV2_AWSUBUNTU_HOST "***" + exit 1 + fi + + errors=0 + testfile="conntest.jpg" + iopngfiles+=(remoteio{1..5}.png) + iojpgfiles+=(remoteio{6..10}.jpg) + + # test connection (basic sanity test) + printf 'http test connection ' + TEST_CON=$("$bin"/conntest http://$EXIV2_AWSUBUNTU_HOST/$testfile) + if [[ "$TEST_CON" == OK* ]]; then + #Tests for httpIo + printf 'OK\nHTTP IO ' + for name in ${iopngfiles[@]}; do + httpIoTest "http://$EXIV2_AWSUBUNTU_HOST/$name" + done + for name in ${iojpgfiles[@]}; do + httpIoTest "http://$EXIV2_AWSUBUNTU_HOST/$name" + done + if [ $errors -eq 0 ]; then + printf '\nAll test cases passed\n' + else + printf "\n---------------------------------------------------------\n" + echo $errors 'httpIo failed!' + fi + else + echo $TEST_CON + printf "FAIL\nnot run httpIo\n" + fi +) + +# That's all Folks! +## \ No newline at end of file diff --git a/test/preview-test.sh b/test/preview-test.sh index 1f61df05..cd6d0bd7 100755 --- a/test/preview-test.sh +++ b/test/preview-test.sh @@ -110,7 +110,7 @@ source ./functions.source echo echo "Command: exiv2 -pp $filename" - $bin/exiv2 -pp "$filename" + runTest exiv2 -pp "$filename" exitcode=$? echo "Exit code: $exitcode" @@ -118,10 +118,10 @@ source ./functions.source echo echo "Command: exiv2 -f -ep $filename" - $bin/exiv2 -f -ep "$filename" + runTest exiv2 -f -ep "$filename" echo "Exit code: $?" - $bin/exiv2 -pp "$filename" 2>/dev/null | sed -n 's,^Preview \([0-9]\+\):.*,\1,p' | while read preview; do + runTest exiv2 -pp "$filename" 2>/dev/null | sed -n 's,^Preview \([0-9]\+\):.*,\1,p' | while read preview; do diff -q "../data/preview/$image-preview$preview."* "$image-preview$preview."* done done diff --git a/test/sshiotest.sh b/test/sshiotest.sh new file mode 100755 index 00000000..4880af1a --- /dev/null +++ b/test/sshiotest.sh @@ -0,0 +1,118 @@ +#!/bin/bash +# Test driver for SshIo + +source ./functions.source + +## +#function to test remote read access in basicio.cpp +SFTPReadTest() +{ + arg=$1 + scheme=${arg:0:4} + + src=$(basename "$arg") + filename=${src%.*} + test=${filename}.txt + good=$datapath/${filename}.txt + dot=. + # run tests + runTest exifprint $1 > $test + #check results + diffCheckAscii $test $good + + printf $dot +} + +## +#function to test remote read access in basicio.cpp +SshIOTest() +{ + arg=$1 + scheme=${arg:0:4} + + src=$(basename "$arg") + filename=${src%.*} + test=${filename}.txt + good=$datapath/remoteio.txt + dot=. + + # print out the metadata + runTest remotetest $1 > $test + + #check results + diffCheckAscii $test $good + + printf $dot +} + +( cd "$testdir" + + # check environmental variable + if [ -z $EXIV2_AWSUBUNTU_HOST ]; then + echo "***" please set the environmental variable EXIV2_AWSUBUNTU_HOST "***" + exit 1 + fi + if [ -z $EXIV2_AWSUBUNTU_USERNAME ]; then + echo "***" please set the environmental variable EXIV2_AWSUBUNTU_USERNAME "***" + exit 1 + fi + if [ -z $EXIV2_AWSUBUNTU_PASSWORD ]; then + echo "***" please set the environmental variable EXIV2_AWSUBUNTU_PASSWORD "***" + exit 1 + fi + + testfile="conntest.jpg" + files+=(remoteImg{0..9}.jpg) + iopngfiles+=(remoteio{1..5}.png) + iojpgfiles+=(remoteio{6..10}.jpg) + USE_SSH=$("$bin"/exiv2 -v -V | grep ^ssh= | sed s/ssh=//) + if [ "$USE_SSH" == "0" ]; then + #Skip remoteIo test cases + echo 'Ssh is not used. Skip sshio test cases.' + else + # test connection + printf 'sftp test connection ' + TEST_CON=$("$bin"/conntest sftp://"$EXIV2_AWSUBUNTU_USERNAME"_sftp:$EXIV2_AWSUBUNTU_PASSWORD@$EXIV2_AWSUBUNTU_HOST/var/www/$testfile) + if [[ "$TEST_CON" == OK* ]]; then + # SFTP protocol + errors=0 + printf 'OK\nSFTP READ ' + for name in ${files[@]}; do + SFTPReadTest "sftp://"$EXIV2_AWSUBUNTU_USERNAME"_sftp:$EXIV2_AWSUBUNTU_PASSWORD@$EXIV2_AWSUBUNTU_HOST/var/www/$name" + done + if [ $errors -eq 0 ]; then + printf '\nAll test cases passed\n' + else + echo $errors ' test cases failed!' + fi + else + echo $TEST_CON + printf "FAIL\nnot run SFTP read\n" + fi + + # test connection + printf 'ssh test connection ' + TEST_CON=$("$bin"/conntest ssh://$EXIV2_AWSUBUNTU_USERNAME:$EXIV2_AWSUBUNTU_PASSWORD@$EXIV2_AWSUBUNTU_HOST/sshtest/$testfile) + if [[ "$TEST_CON" == OK* ]]; then + # SSH protocol + errors=0 + printf 'OK\nSSH IO ' + for name in ${iopngfiles[@]}; do + SshIOTest "ssh://$EXIV2_AWSUBUNTU_USERNAME:$EXIV2_AWSUBUNTU_PASSWORD@$EXIV2_AWSUBUNTU_HOST/sshtest/$name" + done + for name in ${iojpgfiles[@]}; do + SshIOTest "ssh://$EXIV2_AWSUBUNTU_USERNAME:$EXIV2_AWSUBUNTU_PASSWORD@$EXIV2_AWSUBUNTU_HOST/sshtest/$name" + done + if [ $errors -eq 0 ]; then + printf '\nAll test cases passed\n' + else + echo $errors ' test cases failed!' + fi + else + echo $TEST_CON + printf "FAIL\nnot run SSH read\n" + fi + fi +) +# That's all Folks! +## \ No newline at end of file diff --git a/test/testMSVC.sh b/test/testMSVC.sh index 445cc20a..45999f8a 100755 --- a/test/testMSVC.sh +++ b/test/testMSVC.sh @@ -33,6 +33,7 @@ for d in $(find "$msvc" -name exiv2.exe -exec dirname {} ";"); do ( cd "$home/.." make $test + $d/exiv2.exe -v -V ) done diff --git a/xmpsdk/CMakeLists.txt b/xmpsdk/CMakeLists.txt index f7141d95..df0e62c9 100644 --- a/xmpsdk/CMakeLists.txt +++ b/xmpsdk/CMakeLists.txt @@ -9,6 +9,8 @@ include(../CMake_msvc.txt) msvc_runtime_configure(${EXIV2_ENABLE_SHARED}) +cmake_policy(SET CMP0026 OLD) # Something to do with location + FOREACH(_currentfile ${XMPSRC}) # http://www.openguru.com/2009/04/cmake-detecting-platformoperating.html IF(NOT MSVC AND NOT CYGWIN AND NOT MSYS)