add codecvt support

This commit is contained in:
Syping 2021-08-27 01:47:09 +02:00
parent 63c0977ed6
commit c9b33b324d
5 changed files with 167 additions and 62 deletions

View file

@ -5,53 +5,68 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (WIN32) message("-- Testing codecvt")
try_run(CODECVT_RUN CODECVT_COMPILE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/tests/CodecvtTest.cpp)
if (CODECVT_COMPILE)
list(APPEND LIBRAGEPHOTO_DEFINES list(APPEND LIBRAGEPHOTO_DEFINES
USE_WINAPI CODECVT_COMPATIBLE
) )
message("-- Testing codecvt - yes")
else()
message("-- Testing codecvt - no")
endif() endif()
message("-- Testing iconv") message("-- Testing iconv")
try_run(ICONV_RUN ICONV_COMPILE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/tests/IconvTest.cpp) try_run(ICONV_RUN ICONV_COMPILE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/tests/IconvTest.cpp)
if (ICONV_COMPILE) if (ICONV_COMPILE)
list(APPEND LIBRAGEPHOTO_DEFINES list(APPEND LIBRAGEPHOTO_DEFINES
USE_ICONV ICONV_COMPATIBLE
) )
message("-- Testing iconv - yes") message("-- Testing iconv - yes")
else() else()
message("-- Testing iconv - no") message("-- Testing iconv - no")
endif() endif()
option(WITH_BENCHMARK "Benchmark RagePhoto Parsing Engine" OFF) project(ragephoto LANGUAGES CXX)
set(RAGEPHOTO_SOURCES
src/RagePhoto.cpp
src/RagePhoto.h
)
set(RAGEPHOTO_HEADERS
src/libragephoto_global.h
src/RagePhoto.h
)
option(BUILD_SHARED "Build libragephoto as shared library" ON)
if (BUILD_SHARED)
add_library(ragephoto SHARED ${RAGEPHOTO_HEADERS} ${RAGEPHOTO_SOURCES})
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
else()
add_library(ragephoto STATIC ${RAGEPHOTO_HEADERS} ${RAGEPHOTO_SOURCES})
endif()
option(WITH_BENCHMARK "Build with libragephoto benchmark" OFF)
if (WITH_BENCHMARK) if (WITH_BENCHMARK)
list(APPEND LIBRAGEPHOTO_DEFINES list(APPEND LIBRAGEPHOTO_DEFINES
RAGEPHOTO_BENCHMARK RAGEPHOTO_BENCHMARK
) )
endif() endif()
project(ragephoto LANGUAGES CXX)
add_library(ragephoto SHARED
src/libragephoto_global.h
src/RagePhoto.cpp
src/RagePhoto.h
)
target_compile_definitions(ragephoto PRIVATE target_compile_definitions(ragephoto PRIVATE
LIBRAGEPHOTO_LIBRARY LIBRAGEPHOTO_LIBRARY
${LIBRAGEPHOTO_DEFINES} ${LIBRAGEPHOTO_DEFINES}
) )
install(TARGETS ragephoto DESTINATION lib) install(TARGETS ragephoto DESTINATION lib)
install(FILES install(FILES ${RAGEPHOTO_HEADERS} DESTINATION include)
src/RagePhoto.h
src/libragephoto_global.h
DESTINATION include
)
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
project(ragephoto-extract LANGUAGES CXX) option(WITH_EXTRACT "Build ragephoto-extract" ON)
add_executable(ragephoto-extract if (WITH_EXTRACT)
src/libragephoto_global.h project(ragephoto-extract LANGUAGES CXX)
src/RagePhoto-Extract.cpp set(EXTRACT_SOURCES
src/RagePhoto.h src/RagePhoto-Extract.cpp
) )
target_link_libraries(ragephoto-extract ragephoto) add_executable(ragephoto-extract ${RAGEPHOTO_HEADERS} ${EXTRACT_SOURCES})
install(TARGETS ragephoto-extract DESTINATION bin) target_link_libraries(ragephoto-extract ragephoto)
install(TARGETS ragephoto-extract DESTINATION bin)
endif()

View file

@ -25,8 +25,11 @@
#include <chrono> #include <chrono>
#endif #endif
#ifdef USE_ICONV #ifdef CODECVT_COMPATIBLE
#include "iconv.h" #include <codecvt>
#include <locale>
#elif defined ICONV_COMPATIBLE
#include <iconv.h>
#endif #endif
RagePhoto::RagePhoto() RagePhoto::RagePhoto()
@ -81,7 +84,12 @@ bool RagePhoto::load(const char *data, size_t length)
return false; return false;
} }
#ifdef USE_ICONV #ifdef CODECVT_COMPATIBLE
char16_t photoHeader16[128];
memcpy(photoHeader16, photoHeader, sizeof(char) * 256);
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert;
p_photoString = convert.to_bytes(photoHeader16);
#elif defined ICONV_COMPATIBLE
iconv_t iconv_in = iconv_open("UTF-8", "UTF-16LE"); iconv_t iconv_in = iconv_open("UTF-8", "UTF-16LE");
if (iconv_in == (iconv_t)-1) { if (iconv_in == (iconv_t)-1) {
p_error = Error::UnicodeInitError; // 4 p_error = Error::UnicodeInitError; // 4
@ -336,19 +344,6 @@ const std::string RagePhoto::title()
return p_titleString; return p_titleString;
} }
size_t RagePhoto::readBuffer(const char *input, char *output, size_t *pos, size_t len)
{
#ifdef READ_USE_FOR
for (size_t i = 0; i < len; i++) {
output[i] = input[*pos+i];
}
#else
memcpy(output, &input[*pos], sizeof(char) * len);
#endif
*pos = *pos + len;
return len;
}
size_t RagePhoto::readBuffer(const char *input, char *output, size_t *pos, size_t len, size_t inputLen) size_t RagePhoto::readBuffer(const char *input, char *output, size_t *pos, size_t len, size_t inputLen)
{ {
size_t readLen = 0; size_t readLen = 0;
@ -357,13 +352,7 @@ size_t RagePhoto::readBuffer(const char *input, char *output, size_t *pos, size_
readLen = inputLen - *pos; readLen = inputLen - *pos;
if (readLen > len) if (readLen > len)
readLen = len; readLen = len;
#ifdef READ_USE_FOR
for (size_t i = 0; i < readLen; i++) {
output[i] = input[*pos+i];
}
#else
memcpy(output, &input[*pos], sizeof(char) * readLen); memcpy(output, &input[*pos], sizeof(char) * readLen);
#endif
*pos = *pos + readLen; *pos = *pos + readLen;
return readLen; return readLen;
} }

View file

@ -81,7 +81,6 @@ public:
const std::string title(); const std::string title();
private: private:
inline size_t readBuffer(const char *input, char *output, size_t *pos, size_t len);
inline size_t readBuffer(const char *input, char *output, size_t *pos, size_t len, size_t inputLen); inline size_t readBuffer(const char *input, char *output, size_t *pos, size_t len, size_t inputLen);
inline uint32_t charToUInt32BE(char *x); inline uint32_t charToUInt32BE(char *x);
inline uint32_t charToUInt32LE(char *x); inline uint32_t charToUInt32LE(char *x);

66
tests/CodecvtTest.cpp Normal file
View file

@ -0,0 +1,66 @@
/*****************************************************************************
* libragephoto RAGE Photo Parser
* Copyright (C) 2021 Syping
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* This software is provided as-is, no warranties are given to you, we are not
* responsible for anything with use of the software, you are self responsible.
*****************************************************************************/
#include <codecvt>
#include <cstring>
#include <locale>
#include <iostream>
int main(int argc, char *argv[])
{
const char photoHeader[256] = {
0x50, 0x00, 0x48, 0x00, 0x4f, 0x00, 0x54, 0x00,
0x4f, 0x00, 0x20, 0x00, 0x2d, 0x00, 0x20, 0x00,
0x30, 0x00, 0x32, 0x00, 0x2f, 0x00, 0x30, 0x00,
0x31, 0x00, 0x2f, 0x00, 0x31, 0x00, 0x37, 0x00,
0x20, 0x00, 0x30, 0x00, 0x38, 0x00, 0x3a, 0x00,
0x34, 0x00, 0x32, 0x00, 0x3a, 0x00, 0x34, 0x00,
0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
char16_t photoHeader16[128];
memcpy(photoHeader16, photoHeader, sizeof(char) * 256);
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert;
std::string photoString = convert.to_bytes(photoHeader16);
std::cout << photoString << std::endl;
return strcmp(photoString.c_str(), "PHOTO - 02/01/17 08:42:44");
}

View file

@ -16,22 +16,58 @@
* responsible for anything with use of the software, you are self responsible. * responsible for anything with use of the software, you are self responsible.
*****************************************************************************/ *****************************************************************************/
#include "iconv.h" #include <cstdio>
#include "stdio.h" #include <cstring>
#include <iconv.h>
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
iconv_t instance = iconv_open("UTF-16LE", "UTF-8"); char photoHeader[256] = {
if (instance == (iconv_t)-1) 0x50, 0x00, 0x48, 0x00, 0x4f, 0x00, 0x54, 0x00,
return 1; 0x4f, 0x00, 0x20, 0x00, 0x2d, 0x00, 0x20, 0x00,
char src[] = "Test"; 0x30, 0x00, 0x32, 0x00, 0x2f, 0x00, 0x30, 0x00,
char dst[256]; 0x31, 0x00, 0x2f, 0x00, 0x31, 0x00, 0x37, 0x00,
size_t src_s = sizeof(src); 0x20, 0x00, 0x30, 0x00, 0x38, 0x00, 0x3a, 0x00,
size_t dst_s = sizeof(dst); 0x34, 0x00, 0x32, 0x00, 0x3a, 0x00, 0x34, 0x00,
char *isrc = src; 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
char *idst = dst; 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
iconv(instance, &isrc, &src_s, &idst, &dst_s); 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
iconv_close(instance); 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
printf("%s\n", dst); 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
return 0; 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
char photoString[256];
iconv_t iconv_in = iconv_open("UTF-8", "UTF-16LE");
if (iconv_in == (iconv_t)-1)
return -1;
size_t src_s = sizeof(photoHeader);
size_t dst_s = sizeof(photoString);
char *src = photoHeader;
char *dst = photoString;
size_t ret = iconv(iconv_in, &src, &src_s, &dst, &dst_s);
iconv_close(iconv_in);
if (ret == static_cast<size_t>(-1)) {
return -1;
}
return strcmp(photoString, "PHOTO - 02/01/17 08:42:44");
} }