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_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
USE_WINAPI
CODECVT_COMPATIBLE
)
message("-- Testing codecvt - yes")
else()
message("-- Testing codecvt - no")
endif()
message("-- Testing iconv")
try_run(ICONV_RUN ICONV_COMPILE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/tests/IconvTest.cpp)
if (ICONV_COMPILE)
list(APPEND LIBRAGEPHOTO_DEFINES
USE_ICONV
ICONV_COMPATIBLE
)
message("-- Testing iconv - yes")
else()
message("-- Testing iconv - no")
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)
list(APPEND LIBRAGEPHOTO_DEFINES
RAGEPHOTO_BENCHMARK
)
endif()
project(ragephoto LANGUAGES CXX)
add_library(ragephoto SHARED
src/libragephoto_global.h
src/RagePhoto.cpp
src/RagePhoto.h
)
target_compile_definitions(ragephoto PRIVATE
LIBRAGEPHOTO_LIBRARY
${LIBRAGEPHOTO_DEFINES}
)
install(TARGETS ragephoto DESTINATION lib)
install(FILES
src/RagePhoto.h
src/libragephoto_global.h
DESTINATION include
)
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
install(FILES ${RAGEPHOTO_HEADERS} DESTINATION include)
project(ragephoto-extract LANGUAGES CXX)
add_executable(ragephoto-extract
src/libragephoto_global.h
src/RagePhoto-Extract.cpp
src/RagePhoto.h
)
target_link_libraries(ragephoto-extract ragephoto)
install(TARGETS ragephoto-extract DESTINATION bin)
option(WITH_EXTRACT "Build ragephoto-extract" ON)
if (WITH_EXTRACT)
project(ragephoto-extract LANGUAGES CXX)
set(EXTRACT_SOURCES
src/RagePhoto-Extract.cpp
)
add_executable(ragephoto-extract ${RAGEPHOTO_HEADERS} ${EXTRACT_SOURCES})
target_link_libraries(ragephoto-extract ragephoto)
install(TARGETS ragephoto-extract DESTINATION bin)
endif()

View File

@ -25,8 +25,11 @@
#include <chrono>
#endif
#ifdef USE_ICONV
#include "iconv.h"
#ifdef CODECVT_COMPATIBLE
#include <codecvt>
#include <locale>
#elif defined ICONV_COMPATIBLE
#include <iconv.h>
#endif
RagePhoto::RagePhoto()
@ -81,7 +84,12 @@ bool RagePhoto::load(const char *data, size_t length)
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");
if (iconv_in == (iconv_t)-1) {
p_error = Error::UnicodeInitError; // 4
@ -336,19 +344,6 @@ const std::string RagePhoto::title()
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 readLen = 0;
@ -357,13 +352,7 @@ size_t RagePhoto::readBuffer(const char *input, char *output, size_t *pos, size_
readLen = inputLen - *pos;
if (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);
#endif
*pos = *pos + readLen;
return readLen;
}

View File

@ -81,7 +81,6 @@ public:
const std::string title();
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 uint32_t charToUInt32BE(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.
*****************************************************************************/
#include "iconv.h"
#include "stdio.h"
#include <cstdio>
#include <cstring>
#include <iconv.h>
int main(int argc, char *argv[])
{
iconv_t instance = iconv_open("UTF-16LE", "UTF-8");
if (instance == (iconv_t)-1)
return 1;
char src[] = "Test";
char dst[256];
size_t src_s = sizeof(src);
size_t dst_s = sizeof(dst);
char *isrc = src;
char *idst = dst;
iconv(instance, &isrc, &src_s, &idst, &dst_s);
iconv_close(instance);
printf("%s\n", dst);
return 0;
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
};
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");
}