Initial commit
This commit is contained in:
commit
6072b2ba29
844 changed files with 220532 additions and 0 deletions
126
app/src/main/AndroidManifest.xml
Normal file
126
app/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.TTS_SERVICE" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<application
|
||||
android:name=".MyApplication"
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Reader"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.Reader"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- PDF Filter -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="content" />
|
||||
<data android:scheme="file" />
|
||||
<data android:mimeType="application/pdf" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- EPUB Filter -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="content" />
|
||||
<data android:scheme="file" />
|
||||
<data android:mimeType="application/epub+zip" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- MOBI / Kindle Filter -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="content" />
|
||||
<data android:scheme="file" />
|
||||
<data android:mimeType="application/x-mobipocket-ebook" />
|
||||
<data android:mimeType="application/vnd.amazon.mobi8-ebook" />
|
||||
<data android:mimeType="application/vnd.amazon.ebook" />
|
||||
<data android:mimeType="application/octet-stream" />
|
||||
<data android:host="*" />
|
||||
<data android:pathPattern=".*\\.mobi" />
|
||||
<data android:pathPattern=".*\\.azw3" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- Markdown and Plain Text Filter -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="content" />
|
||||
<data android:scheme="file" />
|
||||
<data android:mimeType="text/plain" />
|
||||
<data android:mimeType="text/markdown" />
|
||||
<data android:mimeType="text/x-markdown" />
|
||||
<data android:mimeType="text/*" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="content" />
|
||||
<data android:scheme="file" />
|
||||
<data android:host="*" />
|
||||
<data android:mimeType="*/*" />
|
||||
<data android:pathPattern=".*\\.md" />
|
||||
<data android:pathPattern=".*\\.markdown" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="content" />
|
||||
<data android:mimeType="application/octet-stream" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:name=".tts.TtsService"
|
||||
android:exported="true"
|
||||
android:foregroundServiceType="mediaPlayback">
|
||||
<intent-filter>
|
||||
<action android:name="androidx.media3.session.MediaSessionService"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/provider_paths" />
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
35
app/src/main/assets/MathML-template.html
Normal file
35
app/src/main/assets/MathML-template.html
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script>
|
||||
console.log("MATH_DIAGNOSTIC: MathML-template.html script block started.");
|
||||
window.MathJax = {
|
||||
svg: {
|
||||
fontCache: 'none', // Disable font cache for better performance in this context
|
||||
displayAlign: 'left',
|
||||
displayIndent: '0',
|
||||
scale: 1.0,
|
||||
},
|
||||
startup: {
|
||||
ready: () => {
|
||||
console.log("MATH_DIAGNOSTIC: MathJax startup.ready callback fired.");
|
||||
MathJax.startup.defaultReady();
|
||||
if (window.AndroidBridge) {
|
||||
console.log("MATH_DIAGNOSTIC: Calling AndroidBridge.onMathJaxReady()");
|
||||
window.AndroidBridge.onMathJaxReady();
|
||||
} else {
|
||||
console.error("MATH_DIAGNOSTIC: AndroidBridge not found!");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script type="text/javascript" id="MathJax-script" async
|
||||
src="file:///android_asset/mathjax/tex-mml-svg.js">
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="math-container"></div>
|
||||
</body>
|
||||
</html>
|
||||
70
app/src/main/assets/demo_art.svg
Normal file
70
app/src/main/assets/demo_art.svg
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
<svg viewBox="0 0 800 300" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="underlineGradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" style="stop-color:#F59E0B;stop-opacity:1" />
|
||||
<stop offset="50%" style="stop-color:#EC4899;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#8B5CF6;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- Background -->
|
||||
<rect width="800" height="300" fill="#f0fdf4"/>
|
||||
|
||||
<!-- Decorative dots -->
|
||||
<circle cx="120" cy="90" r="5" fill="#F59E0B" opacity="0.7" />
|
||||
<circle cx="680" cy="210" r="6" fill="#EC4899" opacity="0.7" />
|
||||
<circle cx="700" cy="110" r="4" fill="#8B5CF6" opacity="0.7" />
|
||||
<circle cx="150" cy="230" r="5" fill="#10B981" opacity="0.6" />
|
||||
<circle cx="650" cy="80" r="4" fill="#F59E0B" opacity="0.6" />
|
||||
<circle cx="90" cy="180" r="3" fill="#EC4899" opacity="0.5" />
|
||||
<circle cx="720" cy="170" r="5" fill="#8B5CF6" opacity="0.6" />
|
||||
|
||||
<!-- Single-stroke handwritten "Try Episteme!" -->
|
||||
<g stroke="#10B981" stroke-width="3.5" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- T -->
|
||||
<path d="M 80 115 L 140 115 M 110 115 L 110 175 Q 110 185 115 185" />
|
||||
|
||||
<!-- r -->
|
||||
<path d="M 150 145 L 150 180 M 150 155 Q 155 145 165 145 Q 172 145 175 150" />
|
||||
|
||||
<!-- y -->
|
||||
<path d="M 185 145 L 190 180 L 200 145 L 198 185 Q 197 200 188 210 Q 182 215 176 210" />
|
||||
|
||||
<!-- Space, then E -->
|
||||
<path d="M 240 110 L 240 180 M 240 110 L 285 110 M 240 145 L 275 145 M 240 180 L 285 180" />
|
||||
|
||||
<!-- p -->
|
||||
<path d="M 305 145 L 305 215 M 305 158 Q 305 145 320 145 Q 340 145 345 160 Q 348 170 345 180 Q 340 195 320 195 Q 305 195 305 182" />
|
||||
|
||||
<!-- i -->
|
||||
<path d="M 365 145 L 365 180 M 365 130 L 365 132" />
|
||||
|
||||
<!-- s -->
|
||||
<path d="M 428 148 Q 418 143 408 145 Q 398 147 395 155 Q 393 162 400 165 Q 410 170 420 168 Q 428 166 430 172 Q 432 180 422 183 Q 412 186 402 182" />
|
||||
|
||||
<!-- t -->
|
||||
<path d="M 445 125 L 445 175 Q 445 185 455 185 Q 465 185 470 180 M 435 145 L 460 145" />
|
||||
|
||||
<!-- e -->
|
||||
<path d="M 530 158 L 490 160 Q 488 165 490 172 Q 493 182 505 185 Q 520 187 528 178 Q 533 170 528 160 Q 520 148 505 148 Q 495 148 490 153" />
|
||||
|
||||
<!-- m -->
|
||||
<path d="M 545 145 L 545 180 M 545 155 Q 545 145 555 145 Q 565 145 565 155 L 565 180 M 565 155 Q 565 145 575 145 Q 585 145 585 155 L 585 180" />
|
||||
|
||||
<!-- e (second) -->
|
||||
<path d="M 635 158 L 600 160 Q 598 165 600 172 Q 603 182 615 185 Q 628 187 635 178 Q 640 170 635 160 Q 628 148 613 148 Q 603 148 598 153" />
|
||||
|
||||
<!-- ! -->
|
||||
<path d="M 660 125 L 660 165 M 660 178 L 660 182" />
|
||||
</g>
|
||||
|
||||
<!-- Decorative underline -->
|
||||
<path
|
||||
d="M 180 200 Q 400 220 620 200"
|
||||
stroke="#EC4899"
|
||||
stroke-width="3"
|
||||
fill="none"
|
||||
opacity="0.6"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
1775
app/src/main/assets/epub_reader.js
Normal file
1775
app/src/main/assets/epub_reader.js
Normal file
File diff suppressed because it is too large
Load diff
BIN
app/src/main/assets/fonts/lato.ttf
Normal file
BIN
app/src/main/assets/fonts/lato.ttf
Normal file
Binary file not shown.
BIN
app/src/main/assets/fonts/lexend.ttf
Normal file
BIN
app/src/main/assets/fonts/lexend.ttf
Normal file
Binary file not shown.
BIN
app/src/main/assets/fonts/lora.ttf
Normal file
BIN
app/src/main/assets/fonts/lora.ttf
Normal file
Binary file not shown.
BIN
app/src/main/assets/fonts/merriweather.ttf
Normal file
BIN
app/src/main/assets/fonts/merriweather.ttf
Normal file
Binary file not shown.
BIN
app/src/main/assets/fonts/roboto_mono.ttf
Normal file
BIN
app/src/main/assets/fonts/roboto_mono.ttf
Normal file
Binary file not shown.
1
app/src/main/assets/mathjax/tex-mml-chtml.js
Normal file
1
app/src/main/assets/mathjax/tex-mml-chtml.js
Normal file
File diff suppressed because one or more lines are too long
1
app/src/main/assets/mathjax/tex-mml-svg.js
Normal file
1
app/src/main/assets/mathjax/tex-mml-svg.js
Normal file
File diff suppressed because one or more lines are too long
BIN
app/src/main/assets/sample.pdf
Normal file
BIN
app/src/main/assets/sample.pdf
Normal file
Binary file not shown.
13
app/src/main/assets/test_chapter_1.html
Normal file
13
app/src/main/assets/test_chapter_1.html
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<!-- assets\test_chapter_1.html -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Test Chapter 1</title>
|
||||
</head>
|
||||
<body>
|
||||
<p id='first_para'>Hello World</p>
|
||||
<p>This is a test chapter for UI testing.</p>
|
||||
<p id='search_target'>You can search for the word Espresso.</p>
|
||||
<p>Another paragraph with the word espresso but lowercase.</p>
|
||||
</body>
|
||||
</html>
|
||||
10
app/src/main/assets/test_chapter_2.html
Normal file
10
app/src/main/assets/test_chapter_2.html
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<!-- assets\test_chapter_2.html -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Test Chapter 2</title>
|
||||
</head>
|
||||
<body>
|
||||
<p id='second_chapter_para'>This is the second chapter.</p>
|
||||
</body>
|
||||
</html>
|
||||
95
app/src/main/cpp/CMakeLists.txt
vendored
Normal file
95
app/src/main/cpp/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
# CMakeLists.txt
|
||||
# Sets the minimum version of CMake required.
|
||||
cmake_minimum_required(VERSION 3.22.1)
|
||||
|
||||
# Declares the project name.
|
||||
project("reader-native")
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
# --- CONFIGURE SUBPROJECTS ---
|
||||
# Force subprojects to build as static libraries. This is critical for Android.
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries" FORCE)
|
||||
set(BROTLI_DISABLE_TESTS ON CACHE BOOL "Disable Brotli tests" FORCE)
|
||||
|
||||
|
||||
# ===================================================================
|
||||
# WOFF2 DEPENDENCY SETUP
|
||||
# ===================================================================
|
||||
# 1. Add the brotli project. This defines the `brotlidec-static` target.
|
||||
add_subdirectory(woff2/brotli)
|
||||
|
||||
# 2. Manually define the variables that the woff2/CMakeLists.txt script expects.
|
||||
set(BROTLIDEC_FOUND TRUE)
|
||||
set(BROTLIENC_FOUND TRUE)
|
||||
set(BROTLIDEC_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/woff2/brotli/c/include)
|
||||
set(BROTLIENC_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/woff2/brotli/c/include)
|
||||
set(BROTLIDEC_LIBRARIES brotlidec-static)
|
||||
set(BROTLIENC_LIBRARIES brotlienc-static)
|
||||
|
||||
# 3. Add the woff2 project. This defines the `woff2dec` target.
|
||||
add_subdirectory(woff2)
|
||||
|
||||
|
||||
# ===================================================================
|
||||
# LIBMOBI DEPENDENCY SETUP
|
||||
# ===================================================================
|
||||
# 4. Set libmobi options before adding it.
|
||||
# We disable libxml2 to use the internal writer, simplifying dependencies.
|
||||
# We also disable encryption for now for the same reason.
|
||||
set(USE_LIBXML2 OFF CACHE BOOL "Use libxml2" FORCE)
|
||||
set(USE_ENCRYPTION OFF CACHE BOOL "Enable encryption" FORCE)
|
||||
|
||||
# Temporarily enable shared libs to build libmobi as a .so file for LGPL compliance.
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
# 5. Add the libmobi project. This will define the `mobi` target as a shared library.
|
||||
add_subdirectory(libmobi)
|
||||
|
||||
set_target_properties(mobi PROPERTIES VERSION "" SOVERSION "")
|
||||
# Revert back to building static libs for any subsequent dependencies.
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
# Force all symbols in the mobi shared library to be visible.
|
||||
# This is necessary because some internal functions we use (like mobi_determine_flowpart_type)
|
||||
# are not explicitly exported by the library's public API for shared builds.
|
||||
set_target_properties(mobi PROPERTIES C_VISIBILITY_PRESET default)
|
||||
|
||||
|
||||
# ===================================================================
|
||||
# FINAL NATIVE LIBRARY FOR THE APP
|
||||
# ===================================================================
|
||||
# 6. Define our final JNI wrapper library.
|
||||
# This single .so file will be loaded by the Android app.
|
||||
add_library(
|
||||
native-lib
|
||||
SHARED
|
||||
Woff2Converter.cpp
|
||||
mobi_jni_bridge.c # The placeholder file you created
|
||||
)
|
||||
|
||||
# 7. Tell our library where to find all necessary header files.
|
||||
target_include_directories(native-lib
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/woff2/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libmobi/src
|
||||
)
|
||||
|
||||
# 8. Find the Android logging and zlib libraries.
|
||||
find_library(log-lib log)
|
||||
find_library(z-lib z)
|
||||
|
||||
# 9. Link our final library against all the static libraries and Android libraries.
|
||||
target_link_libraries(
|
||||
native-lib
|
||||
PRIVATE
|
||||
woff2dec # From woff2
|
||||
mobi # From libmobi
|
||||
${log-lib}
|
||||
${z-lib} # libmobi requires zlib
|
||||
)
|
||||
56
app/src/main/cpp/Woff2Converter.cpp
vendored
Normal file
56
app/src/main/cpp/Woff2Converter.cpp
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#include <jni.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// This is the correct header for the public API
|
||||
#include <woff2/decode.h>
|
||||
|
||||
extern "C" JNIEXPORT jbyteArray JNICALL
|
||||
Java_com_aryan_reader_paginatedreader_Woff2Converter_convertWoff2ToTtf(
|
||||
JNIEnv *env,
|
||||
jobject /* this */,
|
||||
jbyteArray woff2_data) {
|
||||
|
||||
// Get the input WOFF2 data from the jbyteArray
|
||||
jbyte* woff2_bytes = env->GetByteArrayElements(woff2_data, nullptr);
|
||||
jsize woff2_size = env->GetArrayLength(woff2_data);
|
||||
const uint8_t* woff2_input = reinterpret_cast<const uint8_t*>(woff2_bytes);
|
||||
|
||||
// Calculate the required size using the correct function name from your header
|
||||
size_t ttf_size = woff2::ComputeWOFF2FinalSize(woff2_input, woff2_size);
|
||||
if (ttf_size == 0) {
|
||||
// This indicates an error in the input font data
|
||||
env->ReleaseByteArrayElements(woff2_data, woff2_bytes, JNI_ABORT);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create the output buffer
|
||||
std::vector<uint8_t> ttf_output(ttf_size);
|
||||
|
||||
// Perform the conversion using the deprecated function signature that matches your header
|
||||
bool success = woff2::ConvertWOFF2ToTTF(
|
||||
ttf_output.data(), ttf_size,
|
||||
woff2_input, woff2_size
|
||||
);
|
||||
|
||||
// Release the input byte array
|
||||
env->ReleaseByteArrayElements(woff2_data, woff2_bytes, JNI_ABORT);
|
||||
|
||||
// If conversion failed, return null
|
||||
if (!success) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create a new Java byte array for the result
|
||||
jbyteArray ttf_data = env->NewByteArray(ttf_size);
|
||||
if (ttf_data == nullptr) {
|
||||
// Out of memory error
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Copy the converted data to the Java byte array
|
||||
env->SetByteArrayRegion(ttf_data, 0, ttf_size,
|
||||
reinterpret_cast<const jbyte*>(ttf_output.data()));
|
||||
|
||||
return ttf_data;
|
||||
}
|
||||
101
app/src/main/cpp/libmobi/.github/workflows/build.yml
vendored
Normal file
101
app/src/main/cpp/libmobi/.github/workflows/build.yml
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ public ]
|
||||
pull_request:
|
||||
branches: [ public ]
|
||||
|
||||
jobs:
|
||||
unix-build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- name: default build with debug
|
||||
options: --enable-debug
|
||||
- name: bulid with internal libs
|
||||
options: --with-zlib=no --with-libxml2=no
|
||||
- name: build without encryption
|
||||
options: --disable-encryption
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: install dependencies
|
||||
run: |
|
||||
if [ "${{ runner.os }}" = "Linux" ]; then
|
||||
sudo apt-get update -qq;
|
||||
sudo apt-get install -y autotools-dev pkg-config automake autoconf libtool;
|
||||
sudo apt-get install -y zlib1g-dev libxml2-dev;
|
||||
elif [ "${{ runner.os }}" = "macOS" ]; then
|
||||
brew update > /dev/null;
|
||||
brew outdated autoconf || brew upgrade autoconf;
|
||||
brew outdated automake || brew upgrade automake;
|
||||
brew outdated libtool || brew upgrade libtool;
|
||||
fi
|
||||
- name: autogen
|
||||
run: ./autogen.sh
|
||||
- name: configure
|
||||
run: ./configure ${{ matrix.config.options }}
|
||||
- name: make
|
||||
run: make -j `nproc`
|
||||
- name: make check
|
||||
run: make -j `nproc` check
|
||||
- name: make distcheck
|
||||
run: make -j `nproc` distcheck
|
||||
- name: upload debug artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
name: test-logs-${{ matrix.runs-on }}
|
||||
path: |
|
||||
**/tests/test-suite.log
|
||||
**/tests/samples/*.log
|
||||
|
||||
win64-build:
|
||||
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- name: setup-msys2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW64
|
||||
path-type: minimal
|
||||
update: true
|
||||
install: >-
|
||||
git
|
||||
autotools
|
||||
base-devel
|
||||
mingw-w64-x86_64-toolchain
|
||||
mingw-w64-x86_64-libtool
|
||||
mingw-w64-x86_64-libxml2
|
||||
mingw-w64-x86_64-zlib
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: autogen
|
||||
run: sh ./autogen.sh
|
||||
- name: configure
|
||||
run: ./configure --enable-debug
|
||||
- name: make
|
||||
run: make -j$(nproc)
|
||||
- name: make check
|
||||
run: make -j$(nproc) check
|
||||
- name: make distcheck
|
||||
run: make -j$(nproc) distcheck
|
||||
- name: upload debug artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
name: test-logs-${{ matrix.runs-on }}
|
||||
path: |
|
||||
**/tests/test-suite.log
|
||||
**/tests/samples/*.log
|
||||
71
app/src/main/cpp/libmobi/.github/workflows/codeql-analysis.yml
vendored
Normal file
71
app/src/main/cpp/libmobi/.github/workflows/codeql-analysis.yml
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ public ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ public ]
|
||||
schedule:
|
||||
- cron: '19 13 * * 3'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
54
app/src/main/cpp/libmobi/.github/workflows/coverity-scan.yml
vendored
Normal file
54
app/src/main/cpp/libmobi/.github/workflows/coverity-scan.yml
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
name: coverity-scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ public ]
|
||||
|
||||
jobs:
|
||||
coverity-build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: install dependencies
|
||||
run: |
|
||||
sudo apt-get update -qq;
|
||||
sudo apt-get install -y autotools-dev pkg-config automake autoconf libtool;
|
||||
sudo apt-get install -y zlib1g-dev libxml2-dev;
|
||||
- name: download coverity tools
|
||||
run: |
|
||||
curl -Lf \
|
||||
-o cov-analysis-linux64.tar.gz \
|
||||
--form project=bfabiszewski/libmobi \
|
||||
--form token=$TOKEN \
|
||||
https://scan.coverity.com/download/linux64
|
||||
mkdir cov-analysis-linux64
|
||||
tar xzf cov-analysis-linux64.tar.gz --strip 1 -C cov-analysis-linux64
|
||||
env:
|
||||
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||
- name: autogen
|
||||
run: ./autogen.sh
|
||||
- name: configure
|
||||
run: ./configure ${{ matrix.config.options }}
|
||||
- name: build with cov-build
|
||||
run: |
|
||||
export PATH=`pwd`/cov-analysis-linux64/bin:$PATH
|
||||
cov-build --dir cov-int make -j `nproc`
|
||||
- name: upload results to coverity-scan
|
||||
run: |
|
||||
tar czvf cov-int.tgz cov-int
|
||||
curl -Lf \
|
||||
--form token=$TOKEN \
|
||||
--form email=scan.coverity@fabiszewski.net \
|
||||
--form file=@cov-int.tgz \
|
||||
--form version="`git describe --tags`" \
|
||||
--form description="libmobi `git describe --tags`" \
|
||||
"https://scan.coverity.com/builds?project=bfabiszewski/libmobi"
|
||||
env:
|
||||
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||
39
app/src/main/cpp/libmobi/.travis.yml
vendored
Normal file
39
app/src/main/cpp/libmobi/.travis.yml
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
os:
|
||||
- linux
|
||||
# - osx
|
||||
language: c
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
before_install:
|
||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then
|
||||
sudo apt-get update -qq;
|
||||
sudo apt-get install -y autotools-dev pkg-config automake autoconf libtool;
|
||||
sudo apt-get install -y zlib1g-dev libxml2-dev;
|
||||
elif [ "$TRAVIS_OS_NAME" == "osx" ]; then
|
||||
brew update > /dev/null;
|
||||
brew outdated autoconf || brew upgrade autoconf;
|
||||
brew outdated automake || brew upgrade automake;
|
||||
brew outdated libtool || brew upgrade libtool;
|
||||
fi
|
||||
- git config --global user.name "Travis CI (libmobi)"
|
||||
- git config --global user.email $HOSTNAME":not-for-mail@travis-ci.org"
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- ./configure --enable-debug && make && make test
|
||||
- make clean
|
||||
- ./configure --with-zlib=no --with-libxml2=no && make && make test
|
||||
|
||||
env:
|
||||
global:
|
||||
- secure: "ShIL3IDvH59cJx4QAKWhVTs7ynCAfID11DqK8pIWJX2UtvXc4pdDQUq6U5ZRLUT0BR6kmLNxYrQUpUKvZ9sYnPuj4X5o9jzXzXsJPXTy/qpjiLK4MCZLIlI4OAHexfAuZTOVZHOoE/B8ABpk8nGYUXk02++LxlmwtE/fIWOOWHs="
|
||||
|
||||
addons:
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "bfabiszewski/libmobi"
|
||||
description: "Build submitted via Travis CI"
|
||||
notification_email: scan.coverity@fabiszewski.net
|
||||
build_command_prepend: "./autogen.sh && ./configure"
|
||||
build_command: "make -j 4"
|
||||
branch_pattern: public
|
||||
0
app/src/main/cpp/libmobi/AUTHORS
vendored
Normal file
0
app/src/main/cpp/libmobi/AUTHORS
vendored
Normal file
118
app/src/main/cpp/libmobi/CMakeLists.txt
vendored
Normal file
118
app/src/main/cpp/libmobi/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
# Copyright (c) 2022 Bartek Fabiszewski
|
||||
# http://www.fabiszewski.net
|
||||
#
|
||||
# This file is part of libmobi.
|
||||
# Licensed under LGPL, either version 3, or any later.
|
||||
# See <http://www.gnu.org/licenses/>
|
||||
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
project(LIBMOBI C)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
|
||||
file(STRINGS ${LIBMOBI_SOURCE_DIR}/configure.ac VERSION_LINE REGEX "AC_INIT\\(\\[libmobi\\], \\[(.*)\\]\\)")
|
||||
string(REGEX MATCH "([0-9]+\\.[0-9]+)" PACKAGE_VERSION "${VERSION_LINE}")
|
||||
message(STATUS "libmobi version ${PACKAGE_VERSION}")
|
||||
add_definitions(-DPACKAGE_VERSION="${PACKAGE_VERSION}")
|
||||
string(REPLACE "." ";" VERSION_LIST ${PACKAGE_VERSION})
|
||||
list(GET VERSION_LIST 0 PACKAGE_VERSION_MAJOR)
|
||||
list(GET VERSION_LIST 1 PACKAGE_VERSION_MINOR)
|
||||
|
||||
# Option to enable encryption
|
||||
option(USE_ENCRYPTION "Enable encryption" ON)
|
||||
|
||||
# Option to enable static tools compilation
|
||||
option(TOOLS_STATIC "Enable static tools compilation" OFF)
|
||||
|
||||
# Option to use libxml2
|
||||
option(USE_LIBXML2 "Use libxml2 instead of internal xmlwriter" ON)
|
||||
|
||||
# Option to use zlib
|
||||
option(USE_ZLIB "Use zlib" ON)
|
||||
|
||||
# Option to enable XMLWRITER
|
||||
option(USE_XMLWRITER "Enable xmlwriter (for opf support)" ON)
|
||||
|
||||
# Option to enable debug
|
||||
option(MOBI_DEBUG "Enable debug" OFF)
|
||||
|
||||
# Option to enable debug alloc
|
||||
option(MOBI_DEBUG_ALLOC "Enable debug alloc" OFF)
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
|
||||
|
||||
if(TOOLS_STATIC)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
endif(TOOLS_STATIC)
|
||||
|
||||
if(USE_ENCRYPTION)
|
||||
add_definitions(-DUSE_ENCRYPTION)
|
||||
endif(USE_ENCRYPTION)
|
||||
|
||||
if(USE_XMLWRITER)
|
||||
add_definitions(-DUSE_XMLWRITER)
|
||||
if(USE_LIBXML2)
|
||||
add_definitions(-DUSE_LIBXML2)
|
||||
find_package(LibXml2 REQUIRED)
|
||||
include_directories(${LIBXML2_INCLUDE_DIR})
|
||||
endif(USE_LIBXML2)
|
||||
endif(USE_XMLWRITER)
|
||||
|
||||
if(MOBI_DEBUG)
|
||||
add_definitions(-DMOBI_DEBUG)
|
||||
message(STATUS "CMAKE_CXX_COMPILER_ID=${CMAKE_C_COMPILER_ID}")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang|GNU")
|
||||
add_compile_options(-pedantic -Wall -Wextra -Werror)
|
||||
endif()
|
||||
endif(MOBI_DEBUG)
|
||||
|
||||
if(MOBI_DEBUG_ALLOC)
|
||||
add_definitions(-DMOBI_DEBUG_ALLOC)
|
||||
endif(MOBI_DEBUG_ALLOC)
|
||||
|
||||
if(USE_ZLIB)
|
||||
find_package(ZLIB REQUIRED)
|
||||
include_directories(${ZLIB_INCLUDE_DIR})
|
||||
else()
|
||||
add_definitions(-DUSE_MINIZ)
|
||||
endif(USE_ZLIB)
|
||||
|
||||
include(CheckIncludeFile)
|
||||
include(CheckFunctionExists)
|
||||
check_include_file(unistd.h HAVE_UNISTD_H)
|
||||
if(HAVE_UNISTD_H)
|
||||
add_definitions(-DHAVE_UNISTD_H)
|
||||
endif(HAVE_UNISTD_H)
|
||||
check_function_exists(getopt HAVE_GETOPT)
|
||||
if(HAVE_GETOPT)
|
||||
add_definitions(-DHAVE_GETOPT)
|
||||
endif(HAVE_GETOPT)
|
||||
|
||||
check_function_exists(strdup HAVE_STRDUP)
|
||||
if(HAVE_STRDUP)
|
||||
add_definitions(-DHAVE_STRDUP)
|
||||
endif(HAVE_STRDUP)
|
||||
|
||||
check_include_file(sys/resource.h HAVE_SYS_RESOURCE_H)
|
||||
if(HAVE_SYS_RESOURCE_H)
|
||||
add_definitions(-DHAVE_SYS_RESOURCE_H)
|
||||
endif(HAVE_SYS_RESOURCE_H)
|
||||
|
||||
|
||||
include(CheckCSourceCompiles)
|
||||
foreach(keyword "inline" "__inline__" "__inline")
|
||||
check_c_source_compiles("${keyword} void func(); void func() { } int main() { func(); return 0; }" HAVE_INLINE)
|
||||
if(HAVE_INLINE)
|
||||
add_definitions(-DMOBI_INLINE=${keyword})
|
||||
break()
|
||||
endif(HAVE_INLINE)
|
||||
endforeach(keyword)
|
||||
|
||||
check_c_source_compiles("void func() { } __attribute__((noreturn)); int main() { func(); return 0; }" HAVE_ATTRIBUTE_NORETURN)
|
||||
if(HAVE_ATTRIBUTE_NORETURN)
|
||||
add_definitions(-DHAVE_ATTRIBUTE_NORETURN)
|
||||
endif(HAVE_ATTRIBUTE_NORETURN)
|
||||
|
||||
add_subdirectory(src)
|
||||
# add_subdirectory(tools)
|
||||
165
app/src/main/cpp/libmobi/COPYING
vendored
Normal file
165
app/src/main/cpp/libmobi/COPYING
vendored
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
372
app/src/main/cpp/libmobi/ChangeLog
vendored
Normal file
372
app/src/main/cpp/libmobi/ChangeLog
vendored
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
2024-10-29: Update github actions
|
||||
2024-10-29: Fix CMake build, closes #49
|
||||
2024-07-04: Minor rewording in man page
|
||||
2024-06-17: Fix typo
|
||||
2024-06-17: Version 0.12
|
||||
2024-02-04: Fix: missing header with libxml2 >= 2.12
|
||||
2024-02-04: Max index count value is too low for some dictionaries
|
||||
2023-08-10: Fix CMake debug build with MSVC, fixes #46
|
||||
2023-07-11: Clean up unused value
|
||||
2023-07-11: Fix clang warning about missing function prototypes (-Wstrict-prototypes)
|
||||
2023-02-21: Update Xcode project settings
|
||||
2023-02-21: Replace deprecated functions
|
||||
2023-02-21: Try to reconstruct sources even on broken indices
|
||||
2023-02-05: Refactor mobi_buffer_get_varlen_internal to be compatible with other buffer functions. Update documentation with information about mobi_buffer_get_varlen_dec limitation.
|
||||
2022-06-26: Fix undefined behavior with null pointer arithmetics in case of corrupt input
|
||||
2022-05-28: Version 0.11
|
||||
2022-05-27: Fix potential null pointer dereference on corrupt input when inflections CNCX record is not initialized
|
||||
2022-05-23: Fix index entries count
|
||||
2022-05-23: Prevent leak of index entries on corrupt data
|
||||
2022-05-23: Add checks for fragments part in case of corrupt data
|
||||
2022-05-17: Fix potential integer overflow with corrupt data
|
||||
2022-05-05: Fix: index entry label not being zero-terminated with corrupt input
|
||||
2022-05-03: Fix boundary checking error in markup search, that could cause buffer over-read with corrupt input
|
||||
2022-05-02: Fix typo in macro name
|
||||
2022-04-27: Fix undefined behavior when passing null to strdup
|
||||
2022-04-27: Fix wrong boundary checks in inflections parser resulting in stack buffer over-read with corrupt input
|
||||
2022-04-26: Fix text formatting
|
||||
2022-04-26: Fix array boundary check when parsing inflections which could result in buffer over-read with corrupt input
|
||||
2022-04-23: Fix formatting
|
||||
2022-04-23: Fix checking boundary of deobfuscation key which could cause buffer over-read with corrupt data
|
||||
2022-04-23: Fix issue with corrupt data with empty lookup string which could lead to read beyond buffer
|
||||
2022-04-23: Fix faulty checks for array boundary which caused buffer over-read with corrupt input
|
||||
2022-04-23: Fix issue with corrupt files with tagvalues_count = 0 that caused null pointer dereference
|
||||
2022-04-23: Fix issues when mobi_buffer_getpointer returns null. With corrupt data this could lead to out-of-bounds read
|
||||
2022-04-13: Add packaging status [skip ci]
|
||||
2022-04-10: Make random generation return proper error codes
|
||||
2022-04-10: Rewrite randombytes for libmobi
|
||||
2022-04-07: Add libsodium randombytes.c
|
||||
2022-04-10: Fix "fallthrough" spelling
|
||||
2022-04-10: Make declaration match definition
|
||||
2022-04-10: Fix different sign comparison warning
|
||||
2022-04-10: Update Xcode project
|
||||
2022-04-10: Don't run tests if bash is missing
|
||||
2022-04-10: Looking for libxml2, first try pkg-config
|
||||
2022-04-04: Update MSVC project
|
||||
2022-04-02: Add support for GNU/kFreeBSD and GNU/Hurd
|
||||
2022-04-02: Check for inline, noreturn support in CMake
|
||||
2022-03-27: Fix format truncation warning
|
||||
2022-03-21: Version 0.10
|
||||
2022-03-21: Update Xcode project [skip ci]
|
||||
2022-03-21: Add functions for retrieving orthographic index entries
|
||||
2022-02-27: Add basic CMake support
|
||||
2022-02-26: GHA: fetch tags with checkout
|
||||
2022-02-26: Minor refactoring of file path manipulation function
|
||||
2022-02-26: Fix memory handling issues
|
||||
2022-02-26: Add coverity scan workflow
|
||||
2022-02-25: Remove obsolete changelog
|
||||
2022-02-25: Fix md5sum output on Windows
|
||||
2022-02-25: Fix inconsistent separators in path on Windows builds
|
||||
2022-02-25: GHA: fix log paths
|
||||
2022-02-25: GHA: fix workflow syntax
|
||||
2022-02-25: GHA: upload test logs on failure
|
||||
2022-02-24: Fix printf format specifier
|
||||
2022-02-24: Fix sample path in Makefile
|
||||
2022-02-24: Missing autotools in mingw workflow
|
||||
2022-02-24: Windows doesn't accept asterisk in file names
|
||||
2022-02-24: Update workflow, add badge
|
||||
2022-02-24: Add mingw workflow
|
||||
2022-02-24: Fix tests in out-of-tree build
|
||||
2022-02-24: Update man pages
|
||||
2022-02-24: Replace non-portable strptime
|
||||
2022-02-24: Make sure both validity period dates are set
|
||||
2022-02-21: Fix strptime not found on linux build
|
||||
2022-02-21: Add build github action
|
||||
2022-02-21: Update README
|
||||
2022-02-21: Minor code cleanups
|
||||
2022-02-21: Unify boolean and static usage in tools
|
||||
2022-02-21: mobimeta: fix null pointer dereference when parsing malformed option
|
||||
2022-02-18: Add hybrid spit option to mobitool
|
||||
2022-02-18: Update documentation
|
||||
2022-02-18: Test both encrypted hybrid parts
|
||||
2022-02-18: Fix: fast decryption routine fails for non-huffman compression
|
||||
2022-02-18: Fix mobitool serial decryption
|
||||
2022-02-18: Add DRM tests
|
||||
2022-02-17: Fix build with encryption disabled
|
||||
2022-02-17: Update tests samples
|
||||
2022-02-16: Add -h option to tools, update man pages
|
||||
2022-02-16: Update Xcode settings
|
||||
2022-02-16: Restructure, cleanup encryption related code, add mobidrm tool
|
||||
2021-11-19: Improve getopt loop, fix config.h to be accessible from all tools
|
||||
2021-11-10: Update xcode project
|
||||
2021-11-10: Add functions to split hybrid files
|
||||
2021-11-10: Avoid modifying existing records, as caller may keep reference to them
|
||||
2021-11-05: Fix: tests fail if pid contains asterisk
|
||||
2021-11-05: Fix: decryption may fail for some records with standard compression
|
||||
2021-11-05: Replace test samples with self-generated smaller ones
|
||||
2021-11-05: Skip test in case of missing checksums
|
||||
2021-10-20: Version 0.9
|
||||
2021-10-24: Fix out-of-tree build
|
||||
2021-10-22: Fix mingw build, code formatting
|
||||
2021-10-14: Fix gcc format truncation warning
|
||||
2021-10-14: Include autogen.sh in distribution bundle
|
||||
2021-10-14: Create codeql-analysis.yml
|
||||
2021-10-14: Fix autoconf 2.70 warnings, clean up
|
||||
2021-10-14: Build fails with autoconf 2.70
|
||||
2021-10-11: Version 0.8
|
||||
2021-10-11: Update Xcode project
|
||||
2021-10-11: Fix warnings about changed signedness
|
||||
2021-09-18: Fix potential out-of-buffer read while parsing corrupt file, closes #38
|
||||
2021-09-18: Fix potential out-of-buffer read while parsing corrupt file, closes #35, #36
|
||||
2021-09-09: Version 0.7
|
||||
2021-09-09: fix oob write bug inside libmobi
|
||||
2021-06-07: Add reference to brew formula
|
||||
2020-09-02: Fix null pointer dereference in case of broken fragment
|
||||
2020-08-01: Update changelog
|
||||
2020-08-01: Version 0.6
|
||||
2020-07-31: Fix typo
|
||||
2020-07-31: Add Readme to dist package
|
||||
2020-07-31: Remove anchor on truncated link
|
||||
2020-07-31: Fix missing option in man page
|
||||
2020-07-30: Include test samples in dist package
|
||||
2020-07-25: Fix gcc 7+ warnings about implicit fall through and format truncation
|
||||
2020-07-24: Unique names for internal functions to avoid confilicts with static linking
|
||||
2020-06-24: Close file in error branch
|
||||
2020-06-24: Fix static compilation with miniz on gcc
|
||||
2020-06-24: Minor documentation fixes
|
||||
2020-06-23: Version 0.5
|
||||
2020-06-23: mobitool: add dump cover option
|
||||
2020-06-23: Minor documentation improvement
|
||||
2020-06-23: Fix potential buffer over-read
|
||||
2019-03-18: Fix: try also "name" attribute when searching for link anchor tags, closes #24
|
||||
2019-02-22: Add mobi_is_replica function
|
||||
2019-02-22: Fix potential read beyond buffer
|
||||
2019-02-22: Travis migration
|
||||
2018-08-07: Fix: missing items in recreated ncx file
|
||||
2018-06-20: Fix: printf format warning on some gcc versions
|
||||
2018-06-20: Fix: make dist broken by nonexistent header files
|
||||
2018-06-20: VERSION 0.4
|
||||
2018-06-20: Fix: buffer overflow (CVE-2018-11726)
|
||||
2018-06-20: Fix: buffer overflow (CVE-2018-11724)
|
||||
2018-06-20: Fix: read beyond buffer (CVE-2018-11725)
|
||||
2018-06-20: Fix: buffer overflow (mobitool), closes #18
|
||||
2018-06-20: Fix: read beyond buffer with corrupted KF8 Boundary record, closes #19
|
||||
2018-06-20: Fix: read beyond buffer, closes #16, #17
|
||||
2018-06-20: Updated xcode project files
|
||||
2018-04-03: Fix: ncx part was not scanned for links, fixes #12
|
||||
2018-04-02: Fix regression, potential use after free
|
||||
2018-04-02: Skip broken resources, fixes #10
|
||||
2018-03-05: Allow processing zero length text records, fixes #9
|
||||
2017-12-25: Skip broken first resource offset instead of dying
|
||||
2017-12-18: Skip broken links reconstruction instead of dying
|
||||
2017-11-27: Disable travis OS X builds, as they usually time out
|
||||
2017-11-16: Fix: increase max number of dictionary entries per record
|
||||
2017-11-14: Fix for some encrypted documents with palmdoc encoding
|
||||
2017-11-06: Fix: potential null pointer dereference
|
||||
2017-10-16: Manpage cleanup
|
||||
2017-09-27: Update README
|
||||
2017-09-26: Increase maximum length of attribute name and value, closes #5
|
||||
2017-02-26: Remove obsolete files from VS build (closes #3) [ci skip]
|
||||
2016-11-05: Mobitool: use epub extension if extracted source resource is epub
|
||||
2016-06-10: Update docs
|
||||
2016-06-10: Update test files
|
||||
2016-06-10: Fix: out of bounds read in corrupt font resource
|
||||
2016-06-10: Prevent memory leak in case of corrupt font resources
|
||||
2016-06-10: Calculate deobfuscation buffer limit from key length
|
||||
2016-06-10: Fix: USE_LIBXML2 macro was not included from config.h
|
||||
2016-06-10: Fix: USE_LIBXML2 macro was not included from config.h
|
||||
2016-06-09: Fix: memory leak in tools
|
||||
2016-06-09: Fix: potential out of bounds read
|
||||
2016-06-09: Fix: memory leak in internal xmlwriter
|
||||
2016-06-01: Update README
|
||||
2016-05-19: Feature: verify decryption key type
|
||||
2016-05-19: Cleanup converting little endian buffer to 32-bit integer
|
||||
2016-05-19: Feature: check drm expiration dates
|
||||
2016-05-18: Fix: memory leaks in encryption
|
||||
2016-05-18: Fix concurrent autotools builds
|
||||
2016-05-18: use relative path, as $(top_srcdir) fails to be substituted (?)
|
||||
2016-05-18: update vcxproj
|
||||
2016-05-18: Include headers in automake sources
|
||||
2016-05-18: Fix: automake out-of-tree miniz build
|
||||
2016-05-18: Fix: wrongly detected fdst record broke some ancient documents
|
||||
2016-05-18: Fix: improve index header parsing, some old dictionaries might not load
|
||||
2016-05-18: Fix: convert encoding of opf strings from cp1252 indices
|
||||
2016-05-18: Quiet warnings about unused values of wiped variables
|
||||
2016-05-18: Fix: potential memory leak
|
||||
2016-05-18: Fix: wrongly decoded "©" entity
|
||||
2016-05-16: Fix: huffdic decompression fails in case of huge documents
|
||||
2016-05-14: Simplify buffer_init_null() function
|
||||
2016-05-14: Use ARRAYSIZE macro
|
||||
2016-05-14: Feature: calculate pid for decryption from device serial number
|
||||
2016-04-29: Use endian-independent byte swapping
|
||||
2016-04-29: Exclude unused miniz functions from binary
|
||||
2016-04-29: Add SHA-1 routines
|
||||
2016-04-27: Fix miniz.c formatting
|
||||
2016-04-27: Documentation
|
||||
2016-04-20: Update changelog
|
||||
2016-04-20: Fix potential null pointer dereference
|
||||
2016-04-20: Remove useless check
|
||||
2016-04-20: Fix text record size calculation
|
||||
2016-04-20: Fix buffer checking and freeing
|
||||
2016-04-19: Update docs
|
||||
2016-04-19: Update ChangeLog
|
||||
2016-04-19: Fix comparison between signed and unsigned integer
|
||||
2016-04-19: use strdup on linux/glibc
|
||||
2016-04-19: Add initial write and metadata editing support. Add mobimeta tool.
|
||||
2016-04-19: Always check whether memory allocation succeeded
|
||||
2016-04-18: Fix: guarantee array resize step is at least 1
|
||||
2016-04-13: Workaround to read some old mobipocket files
|
||||
2016-04-13: Improve pdb dates resolving
|
||||
2016-04-07: Minor documentation edit
|
||||
2016-04-07: Update changelog
|
||||
2016-04-06: Fix format warning
|
||||
2016-04-06: Update test checksums
|
||||
2016-04-06: Fix: <dc:date> "event" attribute needs "opf" namespace
|
||||
2016-04-06: Fix: id attributes in ncx file should be unique
|
||||
2016-04-06: Store full name in MOBIMobiHeader structure
|
||||
2016-04-05: Fix formatting
|
||||
2016-04-05: Fix signedness warning
|
||||
2016-04-04: Fix potential buffer overflow, closes #2
|
||||
2016-04-04: Fix potential null pointer dereference
|
||||
2016-03-23: Fix signedness warnings
|
||||
2016-03-22: Fix: _mkdir needs direct.h on MinGW
|
||||
2016-03-22: Fix tests on Windows
|
||||
2016-03-22: Fix: palmdoc decompression may fail with zero byte in input buffer
|
||||
2016-03-21: VERSION 03: internal xmlwriter, metadata handling functions, bug fixes
|
||||
2016-03-21: Feature: add helper functions for metadata extraction
|
||||
2016-03-21: Load also kf8 data when only kf7 version is requested
|
||||
2016-03-21: Fix: wrong exth header length check could discard some valid headers
|
||||
2016-03-20: Get rid of extended attributes in release archive on OS X
|
||||
2016-03-19: Mobitool: add descriptive error messages based on libmobi return codes
|
||||
2016-03-04: Add extra length check for CMET record extraction
|
||||
2016-03-04: Always check buffer allocation result
|
||||
2016-03-04: Add functions to extract conversion source and log, also add this feature to mobitool
|
||||
2016-03-04: Remove some stray printfs
|
||||
2016-03-03: Remove not used AC_FUNC_MALLOC/REALLOC macros that break cross-compilation
|
||||
2016-03-03: Fix potential illegal memory access in miniz.c
|
||||
2016-03-03: Fix potential dereference of null pointer in miniz.c
|
||||
2016-03-03: Fix for Android bionic libc bug (SIZE_MAX missing in stdint.h)
|
||||
2016-03-03: Fix mobitool compilation on MSVC++
|
||||
2016-03-03: Add EPUB creation feature to mobitool
|
||||
2016-03-02: Fix potential buffer overflow, null pointer dereference
|
||||
2016-03-02: Add travis test for no-external-dependency build
|
||||
2016-03-02: Fix missing strdup on linux
|
||||
2016-03-02: Add internal xmlwriter (as an alternative to libxml2)
|
||||
2016-03-01: Feature: decode html entities in exth header strings
|
||||
2016-02-29: Fix: potential buffer overflow
|
||||
2016-02-29: Fix: wrong pid calculation (regression introduced in 0.2)
|
||||
2016-02-26: VERSION 0.2: increased stability, lots of bugs fixed
|
||||
2016-02-26: Add Xcode project file
|
||||
2016-02-26: Preliminary support for MSVC++ compiler
|
||||
2016-02-26: Do not use variable length arrays
|
||||
2016-02-26: Refactor mobi_reconstruct_parts() to use MOBIFragment list
|
||||
2016-02-26: Fix compiler warning about sign conversion
|
||||
2016-02-26: Fix compiler warning about type conversion
|
||||
2016-02-26: Check the result of malloc/calloc
|
||||
2016-02-26: Fix inconsistent use of const between some definitions and declarations
|
||||
2016-02-24: Fix inconsistence between function declaration and definition
|
||||
2016-02-24: Fix various potential crashes in case of corrupt input (afl-fuzz)
|
||||
2016-02-24: Fix dead code warnings in miniz
|
||||
2015-11-26: Export mobi_get_first_resource_record() function
|
||||
2015-11-26: Fix: double free on corrupt cdic
|
||||
2015-11-02: Update docs
|
||||
2015-11-02: Feature: add helper functions to find resources by flow id
|
||||
2015-11-02: Feature: export MOBI_NOTSET macro
|
||||
2015-11-02: Feature: give more options to parse rawml function
|
||||
2015-10-24: Restore travis.yml
|
||||
2015-10-24: Fix OSX travis build
|
||||
2015-10-24: Fix OSX travis build
|
||||
2015-10-24: Fix multiline inline script
|
||||
2015-10-24: Enable multi-OS feature
|
||||
2015-10-24: Fix: unique temporary name for parallel tests
|
||||
2015-10-24: Fix: decoding video resources falsely reported as failed
|
||||
2015-10-24: Fix: tests, some md5sum implementations insert double spaces
|
||||
2015-10-24: Fix for automake < 1.13
|
||||
2015-10-23: Add simple tests framework
|
||||
2015-10-23: Fix: increase max index entries per record count, as some rare samples fail
|
||||
2015-10-22: Fix: incorrectly decoded video/audio resources
|
||||
2015-10-22: Feature: add option to specify output path
|
||||
2015-10-14: Add some internal functions to public API: mobi_get_flow_by_uid, mobi_get_resource_by_uid, mobi_get_part_by_uid, mobi_get_exthrecord_by_tag
|
||||
2015-06-13: update changelog
|
||||
2015-06-13: fix: various invalid memory access
|
||||
2015-06-13: don't quit on invalid input, instead substitute with replacement character
|
||||
2015-06-12: fix typo
|
||||
2015-06-12: update changelog
|
||||
2015-06-12: fix: reconstruction failed when there were gaps between fragments
|
||||
2015-06-12: add EXTH tags
|
||||
2015-06-12: prevent return of garbage value check return value in case of failed malloc
|
||||
2015-06-12: fix invalid memory access
|
||||
2015-04-12: Fix reconstruction of "kindle:embed" links without mime type (regression)
|
||||
2015-04-12: Add sanity checks to link reconstruction functions, allow skipping some malformed patterns
|
||||
2015-04-12: Fix infinite loop in guide build while unknown tag was found
|
||||
2015-04-12: Increase max recursion level for huffman decompression
|
||||
2015-03-28: update docs
|
||||
2015-03-28: fix solaris studio compiler warnings
|
||||
2015-03-28: fix solaris studio compiler build
|
||||
2015-02-18: Fix "more than one: -compatibility_version specified" error on powerpc
|
||||
2014-11-24: improve docs
|
||||
2014-11-24: simplify public header
|
||||
2014-11-21: changelog update [ci skip]
|
||||
2014-11-21: README
|
||||
2014-11-21: fix: add sanity checks
|
||||
2014-11-21: Fix: add sanity checks
|
||||
2014-11-21: add sanity check to huffcdic indices count
|
||||
2014-11-21: fix number of leaks and other minor issues (by coverity scan)
|
||||
2014-11-20: missing notification email kills coverity scan
|
||||
2014-11-20: update travis.yml
|
||||
2014-11-20: upgrade travis.ml with covert scan
|
||||
2014-11-20: update README.md
|
||||
2014-11-20: add .travis.yml
|
||||
2014-11-20: update REAME.md
|
||||
2014-11-20: update README.md
|
||||
2014-11-20: update docs
|
||||
2014-11-20: feature: add decryption support
|
||||
2014-11-20: mkdir cleanup
|
||||
2014-11-17: documentation
|
||||
2014-11-17: strip unneeded <aid/> tags
|
||||
2014-11-16: fix: potential leak
|
||||
2014-11-16: fix: regression, some image tags were not reconstructed
|
||||
2014-11-16: fix: improve ligatures handling
|
||||
2014-11-16: override darwin linker default versioning
|
||||
2014-11-15: fix: get proper LIGT entries count from index header
|
||||
2014-11-15: feature: unpack records into new folder
|
||||
2014-11-14: make README readable on github
|
||||
2014-11-14: add README for mobitool
|
||||
2014-11-14: fix: dictionaries with large inflection rules failed
|
||||
2014-11-14: feature: support encoded ligatures in index entry labels
|
||||
2014-11-14: readme
|
||||
2014-11-14: update changelog
|
||||
2014-11-13: feature: support for older inflections scheme
|
||||
2014-11-13: bug: files with short tagx header won't open
|
||||
2014-11-13: cleanup unneeded include
|
||||
2014-11-13: use strdup on linux/glibc
|
||||
2014-11-13: debugging cleanup
|
||||
2014-11-13: reorganize source files
|
||||
2014-11-13: use strdup on linux/glibc
|
||||
2014-11-11: update changelog
|
||||
2014-11-11: update changeling
|
||||
2014-11-11: fix: documents with text record size > 4096 failed to load
|
||||
2014-11-11: add: function to decode flat index entries
|
||||
2014-11-11: debug: add functions for debugging indices
|
||||
2014-11-11: cleanup
|
||||
2014-11-11: fix: variable length value wrongly calculated when going backwards
|
||||
2014-11-08: update documentation
|
||||
2014-11-08: update changelog
|
||||
2014-11-08: add support for reconstructing inflections index entries
|
||||
2014-11-08: parsing of exth header failed in some cases
|
||||
2014-11-08: fix: some links reconstruction in kf7 failed
|
||||
2014-11-08: improve debug info
|
||||
2014-11-08: failed malloc false reports
|
||||
2014-11-03: fix problem with uncompressed documents
|
||||
2014-11-03: fix broken locales
|
||||
2014-11-03: remove obsolete includes
|
||||
2014-11-03: git log > changelog
|
||||
2014-11-03: improved buffer handling
|
||||
2014-11-03: improved OPF for dictionaries
|
||||
2014-11-03: proper rawml->orth initialization and freeing
|
||||
2014-11-03: fix subject field in opf
|
||||
2014-11-03: handle UTF-16 surrogates, make ORDT lookups locale independent
|
||||
2014-11-01: move dict reconstruction to separate function
|
||||
2014-11-01: cleanup
|
||||
2014-11-01: quiet gcc warning on printf format
|
||||
2014-11-01: reconstruction of orth dictionary entries
|
||||
2014-09-27: use mobi_list_del_all()
|
||||
2014-09-25: postpone conversion to utf8 after all source reconstructions
|
||||
2014-09-24: comment
|
||||
2014-09-24: comments
|
||||
2014-09-12: doxygen comment
|
||||
2014-09-12: data size in comment
|
||||
2014-09-05: MOBIArray data type fix
|
||||
2014-09-05: config.h fixes
|
||||
2014-06-29: merge master
|
||||
2014-04-11: initial commit
|
||||
12
app/src/main/cpp/libmobi/Makefile.am
vendored
Normal file
12
app/src/main/cpp/libmobi/Makefile.am
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# project Makefile.am
|
||||
|
||||
SUBDIRS = src tools tests
|
||||
|
||||
EXTRA_DIST = README.md autogen.sh
|
||||
|
||||
test: check
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libmobi.pc
|
||||
0
app/src/main/cpp/libmobi/NEWS
vendored
Normal file
0
app/src/main/cpp/libmobi/NEWS
vendored
Normal file
142
app/src/main/cpp/libmobi/README.md
vendored
Normal file
142
app/src/main/cpp/libmobi/README.md
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
# Libmobi
|
||||
|
||||
C library for handling Mobipocket/Kindle (MOBI) ebook format documents.
|
||||
|
||||
Library comes with several [command line tools](https://github.com/bfabiszewski/libmobi/tree/public/tools) for working with mobi ebooks.
|
||||
The tools source may also be used as an example on how to use the library.
|
||||
|
||||
## Features:
|
||||
- reading and parsing:
|
||||
- some older text Palmdoc formats (pdb),
|
||||
- Mobipocket files (prc, mobi),
|
||||
- newer MOBI files including KF8 format (azw, azw3),
|
||||
- Replica Print files (azw4)
|
||||
- recreating source files using indices
|
||||
- reconstructing references (links and embedded) in html files
|
||||
- reconstructing source structure that can be fed back to kindlegen
|
||||
- reconstructing dictionary markup (orth, infl tags)
|
||||
- writing back loaded documents
|
||||
- metadata editing
|
||||
- handling encrypted documents
|
||||
- encrypting documents for use on eInk Kindles
|
||||
|
||||
## Todo:
|
||||
- improve writing
|
||||
- serialize rawml into raw records
|
||||
- process RESC records
|
||||
|
||||
## Doxygen documentation:
|
||||
- [functions](http://www.fabiszewski.net/libmobi/group__mobi__export.html),
|
||||
- [structures for the raw, unparsed records metadata and data](http://www.fabiszewski.net/libmobi/group__raw__structs.html),
|
||||
- [structures for the parsed records metadata and data](http://www.fabiszewski.net/libmobi/group__parsed__structs.html),
|
||||
- [enums](http://www.fabiszewski.net/libmobi/group__mobi__enums.html)
|
||||
|
||||
## Source:
|
||||
- [on github](https://github.com/bfabiszewski/libmobi/)
|
||||
|
||||
## Packages:
|
||||
[](https://repology.org/project/libmobi/versions)
|
||||
|
||||
## Installation:
|
||||
|
||||
[for git] $ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
[optionally] $ make test
|
||||
$ sudo make install
|
||||
|
||||
On macOS, you can install via [Homebrew](https://brew.sh/) with `brew install libmobi`.
|
||||
|
||||
## Alternative build systems
|
||||
- The supported way of building project is by using autotools.
|
||||
- Optionally project provides basic support for CMake, Xcode and MSVC++ systems. However these alternative configurations are not covering all options of autotools project. They are also not tested and not updated regularly.
|
||||
|
||||
## Usage
|
||||
- single include file: `#include <mobi.h>`
|
||||
- linker flag: `-lmobi`
|
||||
- basic usage:
|
||||
```c
|
||||
#include <mobi.h>
|
||||
|
||||
/* Initialize main MOBIData structure */
|
||||
/* Must be deallocated with mobi_free() when not needed */
|
||||
MOBIData *m = mobi_init();
|
||||
if (m == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Open file for reading */
|
||||
FILE *file = fopen(fullpath, "rb");
|
||||
if (file == NULL) {
|
||||
mobi_free(m);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Load file into MOBIData structure */
|
||||
/* This structure will hold raw data/metadata from mobi document */
|
||||
MOBI_RET mobi_ret = mobi_load_file(m, file);
|
||||
fclose(file);
|
||||
if (mobi_ret != MOBI_SUCCESS) {
|
||||
mobi_free(m);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Initialize MOBIRawml structure */
|
||||
/* Must be deallocated with mobi_free_rawml() when not needed */
|
||||
/* In the next step this structure will be filled with parsed data */
|
||||
MOBIRawml *rawml = mobi_init_rawml(m);
|
||||
if (rawml == NULL) {
|
||||
mobi_free(m);
|
||||
return ERROR;
|
||||
}
|
||||
/* Raw data from MOBIData will be converted to html, css, fonts, media resources */
|
||||
/* Parsed data will be available in MOBIRawml structure */
|
||||
mobi_ret = mobi_parse_rawml(rawml, m);
|
||||
if (mobi_ret != MOBI_SUCCESS) {
|
||||
mobi_free(m);
|
||||
mobi_free_rawml(rawml);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Do something useful here */
|
||||
/* ... */
|
||||
/* For examples how to access data in MOBIRawml structure see mobitool.c */
|
||||
|
||||
/* Free MOBIRawml structure */
|
||||
mobi_free_rawml(rawml);
|
||||
|
||||
/* Free MOBIData structure */
|
||||
mobi_free(m);
|
||||
|
||||
return SUCCESS;
|
||||
```
|
||||
- for examples of usage, see [tools](https://github.com/bfabiszewski/libmobi/tree/public/tools)
|
||||
|
||||
|
||||
## Requirements
|
||||
- compiler supporting C99
|
||||
- zlib (optional, configure --with-zlib=no to use included miniz.c instead)
|
||||
- libxml2 (optional, configure --with-libxml2=no to use internal xmlwriter)
|
||||
- tested with gcc (>=4.2.4), clang (llvm >=3.4), sun c (>=5.13), MSVC++ (2015)
|
||||
- builds on Linux, MacOS, Windows (MSVC++, MinGW), Android, Solaris
|
||||
- tested architectures: x86, x86-64, arm, ppc
|
||||
- works cross-compiled on Kindle :)
|
||||
|
||||
## Tests
|
||||
- [](https://github.com/bfabiszewski/libmobi/actions)
|
||||
- [](https://travis-ci.com/bfabiszewski/libmobi)
|
||||
- [](https://scan.coverity.com/projects/3521)
|
||||
|
||||
## Projects using libmobi
|
||||
- [KyBook 2 Reader](http://kybook-reader.com)
|
||||
- [@Voice Aloud Reader](http://www.hyperionics.com/atVoice/)
|
||||
- [QLMobi quicklook plugin](https://github.com/bfabiszewski/QLMobi/tree/master/QLMobi)
|
||||
- [Librera Reader](http://librera.mobi)
|
||||
- ... (let me know to include your project)
|
||||
|
||||
## License:
|
||||
- LGPL, either version 3, or any later
|
||||
|
||||
## Credits:
|
||||
- The huffman decompression and KF8 parsing algorithms were learned by studying python source code of [KindleUnpack](https://github.com/kevinhendricks/KindleUnpack).
|
||||
- Thanks to all contributors of Mobileread [MOBI wiki](http://wiki.mobileread.com/wiki/MOBI)
|
||||
3
app/src/main/cpp/libmobi/autogen.sh
vendored
Normal file
3
app/src/main/cpp/libmobi/autogen.sh
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
mkdir -p m4 && \
|
||||
autoreconf --force --install -I m4
|
||||
419
app/src/main/cpp/libmobi/configure.ac
vendored
Normal file
419
app/src/main/cpp/libmobi/configure.ac
vendored
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.62])
|
||||
AC_INIT([libmobi], [0.12])
|
||||
AC_CONFIG_SRCDIR([src/buffer.c])
|
||||
|
||||
# Enable automake
|
||||
AM_INIT_AUTOMAKE([1.11 -Wall foreign subdir-objects])
|
||||
# all defined C macros (HAVE_*) will be saved to this file
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
m4_version_prereq([2.70], [], [AC_PROG_CC_C99])
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_INSTALL
|
||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||
|
||||
# Init libtool
|
||||
m4_ifdef([LT_INIT], [LT_INIT], [AC_PROG_LIBTOOL])
|
||||
|
||||
# Checks for libraries.
|
||||
|
||||
# Checks for header files.
|
||||
AC_HEADER_STDBOOL
|
||||
AC_CHECK_HEADERS([stdlib.h string.h utime.h unistd.h sys/resource.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_TYPE_INT32_T
|
||||
AC_TYPE_INT64_T
|
||||
AC_TYPE_INT8_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_UINT16_T
|
||||
AC_TYPE_UINT32_T
|
||||
AC_TYPE_UINT64_T
|
||||
AC_TYPE_UINT8_T
|
||||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_MKTIME
|
||||
AC_CHECK_FUNCS([memmove memset mkdir strdup strpbrk strrchr strstr strtoul utime])
|
||||
|
||||
# check for getopt() function
|
||||
AC_MSG_CHECKING([for getopt])
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="-Werror"
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#if HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif]],
|
||||
[[return getopt(0, NULL, NULL);]])],
|
||||
[have_getopt=yes
|
||||
AC_DEFINE([HAVE_GETOPT], [1], [Define whether getopt() function is available])],
|
||||
[have_getopt=no])
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
AC_MSG_RESULT([$have_getopt])
|
||||
AM_CONDITIONAL([USE_INTERNAL_GETOPT], [test x$have_getopt = xno])
|
||||
|
||||
# Check for oracle solaris studio c compiler
|
||||
AC_CHECK_DECL([__SUNPRO_C], [SUNCC=yes], [SUNCC=no])
|
||||
|
||||
# Get rid of extended attributes in release archive on macOS
|
||||
case "$host" in
|
||||
*-*-darwin*)
|
||||
am__tar="COPY_EXTENDED_ATTRIBUTES_DISABLE=1 COPYFILE_DISABLE=1 ${am__tar}"
|
||||
esac
|
||||
|
||||
# Check for -fvisibility=hidden to determine if we can do GNU-style
|
||||
# visibility attributes for symbol export control
|
||||
AC_MSG_CHECKING([for visibility hidden compiler flag])
|
||||
VISIBILITY_HIDDEN=
|
||||
if test x$SUNCC = xyes; then
|
||||
# check if we can use -xldscope=hidden
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="-xldscope=hidden"
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[]], [[]])],
|
||||
[enable_fvisibility_hidden=yes],
|
||||
[enable_fvisibility_hidden=no])
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
|
||||
AS_IF([test x$enable_fvisibility_hidden = xyes], [VISIBILITY_HIDDEN="-xldscope=hidden"])
|
||||
else
|
||||
case "$host" in
|
||||
*-*-mingw*)
|
||||
# on mingw32 we do -fvisibility=hidden and __declspec(dllexport)
|
||||
VISIBILITY_HIDDEN="-fvisibility=hidden"
|
||||
;;
|
||||
*)
|
||||
# on other compilers, check if we can do -fvisibility=hidden
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="-fvisibility=hidden -Werror"
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[]], [[]])],
|
||||
[enable_fvisibility_hidden=yes],
|
||||
[enable_fvisibility_hidden=no])
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
|
||||
AS_IF([test x$enable_fvisibility_hidden = xyes], [VISIBILITY_HIDDEN="-fvisibility=hidden"])
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
AC_MSG_RESULT([$VISIBILITY_HIDDEN])
|
||||
AC_SUBST([VISIBILITY_HIDDEN])
|
||||
|
||||
# MinGW seems to need this
|
||||
case "$host" in
|
||||
*-*-mingw*)
|
||||
NO_UNDEFINED="-no-undefined"
|
||||
AVOID_VERSION="-avoid-version"
|
||||
ISO99_SOURCE="-D_ISOC99_SOURCE=1"
|
||||
WIN32=yes
|
||||
;;
|
||||
*)
|
||||
NO_UNDEFINED=
|
||||
AVOID_VERSION=
|
||||
ISO99_SOURCE=
|
||||
WIN32=no
|
||||
;;
|
||||
esac
|
||||
AC_SUBST([NO_UNDEFINED])
|
||||
AC_SUBST([AVOID_VERSION])
|
||||
AC_SUBST([ISO99_SOURCE])
|
||||
AC_SUBST([WIN32])
|
||||
|
||||
# Override default versioning of Darwin linker
|
||||
case "$host" in
|
||||
*-*-darwin*)
|
||||
case "$host" in
|
||||
# exclude ppc as it breaks linker
|
||||
ppc-* | powerpc-*)
|
||||
DARWIN_LDFLAGS=
|
||||
;;
|
||||
*)
|
||||
MAJOR=`echo "${PACKAGE_VERSION}" | cut -d . -f 1`
|
||||
DARWIN_LDFLAGS="-Wl,-compatibility_version,${MAJOR} -Wl,-current_version,${PACKAGE_VERSION}"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
DARWIN_LDFLAGS=
|
||||
;;
|
||||
esac
|
||||
AC_SUBST([DARWIN_LDFLAGS])
|
||||
|
||||
# Check for --allow-multiple-definition support in linker
|
||||
AC_MSG_CHECKING([whether linker supports --allow-multiple-definition flag])
|
||||
MOBI_ALLOW_MULTIPLE=
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="-Wl,--allow-multiple-definition -Werror"
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[]], [[]])],
|
||||
[def_allow_multiple=yes],
|
||||
[def_allow_multiple=no])
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
AS_IF([test x$def_allow_multiple = xyes], [MOBI_ALLOW_MULTIPLE="-Wl,--allow-multiple-definition"])
|
||||
AC_MSG_RESULT([$def_allow_multiple])
|
||||
AC_SUBST([MOBI_ALLOW_MULTIPLE])
|
||||
|
||||
# Check for non-broken inline under various spellings
|
||||
AC_MSG_CHECKING([for inline keyword])
|
||||
def_inline=""
|
||||
for inline_key in inline __inline__ __inline
|
||||
do
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[]],
|
||||
[[} $inline_key int foo() { return 0; } int bar() { return foo();]])],
|
||||
[def_inline=$inline_key; break])
|
||||
done
|
||||
AC_MSG_RESULT([$def_inline])
|
||||
AC_DEFINE_UNQUOTED([MOBI_INLINE], [$def_inline], [How to obtain function inlining.])
|
||||
|
||||
# Check for noreturn attribute support
|
||||
AC_MSG_CHECKING([whether compiler supports noreturn attribute])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[]], [[void foo( void ) __attribute__((noreturn));]])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_ATTRIBUTE_NORETURN], [1], [Define to 1 if compiler supports __attribute__((noreturn))])],
|
||||
[AC_MSG_RESULT([no])]
|
||||
)
|
||||
|
||||
# Check --enable-xmlwriter
|
||||
XMLWRITER_OPT=""
|
||||
AC_MSG_CHECKING([whether enable xmlwriter (for opf support)])
|
||||
AC_ARG_ENABLE(
|
||||
[xmlwriter],
|
||||
[AS_HELP_STRING([--enable-xmlwriter], [enable xmlwriter (for opf support) @<:@default=yes@:>@])],
|
||||
[case "$enableval" in
|
||||
yes) xmlwriter=yes ;;
|
||||
no) xmlwriter=no ;;
|
||||
*) AC_MSG_ERROR([bad value $enableval for --enable-xmlwriter]) ;;
|
||||
esac],
|
||||
[xmlwriter=yes])
|
||||
AC_MSG_RESULT([$xmlwriter])
|
||||
AM_CONDITIONAL([USE_XMLWRITER], [test x$xmlwriter = xyes])
|
||||
if test x$xmlwriter = xyes; then
|
||||
AC_DEFINE([USE_XMLWRITER], [1], [Define whether enable xmlwriter (for opf support)])
|
||||
|
||||
# test for --with-libxml2
|
||||
AC_MSG_CHECKING([whether compile with libxml2])
|
||||
AC_ARG_WITH(
|
||||
[libxml2],
|
||||
[AS_HELP_STRING([--with-libxml2], [Use libxml2 instead of internal xmlwriter @<:@default=yes@:>@])],
|
||||
[if test "x$withval" = xyes; then use_libxml2=yes; else use_libxml2=no; fi],
|
||||
[use_libxml2=yes])
|
||||
AC_MSG_RESULT([$use_libxml2])
|
||||
|
||||
if test x$use_libxml2 = xyes; then
|
||||
AC_ARG_VAR([XML2_CONFIG], [path to xml2-config utility])
|
||||
AC_CHECK_PROGS([XML2_CONFIG], [xml2-config])
|
||||
AC_CHECK_PROGS([PKG_CONFIG], [pkg-config])
|
||||
AC_MSG_CHECKING([for libxml2 path supplier])
|
||||
if test -n "$PKG_CONFIG" && $PKG_CONFIG --exists libxml-2.0; then
|
||||
LIBXML2_CFLAGS="`$PKG_CONFIG --cflags libxml-2.0`"
|
||||
LIBXML2_LDFLAGS="`$PKG_CONFIG --libs libxml-2.0`"
|
||||
AC_MSG_RESULT([pkg-config])
|
||||
elif test -n "$XML2_CONFIG"; then
|
||||
LIBXML2_CFLAGS="`$XML2_CONFIG --cflags`"
|
||||
LIBXML2_LDFLAGS="`$XML2_CONFIG --libs`"
|
||||
AC_MSG_RESULT([xml2-config])
|
||||
else
|
||||
LIBXML2_CFLAGS=-I/usr/include/libxml2
|
||||
LIBXML2_LDFLAGS=-lxml2
|
||||
AC_MSG_RESULT([generic])
|
||||
fi
|
||||
saved_CPPFLAGS=$CPPFLAGS
|
||||
CPPFLAGS="$CPPFLAGS $LIBXML2_CFLAGS"
|
||||
AC_CHECK_HEADER(
|
||||
[libxml/xmlwriter.h],
|
||||
[AC_DEFINE([USE_LIBXML2], [1], [Define if you want to use libxml2 library])],
|
||||
[AC_MSG_ERROR([couldn't find libxml2])])
|
||||
CPPFLAGS=$saved_CPPFLAGS
|
||||
else
|
||||
LIBXML2_LDFLAGS=
|
||||
LIBXML2_CFLAGS=
|
||||
fi
|
||||
AC_SUBST([LIBXML2_LDFLAGS])
|
||||
AC_SUBST([LIBXML2_CFLAGS])
|
||||
XMLWRITER_OPT="yes"
|
||||
fi
|
||||
AM_CONDITIONAL([USE_LIBXML2], [test x$use_libxml2 = xyes])
|
||||
AC_SUBST([XMLWRITER_OPT])
|
||||
|
||||
# Check --enable-encryption
|
||||
ENCRYPTION_OPT=""
|
||||
AC_MSG_CHECKING([whether enable encryption])
|
||||
AC_ARG_ENABLE(
|
||||
[encryption],
|
||||
[AS_HELP_STRING([--enable-encryption], [enable encryption @<:@default=yes@:>@])],
|
||||
[case "$enableval" in
|
||||
yes) encryption=yes ;;
|
||||
no) encryption=no ;;
|
||||
*) AC_MSG_ERROR([bad value $enableval for --enable-encryption]) ;;
|
||||
esac],
|
||||
[encryption=yes])
|
||||
AC_MSG_RESULT([$encryption])
|
||||
AM_CONDITIONAL([USE_ENCRYPTION], [test x$encryption = xyes])
|
||||
if test x$encryption = xyes; then
|
||||
AC_DEFINE([USE_ENCRYPTION], [1], [Enable encryption])
|
||||
ENCRYPTION_OPT="yes"
|
||||
|
||||
AC_CHECK_HEADERS([sys/random.h])
|
||||
AC_MSG_CHECKING([for getrandom with a standard API])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <stdlib.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_RANDOM_H
|
||||
# include <sys/random.h>
|
||||
#endif]],
|
||||
[[unsigned char buf;
|
||||
if (&getrandom != NULL) {
|
||||
(void) getrandom((void *) &buf, 1U, 0U);
|
||||
}]])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_CHECK_FUNCS([getrandom])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
|
||||
fi
|
||||
AC_SUBST([ENCRYPTION_OPT])
|
||||
|
||||
# Check --enable-debug
|
||||
AC_MSG_CHECKING([whether enable debugging])
|
||||
AC_ARG_ENABLE(
|
||||
[debug],
|
||||
[AS_HELP_STRING([--enable-debug], [enable debugging @<:@default=no@:>@])],
|
||||
[case "$enableval" in
|
||||
yes) debug=yes ;;
|
||||
no) debug=no ;;
|
||||
*) AC_MSG_ERROR([bad value $enableval for --enable-debug]) ;;
|
||||
esac],
|
||||
[debug=no])
|
||||
AC_MSG_RESULT([$debug])
|
||||
|
||||
DEBUG_CFLAGS=
|
||||
if test x$debug = xyes; then
|
||||
AC_DEFINE([MOBI_DEBUG], [1], [Enable debugging])
|
||||
if test x$SUNCC = xyes; then
|
||||
DEBUG_CFLAGS="-v -errwarn"
|
||||
else
|
||||
DEBUG_CFLAGS="-pedantic -Wall -Wextra -Werror"
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([DEBUG_CFLAGS])
|
||||
|
||||
# Check --enable-debug-alloc
|
||||
AC_MSG_CHECKING([whether enable alloc debugging])
|
||||
AC_ARG_ENABLE(
|
||||
[debug_alloc],
|
||||
[AS_HELP_STRING([--enable-debug-alloc], [enable memory allocation debugging @<:@default=no@:>@])],
|
||||
[case "$enableval" in
|
||||
yes) debug_alloc=yes ;;
|
||||
no) debug_alloc=no ;;
|
||||
*) AC_MSG_ERROR([bad value $enableval for --enable-debug-alloc]) ;;
|
||||
esac],
|
||||
[debug_alloc=no])
|
||||
AC_MSG_RESULT([$debug_alloc])
|
||||
|
||||
if test x$debug_alloc = xyes; then
|
||||
AC_DEFINE([MOBI_DEBUG_ALLOC], [1], [Enable alloc debugging])
|
||||
fi
|
||||
|
||||
# Check --enable-tools-static
|
||||
AC_MSG_CHECKING([whether link tools against static libmobi])
|
||||
AC_ARG_ENABLE(
|
||||
[tools_static],
|
||||
[AS_HELP_STRING([--enable-tools-static], [link tools against static libmobi @<:@default=no@:>@])],
|
||||
[case "$enableval" in
|
||||
yes) tools_static=yes ;;
|
||||
no) tools_static=no ;;
|
||||
*) AC_MSG_ERROR([bad value $enableval for --enable-tools-static]) ;;
|
||||
esac],
|
||||
[tools_static=no])
|
||||
AC_MSG_RESULT([$tools_static])
|
||||
TOOLS_STATIC=
|
||||
if test x$tools_static = xyes; then
|
||||
TOOLS_STATIC="-static"
|
||||
fi
|
||||
AC_SUBST([TOOLS_STATIC])
|
||||
|
||||
# test for --with-zlib
|
||||
AC_MSG_CHECKING([whether compile with zlib])
|
||||
AC_ARG_WITH(
|
||||
[zlib],
|
||||
[AS_HELP_STRING([--with-zlib], [Use zlib instead of included miniz @<:@default=yes@:>@])],
|
||||
[if test "x$withval" = xyes; then use_zlib=yes; else use_zlib=no; fi],
|
||||
[use_zlib=yes])
|
||||
AC_MSG_RESULT([$use_zlib])
|
||||
AM_CONDITIONAL([USE_ZLIB], [test x$use_zlib = xyes])
|
||||
AM_CONDITIONAL([USE_MINIZ], [test x$use_zlib = xno])
|
||||
AM_CONDITIONAL([USE_STATIC], [test x$tools_static = xyes])
|
||||
if test x$use_zlib = xyes; then
|
||||
AC_CHECK_HEADER(
|
||||
[zlib.h],
|
||||
[AC_DEFINE([USE_ZLIB], [1], [Define if you want to use system zlib library])
|
||||
LIBZ_LDFLAGS=-lz
|
||||
MINIZ_CFLAGS=],
|
||||
[AC_MSG_ERROR([couldn't find zlib header])])
|
||||
else
|
||||
AC_DEFINE([USE_MINIZ], [1], [Define if you want to use included miniz library])
|
||||
MINIZ_CFLAGS="-D_POSIX_C_SOURCE=200112L"
|
||||
LIBZ_LDFLAGS=
|
||||
fi
|
||||
AC_SUBST([LIBZ_LDFLAGS])
|
||||
AC_SUBST([MINIZ_CFLAGS])
|
||||
|
||||
# Check for md5 or md5sum program, needed for tests
|
||||
AC_ARG_VAR([MD5PROG], [md5 hashing program executable])
|
||||
AS_IF([test -z "$MD5PROG"], [AC_CHECK_PROG([MD5PROG], [md5sum], [md5sum -t])], [])
|
||||
AS_IF([test -z "$MD5PROG"], [AC_CHECK_PROG([MD5PROG], [md5], [md5 -r])], [])
|
||||
AS_IF([test -z "$MD5PROG"], [AC_MSG_WARN([md5 hashing program not found, some tests will be skipped])], [])
|
||||
AC_PATH_PROG([BASH_PATH], [bash])
|
||||
AS_IF(
|
||||
[test -z "$BASH_PATH"],
|
||||
[AC_MSG_WARN([bash not found, tests will be skipped])
|
||||
RUN_TESTS="no"],
|
||||
[RUN_TESTS="yes"
|
||||
AC_SUBST([BASH_PATH])])
|
||||
AC_SUBST([RUN_TESTS])
|
||||
|
||||
if test x$RUN_TESTS = xyes; then
|
||||
# List test files
|
||||
cur_dir=`pwd`
|
||||
cd "$srcdir"/tests
|
||||
|
||||
for sample_path in samples/*.mobi
|
||||
do
|
||||
TESTLIST="${TESTLIST} ${sample_path} \\
|
||||
"
|
||||
done
|
||||
for sample_path in samples/*.fail
|
||||
do
|
||||
TESTLIST="${TESTLIST} ${sample_path} \\
|
||||
"
|
||||
FAILLIST="${FAILLIST} ${sample_path} \\
|
||||
"
|
||||
done
|
||||
cd $cur_dir
|
||||
fi
|
||||
|
||||
AC_SUBST([TESTLIST])
|
||||
AC_SUBST([FAILLIST])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_CONFIG_FILES([libmobi.pc])
|
||||
AC_CONFIG_FILES([src/Makefile])
|
||||
AC_CONFIG_FILES([tools/Makefile])
|
||||
AC_CONFIG_FILES([tools/mobitool.1])
|
||||
AC_CONFIG_FILES([tools/mobimeta.1])
|
||||
AC_CONFIG_FILES([tools/mobidrm.1])
|
||||
AC_CONFIG_FILES([tests/Makefile])
|
||||
AC_CONFIG_FILES([tests/test.sh], [chmod +x tests/test.sh])
|
||||
|
||||
AC_OUTPUT
|
||||
13
app/src/main/cpp/libmobi/libmobi.pc.in
vendored
Normal file
13
app/src/main/cpp/libmobi/libmobi.pc.in
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libmobi
|
||||
Description: MOBI ebook format handling library
|
||||
URL: http://www.fabiszewski.net/libmobi
|
||||
Version: @VERSION@
|
||||
Requires:
|
||||
Libs: -L${libdir} -lmobi
|
||||
Libs.private: @LIBZ_LDFLAGS@ @LIBXML2_LDFLAGS@
|
||||
Cflags: -I${includedir}
|
||||
879
app/src/main/cpp/libmobi/mobi.xcodeproj/project.pbxproj
vendored
Normal file
879
app/src/main/cpp/libmobi/mobi.xcodeproj/project.pbxproj
vendored
Normal file
|
|
@ -0,0 +1,879 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1502448F1CD3A18F0075F4EC /* sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = 1502448D1CD3A18F0075F4EC /* sha1.c */; };
|
||||
150244901CD3A18F0075F4EC /* sha1.h in Headers */ = {isa = PBXBuildFile; fileRef = 1502448E1CD3A18F0075F4EC /* sha1.h */; };
|
||||
1504FD851CBE880B002AA042 /* meta.c in Sources */ = {isa = PBXBuildFile; fileRef = 1504FD831CBE880B002AA042 /* meta.c */; };
|
||||
1504FD861CBE880B002AA042 /* meta.h in Headers */ = {isa = PBXBuildFile; fileRef = 1504FD841CBE880B002AA042 /* meta.h */; };
|
||||
150A318D18E19BF9001A7AD7 /* write.c in Sources */ = {isa = PBXBuildFile; fileRef = 150A318C18E19BF9001A7AD7 /* write.c */; };
|
||||
151A46661909312900FAF3F4 /* miniz.c in Sources */ = {isa = PBXBuildFile; fileRef = 151A46651909312900FAF3F4 /* miniz.c */; settings = {COMPILER_FLAGS = "-w"; }; };
|
||||
152FD1E6270509A900AF276A /* randombytes.h in Headers */ = {isa = PBXBuildFile; fileRef = 152FD1E4270509A900AF276A /* randombytes.h */; };
|
||||
152FD1E7270509A900AF276A /* randombytes.c in Sources */ = {isa = PBXBuildFile; fileRef = 152FD1E5270509A900AF276A /* randombytes.c */; };
|
||||
153D91DB18E9630000E807B6 /* memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 153D91DA18E9630000E807B6 /* memory.c */; };
|
||||
1543065B1CB78A45006AB398 /* mobimeta.c in Sources */ = {isa = PBXBuildFile; fileRef = 151185A31CB6C28500201C8A /* mobimeta.c */; };
|
||||
1543065E1CB78BA8006AB398 /* libmobi.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 150039BB18E06BC100D33077 /* libmobi.dylib */; };
|
||||
154C2D401CC64A170041DD0E /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = 154C2D3E1CC64A170041DD0E /* common.c */; };
|
||||
154C2D411CC64A170041DD0E /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = 154C2D3E1CC64A170041DD0E /* common.c */; };
|
||||
1550ADC318E427D7006F9257 /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 1550ADC218E427D7006F9257 /* buffer.c */; };
|
||||
1550ADCE18E4B925006F9257 /* compression.c in Sources */ = {isa = PBXBuildFile; fileRef = 1550ADCD18E4B925006F9257 /* compression.c */; };
|
||||
1553330118E359AE00334E23 /* read.c in Sources */ = {isa = PBXBuildFile; fileRef = 1553330018E359AE00334E23 /* read.c */; };
|
||||
1553332118E37FC400334E23 /* libmobi.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 150039BB18E06BC100D33077 /* libmobi.dylib */; };
|
||||
15603889192D2E1A002EDB1A /* opf.c in Sources */ = {isa = PBXBuildFile; fileRef = 15603888192D2E1A002EDB1A /* opf.c */; };
|
||||
15615F0818F58C85004EBB6E /* mobitool.c in Sources */ = {isa = PBXBuildFile; fileRef = 15615F0718F58C85004EBB6E /* mobitool.c */; };
|
||||
1563314718EC36A200D4B858 /* debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 1563314618EC36A200D4B858 /* debug.c */; };
|
||||
156AA65D1C81A3860085335A /* xmlwriter.c in Sources */ = {isa = PBXBuildFile; fileRef = 156AA65B1C81A3860085335A /* xmlwriter.c */; };
|
||||
156AA65E1C81A3860085335A /* xmlwriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 156AA65C1C81A3860085335A /* xmlwriter.h */; };
|
||||
157BEA732747BEDA004984B8 /* libmobi.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 150039BB18E06BC100D33077 /* libmobi.dylib */; };
|
||||
157BEA852747BF13004984B8 /* mobidrm.c in Sources */ = {isa = PBXBuildFile; fileRef = 157BEA6B2747B4EC004984B8 /* mobidrm.c */; };
|
||||
157BEA8A2747BF26004984B8 /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = 154C2D3E1CC64A170041DD0E /* common.c */; };
|
||||
157DF7AD191A514D00191502 /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = 157DF7AC191A514D00191502 /* index.c */; };
|
||||
15AB2CB419572C2800EB7F74 /* parse_rawml.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AB2CB319572C2800EB7F74 /* parse_rawml.c */; };
|
||||
15EA81DF1A14D5AC00138554 /* structure.c in Sources */ = {isa = PBXBuildFile; fileRef = 15EA81DE1A14D5AC00138554 /* structure.c */; };
|
||||
15F1A1D118F4192D009CFE05 /* util.c in Sources */ = {isa = PBXBuildFile; fileRef = 15F1A1D018F4192D009CFE05 /* util.c */; };
|
||||
15FB2BB21A1A32970052D5C5 /* encryption.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FB2BB01A1A32970052D5C5 /* encryption.c */; };
|
||||
15FB2BB31A1A32970052D5C5 /* encryption.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB2BB11A1A32970052D5C5 /* encryption.h */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
1543065C1CB78B78006AB398 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 150039B318E06BC100D33077 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 150039BA18E06BC100D33077;
|
||||
remoteInfo = mobi;
|
||||
};
|
||||
1553331F18E37FB800334E23 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 150039B318E06BC100D33077 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 150039BA18E06BC100D33077;
|
||||
remoteInfo = mobi;
|
||||
};
|
||||
157BEA6E2747BEDA004984B8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 150039B318E06BC100D33077 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 150039BA18E06BC100D33077;
|
||||
remoteInfo = mobi;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
154306521CB78A3D006AB398 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
1553331418E37F7000334E23 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
157BEA742747BEDA004984B8 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
150039BB18E06BC100D33077 /* libmobi.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libmobi.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
150039C218E06C1B00D33077 /* mobi.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = mobi.h; path = src/mobi.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
1502448D1CD3A18F0075F4EC /* sha1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sha1.c; path = src/sha1.c; sourceTree = "<group>"; };
|
||||
1502448E1CD3A18F0075F4EC /* sha1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sha1.h; path = src/sha1.h; sourceTree = "<group>"; };
|
||||
1504FD831CBE880B002AA042 /* meta.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = meta.c; path = src/meta.c; sourceTree = "<group>"; };
|
||||
1504FD841CBE880B002AA042 /* meta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = meta.h; path = src/meta.h; sourceTree = "<group>"; };
|
||||
150A318B18E19BD8001A7AD7 /* write.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = write.h; path = src/write.h; sourceTree = "<group>"; };
|
||||
150A318C18E19BF9001A7AD7 /* write.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = write.c; path = src/write.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
|
||||
151185A31CB6C28500201C8A /* mobimeta.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mobimeta.c; path = tools/mobimeta.c; sourceTree = SOURCE_ROOT; };
|
||||
151A46641909302C00FAF3F4 /* miniz.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = miniz.h; path = src/miniz.h; sourceTree = "<group>"; };
|
||||
151A46651909312900FAF3F4 /* miniz.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = miniz.c; path = src/miniz.c; sourceTree = "<absolute>"; };
|
||||
152D509E1BD79AE400E91C09 /* test.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; name = test.sh.in; path = tests/test.sh.in; sourceTree = "<group>"; };
|
||||
152D50A01BD7A08300E91C09 /* Makefile.am */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; name = Makefile.am; path = tests/Makefile.am; sourceTree = "<group>"; usesTabs = 1; xcLanguageSpecificationIdentifier = xcode.lang.sh; };
|
||||
152E5D1218F5DEB100B05EC9 /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = configure.ac; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.csh; };
|
||||
152E5D1318F5DEB100B05EC9 /* Makefile.am */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.am; sourceTree = "<group>"; usesTabs = 1; };
|
||||
152E5D1418F5DEC000B05EC9 /* Makefile.am */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; name = Makefile.am; path = src/Makefile.am; sourceTree = "<group>"; usesTabs = 1; };
|
||||
152E5D1518F5DECF00B05EC9 /* Makefile.am */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; name = Makefile.am; path = tools/Makefile.am; sourceTree = "<group>"; usesTabs = 1; };
|
||||
152E5D1618F5E22000B05EC9 /* autogen.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = autogen.sh; sourceTree = "<group>"; };
|
||||
152ED797195EFBD900ACD1AD /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; };
|
||||
152FD1E4270509A900AF276A /* randombytes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = randombytes.h; path = src/randombytes.h; sourceTree = "<group>"; };
|
||||
152FD1E5270509A900AF276A /* randombytes.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = randombytes.c; path = src/randombytes.c; sourceTree = "<group>"; };
|
||||
153967601907C0AA00EDC923 /* COPYING */ = {isa = PBXFileReference; lastKnownFileType = text; path = COPYING; sourceTree = "<group>"; };
|
||||
153D91DA18E9630000E807B6 /* memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = memory.c; path = src/memory.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
|
||||
153D91DC18E9633500E807B6 /* memory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = memory.h; path = src/memory.h; sourceTree = "<group>"; };
|
||||
1542B8041C7FA5E800C5122F /* getopt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = getopt.c; path = tools/win32/getopt.c; sourceTree = SOURCE_ROOT; };
|
||||
1542B8051C7FA5E900C5122F /* getopt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = getopt.h; path = tools/win32/getopt.h; sourceTree = SOURCE_ROOT; };
|
||||
154306541CB78A3D006AB398 /* mobimeta */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = mobimeta; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
154C2D3E1CC64A170041DD0E /* common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = common.c; path = tools/common.c; sourceTree = SOURCE_ROOT; };
|
||||
154C2D3F1CC64A170041DD0E /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = common.h; path = tools/common.h; sourceTree = SOURCE_ROOT; };
|
||||
1550ADC218E427D7006F9257 /* buffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = buffer.c; path = src/buffer.c; sourceTree = "<group>"; };
|
||||
1550ADC418E42842006F9257 /* buffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = buffer.h; path = src/buffer.h; sourceTree = "<group>"; };
|
||||
1550ADCD18E4B925006F9257 /* compression.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = compression.c; path = src/compression.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
|
||||
1550ADCF18E4BB83006F9257 /* compression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = compression.h; path = src/compression.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
1553330018E359AE00334E23 /* read.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = read.c; path = src/read.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
|
||||
1553330218E359B900334E23 /* read.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = read.h; path = src/read.h; sourceTree = "<group>"; };
|
||||
1553331618E37F7000334E23 /* mobitool */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = mobitool; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1559D790191BB06700636661 /* config.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = config.h; path = src/config.h; sourceTree = "<group>"; };
|
||||
15603888192D2E1A002EDB1A /* opf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = opf.c; path = src/opf.c; sourceTree = "<group>"; };
|
||||
1560388A192D2E34002EDB1A /* opf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = opf.h; path = src/opf.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
|
||||
15615F0718F58C85004EBB6E /* mobitool.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = mobitool.c; path = tools/mobitool.c; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.c; };
|
||||
1563314518EC367300D4B858 /* debug.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = debug.h; path = src/debug.h; sourceTree = "<group>"; };
|
||||
1563314618EC36A200D4B858 /* debug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = debug.c; path = src/debug.c; sourceTree = "<group>"; };
|
||||
156AA65B1C81A3860085335A /* xmlwriter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xmlwriter.c; path = src/xmlwriter.c; sourceTree = "<group>"; };
|
||||
156AA65C1C81A3860085335A /* xmlwriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xmlwriter.h; path = src/xmlwriter.h; sourceTree = "<group>"; };
|
||||
157BEA6B2747B4EC004984B8 /* mobidrm.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = mobidrm.c; path = tools/mobidrm.c; sourceTree = SOURCE_ROOT; };
|
||||
157BEA782747BEDA004984B8 /* mobidrm */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = mobidrm; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
157DF7AC191A514D00191502 /* index.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = index.c; path = src/index.c; sourceTree = "<group>"; };
|
||||
157DF7AE191A51A400191502 /* index.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = index.h; path = src/index.h; sourceTree = "<group>"; };
|
||||
15843DFE19215D0400587C89 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md; sourceTree = "<group>"; };
|
||||
158F44DC191E88010000F44A /* libmobi.pc.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libmobi.pc.in; sourceTree = "<group>"; };
|
||||
15AB2CB319572C2800EB7F74 /* parse_rawml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = parse_rawml.c; path = src/parse_rawml.c; sourceTree = "<group>"; };
|
||||
15AB2CB519572C4400EB7F74 /* parse_rawml.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = parse_rawml.h; path = src/parse_rawml.h; sourceTree = "<group>"; };
|
||||
15B4311D2767840300B7E6A7 /* mobidrm.1.in */ = {isa = PBXFileReference; explicitFileType = text.man; name = mobidrm.1.in; path = tools/mobidrm.1.in; sourceTree = SOURCE_ROOT; };
|
||||
15D7CFD71A167A3A00F08927 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = tools/README.md; sourceTree = "<group>"; };
|
||||
15E5FAD91CC58B4D00F700D1 /* mobimeta.1.in */ = {isa = PBXFileReference; explicitFileType = text.man; name = mobimeta.1.in; path = tools/mobimeta.1.in; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.man; };
|
||||
15E65B5E1A1DF1DA00B7FBBD /* mobitool.1.in */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; name = mobitool.1.in; path = tools/mobitool.1.in; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.man; };
|
||||
15E65B5F1A1E0FC100B7FBBD /* .travis.yml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .travis.yml; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.simpleColoring; };
|
||||
15EA81DD1A14D58500138554 /* structure.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = structure.h; path = src/structure.h; sourceTree = SOURCE_ROOT; };
|
||||
15EA81DE1A14D5AC00138554 /* structure.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = structure.c; path = src/structure.c; sourceTree = "<group>"; };
|
||||
15F1A1D018F4192D009CFE05 /* util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = util.c; path = src/util.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
|
||||
15F1A1D218F4195A009CFE05 /* util.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = util.h; path = src/util.h; sourceTree = "<group>"; };
|
||||
15FB2BB01A1A32970052D5C5 /* encryption.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = encryption.c; path = src/encryption.c; sourceTree = "<group>"; };
|
||||
15FB2BB11A1A32970052D5C5 /* encryption.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = encryption.h; path = src/encryption.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
150039B818E06BC100D33077 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
154306511CB78A3D006AB398 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1543065E1CB78BA8006AB398 /* libmobi.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
1553331318E37F7000334E23 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1553332118E37FC400334E23 /* libmobi.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
157BEA722747BEDA004984B8 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
157BEA732747BEDA004984B8 /* libmobi.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
150039B218E06BC100D33077 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
152D509F1BD79AED00E91C09 /* tests */,
|
||||
1539675F1907BC0600EDC923 /* docs */,
|
||||
1550ADC218E427D7006F9257 /* buffer.c */,
|
||||
1550ADC418E42842006F9257 /* buffer.h */,
|
||||
1550ADCD18E4B925006F9257 /* compression.c */,
|
||||
1550ADCF18E4BB83006F9257 /* compression.h */,
|
||||
1559D790191BB06700636661 /* config.h */,
|
||||
1563314618EC36A200D4B858 /* debug.c */,
|
||||
1563314518EC367300D4B858 /* debug.h */,
|
||||
15FB2BB01A1A32970052D5C5 /* encryption.c */,
|
||||
15FB2BB11A1A32970052D5C5 /* encryption.h */,
|
||||
157DF7AC191A514D00191502 /* index.c */,
|
||||
157DF7AE191A51A400191502 /* index.h */,
|
||||
153D91DA18E9630000E807B6 /* memory.c */,
|
||||
153D91DC18E9633500E807B6 /* memory.h */,
|
||||
1504FD831CBE880B002AA042 /* meta.c */,
|
||||
1504FD841CBE880B002AA042 /* meta.h */,
|
||||
151A46651909312900FAF3F4 /* miniz.c */,
|
||||
151A46641909302C00FAF3F4 /* miniz.h */,
|
||||
150039C218E06C1B00D33077 /* mobi.h */,
|
||||
15603888192D2E1A002EDB1A /* opf.c */,
|
||||
1560388A192D2E34002EDB1A /* opf.h */,
|
||||
15AB2CB319572C2800EB7F74 /* parse_rawml.c */,
|
||||
15AB2CB519572C4400EB7F74 /* parse_rawml.h */,
|
||||
152FD1E4270509A900AF276A /* randombytes.h */,
|
||||
152FD1E5270509A900AF276A /* randombytes.c */,
|
||||
1553330018E359AE00334E23 /* read.c */,
|
||||
1553330218E359B900334E23 /* read.h */,
|
||||
1502448D1CD3A18F0075F4EC /* sha1.c */,
|
||||
1502448E1CD3A18F0075F4EC /* sha1.h */,
|
||||
15EA81DE1A14D5AC00138554 /* structure.c */,
|
||||
15EA81DD1A14D58500138554 /* structure.h */,
|
||||
15F1A1D018F4192D009CFE05 /* util.c */,
|
||||
15F1A1D218F4195A009CFE05 /* util.h */,
|
||||
150A318C18E19BF9001A7AD7 /* write.c */,
|
||||
150A318B18E19BD8001A7AD7 /* write.h */,
|
||||
156AA65B1C81A3860085335A /* xmlwriter.c */,
|
||||
156AA65C1C81A3860085335A /* xmlwriter.h */,
|
||||
1553331718E37F7100334E23 /* tools */,
|
||||
150039BC18E06BC100D33077 /* Products */,
|
||||
152E5CFE18F5DB3200B05EC9 /* autotools */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
150039BC18E06BC100D33077 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
150039BB18E06BC100D33077 /* libmobi.dylib */,
|
||||
1553331618E37F7000334E23 /* mobitool */,
|
||||
154306541CB78A3D006AB398 /* mobimeta */,
|
||||
157BEA782747BEDA004984B8 /* mobidrm */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
152D509F1BD79AED00E91C09 /* tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
152D509E1BD79AE400E91C09 /* test.sh.in */,
|
||||
152D50A01BD7A08300E91C09 /* Makefile.am */,
|
||||
);
|
||||
name = tests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
152E5CFE18F5DB3200B05EC9 /* autotools */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
152E5D1618F5E22000B05EC9 /* autogen.sh */,
|
||||
152E5D1218F5DEB100B05EC9 /* configure.ac */,
|
||||
158F44DC191E88010000F44A /* libmobi.pc.in */,
|
||||
152E5D1518F5DECF00B05EC9 /* Makefile.am */,
|
||||
152E5D1418F5DEC000B05EC9 /* Makefile.am */,
|
||||
152E5D1318F5DEB100B05EC9 /* Makefile.am */,
|
||||
);
|
||||
name = autotools;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1539675F1907BC0600EDC923 /* docs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
152ED797195EFBD900ACD1AD /* ChangeLog */,
|
||||
15843DFE19215D0400587C89 /* README.md */,
|
||||
15D7CFD71A167A3A00F08927 /* README.md */,
|
||||
15E65B5F1A1E0FC100B7FBBD /* .travis.yml */,
|
||||
153967601907C0AA00EDC923 /* COPYING */,
|
||||
15B4311D2767840300B7E6A7 /* mobidrm.1.in */,
|
||||
15E65B5E1A1DF1DA00B7FBBD /* mobitool.1.in */,
|
||||
15E5FAD91CC58B4D00F700D1 /* mobimeta.1.in */,
|
||||
);
|
||||
name = docs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1553331718E37F7100334E23 /* tools */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
151185A31CB6C28500201C8A /* mobimeta.c */,
|
||||
15615F0718F58C85004EBB6E /* mobitool.c */,
|
||||
1542B8041C7FA5E800C5122F /* getopt.c */,
|
||||
1542B8051C7FA5E900C5122F /* getopt.h */,
|
||||
154C2D3E1CC64A170041DD0E /* common.c */,
|
||||
154C2D3F1CC64A170041DD0E /* common.h */,
|
||||
157BEA6B2747B4EC004984B8 /* mobidrm.c */,
|
||||
);
|
||||
name = tools;
|
||||
path = test;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
150039B918E06BC100D33077 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
15FB2BB31A1A32970052D5C5 /* encryption.h in Headers */,
|
||||
152FD1E6270509A900AF276A /* randombytes.h in Headers */,
|
||||
150244901CD3A18F0075F4EC /* sha1.h in Headers */,
|
||||
156AA65E1C81A3860085335A /* xmlwriter.h in Headers */,
|
||||
1504FD861CBE880B002AA042 /* meta.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
150039BA18E06BC100D33077 /* mobi */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 150039BF18E06BC100D33077 /* Build configuration list for PBXNativeTarget "mobi" */;
|
||||
buildPhases = (
|
||||
150039B718E06BC100D33077 /* Sources */,
|
||||
150039B818E06BC100D33077 /* Frameworks */,
|
||||
150039B918E06BC100D33077 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = mobi;
|
||||
productName = libmobi;
|
||||
productReference = 150039BB18E06BC100D33077 /* libmobi.dylib */;
|
||||
productType = "com.apple.product-type.library.dynamic";
|
||||
};
|
||||
154306531CB78A3D006AB398 /* mobimeta */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1543065A1CB78A3D006AB398 /* Build configuration list for PBXNativeTarget "mobimeta" */;
|
||||
buildPhases = (
|
||||
154306501CB78A3D006AB398 /* Sources */,
|
||||
154306511CB78A3D006AB398 /* Frameworks */,
|
||||
154306521CB78A3D006AB398 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
1543065D1CB78B78006AB398 /* PBXTargetDependency */,
|
||||
);
|
||||
name = mobimeta;
|
||||
productName = write_test;
|
||||
productReference = 154306541CB78A3D006AB398 /* mobimeta */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
1553331518E37F7000334E23 /* mobitool */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1553331C18E37F7100334E23 /* Build configuration list for PBXNativeTarget "mobitool" */;
|
||||
buildPhases = (
|
||||
1553331218E37F7000334E23 /* Sources */,
|
||||
1553331318E37F7000334E23 /* Frameworks */,
|
||||
1553331418E37F7000334E23 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
1553332018E37FB800334E23 /* PBXTargetDependency */,
|
||||
);
|
||||
name = mobitool;
|
||||
productName = test;
|
||||
productReference = 1553331618E37F7000334E23 /* mobitool */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
157BEA6C2747BEDA004984B8 /* mobidrm */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 157BEA752747BEDA004984B8 /* Build configuration list for PBXNativeTarget "mobidrm" */;
|
||||
buildPhases = (
|
||||
157BEA6F2747BEDA004984B8 /* Sources */,
|
||||
157BEA722747BEDA004984B8 /* Frameworks */,
|
||||
157BEA742747BEDA004984B8 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
157BEA6D2747BEDA004984B8 /* PBXTargetDependency */,
|
||||
);
|
||||
name = mobidrm;
|
||||
productName = test;
|
||||
productReference = 157BEA782747BEDA004984B8 /* mobidrm */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
150039B318E06BC100D33077 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1420;
|
||||
ORGANIZATIONNAME = "Bartek Fabiszewski";
|
||||
TargetAttributes = {
|
||||
154306531CB78A3D006AB398 = {
|
||||
CreatedOnToolsVersion = 7.3;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 150039B618E06BC100D33077 /* Build configuration list for PBXProject "mobi" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 150039B218E06BC100D33077;
|
||||
productRefGroup = 150039BC18E06BC100D33077 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
150039BA18E06BC100D33077 /* mobi */,
|
||||
1553331518E37F7000334E23 /* mobitool */,
|
||||
154306531CB78A3D006AB398 /* mobimeta */,
|
||||
157BEA6C2747BEDA004984B8 /* mobidrm */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
150039B718E06BC100D33077 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1550ADCE18E4B925006F9257 /* compression.c in Sources */,
|
||||
15EA81DF1A14D5AC00138554 /* structure.c in Sources */,
|
||||
1563314718EC36A200D4B858 /* debug.c in Sources */,
|
||||
15F1A1D118F4192D009CFE05 /* util.c in Sources */,
|
||||
1502448F1CD3A18F0075F4EC /* sha1.c in Sources */,
|
||||
15603889192D2E1A002EDB1A /* opf.c in Sources */,
|
||||
150A318D18E19BF9001A7AD7 /* write.c in Sources */,
|
||||
1550ADC318E427D7006F9257 /* buffer.c in Sources */,
|
||||
1553330118E359AE00334E23 /* read.c in Sources */,
|
||||
157DF7AD191A514D00191502 /* index.c in Sources */,
|
||||
153D91DB18E9630000E807B6 /* memory.c in Sources */,
|
||||
156AA65D1C81A3860085335A /* xmlwriter.c in Sources */,
|
||||
15AB2CB419572C2800EB7F74 /* parse_rawml.c in Sources */,
|
||||
152FD1E7270509A900AF276A /* randombytes.c in Sources */,
|
||||
15FB2BB21A1A32970052D5C5 /* encryption.c in Sources */,
|
||||
1504FD851CBE880B002AA042 /* meta.c in Sources */,
|
||||
151A46661909312900FAF3F4 /* miniz.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
154306501CB78A3D006AB398 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
154C2D411CC64A170041DD0E /* common.c in Sources */,
|
||||
1543065B1CB78A45006AB398 /* mobimeta.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
1553331218E37F7000334E23 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
154C2D401CC64A170041DD0E /* common.c in Sources */,
|
||||
15615F0818F58C85004EBB6E /* mobitool.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
157BEA6F2747BEDA004984B8 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
157BEA8A2747BF26004984B8 /* common.c in Sources */,
|
||||
157BEA852747BF13004984B8 /* mobidrm.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
1543065D1CB78B78006AB398 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 150039BA18E06BC100D33077 /* mobi */;
|
||||
targetProxy = 1543065C1CB78B78006AB398 /* PBXContainerItemProxy */;
|
||||
};
|
||||
1553332018E37FB800334E23 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 150039BA18E06BC100D33077 /* mobi */;
|
||||
targetProxy = 1553331F18E37FB800334E23 /* PBXContainerItemProxy */;
|
||||
};
|
||||
157BEA6D2747BEDA004984B8 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 150039BA18E06BC100D33077 /* mobi */;
|
||||
targetProxy = 157BEA6E2747BEDA004984B8 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
150039BD18E06BC100D33077 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_GCD_PERFORMANCE = YES;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
|
||||
CLANG_CXX_LIBRARY = "compiler-default";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_ASSIGN_ENUM = NO;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_COMPLETION_HANDLER_MISUSE = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_FRAMEWORK_INCLUDE_PRIVATE_FROM_PUBLIC = YES;
|
||||
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = "compiler-default";
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
|
||||
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_PEDANTIC = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_SIGN_COMPARE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNKNOWN_PRAGMAS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
/usr/include/libxml2,
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_CFLAGS = (
|
||||
"-DHAVE_CONFIG_H",
|
||||
"-DHAVE_STRDUP",
|
||||
);
|
||||
OTHER_LDFLAGS = "-lz";
|
||||
SDKROOT = macosx;
|
||||
USER_HEADER_SEARCH_PATHS = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
150039BE18E06BC100D33077 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_GCD_PERFORMANCE = YES;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
|
||||
CLANG_CXX_LIBRARY = "compiler-default";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_ASSIGN_ENUM = NO;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_COMPLETION_HANDLER_MISUSE = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_FRAMEWORK_INCLUDE_PRIVATE_FROM_PUBLIC = YES;
|
||||
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = "compiler-default";
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
|
||||
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_PEDANTIC = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_SIGN_COMPARE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNKNOWN_PRAGMAS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
/usr/include/libxml2,
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_CFLAGS = (
|
||||
"-DHAVE_CONFIG_H",
|
||||
"-DHAVE_STRDUP",
|
||||
);
|
||||
OTHER_LDFLAGS = "-lz";
|
||||
SDKROOT = macosx;
|
||||
USER_HEADER_SEARCH_PATHS = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
150039C018E06BC100D33077 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/libxml2,
|
||||
);
|
||||
OTHER_CFLAGS = (
|
||||
"-DHAVE_CONFIG_H",
|
||||
"-DHAVE_STRDUP",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-lxml2",
|
||||
"-lz",
|
||||
);
|
||||
PRODUCT_NAME = mobi;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
150039C118E06BC100D33077 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_OPTIMIZATION_LEVEL = 3;
|
||||
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/libxml2,
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-lxml2",
|
||||
"-lz",
|
||||
);
|
||||
PRODUCT_NAME = mobi;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
154306581CB78A3D006AB398 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
./src,
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
154306591CB78A3D006AB398 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
./src,
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
1553331D18E37F7100334E23 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = ./src;
|
||||
"HEADER_SEARCH_PATHS[arch=*]" = ./src;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_NAME = mobitool;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1553331E18E37F7100334E23 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
HEADER_SEARCH_PATHS = ./src;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_NAME = mobitool;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
157BEA762747BEDA004984B8 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = ./src;
|
||||
"HEADER_SEARCH_PATHS[arch=*]" = ./src;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
157BEA772747BEDA004984B8 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
HEADER_SEARCH_PATHS = ./src;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
150039B618E06BC100D33077 /* Build configuration list for PBXProject "mobi" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
150039BD18E06BC100D33077 /* Debug */,
|
||||
150039BE18E06BC100D33077 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
150039BF18E06BC100D33077 /* Build configuration list for PBXNativeTarget "mobi" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
150039C018E06BC100D33077 /* Debug */,
|
||||
150039C118E06BC100D33077 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
1543065A1CB78A3D006AB398 /* Build configuration list for PBXNativeTarget "mobimeta" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
154306581CB78A3D006AB398 /* Debug */,
|
||||
154306591CB78A3D006AB398 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
1553331C18E37F7100334E23 /* Build configuration list for PBXNativeTarget "mobitool" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1553331D18E37F7100334E23 /* Debug */,
|
||||
1553331E18E37F7100334E23 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
157BEA752747BEDA004984B8 /* Build configuration list for PBXNativeTarget "mobidrm" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
157BEA762747BEDA004984B8 /* Debug */,
|
||||
157BEA772747BEDA004984B8 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 150039B318E06BC100D33077 /* Project object */;
|
||||
}
|
||||
97
app/src/main/cpp/libmobi/msvc/libmobi.sln
vendored
Normal file
97
app/src/main/cpp/libmobi/msvc/libmobi.sln
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.1.32328.378
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmobi", "libmobi.vcxproj", "{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mobidrm", "mobidrm\mobidrm.vcxproj", "{288A84A9-2AFD-4995-A397-E4554C8087AE}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mobitool", "mobitool\mobitool.vcxproj", "{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mobimeta", "mobimeta\mobimeta.vcxproj", "{2790D05E-6891-48E5-8450-F8D030763AD6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
NoDependenciesDebug|x64 = NoDependenciesDebug|x64
|
||||
NoDependenciesDebug|x86 = NoDependenciesDebug|x86
|
||||
NoDependenciesRelease|x64 = NoDependenciesRelease|x64
|
||||
NoDependenciesRelease|x86 = NoDependenciesRelease|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.Debug|x64.Build.0 = Debug|x64
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.Debug|x86.Build.0 = Debug|Win32
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.NoDependenciesDebug|x64.ActiveCfg = NoDependenciesDebug|x64
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.NoDependenciesDebug|x64.Build.0 = NoDependenciesDebug|x64
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.NoDependenciesDebug|x86.ActiveCfg = NoDependenciesDebug|Win32
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.NoDependenciesDebug|x86.Build.0 = NoDependenciesDebug|Win32
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.NoDependenciesRelease|x64.ActiveCfg = NoDependenciesRelease|x64
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.NoDependenciesRelease|x64.Build.0 = NoDependenciesRelease|x64
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.NoDependenciesRelease|x86.ActiveCfg = NoDependenciesRelease|Win32
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.NoDependenciesRelease|x86.Build.0 = NoDependenciesRelease|Win32
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.Release|x64.ActiveCfg = Release|x64
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.Release|x64.Build.0 = Release|x64
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.Release|x86.ActiveCfg = Release|Win32
|
||||
{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}.Release|x86.Build.0 = Release|Win32
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.Debug|x64.Build.0 = Debug|x64
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.Debug|x86.Build.0 = Debug|Win32
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.NoDependenciesDebug|x64.ActiveCfg = Debug|x64
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.NoDependenciesDebug|x64.Build.0 = Debug|x64
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.NoDependenciesDebug|x86.ActiveCfg = Debug|Win32
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.NoDependenciesDebug|x86.Build.0 = Debug|Win32
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.NoDependenciesRelease|x64.ActiveCfg = Release|x64
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.NoDependenciesRelease|x64.Build.0 = Release|x64
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.NoDependenciesRelease|x86.ActiveCfg = Release|Win32
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.NoDependenciesRelease|x86.Build.0 = Release|Win32
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.Release|x64.ActiveCfg = Release|x64
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.Release|x64.Build.0 = Release|x64
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.Release|x86.ActiveCfg = Release|Win32
|
||||
{288A84A9-2AFD-4995-A397-E4554C8087AE}.Release|x86.Build.0 = Release|Win32
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.Debug|x64.Build.0 = Debug|x64
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.Debug|x86.Build.0 = Debug|Win32
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.NoDependenciesDebug|x64.ActiveCfg = Debug|x64
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.NoDependenciesDebug|x64.Build.0 = Debug|x64
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.NoDependenciesDebug|x86.ActiveCfg = Debug|Win32
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.NoDependenciesDebug|x86.Build.0 = Debug|Win32
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.NoDependenciesRelease|x64.ActiveCfg = Release|x64
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.NoDependenciesRelease|x64.Build.0 = Release|x64
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.NoDependenciesRelease|x86.ActiveCfg = Release|Win32
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.NoDependenciesRelease|x86.Build.0 = Release|Win32
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.Release|x64.ActiveCfg = Release|x64
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.Release|x64.Build.0 = Release|x64
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.Release|x86.ActiveCfg = Release|Win32
|
||||
{D8E9C708-FBD0-400C-B5B6-F8555FDE8767}.Release|x86.Build.0 = Release|Win32
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.Debug|x64.Build.0 = Debug|x64
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.Debug|x86.Build.0 = Debug|Win32
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.NoDependenciesDebug|x64.ActiveCfg = Debug|x64
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.NoDependenciesDebug|x64.Build.0 = Debug|x64
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.NoDependenciesDebug|x86.ActiveCfg = Debug|Win32
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.NoDependenciesDebug|x86.Build.0 = Debug|Win32
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.NoDependenciesRelease|x64.ActiveCfg = Release|x64
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.NoDependenciesRelease|x64.Build.0 = Release|x64
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.NoDependenciesRelease|x86.ActiveCfg = Release|Win32
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.NoDependenciesRelease|x86.Build.0 = Release|Win32
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.Release|x64.ActiveCfg = Release|x64
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.Release|x64.Build.0 = Release|x64
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.Release|x86.ActiveCfg = Release|Win32
|
||||
{2790D05E-6891-48E5-8450-F8D030763AD6}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {673B11AC-E877-465E-89D0-97CAA6C1B389}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
395
app/src/main/cpp/libmobi/msvc/libmobi.vcxproj
vendored
Normal file
395
app/src/main/cpp/libmobi/msvc/libmobi.vcxproj
vendored
Normal file
|
|
@ -0,0 +1,395 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="NoDependenciesDebug|Win32">
|
||||
<Configuration>NoDependenciesDebug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="NoDependenciesDebug|x64">
|
||||
<Configuration>NoDependenciesDebug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="NoDependenciesRelease|Win32">
|
||||
<Configuration>NoDependenciesRelease</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="NoDependenciesRelease|x64">
|
||||
<Configuration>NoDependenciesRelease</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<ProjectGuid>{A48F597C-ADBC-499E-B282-0F8A2B1A4B5F}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|x64'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|x64'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H;USE_XMLWRITER;USE_ENCRYPTION;MOBI_DEBUG=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ProjectReference />
|
||||
<ProjectReference />
|
||||
<PreBuildEvent>
|
||||
<Command>for /f "tokens=4 delims=[]" %%a in ('type "$(SolutionDir)..\configure.ac" ^| find "AC_INIT"') do (
|
||||
set version=%%a
|
||||
)
|
||||
echo Compiling libmobi version %version%
|
||||
echo #define PACKAGE_VERSION "%version%" > "$(SolutionDir)..\config.h"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H;USE_XMLWRITER;USE_ENCRYPTION;MOBI_DEBUG=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ProjectReference />
|
||||
<ProjectReference />
|
||||
<PreBuildEvent>
|
||||
<Command>for /f "tokens=4 delims=[]" %%a in ('type "$(SolutionDir)..\configure.ac" ^| find "AC_INIT"') do (
|
||||
set version=%%a
|
||||
)
|
||||
echo Compiling libmobi version %version%
|
||||
echo #define PACKAGE_VERSION "%version%" > "$(SolutionDir)..\config.h"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H;USE_XMLWRITER;USE_ENCRYPTION;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ProjectReference />
|
||||
<ProjectReference />
|
||||
<PreBuildEvent>
|
||||
<Command>for /f "tokens=4 delims=[]" %%a in ('type "$(SolutionDir)..\configure.ac" ^| find "AC_INIT"') do (
|
||||
set version=%%a
|
||||
)
|
||||
echo Compiling libmobi version %version%
|
||||
echo #define PACKAGE_VERSION "%version%" > "$(SolutionDir)..\config.h"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H;USE_XMLWRITER;USE_ENCRYPTION;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<ProjectReference />
|
||||
<ProjectReference />
|
||||
<PreBuildEvent>
|
||||
<Command>for /f "tokens=4 delims=[]" %%a in ('type "$(SolutionDir)..\configure.ac" ^| find "AC_INIT"') do (
|
||||
set version=%%a
|
||||
)
|
||||
echo Compiling libmobi version %version%
|
||||
echo #define PACKAGE_VERSION "%version%" > "$(SolutionDir)..\config.h"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ProjectReference />
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H;USE_XMLWRITER;USE_ENCRYPTION;MOBI_DEBUG=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<ProjectReference />
|
||||
<ProjectReference />
|
||||
<PreBuildEvent>
|
||||
<Command>for /f "tokens=4 delims=[]" %%a in ('type "$(SolutionDir)..\configure.ac" ^| find "AC_INIT"') do (
|
||||
set version=%%a
|
||||
)
|
||||
echo Compiling libmobi version %version%
|
||||
echo #define PACKAGE_VERSION "%version%" > "$(SolutionDir)..\config.h"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|x64'">
|
||||
<ProjectReference />
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H;USE_XMLWRITER;USE_ENCRYPTION;MOBI_DEBUG=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<ProjectReference />
|
||||
<ProjectReference />
|
||||
<PreBuildEvent>
|
||||
<Command>for /f "tokens=4 delims=[]" %%a in ('type "$(SolutionDir)..\configure.ac" ^| find "AC_INIT"') do (
|
||||
set version=%%a
|
||||
)
|
||||
echo Compiling libmobi version %version%
|
||||
echo #define PACKAGE_VERSION "%version%" > "$(SolutionDir)..\config.h"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|x64'">
|
||||
<ProjectReference />
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H;USE_XMLWRITER;USE_ENCRYPTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
</ClCompile>
|
||||
<ProjectReference />
|
||||
<ProjectReference />
|
||||
<PreBuildEvent>
|
||||
<Command>for /f "tokens=4 delims=[]" %%a in ('type "$(SolutionDir)..\configure.ac" ^| find "AC_INIT"') do (
|
||||
set version=%%a
|
||||
)
|
||||
echo Compiling libmobi version %version%
|
||||
echo #define PACKAGE_VERSION "%version%" > "$(SolutionDir)..\config.h"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ProjectReference />
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H;USE_XMLWRITER;USE_ENCRYPTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<ProjectReference />
|
||||
<ProjectReference />
|
||||
<PreBuildEvent>
|
||||
<Command>for /f "tokens=4 delims=[]" %%a in ('type "$(SolutionDir)..\configure.ac" ^| find "AC_INIT"') do (
|
||||
set version=%%a
|
||||
)
|
||||
echo Compiling libmobi version %version%
|
||||
echo #define PACKAGE_VERSION "%version%" > "$(SolutionDir)..\config.h"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\buffer.c" />
|
||||
<ClCompile Include="..\src\compression.c" />
|
||||
<ClCompile Include="..\src\debug.c" />
|
||||
<ClCompile Include="..\src\encryption.c" />
|
||||
<ClCompile Include="..\src\index.c" />
|
||||
<ClCompile Include="..\src\memory.c" />
|
||||
<ClCompile Include="..\src\meta.c" />
|
||||
<ClCompile Include="..\src\miniz.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|Win32'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|Win32'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\opf.c" />
|
||||
<ClCompile Include="..\src\parse_rawml.c" />
|
||||
<ClCompile Include="..\src\randombytes.c" />
|
||||
<ClCompile Include="..\src\read.c" />
|
||||
<ClCompile Include="..\src\sha1.c" />
|
||||
<ClCompile Include="..\src\structure.c" />
|
||||
<ClCompile Include="..\src\util.c" />
|
||||
<ClCompile Include="..\src\write.c" />
|
||||
<ClCompile Include="..\src\xmlwriter.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|Win32'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|Win32'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\buffer.h" />
|
||||
<ClInclude Include="..\src\compression.h" />
|
||||
<ClInclude Include="..\src\config.h" />
|
||||
<ClInclude Include="..\src\debug.h" />
|
||||
<ClInclude Include="..\src\encryption.h" />
|
||||
<ClInclude Include="..\src\index.h" />
|
||||
<ClInclude Include="..\src\memory.h" />
|
||||
<ClInclude Include="..\src\meta.h" />
|
||||
<ClInclude Include="..\src\miniz.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|Win32'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|Win32'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\mobi.h" />
|
||||
<ClInclude Include="..\src\opf.h" />
|
||||
<ClInclude Include="..\src\parse_rawml.h" />
|
||||
<ClInclude Include="..\src\randombytes.h" />
|
||||
<ClInclude Include="..\src\read.h" />
|
||||
<ClInclude Include="..\src\sha1.h" />
|
||||
<ClInclude Include="..\src\structure.h" />
|
||||
<ClInclude Include="..\src\util.h" />
|
||||
<ClInclude Include="..\src\write.h" />
|
||||
<ClInclude Include="..\src\xmlwriter.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|Win32'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|Win32'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesDebug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoDependenciesRelease|x64'">true</ExcludedFromBuild>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets" Condition="Exists('packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets')" />
|
||||
<Import Project="packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets" Condition="Exists('packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets'))" />
|
||||
<Error Condition="!Exists('packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
182
app/src/main/cpp/libmobi/msvc/mobidrm/mobidrm.vcxproj
vendored
Normal file
182
app/src/main/cpp/libmobi/msvc/mobidrm/mobidrm.vcxproj
vendored
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\tools\common.c" />
|
||||
<ClCompile Include="..\..\tools\mobidrm.c" />
|
||||
<ClCompile Include="..\..\tools\win32\getopt.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\tools\common.h" />
|
||||
<ClInclude Include="..\..\tools\win32\getopt.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\libmobi.vcxproj">
|
||||
<Project>{a48f597c-adbc-499e-b282-0f8a2b1a4b5f}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{288a84a9-2afd-4995-a397-e4554c8087ae}</ProjectGuid>
|
||||
<RootNamespace>mobidrm</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>USE_XMLWRITER;USE_ENCRYPTION;_CRT_SECURE_NO_WARNINGS;MOBI_DEBUG=1;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\..\src</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/NODEFAULTLIB:libcmtd.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>USE_XMLWRITER;USE_ENCRYPTION;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\..\src</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/NODEFAULTLIB:libcmt.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>USE_XMLWRITER;USE_ENCRYPTION;_CRT_SECURE_NO_WARNINGS;MOBI_DEBUG=1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\..\src</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/NODEFAULTLIB:libcmtd.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>USE_XMLWRITER;USE_ENCRYPTION;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\..\src</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/NODEFAULTLIB:libcmt.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets" Condition="Exists('..\packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets')" />
|
||||
<Import Project="..\packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets" Condition="Exists('..\packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
5
app/src/main/cpp/libmobi/msvc/mobidrm/packages.config
vendored
Normal file
5
app/src/main/cpp/libmobi/msvc/mobidrm/packages.config
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="libxml2-vc140-static-32_64" version="2.9.4.1" targetFramework="native" />
|
||||
<package id="zlib128-vc140-static-32_64" version="1.2.8" targetFramework="native" />
|
||||
</packages>
|
||||
182
app/src/main/cpp/libmobi/msvc/mobimeta/mobimeta.vcxproj
vendored
Normal file
182
app/src/main/cpp/libmobi/msvc/mobimeta/mobimeta.vcxproj
vendored
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\tools\common.c" />
|
||||
<ClCompile Include="..\..\tools\mobimeta.c" />
|
||||
<ClCompile Include="..\..\tools\win32\getopt.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\tools\common.h" />
|
||||
<ClInclude Include="..\..\tools\win32\getopt.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\libmobi.vcxproj">
|
||||
<Project>{a48f597c-adbc-499e-b282-0f8a2b1a4b5f}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{2790d05e-6891-48e5-8450-f8d030763ad6}</ProjectGuid>
|
||||
<RootNamespace>mobimeta</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>USE_XMLWRITER;USE_ENCRYPTION;_CRT_SECURE_NO_WARNINGS;MOBI_DEBUG=1;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\..\src</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/NODEFAULTLIB:libcmtd.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>USE_XMLWRITER;USE_ENCRYPTION;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\..\src</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/NODEFAULTLIB:libcmt.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>USE_XMLWRITER;USE_ENCRYPTION;_CRT_SECURE_NO_WARNINGS;MOBI_DEBUG=1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\..\src</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/NODEFAULTLIB:libcmtd.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>USE_XMLWRITER;USE_ENCRYPTION;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\..\src</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/NODEFAULTLIB:libcmt.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets" Condition="Exists('..\packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets')" />
|
||||
<Import Project="..\packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets" Condition="Exists('..\packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
5
app/src/main/cpp/libmobi/msvc/mobimeta/packages.config
vendored
Normal file
5
app/src/main/cpp/libmobi/msvc/mobimeta/packages.config
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="libxml2-vc140-static-32_64" version="2.9.4.1" targetFramework="native" />
|
||||
<package id="zlib128-vc140-static-32_64" version="1.2.8" targetFramework="native" />
|
||||
</packages>
|
||||
184
app/src/main/cpp/libmobi/msvc/mobitool/mobitool.vcxproj
vendored
Normal file
184
app/src/main/cpp/libmobi/msvc/mobitool/mobitool.vcxproj
vendored
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\miniz.c" />
|
||||
<ClCompile Include="..\..\tools\common.c" />
|
||||
<ClCompile Include="..\..\tools\mobitool.c" />
|
||||
<ClCompile Include="..\..\tools\win32\getopt.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\miniz.h" />
|
||||
<ClInclude Include="..\..\tools\common.h" />
|
||||
<ClInclude Include="..\..\tools\win32\getopt.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\libmobi.vcxproj">
|
||||
<Project>{a48f597c-adbc-499e-b282-0f8a2b1a4b5f}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{d8e9c708-fbd0-400c-b5b6-f8555fde8767}</ProjectGuid>
|
||||
<RootNamespace>mobitool</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Linkage-libxml2>static</Linkage-libxml2>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>USE_XMLWRITER;USE_ENCRYPTION;_CRT_SECURE_NO_WARNINGS;MOBI_DEBUG=1;MOBI_DEBUG=1WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\..\src</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/NODEFAULTLIB:libcmtd.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>USE_XMLWRITER;USE_ENCRYPTION;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\..\src</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/NODEFAULTLIB:libcmt.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>USE_XMLWRITER;USE_ENCRYPTION;_CRT_SECURE_NO_WARNINGS;MOBI_DEBUG=1;MOBI_DEBUG=1_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\..\src</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/NODEFAULTLIB:libcmtd.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>USE_XMLWRITER;USE_ENCRYPTION;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\..\src</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/NODEFAULTLIB:libcmt.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets" Condition="Exists('..\packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets')" />
|
||||
<Import Project="..\packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets" Condition="Exists('..\packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\zlib128-vc140-static-32_64.1.2.8\build\native\zlib128-vc140-static-32_64.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\libxml2-vc140-static-32_64.2.9.4.1\build\native\libxml2-vc140-static-32_64.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
5
app/src/main/cpp/libmobi/msvc/mobitool/packages.config
vendored
Normal file
5
app/src/main/cpp/libmobi/msvc/mobitool/packages.config
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="libxml2-vc140-static-32_64" version="2.9.4.1" targetFramework="native" />
|
||||
<package id="zlib128-vc140-static-32_64" version="1.2.8" targetFramework="native" />
|
||||
</packages>
|
||||
5
app/src/main/cpp/libmobi/msvc/packages.config
vendored
Normal file
5
app/src/main/cpp/libmobi/msvc/packages.config
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="libxml2-vc140-static-32_64" version="2.9.4.1" targetFramework="native" />
|
||||
<package id="zlib128-vc140-static-32_64" version="1.2.8" targetFramework="native" />
|
||||
</packages>
|
||||
87
app/src/main/cpp/libmobi/src/CMakeLists.txt
vendored
Normal file
87
app/src/main/cpp/libmobi/src/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# Copyright (c) 2022 Bartek Fabiszewski
|
||||
# http://www.fabiszewski.net
|
||||
#
|
||||
# This file is part of libmobi.
|
||||
# Licensed under LGPL, either version 3, or any later.
|
||||
# See <http://www.gnu.org/licenses/>
|
||||
|
||||
set(mobi_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/buffer.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/buffer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/compression.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/compression.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/config.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/debug.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/debug.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/index.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/index.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/memory.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/memory.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/meta.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/meta.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mobi.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/parse_rawml.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/parse_rawml.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/read.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/read.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/structure.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/structure.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/util.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/util.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/write.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/write.h
|
||||
)
|
||||
|
||||
if(USE_ENCRYPTION)
|
||||
list(APPEND mobi_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/encryption.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/encryption.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sha1.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sha1.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/randombytes.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/randombytes.h)
|
||||
endif(USE_ENCRYPTION)
|
||||
|
||||
if(USE_XMLWRITER)
|
||||
list(APPEND mobi_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/opf.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/opf.h)
|
||||
if(NOT USE_LIBXML2)
|
||||
list(APPEND mobi_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/xmlwriter.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xmlwriter.h)
|
||||
endif(NOT USE_LIBXML2)
|
||||
endif(USE_XMLWRITER)
|
||||
|
||||
|
||||
add_library(mobi ${mobi_SOURCES})
|
||||
|
||||
set_target_properties(mobi PROPERTIES
|
||||
OUTPUT_NAME "mobi"
|
||||
SOVERSION ${PACKAGE_VERSION_MAJOR}
|
||||
VERSION "${PACKAGE_VERSION}"
|
||||
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
|
||||
C_VISIBILITY_PRESET hidden
|
||||
VISIBILITY_INLINES_HIDDEN ON
|
||||
MACOSX_RPATH 1)
|
||||
|
||||
if(USE_MINIZ)
|
||||
set(miniz_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/miniz.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/miniz.h
|
||||
)
|
||||
add_library(miniz OBJECT ${miniz_SOURCES})
|
||||
target_compile_definitions(miniz PRIVATE
|
||||
MINIZ_NO_STDIO
|
||||
MINIZ_NO_ZLIB_COMPATIBLE_NAMES
|
||||
MINIZ_NO_TIME
|
||||
MINIZ_NO_ARCHIVE_APIS
|
||||
MINIZ_NO_ARCHIVE_WRITING_APIS
|
||||
_POSIX_C_SOURCE=200112L)
|
||||
target_link_libraries(mobi PRIVATE miniz)
|
||||
endif(USE_MINIZ)
|
||||
|
||||
if(USE_LIBXML2)
|
||||
target_link_libraries(mobi PUBLIC LibXml2::LibXml2)
|
||||
endif(USE_LIBXML2)
|
||||
|
||||
if(USE_ZLIB)
|
||||
target_link_libraries(mobi PUBLIC ZLIB::ZLIB)
|
||||
endif(USE_ZLIB)
|
||||
27
app/src/main/cpp/libmobi/src/Makefile.am
vendored
Normal file
27
app/src/main/cpp/libmobi/src/Makefile.am
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# libmobi
|
||||
|
||||
lib_LTLIBRARIES = libmobi.la
|
||||
libmobi_la_SOURCES = buffer.c buffer.h compression.c compression.h config.h debug.c debug.h index.c index.h memory.c memory.h \
|
||||
meta.c meta.h parse_rawml.c parse_rawml.h read.c read.h structure.c structure.h util.c util.h write.c write.h
|
||||
|
||||
if USE_XMLWRITER
|
||||
libmobi_la_SOURCES += opf.c opf.h
|
||||
if !USE_LIBXML2
|
||||
libmobi_la_SOURCES += xmlwriter.c xmlwriter.h
|
||||
endif
|
||||
endif
|
||||
if USE_ENCRYPTION
|
||||
libmobi_la_SOURCES += encryption.c encryption.h randombytes.c randombytes.h sha1.c sha1.h
|
||||
endif
|
||||
EXTRA_LTLIBRARIES = libminiz.la
|
||||
libminiz_la_SOURCES = miniz.c miniz.h
|
||||
libminiz_la_CFLAGS = $(VISIBILITY_HIDDEN) $(MINIZ_CFLAGS) \
|
||||
-DMINIZ_NO_STDIO -DMINIZ_NO_ZLIB_COMPATIBLE_NAMES \
|
||||
-DMINIZ_NO_TIME -DMINIZ_NO_ARCHIVE_APIS -DMINIZ_NO_ARCHIVE_WRITING_APIS
|
||||
libminiz_la_LDFLAGS =
|
||||
if USE_MINIZ
|
||||
libmobi_la_LIBADD = libminiz.la
|
||||
endif
|
||||
include_HEADERS = mobi.h
|
||||
libmobi_la_LDFLAGS = $(AVOID_VERSION) $(NO_UNDEFINED) $(DARWIN_LDFLAGS) $(LIBZ_LDFLAGS) $(LIBXML2_LDFLAGS)
|
||||
libmobi_la_CFLAGS = $(VISIBILITY_HIDDEN) $(ISO99_SOURCE) $(DEBUG_CFLAGS) $(LIBXML2_CFLAGS)
|
||||
637
app/src/main/cpp/libmobi/src/buffer.c
vendored
Normal file
637
app/src/main/cpp/libmobi/src/buffer.c
vendored
Normal file
|
|
@ -0,0 +1,637 @@
|
|||
/** @file buffer.c
|
||||
* @brief Functions to read/write raw big endian data
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "buffer.h"
|
||||
#include "debug.h"
|
||||
|
||||
/**
|
||||
@brief Initializer for MOBIBuffer structure
|
||||
|
||||
It allocates memory for structure and for data.
|
||||
Memory should be freed with mobi_buffer_free().
|
||||
|
||||
@param[in] len Size of data to be allocated for the buffer
|
||||
@return MOBIBuffer on success, NULL otherwise
|
||||
*/
|
||||
MOBIBuffer * mobi_buffer_init(const size_t len) {
|
||||
unsigned char *data = malloc(len);
|
||||
if (data == NULL) {
|
||||
debug_print("%s", "Buffer data allocation failed\n");
|
||||
return NULL;
|
||||
}
|
||||
MOBIBuffer *buf = mobi_buffer_init_null(data, len);
|
||||
if (buf == NULL) {
|
||||
free(data);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Initializer for MOBIBuffer structure
|
||||
|
||||
It allocates memory for structure but, unlike mobi_buffer_init(), it does not allocate memory for data.
|
||||
Instead it works on external data.
|
||||
Memory should be freed with mobi_buffer_free_null() (buf->data will not be deallocated).
|
||||
|
||||
@param[in,out] data Set data as buffer data
|
||||
@param[in] len Size of data held by the buffer
|
||||
@return MOBIBuffer on success, NULL otherwise
|
||||
*/
|
||||
MOBIBuffer * mobi_buffer_init_null(unsigned char *data, const size_t len) {
|
||||
MOBIBuffer *buf = malloc(sizeof(MOBIBuffer));
|
||||
if (buf == NULL) {
|
||||
debug_print("%s", "Buffer allocation failed\n");
|
||||
return NULL;
|
||||
}
|
||||
buf->data = data;
|
||||
buf->offset = 0;
|
||||
buf->maxlen = len;
|
||||
buf->error = MOBI_SUCCESS;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Resize buffer
|
||||
|
||||
Smaller size than offset will cause data truncation.
|
||||
|
||||
@param[in,out] buf MOBIBuffer structure to be filled with data
|
||||
@param[in] newlen New buffer size
|
||||
*/
|
||||
void mobi_buffer_resize(MOBIBuffer *buf, const size_t newlen) {
|
||||
unsigned char *tmp = realloc(buf->data, newlen);
|
||||
if (tmp == NULL) {
|
||||
debug_print("%s", "Buffer allocation failed\n");
|
||||
buf->error = MOBI_MALLOC_FAILED;
|
||||
return;
|
||||
}
|
||||
buf->data = tmp;
|
||||
buf->maxlen = newlen;
|
||||
if (buf->offset >= newlen) {
|
||||
buf->offset = newlen - 1;
|
||||
}
|
||||
debug_print("Buffer successfully resized to %zu\n", newlen);
|
||||
buf->error = MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Adds 8-bit value to MOBIBuffer
|
||||
|
||||
@param[in,out] buf MOBIBuffer structure to be filled with data
|
||||
@param[in] data Integer to be put into the buffer
|
||||
*/
|
||||
void mobi_buffer_add8(MOBIBuffer *buf, const uint8_t data) {
|
||||
if (buf->offset + 1 > buf->maxlen) {
|
||||
debug_print("%s", "Buffer full\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
return;
|
||||
}
|
||||
buf->data[buf->offset++] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Adds 16-bit value to MOBIBuffer
|
||||
|
||||
@param[in,out] buf MOBIBuffer structure to be filled with data
|
||||
@param[in] data Integer to be put into the buffer
|
||||
*/
|
||||
void mobi_buffer_add16(MOBIBuffer *buf, const uint16_t data) {
|
||||
if (buf->offset + 2 > buf->maxlen) {
|
||||
debug_print("%s", "Buffer full\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
return;
|
||||
}
|
||||
unsigned char *buftr = buf->data + buf->offset;
|
||||
*buftr++ = (uint8_t)((uint32_t)(data & 0xff00U) >> 8);
|
||||
*buftr = (uint8_t)((uint32_t)(data & 0xffU));
|
||||
buf->offset += 2;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Adds 32-bit value to MOBIBuffer
|
||||
|
||||
@param[in,out] buf MOBIBuffer structure to be filled with data
|
||||
@param[in] data Integer to be put into the buffer
|
||||
*/
|
||||
void mobi_buffer_add32(MOBIBuffer *buf, const uint32_t data) {
|
||||
if (buf->offset + 4 > buf->maxlen) {
|
||||
debug_print("%s", "Buffer full\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
return;
|
||||
}
|
||||
unsigned char *buftr = buf->data + buf->offset;
|
||||
*buftr++ = (uint8_t)((uint32_t)(data & 0xff000000U) >> 24);
|
||||
*buftr++ = (uint8_t)((uint32_t)(data & 0xff0000U) >> 16);
|
||||
*buftr++ = (uint8_t)((uint32_t)(data & 0xff00U) >> 8);
|
||||
*buftr = (uint8_t)((uint32_t)(data & 0xffU));
|
||||
buf->offset += 4;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Adds raw data to MOBIBuffer
|
||||
|
||||
@param[in,out] buf MOBIBuffer structure to be filled with data
|
||||
@param[in] data Pointer to read data
|
||||
@param[in] len Size of the read data
|
||||
*/
|
||||
void mobi_buffer_addraw(MOBIBuffer *buf, const unsigned char* data, const size_t len) {
|
||||
if (buf->offset + len > buf->maxlen) {
|
||||
debug_print("%s", "Buffer full\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
return;
|
||||
}
|
||||
memcpy(buf->data + buf->offset, data, len);
|
||||
buf->offset += len;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Adds string to MOBIBuffer without null terminator
|
||||
|
||||
@param[in,out] buf MOBIBuffer structure to be filled with data
|
||||
@param[in] str Pointer to string
|
||||
*/
|
||||
void mobi_buffer_addstring(MOBIBuffer *buf, const char *str) {
|
||||
const size_t len = strlen(str);
|
||||
mobi_buffer_addraw(buf, (const unsigned char *) str, len);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Adds count of zeroes to MOBIBuffer
|
||||
|
||||
@param[in,out] buf MOBIBuffer structure to be filled with data
|
||||
@param[in] count Number of zeroes to be put into the buffer
|
||||
*/
|
||||
void mobi_buffer_addzeros(MOBIBuffer *buf, const size_t count) {
|
||||
if (buf->offset + count > buf->maxlen) {
|
||||
debug_print("%s", "Buffer full\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
return;
|
||||
}
|
||||
memset(buf->data + buf->offset, 0, count);
|
||||
buf->offset += count;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Reads 8-bit value from MOBIBuffer
|
||||
|
||||
@param[in] buf MOBIBuffer structure containing data
|
||||
@return Read value, 0 if end of buffer is encountered
|
||||
*/
|
||||
uint8_t mobi_buffer_get8(MOBIBuffer *buf) {
|
||||
if (buf->offset + 1 > buf->maxlen) {
|
||||
debug_print("%s", "End of buffer\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
return 0;
|
||||
}
|
||||
return buf->data[buf->offset++];
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Reads 16-bit value from MOBIBuffer
|
||||
|
||||
@param[in] buf MOBIBuffer structure containing data
|
||||
@return Read value, 0 if end of buffer is encountered
|
||||
*/
|
||||
uint16_t mobi_buffer_get16(MOBIBuffer *buf) {
|
||||
if (buf->offset + 2 > buf->maxlen) {
|
||||
debug_print("%s", "End of buffer\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
return 0;
|
||||
}
|
||||
uint16_t val;
|
||||
val = (uint16_t)((uint16_t) buf->data[buf->offset] << 8 | (uint16_t) buf->data[buf->offset + 1]);
|
||||
buf->offset += 2;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Reads 32-bit value from MOBIBuffer
|
||||
|
||||
@param[in] buf MOBIBuffer structure containing data
|
||||
@return Read value, 0 if end of buffer is encountered
|
||||
*/
|
||||
uint32_t mobi_buffer_get32(MOBIBuffer *buf) {
|
||||
if (buf->offset + 4 > buf->maxlen) {
|
||||
debug_print("%s", "End of buffer\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
return 0;
|
||||
}
|
||||
uint32_t val;
|
||||
val = (uint32_t) buf->data[buf->offset] << 24 | (uint32_t) buf->data[buf->offset + 1] << 16 | (uint32_t) buf->data[buf->offset + 2] << 8 | (uint32_t) buf->data[buf->offset + 3];
|
||||
buf->offset += 4;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Reads variable length value from MOBIBuffer
|
||||
|
||||
Internal function for wrappers:
|
||||
mobi_buffer_get_varlen();
|
||||
mobi_buffer_get_varlen_dec();
|
||||
|
||||
Reads maximum 4 bytes from the buffer. Stops when byte has bit 7 set.
|
||||
|
||||
This function has a limitation while reading backwards.
|
||||
In such case it will not read first byte in a buffer, as it would cause buffer offset to underflow.
|
||||
That means that going bacwards it cannot read variable length values that are placed at the beginning of a buffer.
|
||||
This will result in an error.
|
||||
|
||||
@param[in] buf MOBIBuffer structure containing data
|
||||
@param[out] len Value will be increased by number of bytes read
|
||||
@param[in] direction 1 - read buffer forward, -1 - read buffer backwards
|
||||
@return Read value, 0 if end of buffer is encountered
|
||||
*/
|
||||
static uint32_t mobi_buffer_get_varlen_internal(MOBIBuffer *buf, size_t *len, const int direction) {
|
||||
bool has_stop = false;
|
||||
uint32_t val = 0;
|
||||
uint8_t byte_count = 0;
|
||||
size_t max_count = direction == 1 ? buf->maxlen - buf->offset : buf->offset;
|
||||
if (buf->offset < buf->maxlen && max_count) {
|
||||
max_count = max_count < 4 ? max_count : 4;
|
||||
uint8_t byte;
|
||||
const uint8_t stop_flag = 0x80;
|
||||
const uint8_t mask = 0x7f;
|
||||
uint32_t shift = 0;
|
||||
unsigned char *p = buf->data + buf->offset;
|
||||
do {
|
||||
if (direction == 1) {
|
||||
byte = *p++;
|
||||
val <<= 7;
|
||||
val |= (byte & mask);
|
||||
} else {
|
||||
byte = *p--;
|
||||
val = val | (uint32_t)(byte & mask) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
byte_count++;
|
||||
has_stop = byte & stop_flag;
|
||||
} while (!has_stop && (byte_count < max_count));
|
||||
}
|
||||
if (!has_stop) {
|
||||
debug_print("%s", "End of buffer\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
return 0;
|
||||
}
|
||||
*len += byte_count;
|
||||
buf->offset = direction == 1 ? buf->offset + byte_count : buf->offset - byte_count;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Reads variable length value from MOBIBuffer
|
||||
|
||||
Reads maximum 4 bytes from the buffer. Stops when byte has bit 7 set.
|
||||
|
||||
@param[in] buf MOBIBuffer structure containing data
|
||||
@param[out] len Value will be increased by number of bytes read
|
||||
@return Read value, 0 if end of buffer is encountered
|
||||
*/
|
||||
uint32_t mobi_buffer_get_varlen(MOBIBuffer *buf, size_t *len) {
|
||||
return mobi_buffer_get_varlen_internal(buf, len, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Reads variable length value from MOBIBuffer going backwards
|
||||
|
||||
Reads maximum 4 bytes from the buffer. Stops when byte has bit 7 set.
|
||||
|
||||
This function has a limitation. It will not read first byte in a buffer, as it would cause buffer offset to underflow.
|
||||
That means that it cannot read variable length values that are placed at the beginning of a buffer.
|
||||
This will result in an error.
|
||||
|
||||
@param[in] buf MOBIBuffer structure containing data
|
||||
@param[out] len Value will be increased by number of bytes read
|
||||
@return Read value, 0 if end of buffer is encountered
|
||||
*/
|
||||
uint32_t mobi_buffer_get_varlen_dec(MOBIBuffer *buf, size_t *len) {
|
||||
return mobi_buffer_get_varlen_internal(buf, len, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Reads raw data from MOBIBuffer and pads it with zero character
|
||||
|
||||
@param[out] str Destination for string read from buffer. Length must be (len + 1)
|
||||
@param[in] buf MOBIBuffer structure containing data
|
||||
@param[in] len Length of the data to be read from buffer
|
||||
*/
|
||||
void mobi_buffer_getstring(char *str, MOBIBuffer *buf, const size_t len) {
|
||||
if (!str) {
|
||||
buf->error = MOBI_PARAM_ERR;
|
||||
return;
|
||||
}
|
||||
if (buf->offset + len > buf->maxlen) {
|
||||
debug_print("%s", "End of buffer\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
str[0] = '\0';
|
||||
return;
|
||||
}
|
||||
memcpy(str, buf->data + buf->offset, len);
|
||||
str[len] = '\0';
|
||||
buf->offset += len;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Reads raw data from MOBIBuffer, appends it to a string and pads it with zero character
|
||||
|
||||
@param[in,out] str A string to which data will be appended
|
||||
@param[in] buf MOBIBuffer structure containing data
|
||||
@param[in] len Length of the data to be read from buffer
|
||||
*/
|
||||
void mobi_buffer_appendstring(char *str, MOBIBuffer *buf, const size_t len) {
|
||||
if (!str) {
|
||||
buf->error = MOBI_PARAM_ERR;
|
||||
return;
|
||||
}
|
||||
if (buf->offset + len > buf->maxlen) {
|
||||
debug_print("%s", "End of buffer\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
return;
|
||||
}
|
||||
size_t str_len = strlen(str);
|
||||
memcpy(str + str_len, buf->data + buf->offset, len);
|
||||
str[str_len + len] = '\0';
|
||||
buf->offset += len;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Reads raw data from MOBIBuffer
|
||||
|
||||
@param[out] data Destination to which data will be appended
|
||||
@param[in] buf MOBIBuffer structure containing data
|
||||
@param[in] len Length of the data to be read from buffer
|
||||
*/
|
||||
void mobi_buffer_getraw(void *data, MOBIBuffer *buf, const size_t len) {
|
||||
if (!data) {
|
||||
buf->error = MOBI_PARAM_ERR;
|
||||
return;
|
||||
}
|
||||
if (buf->offset + len > buf->maxlen) {
|
||||
debug_print("%s", "End of buffer\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
return;
|
||||
}
|
||||
memcpy(data, buf->data + buf->offset, len);
|
||||
buf->offset += len;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get pointer to MOBIBuffer data at offset
|
||||
|
||||
@param[in] buf MOBIBuffer structure containing data
|
||||
@param[in] len Check if requested length is available in buffer
|
||||
@return Pointer to offset, or NULL on failure
|
||||
*/
|
||||
unsigned char * mobi_buffer_getpointer(MOBIBuffer *buf, const size_t len) {
|
||||
if (buf->offset + len > buf->maxlen) {
|
||||
debug_print("%s", "End of buffer\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
return NULL;
|
||||
}
|
||||
buf->offset += len;
|
||||
return buf->data + buf->offset - len;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Read 8-bit value from MOBIBuffer into allocated memory
|
||||
|
||||
Read 8-bit value from buffer into memory allocated by the function.
|
||||
Returns pointer to the value, which must be freed later.
|
||||
If the data is not accessible function will return null pointer.
|
||||
|
||||
@param[out] val Pointer to value or null pointer on failure
|
||||
@param[in] buf MOBIBuffer structure containing data
|
||||
*/
|
||||
void mobi_buffer_dup8(uint8_t **val, MOBIBuffer *buf) {
|
||||
*val = NULL;
|
||||
if (buf->offset + 1 > buf->maxlen) {
|
||||
return;
|
||||
}
|
||||
*val = malloc(sizeof(uint8_t));
|
||||
if (*val == NULL) {
|
||||
return;
|
||||
}
|
||||
**val = mobi_buffer_get8(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Read 16-bit value from MOBIBuffer into allocated memory
|
||||
|
||||
Read 16-bit value from buffer into allocated memory.
|
||||
Returns pointer to the value, which must be freed later.
|
||||
If the data is not accessible function will return null pointer.
|
||||
|
||||
@param[out] val Pointer to value or null pointer on failure
|
||||
@param[in] buf MOBIBuffer structure containing data
|
||||
*/
|
||||
void mobi_buffer_dup16(uint16_t **val, MOBIBuffer *buf) {
|
||||
*val = NULL;
|
||||
if (buf->offset + 2 > buf->maxlen) {
|
||||
return;
|
||||
}
|
||||
*val = malloc(sizeof(uint16_t));
|
||||
if (*val == NULL) {
|
||||
return;
|
||||
}
|
||||
**val = mobi_buffer_get16(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Read 32-bit value from MOBIBuffer into allocated memory
|
||||
|
||||
Read 32-bit value from buffer into allocated memory.
|
||||
Returns pointer to the value, which must be freed later.
|
||||
If the data is not accessible function will return null pointer.
|
||||
|
||||
@param[out] val Pointer to value
|
||||
@param[in] buf MOBIBuffer structure containing data
|
||||
*/
|
||||
void mobi_buffer_dup32(uint32_t **val, MOBIBuffer *buf) {
|
||||
*val = NULL;
|
||||
if (buf->offset + 4 > buf->maxlen) {
|
||||
return;
|
||||
}
|
||||
*val = malloc(sizeof(uint32_t));
|
||||
if (*val == NULL) {
|
||||
return;
|
||||
}
|
||||
**val = mobi_buffer_get32(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Copy 8-bit value from one MOBIBuffer into another
|
||||
|
||||
@param[out] dest Destination buffer
|
||||
@param[in] source Source buffer
|
||||
*/
|
||||
void mobi_buffer_copy8(MOBIBuffer *dest, MOBIBuffer *source) {
|
||||
mobi_buffer_add8(dest, mobi_buffer_get8(source));
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Copy raw value from one MOBIBuffer into another
|
||||
|
||||
@param[out] dest Destination buffer
|
||||
@param[in] source Source buffer
|
||||
@param[in] len Number of bytes to copy
|
||||
*/
|
||||
void mobi_buffer_copy(MOBIBuffer *dest, MOBIBuffer *source, const size_t len) {
|
||||
if (source->offset + len > source->maxlen) {
|
||||
debug_print("%s", "End of buffer\n");
|
||||
source->error = MOBI_BUFFER_END;
|
||||
return;
|
||||
}
|
||||
if (dest->offset + len > dest->maxlen) {
|
||||
debug_print("%s", "End of buffer\n");
|
||||
dest->error = MOBI_BUFFER_END;
|
||||
return;
|
||||
}
|
||||
memcpy(dest->data + dest->offset, source->data + source->offset, len);
|
||||
dest->offset += len;
|
||||
source->offset += len;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Copy raw value within one MOBIBuffer
|
||||
|
||||
Memmove len bytes from offset (relative to current position)
|
||||
to current position in buffer and advance buffer position.
|
||||
Data may overlap.
|
||||
|
||||
@param[out] buf Buffer
|
||||
@param[in] offset Offset to read from
|
||||
@param[in] len Number of bytes to copy
|
||||
*/
|
||||
void mobi_buffer_move(MOBIBuffer *buf, const int offset, const size_t len) {
|
||||
size_t aoffset = (size_t) abs(offset);
|
||||
unsigned char *source = buf->data + buf->offset;
|
||||
if (offset >= 0) {
|
||||
if (buf->offset + aoffset + len > buf->maxlen) {
|
||||
debug_print("%s", "End of buffer\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
return;
|
||||
}
|
||||
source += aoffset;
|
||||
} else {
|
||||
if ( (buf->offset < aoffset) || (buf->offset + len > buf->maxlen) ) {
|
||||
debug_print("%s", "Beyond start/end of buffer\n");
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
return;
|
||||
}
|
||||
source -= aoffset;
|
||||
}
|
||||
memmove(buf->data + buf->offset, source, len);
|
||||
buf->offset += len;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Check if buffer data header contains magic signature
|
||||
|
||||
@param[in] buf MOBIBuffer buffer containing data
|
||||
@param[in] magic Magic signature
|
||||
@return boolean true on match, false otherwise
|
||||
*/
|
||||
bool mobi_buffer_match_magic(MOBIBuffer *buf, const char *magic) {
|
||||
const size_t magic_length = strlen(magic);
|
||||
if (buf->offset + magic_length > buf->maxlen) {
|
||||
return false;
|
||||
}
|
||||
if (memcmp(buf->data + buf->offset, magic, magic_length) == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Check if buffer contains magic signature at given offset
|
||||
|
||||
@param[in] buf MOBIBuffer buffer containing data
|
||||
@param[in] magic Magic signature
|
||||
@param[in] offset Offset
|
||||
@return boolean true on match, false otherwise
|
||||
*/
|
||||
bool mobi_buffer_match_magic_offset(MOBIBuffer *buf, const char *magic, const size_t offset) {
|
||||
bool match = false;
|
||||
if (offset <= buf->maxlen) {
|
||||
const size_t save_offset = buf->offset;
|
||||
buf->offset = offset;
|
||||
match = mobi_buffer_match_magic(buf, magic);
|
||||
buf->offset = save_offset;
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Move current buffer offset by diff bytes
|
||||
|
||||
@param[in,out] buf MOBIBuffer buffer containing data
|
||||
@param[in] diff Number of bytes by which the offset is adjusted
|
||||
*/
|
||||
void mobi_buffer_seek(MOBIBuffer *buf, const int diff) {
|
||||
size_t adiff = (size_t) abs(diff);
|
||||
if (diff >= 0) {
|
||||
if (buf->offset + adiff <= buf->maxlen) {
|
||||
buf->offset += adiff;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (buf->offset >= adiff) {
|
||||
buf->offset -= adiff;
|
||||
return;
|
||||
}
|
||||
}
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
debug_print("%s", "End of buffer\n");
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set buffer offset to pos position
|
||||
|
||||
@param[in,out] buf MOBIBuffer buffer containing data
|
||||
@param[in] pos New position
|
||||
*/
|
||||
void mobi_buffer_setpos(MOBIBuffer *buf, const size_t pos) {
|
||||
if (pos <= buf->maxlen) {
|
||||
buf->offset = pos;
|
||||
return;
|
||||
}
|
||||
buf->error = MOBI_BUFFER_END;
|
||||
debug_print("%s", "End of buffer\n");
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free pointer to MOBIBuffer structure and pointer to data
|
||||
|
||||
Free data initialized with mobi_buffer_init();
|
||||
|
||||
@param[in] buf MOBIBuffer structure
|
||||
*/
|
||||
void mobi_buffer_free(MOBIBuffer *buf) {
|
||||
if (buf == NULL) { return; }
|
||||
if (buf->data != NULL) {
|
||||
free(buf->data);
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free pointer to MOBIBuffer structure
|
||||
|
||||
Free data initialized with mobi_buffer_init_null();
|
||||
Unlike mobi_buffer_free() it will not free pointer to buf->data
|
||||
|
||||
@param[in] buf MOBIBuffer structure
|
||||
*/
|
||||
void mobi_buffer_free_null(MOBIBuffer *buf) {
|
||||
if (buf == NULL) { return; }
|
||||
free(buf);
|
||||
}
|
||||
58
app/src/main/cpp/libmobi/src/buffer.h
vendored
Normal file
58
app/src/main/cpp/libmobi/src/buffer.h
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/** @file buffer.h
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef libmobi_buffer_h
|
||||
#define libmobi_buffer_h
|
||||
|
||||
#include "config.h"
|
||||
#include "mobi.h"
|
||||
|
||||
/**
|
||||
@brief Buffer to read to/write from
|
||||
*/
|
||||
typedef struct {
|
||||
size_t offset; /**< Current offset in respect to buffer start */
|
||||
size_t maxlen; /**< Length of the buffer data */
|
||||
unsigned char *data; /**< Pointer to buffer data */
|
||||
MOBI_RET error; /**< MOBI_SUCCESS = 0 if operation on buffer is successful, non-zero value on failure */
|
||||
} MOBIBuffer;
|
||||
|
||||
MOBIBuffer * mobi_buffer_init(const size_t len);
|
||||
MOBIBuffer * mobi_buffer_init_null(unsigned char *data, const size_t len);
|
||||
void mobi_buffer_resize(MOBIBuffer *buf, const size_t newlen);
|
||||
void mobi_buffer_add8(MOBIBuffer *buf, const uint8_t data);
|
||||
void mobi_buffer_add16(MOBIBuffer *buf, const uint16_t data);
|
||||
void mobi_buffer_add32(MOBIBuffer *buf, const uint32_t data);
|
||||
void mobi_buffer_addraw(MOBIBuffer *buf, const unsigned char* data, const size_t len);
|
||||
void mobi_buffer_addstring(MOBIBuffer *buf, const char *str);
|
||||
void mobi_buffer_addzeros(MOBIBuffer *buf, const size_t count);
|
||||
uint8_t mobi_buffer_get8(MOBIBuffer *buf);
|
||||
uint16_t mobi_buffer_get16(MOBIBuffer *buf);
|
||||
uint32_t mobi_buffer_get32(MOBIBuffer *buf);
|
||||
uint32_t mobi_buffer_get_varlen(MOBIBuffer *buf, size_t *len);
|
||||
uint32_t mobi_buffer_get_varlen_dec(MOBIBuffer *buf, size_t *len);
|
||||
void mobi_buffer_dup8(uint8_t **val, MOBIBuffer *buf);
|
||||
void mobi_buffer_dup16(uint16_t **val, MOBIBuffer *buf);
|
||||
void mobi_buffer_dup32(uint32_t **val, MOBIBuffer *buf);
|
||||
void mobi_buffer_getstring(char *str, MOBIBuffer *buf, const size_t len);
|
||||
void mobi_buffer_appendstring(char *str, MOBIBuffer *buf, const size_t len);
|
||||
void mobi_buffer_getraw(void *data, MOBIBuffer *buf, const size_t len);
|
||||
unsigned char * mobi_buffer_getpointer(MOBIBuffer *buf, const size_t len);
|
||||
void mobi_buffer_copy8(MOBIBuffer *dest, MOBIBuffer *source);
|
||||
void mobi_buffer_move(MOBIBuffer *buf, const int offset, const size_t len);
|
||||
void mobi_buffer_copy(MOBIBuffer *dest, MOBIBuffer *source, const size_t len);
|
||||
bool mobi_buffer_match_magic(MOBIBuffer *buf, const char *magic);
|
||||
bool mobi_buffer_match_magic_offset(MOBIBuffer *buf, const char *magic, const size_t offset);
|
||||
void mobi_buffer_seek(MOBIBuffer *buf, const int diff);
|
||||
void mobi_buffer_setpos(MOBIBuffer *buf, const size_t pos);
|
||||
void mobi_buffer_free(MOBIBuffer *buf);
|
||||
void mobi_buffer_free_null(MOBIBuffer *buf);
|
||||
|
||||
#endif
|
||||
221
app/src/main/cpp/libmobi/src/compression.c
vendored
Normal file
221
app/src/main/cpp/libmobi/src/compression.c
vendored
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
/** @file compression.c
|
||||
* @brief Functions handling compression
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "compression.h"
|
||||
#include "buffer.h"
|
||||
#include "mobi.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
/**
|
||||
@brief Decompressor fo PalmDOC version of LZ77 compression
|
||||
|
||||
Decompressor based on this algorithm:
|
||||
http://en.wikibooks.org/wiki/Data_Compression/Dictionary_compression#PalmDoc
|
||||
|
||||
@param[out] out Decompressed destination data
|
||||
@param[in] in Compressed source data
|
||||
@param[in,out] len_out Size of the memory reserved for decompressed data.
|
||||
On return it is set to actual size of decompressed data
|
||||
@param[in] len_in Size of compressed data
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_decompress_lz77(unsigned char *out, const unsigned char *in, size_t *len_out, const size_t len_in) {
|
||||
MOBI_RET ret = MOBI_SUCCESS;
|
||||
MOBIBuffer *buf_in = mobi_buffer_init_null((unsigned char *) in, len_in);
|
||||
if (buf_in == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
MOBIBuffer *buf_out = mobi_buffer_init_null(out, *len_out);
|
||||
if (buf_out == NULL) {
|
||||
mobi_buffer_free_null(buf_in);
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
while (ret == MOBI_SUCCESS && buf_in->offset < buf_in->maxlen) {
|
||||
uint8_t byte = mobi_buffer_get8(buf_in);
|
||||
/* byte pair: space + char */
|
||||
if (byte >= 0xc0) {
|
||||
mobi_buffer_add8(buf_out, ' ');
|
||||
mobi_buffer_add8(buf_out, byte ^ 0x80);
|
||||
}
|
||||
/* length, distance pair */
|
||||
/* 0x8000 + (distance << 3) + ((length-3) & 0x07) */
|
||||
else if (byte >= 0x80) {
|
||||
uint8_t next = mobi_buffer_get8(buf_in);
|
||||
uint16_t distance = ((((byte << 8) | ((uint8_t)next)) >> 3) & 0x7ff);
|
||||
uint8_t length = (next & 0x7) + 3;
|
||||
while (length--) {
|
||||
mobi_buffer_move(buf_out, -distance, 1);
|
||||
}
|
||||
}
|
||||
/* single char, not modified */
|
||||
else if (byte >= 0x09) {
|
||||
mobi_buffer_add8(buf_out, byte);
|
||||
}
|
||||
/* val chars not modified */
|
||||
else if (byte >= 0x01) {
|
||||
mobi_buffer_copy(buf_out, buf_in, byte);
|
||||
}
|
||||
/* char '\0', not modified */
|
||||
else {
|
||||
mobi_buffer_add8(buf_out, byte);
|
||||
}
|
||||
if (buf_in->error || buf_out->error) {
|
||||
ret = MOBI_BUFFER_END;
|
||||
}
|
||||
}
|
||||
*len_out = buf_out->offset;
|
||||
mobi_buffer_free_null(buf_out);
|
||||
mobi_buffer_free_null(buf_in);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Read at most 8 bytes from buffer, big-endian
|
||||
|
||||
If buffer data is shorter returned value is padded with zeroes
|
||||
|
||||
@param[in] buf MOBIBuffer structure to read from
|
||||
@return 64-bit value
|
||||
*/
|
||||
static MOBI_INLINE uint64_t mobi_buffer_fill64(MOBIBuffer *buf) {
|
||||
uint64_t val = 0;
|
||||
uint8_t i = 8;
|
||||
size_t bytesleft = buf->maxlen - buf->offset;
|
||||
unsigned char *ptr = buf->data + buf->offset;
|
||||
while (i-- && bytesleft--) {
|
||||
val |= (uint64_t) *ptr++ << (i * 8);
|
||||
}
|
||||
/* increase counter by 4 bytes only, 4 bytes overlap on each call */
|
||||
buf->offset += 4;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Internal function for huff/cdic decompression
|
||||
|
||||
Decompressor and HUFF/CDIC records parsing based on:
|
||||
perl EBook::Tools::Mobipocket
|
||||
python mobiunpack.py, calibre
|
||||
|
||||
@param[out] buf_out MOBIBuffer structure with decompressed data
|
||||
@param[in] buf_in MOBIBuffer structure with compressed data
|
||||
@param[in] huffcdic MOBIHuffCdic structure with parsed data from huff/cdic records
|
||||
@param[in] depth Depth of current recursion level
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_decompress_huffman_internal(MOBIBuffer *buf_out, MOBIBuffer *buf_in, const MOBIHuffCdic *huffcdic, size_t depth) {
|
||||
if (depth > MOBI_HUFFMAN_MAXDEPTH) {
|
||||
debug_print("Too many levels of recursion: %zu\n", depth);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
MOBI_RET ret = MOBI_SUCCESS;
|
||||
int8_t bitcount = 32;
|
||||
/* this cast should be safe: max record size is 4096 */
|
||||
int bitsleft = (int) (buf_in->maxlen * 8);
|
||||
uint8_t code_length = 0;
|
||||
uint64_t buffer = mobi_buffer_fill64(buf_in);
|
||||
while (ret == MOBI_SUCCESS) {
|
||||
if (bitcount <= 0) {
|
||||
bitcount += 32;
|
||||
buffer = mobi_buffer_fill64(buf_in);
|
||||
}
|
||||
uint32_t code = (buffer >> bitcount) & 0xffffffffU;
|
||||
/* lookup code in table1 */
|
||||
uint32_t t1 = huffcdic->table1[code >> 24];
|
||||
/* get maxcode and codelen from t1 */
|
||||
code_length = t1 & 0x1f;
|
||||
uint32_t maxcode = (((t1 >> 8) + 1) << (32 - code_length)) - 1;
|
||||
/* check termination bit */
|
||||
if (!(t1 & 0x80)) {
|
||||
/* get offset from mincode, maxcode tables */
|
||||
while (code < huffcdic->mincode_table[code_length]) {
|
||||
if (++code_length >= HUFF_CODETABLE_SIZE) {
|
||||
debug_print("Wrong offset to mincode table: %hhu\n", code_length);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
}
|
||||
maxcode = huffcdic->maxcode_table[code_length];
|
||||
}
|
||||
bitcount -= code_length;
|
||||
bitsleft -= code_length;
|
||||
if (bitsleft < 0) {
|
||||
break;
|
||||
}
|
||||
/* get index for symbol offset */
|
||||
uint32_t index = (uint32_t) (maxcode - code) >> (32 - code_length);
|
||||
/* check which part of cdic to use */
|
||||
uint16_t cdic_index = (uint16_t) ((uint32_t)index >> huffcdic->code_length);
|
||||
if (index >= huffcdic->index_count) {
|
||||
debug_print("Wrong symbol offsets index: %u\n", index);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
/* get offset */
|
||||
uint32_t offset = huffcdic->symbol_offsets[index];
|
||||
uint32_t symbol_length = (uint32_t) huffcdic->symbols[cdic_index][offset] << 8 | (uint32_t) huffcdic->symbols[cdic_index][offset + 1];
|
||||
/* 1st bit is is_decompressed flag */
|
||||
int is_decompressed = symbol_length >> 15;
|
||||
/* get rid of flag */
|
||||
symbol_length &= 0x7fff;
|
||||
if (is_decompressed) {
|
||||
/* symbol is at (offset + 2), 2 bytes used earlier for symbol length */
|
||||
mobi_buffer_addraw(buf_out, (huffcdic->symbols[cdic_index] + offset + 2), symbol_length);
|
||||
ret = buf_out->error;
|
||||
} else {
|
||||
/* symbol is compressed */
|
||||
/* TODO cache uncompressed symbols? */
|
||||
MOBIBuffer buf_sym;
|
||||
buf_sym.data = huffcdic->symbols[cdic_index] + offset + 2;
|
||||
buf_sym.offset = 0;
|
||||
buf_sym.maxlen = symbol_length;
|
||||
buf_sym.error = MOBI_SUCCESS;
|
||||
ret = mobi_decompress_huffman_internal(buf_out, &buf_sym, huffcdic, depth + 1);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Decompressor for huff/cdic compressed text records
|
||||
|
||||
Decompressor and HUFF/CDIC records parsing based on:
|
||||
perl EBook::Tools::Mobipocket
|
||||
python mobiunpack.py, calibre
|
||||
|
||||
@param[out] out Decompressed destination data
|
||||
@param[in] in Compressed source data
|
||||
@param[in,out] len_out Size of the memory reserved for decompressed data.
|
||||
On return it is set to actual size of decompressed data
|
||||
@param[in] len_in Size of compressed data
|
||||
@param[in] huffcdic MOBIHuffCdic structure with parsed data from huff/cdic records
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_decompress_huffman(unsigned char *out, const unsigned char *in, size_t *len_out, size_t len_in, const MOBIHuffCdic *huffcdic) {
|
||||
MOBIBuffer *buf_in = mobi_buffer_init_null((unsigned char *) in, len_in);
|
||||
if (buf_in == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
MOBIBuffer *buf_out = mobi_buffer_init_null(out, *len_out);
|
||||
if (buf_out == NULL) {
|
||||
mobi_buffer_free_null(buf_in);
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
MOBI_RET ret = mobi_decompress_huffman_internal(buf_out, buf_in, huffcdic, 0);
|
||||
*len_out = buf_out->offset;
|
||||
mobi_buffer_free_null(buf_out);
|
||||
mobi_buffer_free_null(buf_in);
|
||||
return ret;
|
||||
}
|
||||
43
app/src/main/cpp/libmobi/src/compression.h
vendored
Normal file
43
app/src/main/cpp/libmobi/src/compression.h
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/** @file compression.h
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef libmobi_compression_h
|
||||
#define libmobi_compression_h
|
||||
|
||||
#include "config.h"
|
||||
#include "mobi.h"
|
||||
|
||||
#ifndef MOBI_INLINE
|
||||
#define MOBI_INLINE /**< Syntax for compiler inline keyword from config.h */
|
||||
#endif
|
||||
|
||||
/* FIXME: what is the reasonable value? */
|
||||
#define MOBI_HUFFMAN_MAXDEPTH 20 /**< Maximal recursion level for huffman decompression routine */
|
||||
#define HUFF_CODETABLE_SIZE 33 /**< Size of min- and maxcode tables */
|
||||
|
||||
|
||||
/**
|
||||
@brief Parsed data from HUFF and CDIC records needed to unpack huffman compressed text
|
||||
*/
|
||||
typedef struct {
|
||||
size_t index_count; /**< Total number of indices in all CDIC records, stored in each CDIC record header */
|
||||
size_t index_read; /**< Number of indices parsed, used by parser */
|
||||
size_t code_length; /**< Code length value stored in CDIC record header */
|
||||
uint32_t table1[256]; /**< Table of big-endian indices from HUFF record data1 */
|
||||
uint32_t mincode_table[HUFF_CODETABLE_SIZE]; /**< Table of big-endian mincodes from HUFF record data2 */
|
||||
uint32_t maxcode_table[HUFF_CODETABLE_SIZE]; /**< Table of big-endian maxcodes from HUFF record data2 */
|
||||
uint16_t *symbol_offsets; /**< Index of symbol offsets parsed from CDIC records (index_count entries) */
|
||||
unsigned char **symbols; /**< Array of pointers to start of symbols data in each CDIC record (index = number of CDIC record) */
|
||||
} MOBIHuffCdic;
|
||||
|
||||
MOBI_RET mobi_decompress_lz77(unsigned char *out, const unsigned char *in, size_t *len_out, const size_t len_in);
|
||||
MOBI_RET mobi_decompress_huffman(unsigned char *out, const unsigned char *in, size_t *len_out, size_t len_in, const MOBIHuffCdic *huffcdic);
|
||||
|
||||
#endif
|
||||
18
app/src/main/cpp/libmobi/src/config.h
vendored
Normal file
18
app/src/main/cpp/libmobi/src/config.h
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/** @file src/config.h
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef mobi_config_h
|
||||
#define mobi_config_h
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
159
app/src/main/cpp/libmobi/src/debug.c
vendored
Normal file
159
app/src/main/cpp/libmobi/src/debug.c
vendored
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
/** @file debug.c
|
||||
* @brief Debugging functions, enable by running configure --enable-debug
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "index.h"
|
||||
|
||||
/**
|
||||
@brief Debugging wrapper for free(void *ptr)
|
||||
|
||||
@param[in] ptr Pointer
|
||||
@param[in] file Calling file
|
||||
@param[in] line Calling line
|
||||
*/
|
||||
void debug_free(void *ptr, const char *file, const int line) {
|
||||
printf("%s:%d: free(%p)\n",file, line, ptr);
|
||||
(free)(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Debugging wrapper for malloc(size_t size)
|
||||
|
||||
@param[in] size Size of memory
|
||||
@param[in] file Calling file
|
||||
@param[in] line Calling line
|
||||
@return A pointer to the allocated memory block on success, NULL on failure
|
||||
|
||||
*/
|
||||
void *debug_malloc(const size_t size, const char *file, const int line) {
|
||||
void *ptr = (malloc)(size);
|
||||
printf("%s:%d: malloc(%d)=%p\n", file, line, (int)size, ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Debugging wrapper for realloc(void* ptr, size_t size)
|
||||
|
||||
@param[in] ptr Pointer
|
||||
@param[in] size Size of memory
|
||||
@param[in] file Calling file
|
||||
@param[in] line Calling line
|
||||
@return A pointer to the reallocated memory block on success, NULL on failure
|
||||
*/
|
||||
void *debug_realloc(void *ptr, const size_t size, const char *file, const int line) {
|
||||
printf("%s:%d: realloc(%p", file, line, ptr);
|
||||
void *rptr = (realloc)(ptr, size);
|
||||
printf(", %d)=%p\n", (int)size, rptr);
|
||||
return rptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Debugging wrapper for calloc(size_t num, size_t size)
|
||||
|
||||
@param[in] num Number of elements to allocate
|
||||
@param[in] size Size of each element
|
||||
@param[in] file Calling file
|
||||
@param[in] line Calling line
|
||||
@return A pointer to the allocated memory block on success, NULL on failure
|
||||
*/
|
||||
void *debug_calloc(const size_t num, const size_t size, const char *file, const int line) {
|
||||
void *ptr = (calloc)(num, size);
|
||||
printf("%s:%d: calloc(%d, %d)=%p\n", file, line, (int)num, (int)size, ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Dump index values
|
||||
|
||||
@param[in] indx Parsed index
|
||||
*/
|
||||
void print_indx(const MOBIIndx *indx) {
|
||||
if (indx == NULL) { return; }
|
||||
for (size_t i = 0; i < indx->entries_count; i++) {
|
||||
MOBIIndexEntry e = indx->entries[i];
|
||||
printf("entry[%zu]: \"%s\"\n", i, e.label);
|
||||
for (size_t j = 0; j < e.tags_count; j++) {
|
||||
MOBIIndexTag t = e.tags[j];
|
||||
printf(" tag[%zu] ", t.tagid);
|
||||
for (size_t k = 0; k < t.tagvalues_count; k++) {
|
||||
printf("[%u] ", t.tagvalues[k]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Dump inflections index (old version)
|
||||
|
||||
@param[in] indx Parsed index
|
||||
*/
|
||||
void print_indx_infl_old(const MOBIIndx *indx) {
|
||||
if (indx == NULL) { return; }
|
||||
for (size_t i = 0; i < indx->entries_count; i++) {
|
||||
MOBIIndexEntry e = indx->entries[i];
|
||||
printf("entry[%zu]: \"%s\"\n", i, e.label);
|
||||
for (size_t j = 0; j < e.tags_count; j++) {
|
||||
MOBIIndexTag t = e.tags[j];
|
||||
printf(" tag[%zu] ", t.tagid);
|
||||
if (t.tagid == 7) {
|
||||
for (size_t k = 0; k < t.tagvalues_count; k += 2) {
|
||||
uint32_t len = t.tagvalues[k];
|
||||
uint32_t offset = t.tagvalues[k + 1];
|
||||
char *string = mobi_get_cncx_string_flat(indx->cncx_record, offset, len);
|
||||
if (string) {
|
||||
printf("\"%s\" [%u] [%u]", string, len, offset);
|
||||
free(string);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (size_t k = 0; k < t.tagvalues_count; k++) {
|
||||
printf("[%u] ", t.tagvalues[k]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Dump orthographic index (old version)
|
||||
|
||||
@param[in] indx Parsed index
|
||||
*/
|
||||
void print_indx_orth_old(const MOBIIndx *indx) {
|
||||
if (indx == NULL) { return; }
|
||||
for (size_t i = 0; i < indx->entries_count; i++) {
|
||||
MOBIIndexEntry e = indx->entries[i];
|
||||
printf("entry[%zu]: \"%s\"\n", i, e.label);
|
||||
for (size_t j = 0; j < e.tags_count; j++) {
|
||||
MOBIIndexTag t = e.tags[j];
|
||||
printf(" tag[%zu] ", t.tagid);
|
||||
if (t.tagid >= 69) {
|
||||
for (size_t k = 0; k < t.tagvalues_count; k++) {
|
||||
uint32_t offset = t.tagvalues[k];
|
||||
char *string = mobi_get_cncx_string(indx->cncx_record, offset);
|
||||
if (string) {
|
||||
printf("\"%s\" [%u] ", string, t.tagvalues[k]);
|
||||
free(string);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (size_t k = 0; k < t.tagvalues_count; k++) {
|
||||
printf("[%u] ", t.tagvalues[k]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
57
app/src/main/cpp/libmobi/src/debug.h
vendored
Normal file
57
app/src/main/cpp/libmobi/src/debug.h
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/** @file debug.h
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef libmobi_debug_h
|
||||
#define libmobi_debug_h
|
||||
|
||||
#include "config.h"
|
||||
#include "mobi.h"
|
||||
|
||||
#ifndef MOBI_DEBUG
|
||||
#define MOBI_DEBUG 0 /**< Turn on debugging, set this on by running "configure --enable-debug" */
|
||||
#endif
|
||||
|
||||
#if MOBI_DEBUG_ALLOC
|
||||
/**
|
||||
@defgroup mobi_debug Debug wrappers for memory allocation functions
|
||||
|
||||
Set this on by running "configure --enable-debug-alloc"
|
||||
@{
|
||||
*/
|
||||
#define free(x) debug_free(x, __FILE__, __LINE__)
|
||||
#define malloc(x) debug_malloc(x, __FILE__, __LINE__)
|
||||
#define realloc(x, y) debug_realloc(x, y, __FILE__, __LINE__)
|
||||
#define calloc(x, y) debug_calloc(x, y, __FILE__, __LINE__)
|
||||
/** @} */
|
||||
#endif
|
||||
|
||||
void debug_free(void *ptr, const char *file, const int line);
|
||||
void *debug_malloc(const size_t size, const char *file, const int line);
|
||||
void *debug_realloc(void *ptr, const size_t size, const char *file, const int line);
|
||||
void *debug_calloc(const size_t num, const size_t size, const char *file, const int line);
|
||||
void print_indx(const MOBIIndx *indx);
|
||||
void print_indx_infl_old(const MOBIIndx *indx);
|
||||
void print_indx_orth_old(const MOBIIndx *indx);
|
||||
|
||||
/**
|
||||
@brief Macro for printing debug info to stderr. Wrapper for fprintf
|
||||
@param[in] fmt Format
|
||||
@param[in] ... Additional arguments
|
||||
*/
|
||||
#if (MOBI_DEBUG)
|
||||
#define debug_print(fmt, ...) { \
|
||||
fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \
|
||||
__LINE__, __func__, __VA_ARGS__); \
|
||||
}
|
||||
#else
|
||||
#define debug_print(fmt, ...)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1515
app/src/main/cpp/libmobi/src/encryption.c
vendored
Normal file
1515
app/src/main/cpp/libmobi/src/encryption.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
47
app/src/main/cpp/libmobi/src/encryption.h
vendored
Normal file
47
app/src/main/cpp/libmobi/src/encryption.h
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/** @file encryption.h
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef mobi_encryption_h
|
||||
#define mobi_encryption_h
|
||||
|
||||
#include "config.h"
|
||||
#include "mobi.h"
|
||||
#include "buffer.h"
|
||||
|
||||
/**
|
||||
@brief Drm cookie data
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char *pid; /**< PIDs for decryption, NULL if not set */
|
||||
uint32_t valid_from; /**< validity period start time, unix time in minutes, 0 if not set */
|
||||
uint32_t valid_to; /**< validity period end time, unix time in minutes, MOBI_NOTSET if not set */
|
||||
} MOBICookie;
|
||||
|
||||
/**
|
||||
@brief Drm data
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned char *key; /**< key for decryption, NULL if not set */
|
||||
uint32_t cookies_count; /**< Cookies count */
|
||||
MOBICookie **cookies; /**< DRM cookie */
|
||||
} MOBIDrm;
|
||||
|
||||
void mobi_free_drm(MOBIData *m);
|
||||
MOBI_RET mobi_buffer_decrypt(unsigned char *out, const unsigned char *in, const size_t length, const MOBIData *m);
|
||||
MOBI_RET mobi_drmkey_set(MOBIData *m, const char *pid);
|
||||
MOBI_RET mobi_drmkey_set_serial(MOBIData *m, const char *serial);
|
||||
MOBI_RET mobi_drmkey_delete(MOBIData *m);
|
||||
MOBI_RET mobi_voucher_add(MOBIData *m, const char *serial, const time_t valid_from, const time_t valid_to,
|
||||
const MOBIExthTag *tamperkeys, const size_t tamperkeys_count);
|
||||
MOBI_RET mobi_drm_serialize_v1(MOBIBuffer *buf, const MOBIData *m);
|
||||
MOBI_RET mobi_drm_serialize_v2(MOBIBuffer *buf, const MOBIData *m);
|
||||
|
||||
#endif /* defined(mobi_encryption_h) */
|
||||
1092
app/src/main/cpp/libmobi/src/index.c
vendored
Normal file
1092
app/src/main/cpp/libmobi/src/index.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
128
app/src/main/cpp/libmobi/src/index.h
vendored
Normal file
128
app/src/main/cpp/libmobi/src/index.h
vendored
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/** @file index.h
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef mobi_index_h
|
||||
#define mobi_index_h
|
||||
|
||||
#include "config.h"
|
||||
#include "structure.h"
|
||||
#include "mobi.h"
|
||||
|
||||
/**
|
||||
@defgroup index_tag Predefined tag arrays: {tagid, tagindex} for mobi_get_indxentry_tagvalue()
|
||||
@{
|
||||
*/
|
||||
#define INDX_TAG_GUIDE_TITLE_CNCX (unsigned[]) {1, 0} /**< Guide title CNCX offset */
|
||||
|
||||
#define INDX_TAG_NCX_FILEPOS (unsigned[]) {1, 0} /**< NCX filepos offset */
|
||||
#define INDX_TAG_NCX_TEXT_CNCX (unsigned[]) {3, 0} /**< NCX text CNCX offset */
|
||||
#define INDX_TAG_NCX_LEVEL (unsigned[]) {4, 0} /**< NCX level */
|
||||
#define INDX_TAG_NCX_KIND_CNCX (unsigned[]) {5, 0} /**< NCX kind CNCX offset */
|
||||
#define INDX_TAG_NCX_POSFID (unsigned[]) {6, 0} /**< NCX pos:fid */
|
||||
#define INDX_TAG_NCX_POSOFF (unsigned[]) {6, 1} /**< NCX pos:off */
|
||||
#define INDX_TAG_NCX_PARENT (unsigned[]) {21, 0} /**< NCX parent */
|
||||
#define INDX_TAG_NCX_CHILD_START (unsigned[]) {22, 0} /**< NCX start child */
|
||||
#define INDX_TAG_NCX_CHILD_END (unsigned[]) {23, 0} /**< NCX last child */
|
||||
|
||||
#define INDX_TAG_SKEL_COUNT (unsigned[]) {1, 0} /**< Skel fragments count */
|
||||
#define INDX_TAG_SKEL_POSITION (unsigned[]) {6, 0} /**< Skel position */
|
||||
#define INDX_TAG_SKEL_LENGTH (unsigned[]) {6, 1} /**< Skel length */
|
||||
|
||||
#define INDX_TAG_FRAG_AID_CNCX (unsigned[]) {2, 0} /**< Frag aid CNCX offset */
|
||||
#define INDX_TAG_FRAG_FILE_NR (unsigned[]) {3, 0} /**< Frag file number */
|
||||
#define INDX_TAG_FRAG_SEQUENCE_NR (unsigned[]) {4, 0} /**< Frag sequence number */
|
||||
#define INDX_TAG_FRAG_POSITION (unsigned[]) {6, 0} /**< Frag position */
|
||||
#define INDX_TAG_FRAG_LENGTH (unsigned[]) {6, 1} /**< Frag length */
|
||||
|
||||
#define INDX_TAG_ORTH_POSITION (unsigned[]) {1, 0} /**< Orth entry start position */
|
||||
#define INDX_TAG_ORTH_LENGTH (unsigned[]) {2, 0} /**< Orth entry end position */
|
||||
|
||||
#define INDX_TAGARR_ORTH_INFL 42 /**< Inflection groups for orth entry */
|
||||
#define INDX_TAGARR_INFL_GROUPS 5 /**< Inflection groups in infl index */
|
||||
#define INDX_TAGARR_INFL_PARTS_V2 26 /**< Inflection particles in infl index */
|
||||
|
||||
#define INDX_TAGARR_INFL_PARTS_V1 7 /**< Inflection particles in old type infl index */
|
||||
/** @} */
|
||||
|
||||
#define INDX_LABEL_SIZEMAX 1000 /**< Max size of index label */
|
||||
#define INDX_INFLTAG_SIZEMAX 25000 /**< Max size of inflections tags per entry */
|
||||
#define INDX_INFLBUF_SIZEMAX 500 /**< Max size of index label */
|
||||
#define INDX_INFLSTRINGS_MAX 500 /**< Max number of inflected strings */
|
||||
#define ORDT_RECORD_MAXCNT 256 /* max entries count in old ordt */
|
||||
#define CNCX_RECORD_MAXCNT 0xf /* max entries count */
|
||||
#define INDX_RECORD_MAXCNT 10000 /* max index entries per record */
|
||||
#define INDX_TOTAL_MAXCNT ((size_t) INDX_RECORD_MAXCNT * 0xffff) /* max total index entries */
|
||||
#define INDX_NAME_SIZEMAX 0xff
|
||||
|
||||
/**
|
||||
@brief Maximum value of tag values in index entry (MOBIIndexTag)
|
||||
*/
|
||||
#define INDX_TAGVALUES_MAX 100
|
||||
|
||||
/**
|
||||
@brief Tag entries in TAGX section (for internal INDX parsing)
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t tag; /**< Tag */
|
||||
uint8_t values_count; /**< Number of values */
|
||||
uint8_t bitmask; /**< Bitmask */
|
||||
uint8_t control_byte; /**< EOF control byte */
|
||||
} TAGXTags;
|
||||
|
||||
/**
|
||||
@brief Parsed TAGX section (for internal INDX parsing)
|
||||
|
||||
TAGX tags hold metadata of index entries.
|
||||
It is present in the first index record.
|
||||
*/
|
||||
typedef struct {
|
||||
TAGXTags *tags; /**< Array of tag entries */
|
||||
size_t tags_count; /**< Number of tag entries */
|
||||
size_t control_byte_count; /**< Number of control bytes */
|
||||
} MOBITagx;
|
||||
|
||||
/**
|
||||
@brief Parsed IDXT section (for internal INDX parsing)
|
||||
|
||||
IDXT section holds offsets to index entries
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t *offsets; /**< Offsets to index entries */
|
||||
size_t offsets_count; /**< Offsets count */
|
||||
} MOBIIdxt;
|
||||
|
||||
/**
|
||||
@brief Parsed ORDT sections (for internal INDX parsing)
|
||||
|
||||
ORDT sections hold data for decoding index labels.
|
||||
It is mapping of encoded chars to unicode.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t *ordt1; /**< ORDT1 offsets */
|
||||
uint16_t *ordt2; /**< ORDT2 offsets */
|
||||
size_t type; /**< Type (0: 16, 1: 8 bit offsets) */
|
||||
size_t ordt1_pos; /**< Offset of ORDT1 data */
|
||||
size_t ordt2_pos; /**< Offset of ORDT2 data */
|
||||
size_t offsets_count; /**< Offsets count */
|
||||
} MOBIOrdt;
|
||||
|
||||
MOBI_RET mobi_parse_index(const MOBIData *m, MOBIIndx *indx, const size_t indx_record_number);
|
||||
MOBI_RET mobi_parse_indx(const MOBIPdbRecord *indx_record, MOBIIndx *indx, MOBITagx *tagx, MOBIOrdt *ordt);
|
||||
MOBI_RET mobi_get_indxentry_tagvalue(uint32_t *tagvalue, const MOBIIndexEntry *entry, const unsigned tag_arr[]);
|
||||
size_t mobi_get_indxentry_tagarray(uint32_t **tagarr, const MOBIIndexEntry *entry, const size_t tagid);
|
||||
bool mobi_indx_has_tag(const MOBIIndx *indx, const size_t tagid);
|
||||
char * mobi_get_cncx_string(const MOBIPdbRecord *cncx_record, const uint32_t cncx_offset);
|
||||
char * mobi_get_cncx_string_utf8(const MOBIPdbRecord *cncx_record, const uint32_t cncx_offset, MOBIEncoding cncx_encoding);
|
||||
char * mobi_get_cncx_string_flat(const MOBIPdbRecord *cncx_record, const uint32_t cncx_offset, const size_t length);
|
||||
MOBI_RET mobi_decode_infl(unsigned char *decoded, int *decoded_size, const unsigned char *rule);
|
||||
MOBI_RET mobi_trie_insert_infl(MOBITrie **root, const MOBIIndx *indx, size_t i);
|
||||
size_t mobi_trie_get_inflgroups(char **infl_strings, MOBITrie * const root, const char *string);
|
||||
|
||||
#endif
|
||||
444
app/src/main/cpp/libmobi/src/memory.c
vendored
Normal file
444
app/src/main/cpp/libmobi/src/memory.c
vendored
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
/** @file memory.c
|
||||
* @brief Functions for initializing and releasing structures and data containers
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "memory.h"
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
@brief Initializer for MOBIData structure
|
||||
|
||||
It allocates memory for structure.
|
||||
Memory should be freed with mobi_free().
|
||||
|
||||
@return MOBIData on success, NULL otherwise
|
||||
*/
|
||||
MOBIData * mobi_init(void) {
|
||||
MOBIData *m = NULL;
|
||||
m = calloc(1, sizeof(MOBIData));
|
||||
if (m == NULL) { return NULL; }
|
||||
m->use_kf8 = true;
|
||||
m->kf8_boundary_offset = MOBI_NOTSET;
|
||||
m->drm_key = NULL;
|
||||
m->ph = NULL;
|
||||
m->rh = NULL;
|
||||
m->mh = NULL;
|
||||
m->eh = NULL;
|
||||
m->rec = NULL;
|
||||
m->next = NULL;
|
||||
m->internals = NULL;
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free MOBIMobiHeader structure
|
||||
|
||||
@param[in] mh MOBIMobiHeader structure
|
||||
*/
|
||||
void mobi_free_mh(MOBIMobiHeader *mh) {
|
||||
if (mh == NULL) {
|
||||
return;
|
||||
}
|
||||
free(mh->header_length);
|
||||
free(mh->mobi_type);
|
||||
free(mh->text_encoding);
|
||||
free(mh->uid);
|
||||
free(mh->version);
|
||||
free(mh->orth_index);
|
||||
free(mh->infl_index);
|
||||
free(mh->names_index);
|
||||
free(mh->keys_index);
|
||||
free(mh->extra0_index);
|
||||
free(mh->extra1_index);
|
||||
free(mh->extra2_index);
|
||||
free(mh->extra3_index);
|
||||
free(mh->extra4_index);
|
||||
free(mh->extra5_index);
|
||||
free(mh->non_text_index);
|
||||
free(mh->full_name_offset);
|
||||
free(mh->full_name_length);
|
||||
free(mh->locale);
|
||||
free(mh->dict_input_lang);
|
||||
free(mh->dict_output_lang);
|
||||
free(mh->min_version);
|
||||
free(mh->image_index);
|
||||
free(mh->huff_rec_index);
|
||||
free(mh->huff_rec_count);
|
||||
free(mh->datp_rec_index);
|
||||
free(mh->datp_rec_count);
|
||||
free(mh->exth_flags);
|
||||
free(mh->unknown6);
|
||||
free(mh->drm_offset);
|
||||
free(mh->drm_count);
|
||||
free(mh->drm_size);
|
||||
free(mh->drm_flags);
|
||||
free(mh->fdst_index);
|
||||
free(mh->first_text_index);
|
||||
free(mh->last_text_index);
|
||||
free(mh->fdst_section_count);
|
||||
//free(mh->unknown9);
|
||||
free(mh->fcis_index);
|
||||
free(mh->fcis_count);
|
||||
free(mh->flis_index);
|
||||
free(mh->flis_count);
|
||||
free(mh->unknown10);
|
||||
free(mh->unknown11);
|
||||
free(mh->srcs_index);
|
||||
free(mh->srcs_count);
|
||||
free(mh->unknown12);
|
||||
free(mh->unknown13);
|
||||
free(mh->extra_flags);
|
||||
free(mh->ncx_index);
|
||||
free(mh->fragment_index);
|
||||
free(mh->skeleton_index);
|
||||
free(mh->unknown14);
|
||||
free(mh->unknown15);
|
||||
free(mh->datp_index);
|
||||
free(mh->guide_index);
|
||||
free(mh->unknown16);
|
||||
free(mh->unknown17);
|
||||
free(mh->unknown18);
|
||||
free(mh->unknown19);
|
||||
free(mh->unknown20);
|
||||
free(mh->full_name);
|
||||
free(mh);
|
||||
mh = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free all MOBIPdbRecord structures and its respective data attached to MOBIData structure
|
||||
|
||||
Each MOBIPdbRecord structure holds metadata and data for each pdb record
|
||||
|
||||
@param[in,out] m MOBIData structure
|
||||
*/
|
||||
void mobi_free_rec(MOBIData *m) {
|
||||
MOBIPdbRecord *curr, *tmp;
|
||||
curr = m->rec;
|
||||
while (curr != NULL) {
|
||||
tmp = curr;
|
||||
curr = curr->next;
|
||||
free(tmp->data);
|
||||
free(tmp);
|
||||
tmp = NULL;
|
||||
}
|
||||
m->rec = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free all MOBIExthHeader structures and its respective data attached to MOBIData structure
|
||||
|
||||
Each MOBIExthHeader structure holds metadata and data for each EXTH record
|
||||
|
||||
@param[in,out] m MOBIData structure
|
||||
*/
|
||||
void mobi_free_eh(MOBIData *m) {
|
||||
MOBIExthHeader *curr, *tmp;
|
||||
curr = m->eh;
|
||||
while (curr != NULL) {
|
||||
tmp = curr;
|
||||
curr = curr->next;
|
||||
free(tmp->data);
|
||||
free(tmp);
|
||||
tmp = NULL;
|
||||
}
|
||||
m->eh = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free MOBIData structure for currenly unused hybrid part and all its children
|
||||
|
||||
@param[in] m MOBIData structure
|
||||
*/
|
||||
void mobi_free_next(MOBIData *m) {
|
||||
if (m && m->next) {
|
||||
mobi_free_mh(m->next->mh);
|
||||
mobi_free_eh(m->next);
|
||||
free(m->next->rh);
|
||||
free(m->next);
|
||||
m->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free MOBIData structure and all its children
|
||||
|
||||
@param[in] m MOBIData structure
|
||||
*/
|
||||
void mobi_free(MOBIData *m) {
|
||||
if (m == NULL) {
|
||||
return;
|
||||
}
|
||||
mobi_free_mh(m->mh);
|
||||
mobi_free_eh(m);
|
||||
mobi_free_rec(m);
|
||||
free(m->ph);
|
||||
free(m->rh);
|
||||
mobi_free_next(m);
|
||||
mobi_free_internals(m);
|
||||
free(m);
|
||||
m = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Initialize and return MOBIHuffCdic structure.
|
||||
|
||||
MOBIHuffCdic structure holds parsed data from HUFF, CDIC records.
|
||||
It is used for huffman decompression.
|
||||
Initialized structure is a child of MOBIData structure.
|
||||
It must be freed with mobi_free_huffcdic().
|
||||
|
||||
@return MOBIHuffCdic on success, NULL otherwise
|
||||
*/
|
||||
MOBIHuffCdic * mobi_init_huffcdic(void) {
|
||||
MOBIHuffCdic *huffcdic = calloc(1, sizeof(MOBIHuffCdic));
|
||||
if (huffcdic == NULL) {
|
||||
debug_print("%s", "Memory allocation for huffcdic structure failed\n");
|
||||
return NULL;
|
||||
}
|
||||
return huffcdic;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free MOBIHuffCdic structure and all its children
|
||||
|
||||
@param[in] huffcdic MOBIData structure
|
||||
*/
|
||||
void mobi_free_huffcdic(MOBIHuffCdic *huffcdic) {
|
||||
if (huffcdic == NULL) {
|
||||
return;
|
||||
}
|
||||
free(huffcdic->symbol_offsets);
|
||||
free(huffcdic->symbols);
|
||||
free(huffcdic);
|
||||
huffcdic = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Initialize and return MOBIRawml structure.
|
||||
|
||||
MOBIRawml structure holds parsed text record metadata.
|
||||
It is used in the process of parsing rawml text data.
|
||||
It must be freed with mobi_free_rawml().
|
||||
|
||||
@param[in] m Initialized MOBIData structure
|
||||
@return MOBIRawml on success, NULL otherwise
|
||||
*/
|
||||
MOBIRawml * mobi_init_rawml(const MOBIData *m) {
|
||||
MOBIRawml *rawml = malloc(sizeof(MOBIRawml));
|
||||
if (rawml == NULL) {
|
||||
debug_print("%s", "Memory allocation failed for rawml structure\n");
|
||||
return NULL;
|
||||
}
|
||||
rawml->version = mobi_get_fileversion(m);
|
||||
rawml->fdst = NULL;
|
||||
rawml->skel = NULL;
|
||||
rawml->frag = NULL;
|
||||
rawml->guide = NULL;
|
||||
rawml->ncx = NULL;
|
||||
rawml->orth = NULL;
|
||||
rawml->infl = NULL;
|
||||
rawml->flow = NULL;
|
||||
rawml->markup = NULL;
|
||||
rawml->resources = NULL;
|
||||
return rawml;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free MOBIFdst structure and all its children
|
||||
|
||||
@param[in] fdst MOBIFdst structure
|
||||
*/
|
||||
void mobi_free_fdst(MOBIFdst *fdst) {
|
||||
if (fdst == NULL) {
|
||||
return;
|
||||
}
|
||||
if (fdst->fdst_section_count > 0) {
|
||||
free(fdst->fdst_section_starts);
|
||||
free(fdst->fdst_section_ends);
|
||||
}
|
||||
free(fdst);
|
||||
fdst = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Initialize and return MOBIIndx structure.
|
||||
|
||||
MOBIIndx structure holds INDX index record entries.
|
||||
Must be freed with mobi_free_indx()
|
||||
|
||||
@return MOBIIndx on success, NULL otherwise
|
||||
*/
|
||||
MOBIIndx * mobi_init_indx(void) {
|
||||
MOBIIndx *indx = calloc(1, sizeof(MOBIIndx));
|
||||
if (indx == NULL) {
|
||||
debug_print("%s", "Memory allocation failed for indx structure\n");
|
||||
return NULL;
|
||||
}
|
||||
indx->entries = NULL;
|
||||
indx->cncx_record = NULL;
|
||||
indx->orth_index_name = NULL;
|
||||
return indx;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free index entries data and all its children
|
||||
|
||||
@param[in] indx MOBIIndx structure that holds indx->entries
|
||||
*/
|
||||
void mobi_free_index_entries(MOBIIndx *indx) {
|
||||
if (indx == NULL || indx->entries == NULL) {
|
||||
return;
|
||||
}
|
||||
size_t i = 0;
|
||||
while (i < indx->entries_count) {
|
||||
free(indx->entries[i].label);
|
||||
if (indx->entries[i].tags != NULL) {
|
||||
size_t j = 0;
|
||||
while (j < indx->entries[i].tags_count) {
|
||||
free(indx->entries[i].tags[j++].tagvalues);
|
||||
}
|
||||
free(indx->entries[i].tags);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
free(indx->entries);
|
||||
indx->entries = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free MOBIIndx structure and all its children
|
||||
|
||||
@param[in] indx MOBIIndx structure that holds indx->entries
|
||||
*/
|
||||
void mobi_free_indx(MOBIIndx *indx) {
|
||||
if (indx == NULL) {
|
||||
return;
|
||||
}
|
||||
mobi_free_index_entries(indx);
|
||||
if (indx->orth_index_name) {
|
||||
free(indx->orth_index_name);
|
||||
}
|
||||
free(indx);
|
||||
indx = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free MOBITagx structure and all its children
|
||||
|
||||
@param[in] tagx MOBITagx structure
|
||||
*/
|
||||
void mobi_free_tagx(MOBITagx *tagx) {
|
||||
if (tagx == NULL) {
|
||||
return;
|
||||
}
|
||||
free(tagx->tags);
|
||||
free(tagx);
|
||||
tagx = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free MOBIOrdt structure and all its children
|
||||
|
||||
@param[in] ordt MOBIOrdt structure
|
||||
*/
|
||||
void mobi_free_ordt(MOBIOrdt *ordt) {
|
||||
if (ordt == NULL) {
|
||||
return;
|
||||
}
|
||||
free(ordt->ordt1);
|
||||
free(ordt->ordt2);
|
||||
free(ordt);
|
||||
ordt = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free MOBIPart structure
|
||||
|
||||
Pointer to data may point to memory area also used by record->data.
|
||||
So we need a flag to leave the memory allocated, while freeing MOBIPart structure
|
||||
|
||||
@param[in] part MOBIPart structure
|
||||
@param[in] free_data Flag, if set - a pointer to part->data is also released, otherwise not released
|
||||
*/
|
||||
void mobi_free_part(MOBIPart *part, int free_data) {
|
||||
MOBIPart *curr, *tmp;
|
||||
curr = part;
|
||||
while (curr != NULL) {
|
||||
tmp = curr;
|
||||
curr = curr->next;
|
||||
if (free_data) { free(tmp->data); }
|
||||
free(tmp);
|
||||
}
|
||||
part = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free MOBIPart structure for opf and ncx data
|
||||
|
||||
@param[in] part MOBIPart structure
|
||||
*/
|
||||
void mobi_free_opf_data(MOBIPart *part) {
|
||||
while (part != NULL) {
|
||||
if (part->type == T_NCX || part->type == T_OPF) {
|
||||
free(part->data);
|
||||
}
|
||||
part = part->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free MOBIPart structure for decoded font data
|
||||
|
||||
@param[in] part MOBIPart structure
|
||||
*/
|
||||
void mobi_free_font_data(MOBIPart *part) {
|
||||
while (part != NULL) {
|
||||
if (part->type == T_OTF || part->type == T_TTF) {
|
||||
free(part->data);
|
||||
}
|
||||
part = part->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free MOBIRawml structure allocated by mobi_init_rawml()
|
||||
|
||||
Pointer to data may point to memory area also used by record->data.
|
||||
So we need a flag to leave the memory allocated, while freeing MOBIPart structure
|
||||
|
||||
@param[in] rawml MOBIRawml structure
|
||||
*/
|
||||
void mobi_free_rawml(MOBIRawml *rawml) {
|
||||
if (rawml == NULL) {
|
||||
return;
|
||||
}
|
||||
mobi_free_fdst(rawml->fdst);
|
||||
mobi_free_indx(rawml->skel);
|
||||
mobi_free_indx(rawml->frag);
|
||||
mobi_free_indx(rawml->guide);
|
||||
mobi_free_indx(rawml->ncx);
|
||||
mobi_free_indx(rawml->orth);
|
||||
mobi_free_indx(rawml->infl);
|
||||
mobi_free_part(rawml->flow, true);
|
||||
mobi_free_part(rawml->markup,true);
|
||||
/* do not free resources data, these are links to records data */
|
||||
/* only free opf and ncx data */
|
||||
mobi_free_opf_data(rawml->resources);
|
||||
/* and free decoded fonts data */
|
||||
mobi_free_font_data(rawml->resources);
|
||||
mobi_free_part(rawml->resources, false);
|
||||
free(rawml);
|
||||
rawml = NULL;
|
||||
}
|
||||
|
||||
|
||||
33
app/src/main/cpp/libmobi/src/memory.h
vendored
Normal file
33
app/src/main/cpp/libmobi/src/memory.h
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/** @file memory.h
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef libmobi_memory_h
|
||||
#define libmobi_memory_h
|
||||
|
||||
#include "config.h"
|
||||
#include "index.h"
|
||||
#include "compression.h"
|
||||
#include "mobi.h"
|
||||
|
||||
void mobi_free_mh(MOBIMobiHeader *mh);
|
||||
void mobi_free_rec(MOBIData *m);
|
||||
void mobi_free_eh(MOBIData *m);
|
||||
void mobi_free_next(MOBIData *m);
|
||||
|
||||
MOBIHuffCdic * mobi_init_huffcdic(void);
|
||||
void mobi_free_huffcdic(MOBIHuffCdic *huffcdic);
|
||||
|
||||
MOBIIndx * mobi_init_indx(void);
|
||||
void mobi_free_indx(MOBIIndx *indx);
|
||||
void mobi_free_tagx(MOBITagx *tagx);
|
||||
void mobi_free_ordt(MOBIOrdt *ordt);
|
||||
void mobi_free_index_entries(MOBIIndx *indx);
|
||||
|
||||
#endif
|
||||
864
app/src/main/cpp/libmobi/src/meta.c
vendored
Normal file
864
app/src/main/cpp/libmobi/src/meta.c
vendored
Normal file
|
|
@ -0,0 +1,864 @@
|
|||
/** @file meta.c
|
||||
* @brief Functions for metadata manipulation
|
||||
*
|
||||
* Copyright (c) 2016 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
#ifndef __USE_BSD
|
||||
#define __USE_BSD /* for strdup on linux/glibc */
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "meta.h"
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
@brief Get document metadata from exth string
|
||||
|
||||
Returned string must be deallocated by caller
|
||||
|
||||
@param[in] m MOBIData structure with loaded data
|
||||
@param[in] exth_tag MOBIExthTag
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
char * mobi_meta_get_exthstring(const MOBIData *m, const MOBIExthTag exth_tag) {
|
||||
char *string = NULL;
|
||||
|
||||
MOBIExthHeader *exth;
|
||||
MOBIExthHeader *start = NULL;
|
||||
while ((exth = mobi_next_exthrecord_by_tag(m, exth_tag, &start))) {
|
||||
char *exth_string = mobi_decode_exthstring(m, exth->data, exth->size);
|
||||
if (string == NULL) {
|
||||
string = exth_string;
|
||||
} else if (exth_string) {
|
||||
const char *separator = "; ";
|
||||
size_t new_length = strlen(string) + strlen(exth_string) + strlen(separator) + 1;
|
||||
char *new = malloc(new_length);
|
||||
if (new == NULL) {
|
||||
free(string);
|
||||
free(exth_string);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(new, string);
|
||||
strcat(new, separator);
|
||||
strcat(new, exth_string);
|
||||
free(string);
|
||||
free(exth_string);
|
||||
string = new;
|
||||
}
|
||||
if (start == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get document title metadata
|
||||
|
||||
Returned string must be deallocated by caller
|
||||
|
||||
@param[in] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
char * mobi_meta_get_title(const MOBIData *m) {
|
||||
if (m == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
char *title = mobi_meta_get_exthstring(m, EXTH_UPDATEDTITLE);
|
||||
if (title) {
|
||||
return title;
|
||||
}
|
||||
char fullname[MOBI_TITLE_SIZEMAX + 1];
|
||||
MOBI_RET ret = mobi_get_fullname(m, fullname, MOBI_TITLE_SIZEMAX);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
title = strdup(fullname);
|
||||
} else if (m->ph) {
|
||||
title = strdup(m->ph->name);
|
||||
}
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Add document title metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] title String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_add_title(MOBIData *m, const char *title) {
|
||||
if (title == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
size_t size = min(strlen(title), UINT32_MAX);
|
||||
return mobi_add_exthrecord(m, EXTH_UPDATEDTITLE, (uint32_t) size, title);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete all title metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_delete_title(MOBIData *m) {
|
||||
if (mobi_exists_mobiheader(m) && m->mh->full_name) {
|
||||
m->mh->full_name[0] = '\0';
|
||||
}
|
||||
if (mobi_is_hybrid(m) && mobi_exists_mobiheader(m->next) && m->next->mh->full_name) {
|
||||
m->next->mh->full_name[0] = '\0';
|
||||
}
|
||||
return mobi_delete_exthrecord_by_tag(m, EXTH_UPDATEDTITLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set document title metadata
|
||||
|
||||
Replaces all title metadata with new string
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] title String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_set_title(MOBIData *m, const char *title) {
|
||||
if (title == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
/* set title in mobi header */
|
||||
MOBI_RET ret = mobi_set_fullname(m, title);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
/* set title in palm header */
|
||||
ret = mobi_set_pdbname(m, title);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
/* set title in exth header */
|
||||
ret = mobi_delete_exthrecord_by_tag(m, EXTH_UPDATEDTITLE);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
ret = mobi_meta_add_title(m, title);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get document author metadata
|
||||
|
||||
Returned string must be deallocated by caller
|
||||
|
||||
@param[in] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
char * mobi_meta_get_author(const MOBIData *m) {
|
||||
return mobi_meta_get_exthstring(m, EXTH_AUTHOR);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Add document author metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] author String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_add_author(MOBIData *m, const char *author) {
|
||||
if (author == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
size_t size = min(strlen(author), UINT32_MAX);
|
||||
return mobi_add_exthrecord(m, EXTH_AUTHOR, (uint32_t) size, author);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete all author metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_delete_author(MOBIData *m) {
|
||||
return mobi_delete_exthrecord_by_tag(m, EXTH_AUTHOR);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set document author metadata
|
||||
|
||||
Replaces all author metadata with new string
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] author String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_set_author(MOBIData *m, const char *author) {
|
||||
if (author == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
MOBI_RET ret = mobi_meta_delete_author(m);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
ret = mobi_meta_add_author(m, author);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get document subject metadata
|
||||
|
||||
Returned string must be deallocated by caller
|
||||
|
||||
@param[in] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
char * mobi_meta_get_subject(const MOBIData *m) {
|
||||
return mobi_meta_get_exthstring(m, EXTH_SUBJECT);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Add document subject metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] subject String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_add_subject(MOBIData *m, const char *subject) {
|
||||
if (subject == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
size_t size = min(strlen(subject), UINT32_MAX);
|
||||
return mobi_add_exthrecord(m, EXTH_SUBJECT, (uint32_t) size, subject);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete all subject metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_delete_subject(MOBIData *m) {
|
||||
return mobi_delete_exthrecord_by_tag(m, EXTH_SUBJECT);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set document subject metadata
|
||||
|
||||
Replaces all subject metadata with new string
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] subject String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_set_subject(MOBIData *m, const char *subject) {
|
||||
if (subject == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
MOBI_RET ret = mobi_meta_delete_subject(m);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
ret = mobi_meta_add_subject(m, subject);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get document publisher metadata
|
||||
|
||||
Returned string must be deallocated by caller
|
||||
|
||||
@param[in] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
char * mobi_meta_get_publisher(const MOBIData *m) {
|
||||
return mobi_meta_get_exthstring(m, EXTH_PUBLISHER);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Add document publisher metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] publisher String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_add_publisher(MOBIData *m, const char *publisher) {
|
||||
if (publisher == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
size_t size = min(strlen(publisher), UINT32_MAX);
|
||||
return mobi_add_exthrecord(m, EXTH_PUBLISHER, (uint32_t) size, publisher);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete all publisher metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_delete_publisher(MOBIData *m) {
|
||||
return mobi_delete_exthrecord_by_tag(m, EXTH_PUBLISHER);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set document publisher metadata
|
||||
|
||||
Replaces all publisher metadata with new string
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] publisher String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_set_publisher(MOBIData *m, const char *publisher) {
|
||||
if (publisher == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
MOBI_RET ret = mobi_meta_delete_publisher(m);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
ret = mobi_meta_add_publisher(m, publisher);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get document publishing date metadata
|
||||
|
||||
Returned string must be deallocated by caller
|
||||
|
||||
@param[in] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
char * mobi_meta_get_publishdate(const MOBIData *m) {
|
||||
return mobi_meta_get_exthstring(m, EXTH_PUBLISHINGDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Add document publishdate metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] publishdate String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_add_publishdate(MOBIData *m, const char *publishdate) {
|
||||
if (publishdate == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
size_t size = min(strlen(publishdate), UINT32_MAX);
|
||||
return mobi_add_exthrecord(m, EXTH_PUBLISHINGDATE, (uint32_t) size, publishdate);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete all publishdate metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_delete_publishdate(MOBIData *m) {
|
||||
return mobi_delete_exthrecord_by_tag(m, EXTH_PUBLISHINGDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set document publishdate metadata
|
||||
|
||||
Replaces all publishdate metadata with new string
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] publishdate String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_set_publishdate(MOBIData *m, const char *publishdate) {
|
||||
if (publishdate == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
MOBI_RET ret = mobi_meta_delete_publishdate(m);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
ret = mobi_meta_add_publishdate(m, publishdate);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get document description metadata
|
||||
|
||||
Returned string must be deallocated by caller
|
||||
|
||||
@param[in] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
char * mobi_meta_get_description(const MOBIData *m) {
|
||||
return mobi_meta_get_exthstring(m, EXTH_DESCRIPTION);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Add document description metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] description String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_add_description(MOBIData *m, const char *description) {
|
||||
if (description == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
size_t size = min(strlen(description), UINT32_MAX);
|
||||
return mobi_add_exthrecord(m, EXTH_DESCRIPTION, (uint32_t) size, description);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete all description metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_delete_description(MOBIData *m) {
|
||||
return mobi_delete_exthrecord_by_tag(m, EXTH_DESCRIPTION);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set document description metadata
|
||||
|
||||
Replaces all description metadata with new string
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] description String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_set_description(MOBIData *m, const char *description) {
|
||||
if (description == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
MOBI_RET ret = mobi_meta_delete_description(m);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
ret = mobi_meta_add_description(m, description);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get document imprint metadata
|
||||
|
||||
Returned string must be deallocated by caller
|
||||
|
||||
@param[in] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
char * mobi_meta_get_imprint(const MOBIData *m) {
|
||||
return mobi_meta_get_exthstring(m, EXTH_IMPRINT);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Add document imprint metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] imprint String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_add_imprint(MOBIData *m, const char *imprint) {
|
||||
if (imprint == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
size_t size = min(strlen(imprint), UINT32_MAX);
|
||||
return mobi_add_exthrecord(m, EXTH_IMPRINT, (uint32_t) size, imprint);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete all imprint metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_delete_imprint(MOBIData *m) {
|
||||
return mobi_delete_exthrecord_by_tag(m, EXTH_IMPRINT);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set document imprint metadata
|
||||
|
||||
Replaces all imprint metadata with new string
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] imprint String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_set_imprint(MOBIData *m, const char *imprint) {
|
||||
if (imprint == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
MOBI_RET ret = mobi_meta_delete_imprint(m);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
ret = mobi_meta_add_imprint(m, imprint);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get document contributor metadata
|
||||
|
||||
Returned string must be deallocated by caller
|
||||
|
||||
@param[in] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
char * mobi_meta_get_contributor(const MOBIData *m) {
|
||||
return mobi_meta_get_exthstring(m, EXTH_CONTRIBUTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Add document contributor metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] contributor String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_add_contributor(MOBIData *m, const char *contributor) {
|
||||
if (contributor == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
size_t size = min(strlen(contributor), UINT32_MAX);
|
||||
return mobi_add_exthrecord(m, EXTH_CONTRIBUTOR, (uint32_t) size, contributor);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete all contributor metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_delete_contributor(MOBIData *m) {
|
||||
return mobi_delete_exthrecord_by_tag(m, EXTH_CONTRIBUTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set document contributor metadata
|
||||
|
||||
Replaces all contributor metadata with new string
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] contributor String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_set_contributor(MOBIData *m, const char *contributor) {
|
||||
if (contributor == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
MOBI_RET ret = mobi_meta_delete_contributor(m);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
ret = mobi_meta_add_contributor(m, contributor);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get document review metadata
|
||||
|
||||
Returned string must be deallocated by caller
|
||||
|
||||
@param[in] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
char * mobi_meta_get_review(const MOBIData *m) {
|
||||
return mobi_meta_get_exthstring(m, EXTH_REVIEW);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Add document review metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] review String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_add_review(MOBIData *m, const char *review) {
|
||||
if (review == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
size_t size = min(strlen(review), UINT32_MAX);
|
||||
return mobi_add_exthrecord(m, EXTH_REVIEW, (uint32_t) size, review);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete all review metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_delete_review(MOBIData *m) {
|
||||
return mobi_delete_exthrecord_by_tag(m, EXTH_REVIEW);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set document review metadata
|
||||
|
||||
Replaces all review metadata with new string
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] review String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_set_review(MOBIData *m, const char *review) {
|
||||
if (review == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
MOBI_RET ret = mobi_meta_delete_review(m);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
ret = mobi_meta_add_review(m, review);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get document copyright metadata
|
||||
|
||||
Returned string must be deallocated by caller
|
||||
|
||||
@param[in] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
char * mobi_meta_get_copyright(const MOBIData *m) {
|
||||
return mobi_meta_get_exthstring(m, EXTH_RIGHTS);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Add document copyright metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] copyright String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_add_copyright(MOBIData *m, const char *copyright) {
|
||||
if (copyright == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
size_t size = min(strlen(copyright), UINT32_MAX);
|
||||
return mobi_add_exthrecord(m, EXTH_RIGHTS, (uint32_t) size, copyright);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete all copyright metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_delete_copyright(MOBIData *m) {
|
||||
return mobi_delete_exthrecord_by_tag(m, EXTH_RIGHTS);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set document copyright metadata
|
||||
|
||||
Replaces all copyright metadata with new string
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] copyright String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_set_copyright(MOBIData *m, const char *copyright) {
|
||||
if (copyright == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
MOBI_RET ret = mobi_meta_delete_copyright(m);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
ret = mobi_meta_add_copyright(m, copyright);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get document ISBN metadata
|
||||
|
||||
Returned string must be deallocated by caller
|
||||
|
||||
@param[in] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
char * mobi_meta_get_isbn(const MOBIData *m) {
|
||||
return mobi_meta_get_exthstring(m, EXTH_ISBN);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Add document isbn metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] isbn String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_add_isbn(MOBIData *m, const char *isbn) {
|
||||
if (isbn == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
size_t size = min(strlen(isbn), UINT32_MAX);
|
||||
return mobi_add_exthrecord(m, EXTH_ISBN, (uint32_t) size, isbn);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete all isbn metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_delete_isbn(MOBIData *m) {
|
||||
return mobi_delete_exthrecord_by_tag(m, EXTH_ISBN);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set document isbn metadata
|
||||
|
||||
Replaces all isbn metadata with new string
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] isbn String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_set_isbn(MOBIData *m, const char *isbn) {
|
||||
if (isbn == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
MOBI_RET ret = mobi_meta_delete_isbn(m);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
ret = mobi_meta_add_isbn(m, isbn);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get document ASIN metadata
|
||||
|
||||
Returned string must be deallocated by caller
|
||||
|
||||
@param[in] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
char * mobi_meta_get_asin(const MOBIData *m) {
|
||||
return mobi_meta_get_exthstring(m, EXTH_ASIN);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Add document asin metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] asin String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_add_asin(MOBIData *m, const char *asin) {
|
||||
if (asin == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
size_t size = min(strlen(asin), UINT32_MAX);
|
||||
return mobi_add_exthrecord(m, EXTH_ASIN, (uint32_t) size, asin);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete all asin metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_delete_asin(MOBIData *m) {
|
||||
return mobi_delete_exthrecord_by_tag(m, EXTH_ASIN);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set document asin metadata
|
||||
|
||||
Replaces all asin metadata with new string
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] asin String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_set_asin(MOBIData *m, const char *asin) {
|
||||
if (asin == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
MOBI_RET ret = mobi_meta_delete_asin(m);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
ret = mobi_meta_add_asin(m, asin);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get document language code metadata
|
||||
|
||||
Locale strings are based on IANA language-subtag registry with some custom Mobipocket modifications.
|
||||
See mobi_locale array.
|
||||
|
||||
Returned string must be deallocated by caller
|
||||
|
||||
@param[in] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
char * mobi_meta_get_language(const MOBIData *m) {
|
||||
if (m == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
char *lang = mobi_meta_get_exthstring(m, EXTH_LANGUAGE);
|
||||
if(lang == NULL && m->mh && m->mh->locale && *m->mh->locale) {
|
||||
const char *locale_string = mobi_get_locale_string(*m->mh->locale);
|
||||
if (locale_string) {
|
||||
lang = strdup(locale_string);
|
||||
}
|
||||
}
|
||||
return lang;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Add document language code metadata
|
||||
|
||||
Locale strings are based on IANA language-subtag registry with some custom Mobipocket modifications.
|
||||
See mobi_locale array.
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] language String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_add_language(MOBIData *m, const char *language) {
|
||||
if (language == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
size_t size = min(strlen(language), UINT32_MAX);
|
||||
return mobi_add_exthrecord(m, EXTH_LANGUAGE, (uint32_t) size, language);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete all language code metadata
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_delete_language(MOBIData *m) {
|
||||
if(mobi_exists_mobiheader(m) && m->mh->locale) {
|
||||
*m->mh->locale = 0;
|
||||
}
|
||||
if(mobi_is_hybrid(m) && mobi_exists_mobiheader(m->next) && m->next->mh->locale) {
|
||||
*m->next->mh->locale = 0;
|
||||
}
|
||||
return mobi_delete_exthrecord_by_tag(m, EXTH_LANGUAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set document language code metadata
|
||||
|
||||
Replaces all language metadata with new string
|
||||
Locale strings are based on IANA language-subtag registry with some custom Mobipocket modifications.
|
||||
See mobi_locale array.
|
||||
|
||||
@param[in,out] m MOBIData structure with loaded data
|
||||
@param[in] language String value
|
||||
@return Pointer to null terminated string, NULL on failure
|
||||
*/
|
||||
MOBI_RET mobi_meta_set_language(MOBIData *m, const char *language) {
|
||||
if (language == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
MOBI_RET ret = mobi_meta_delete_language(m);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
ret = mobi_meta_add_language(m, language);
|
||||
}
|
||||
if(mobi_exists_mobiheader(m) && m->mh->locale) {
|
||||
*m->mh->locale = (uint32_t) mobi_get_locale_number(language);
|
||||
}
|
||||
if(mobi_is_hybrid(m) && mobi_exists_mobiheader(m->next) && m->next->mh->locale) {
|
||||
*m->next->mh->locale = (uint32_t) mobi_get_locale_number(language);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
17
app/src/main/cpp/libmobi/src/meta.h
vendored
Normal file
17
app/src/main/cpp/libmobi/src/meta.h
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/** @file meta.h
|
||||
*
|
||||
* Copyright (c) 2016 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef libmobi_meta_h
|
||||
#define libmobi_meta_h
|
||||
|
||||
#include "config.h"
|
||||
#include "mobi.h"
|
||||
|
||||
#endif /* libmobi_meta_h */
|
||||
5164
app/src/main/cpp/libmobi/src/miniz.c
vendored
Normal file
5164
app/src/main/cpp/libmobi/src/miniz.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
24
app/src/main/cpp/libmobi/src/miniz.h
vendored
Normal file
24
app/src/main/cpp/libmobi/src/miniz.h
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/** @file miniz.h
|
||||
* @brief header file for third party miniz.c, zlib replacement
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef libmobi_miniz_h
|
||||
#define libmobi_miniz_h
|
||||
|
||||
#define MINIZ_HEADER_FILE_ONLY
|
||||
#define MINIZ_NO_STDIO
|
||||
#define MINIZ_NO_ARCHIVE_APIS
|
||||
#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
|
||||
#define MINIZ_NO_TIME
|
||||
#define MINIZ_NO_ARCHIVE_WRITING_APIS
|
||||
|
||||
#include "miniz.c"
|
||||
|
||||
#endif
|
||||
623
app/src/main/cpp/libmobi/src/mobi.h
vendored
Normal file
623
app/src/main/cpp/libmobi/src/mobi.h
vendored
Normal file
|
|
@ -0,0 +1,623 @@
|
|||
/** @file mobi.h
|
||||
* @brief Libmobi main header file
|
||||
*
|
||||
* This file is installed with the library.
|
||||
* Include it in your project with "#include <mobi.h>".
|
||||
* See aryan of usage in mobitool.c, mobimeta.c, mobidrm.c
|
||||
*
|
||||
* Copyright (c) 2014-2022 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef libmobi_mobi_h
|
||||
#define libmobi_mobi_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
|
||||
/** @brief Visibility attributes for symbol export */
|
||||
#if defined (__CYGWIN__) || defined (__MINGW32__)
|
||||
#define MOBI_EXPORT __attribute__((visibility("default"))) __declspec(dllexport) extern
|
||||
#elif defined (_WIN32)
|
||||
#define MOBI_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define MOBI_EXPORT __attribute__((__visibility__("default")))
|
||||
#endif
|
||||
|
||||
/**
|
||||
@brief Usually 32-bit values in mobi records
|
||||
with value 0xffffffff mean "value not set"
|
||||
*/
|
||||
#define MOBI_NOTSET UINT32_MAX
|
||||
|
||||
#define MOBI_ENCRYPTION_NONE 0 /**< Text record encryption type: none */
|
||||
#define MOBI_ENCRYPTION_V1 1 /**< Text record encryption type: old mobipocket */
|
||||
#define MOBI_ENCRYPTION_V2 2 /**< Text record encryption type: mobipocket */
|
||||
|
||||
#define MOBI_COMPRESSION_NONE 1 /**< Text record compression type: none */
|
||||
#define MOBI_COMPRESSION_PALMDOC 2 /**< Text record compression type: palmdoc */
|
||||
#define MOBI_COMPRESSION_HUFFCDIC 17480 /**< Text record compression type: huff/cdic */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
/**
|
||||
@defgroup mobi_enums Exported enums
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
@brief Error codes returned by functions
|
||||
*/
|
||||
typedef enum {
|
||||
MOBI_SUCCESS = 0, /**< Generic success return value */
|
||||
MOBI_ERROR = 1, /**< Generic error return value */
|
||||
MOBI_PARAM_ERR = 2, /**< Wrong function parameter */
|
||||
MOBI_DATA_CORRUPT = 3, /**< Corrupted data */
|
||||
MOBI_FILE_NOT_FOUND = 4, /**< File not found */
|
||||
MOBI_FILE_ENCRYPTED = 5, /**< Unsupported encrypted data */
|
||||
MOBI_FILE_UNSUPPORTED = 6, /**< Unsupported document type */
|
||||
MOBI_MALLOC_FAILED = 7, /**< Memory allocation error */
|
||||
MOBI_INIT_FAILED = 8, /**< Initialization error */
|
||||
MOBI_BUFFER_END = 9, /**< Out of buffer error */
|
||||
MOBI_XML_ERR = 10, /**< XMLwriter error */
|
||||
MOBI_DRM_PIDINV = 11, /**< Invalid DRM PID */
|
||||
MOBI_DRM_KEYNOTFOUND = 12, /**< Key not found */
|
||||
MOBI_DRM_UNSUPPORTED = 13, /**< DRM support not included */
|
||||
MOBI_WRITE_FAILED = 14, /**< Writing to file failed */
|
||||
MOBI_DRM_EXPIRED = 15, /**< DRM expired */
|
||||
MOBI_DRM_RANDOM_ERR = 16 /**< DRM random bytes generation failed */
|
||||
} MOBI_RET;
|
||||
|
||||
/**
|
||||
@brief EXTH record types
|
||||
*/
|
||||
typedef enum {
|
||||
EXTH_NUMERIC = 0,
|
||||
EXTH_STRING = 1,
|
||||
EXTH_BINARY = 2
|
||||
} MOBIExthType;
|
||||
|
||||
/**
|
||||
@brief EXTH record tags
|
||||
*/
|
||||
typedef enum {
|
||||
EXTH_DRMSERVER = 1,
|
||||
EXTH_DRMCOMMERCE = 2,
|
||||
EXTH_DRMEBOOKBASE = 3,
|
||||
|
||||
EXTH_TITLE = 99, /**< <dc:title> */
|
||||
EXTH_AUTHOR = 100, /**< <dc:creator> */
|
||||
EXTH_PUBLISHER = 101, /**< <dc:publisher> */
|
||||
EXTH_IMPRINT = 102, /**< <imprint> */
|
||||
EXTH_DESCRIPTION = 103, /**< <dc:description> */
|
||||
EXTH_ISBN = 104, /**< <dc:identifier opf:scheme="ISBN"> */
|
||||
EXTH_SUBJECT = 105, /**< <dc:subject> */
|
||||
EXTH_PUBLISHINGDATE = 106, /**< <dc:date> */
|
||||
EXTH_REVIEW = 107, /**< <review> */
|
||||
EXTH_CONTRIBUTOR = 108, /**< <dc:contributor> */
|
||||
EXTH_RIGHTS = 109, /**< <dc:rights> */
|
||||
EXTH_SUBJECTCODE = 110, /**< <dc:subject BASICCode="subjectcode"> */
|
||||
EXTH_TYPE = 111, /**< <dc:type> */
|
||||
EXTH_SOURCE = 112, /**< <dc:source> */
|
||||
EXTH_ASIN = 113,
|
||||
EXTH_VERSION = 114,
|
||||
EXTH_SAMPLE = 115,
|
||||
EXTH_STARTREADING = 116, /**< Start reading */
|
||||
EXTH_ADULT = 117, /**< <adult> */
|
||||
EXTH_PRICE = 118, /**< <srp> */
|
||||
EXTH_CURRENCY = 119, /**< <srp currency="currency"> */
|
||||
EXTH_KF8BOUNDARY = 121,
|
||||
EXTH_FIXEDLAYOUT = 122, /**< <fixed-layout> */
|
||||
EXTH_BOOKTYPE = 123, /**< <book-type> */
|
||||
EXTH_ORIENTATIONLOCK = 124, /**< <orientation-lock> */
|
||||
EXTH_COUNTRESOURCES = 125,
|
||||
EXTH_ORIGRESOLUTION = 126, /**< <original-resolution> */
|
||||
EXTH_ZEROGUTTER = 127, /**< <zero-gutter> */
|
||||
EXTH_ZEROMARGIN = 128, /**< <zero-margin> */
|
||||
EXTH_KF8COVERURI = 129,
|
||||
EXTH_RESCOFFSET = 131,
|
||||
EXTH_REGIONMAGNI = 132, /**< <region-mag> */
|
||||
|
||||
EXTH_DICTNAME = 200, /**< <DictionaryVeryShortName> */
|
||||
EXTH_COVEROFFSET = 201, /**< <EmbeddedCover> */
|
||||
EXTH_THUMBOFFSET = 202,
|
||||
EXTH_HASFAKECOVER = 203,
|
||||
EXTH_CREATORSOFT = 204,
|
||||
EXTH_CREATORMAJOR = 205,
|
||||
EXTH_CREATORMINOR = 206,
|
||||
EXTH_CREATORBUILD = 207,
|
||||
EXTH_WATERMARK = 208,
|
||||
EXTH_TAMPERKEYS = 209,
|
||||
|
||||
EXTH_FONTSIGNATURE = 300,
|
||||
|
||||
EXTH_CLIPPINGLIMIT = 401,
|
||||
EXTH_PUBLISHERLIMIT = 402,
|
||||
EXTH_UNK403 = 403,
|
||||
EXTH_TTSDISABLE = 404,
|
||||
EXTH_READFORFREE = 405, // uint32_t, rental related, ReadForFree
|
||||
EXTH_RENTAL = 406, // uint64_t
|
||||
EXTH_UNK407 = 407,
|
||||
EXTH_UNK450 = 450,
|
||||
EXTH_UNK451 = 451,
|
||||
EXTH_UNK452 = 452,
|
||||
EXTH_UNK453 = 453,
|
||||
|
||||
EXTH_DOCTYPE = 501, /**< PDOC - Personal Doc; EBOK - ebook; EBSP - ebook sample; */
|
||||
EXTH_LASTUPDATE = 502,
|
||||
EXTH_UPDATEDTITLE = 503,
|
||||
EXTH_ASIN504 = 504,
|
||||
EXTH_TITLEFILEAS = 508,
|
||||
EXTH_CREATORFILEAS = 517,
|
||||
EXTH_PUBLISHERFILEAS = 522,
|
||||
EXTH_LANGUAGE = 524, /**< <dc:language> */
|
||||
EXTH_ALIGNMENT = 525, /**< <primary-writing-mode> */
|
||||
EXTH_CREATORSTRING = 526,
|
||||
EXTH_PAGEDIR = 527,
|
||||
EXTH_OVERRIDEFONTS = 528, /**< <override-kindle-fonts> */
|
||||
EXTH_SORCEDESC = 529,
|
||||
EXTH_DICTLANGIN = 531,
|
||||
EXTH_DICTLANGOUT = 532,
|
||||
EXTH_INPUTSOURCE = 534,
|
||||
EXTH_CREATORBUILDREV = 535,
|
||||
} MOBIExthTag;
|
||||
|
||||
/**
|
||||
@brief Types of files stored in database records
|
||||
*/
|
||||
typedef enum {
|
||||
T_UNKNOWN, /**< unknown */
|
||||
/* markup */
|
||||
T_HTML, /**< html */
|
||||
T_CSS, /**< css */
|
||||
T_SVG, /**< svg */
|
||||
T_OPF, /**< opf */
|
||||
T_NCX, /**< ncx */
|
||||
/* images */
|
||||
T_JPG, /**< jpg */
|
||||
T_GIF, /**< gif */
|
||||
T_PNG, /**< png */
|
||||
T_BMP, /**< bmp */
|
||||
/* fonts */
|
||||
T_OTF, /**< otf */
|
||||
T_TTF, /**< ttf */
|
||||
/* media */
|
||||
T_MP3, /**< mp3 */
|
||||
T_MPG, /**< mp3 */
|
||||
T_PDF, /**< pdf */
|
||||
/* generic types */
|
||||
T_FONT, /**< encoded font */
|
||||
T_AUDIO, /**< audio resource */
|
||||
T_VIDEO, /**< video resource */
|
||||
T_BREAK /**< end of file */
|
||||
} MOBIFiletype;
|
||||
|
||||
/**
|
||||
@brief Metadata of file types
|
||||
*/
|
||||
typedef struct {
|
||||
MOBIFiletype type; /**< MOBIFiletype type */
|
||||
char extension[5]; /**< file extension */
|
||||
char mime_type[30]; /**< mime-type */
|
||||
} MOBIFileMeta;
|
||||
|
||||
/**
|
||||
@brief Encoding types in MOBI header (offset 28)
|
||||
*/
|
||||
typedef enum {
|
||||
MOBI_CP1252 = 1252, /**< cp-1252 encoding */
|
||||
MOBI_UTF8 = 65001, /**< utf-8 encoding */
|
||||
MOBI_UTF16 = 65002, /**< utf-16 encoding */
|
||||
} MOBIEncoding;
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@defgroup raw_structs Exported structures for the raw, unparsed records metadata and data
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
@brief Header of palmdoc database file
|
||||
*/
|
||||
typedef struct {
|
||||
char name[33]; /**< 0: Database name, zero terminated, trimmed title (+author) */
|
||||
uint16_t attributes; /**< 32: Attributes bitfield, PALMDB_ATTRIBUTE_DEFAULT */
|
||||
uint16_t version; /**< 34: File version, PALMDB_VERSION_DEFAULT */
|
||||
uint32_t ctime; /**< 36: Creation time */
|
||||
uint32_t mtime; /**< 40: Modification time */
|
||||
uint32_t btime; /**< 44: Backup time */
|
||||
uint32_t mod_num; /**< 48: Modification number, PALMDB_MODNUM_DEFAULT */
|
||||
uint32_t appinfo_offset; /**< 52: Offset to application info (if present) or zero, PALMDB_APPINFO_DEFAULT */
|
||||
uint32_t sortinfo_offset; /**< 56: Offset to sort info (if present) or zero, PALMDB_SORTINFO_DEFAULT */
|
||||
char type[5]; /**< 60: Database type, zero terminated, PALMDB_TYPE_DEFAULT */
|
||||
char creator[5]; /**< 64: Creator type, zero terminated, PALMDB_CREATOR_DEFAULT */
|
||||
uint32_t uid; /**< 68: Used internally to identify record */
|
||||
uint32_t next_rec; /**< 72: Used only when database is loaded into memory, PALMDB_NEXTREC_DEFAULT */
|
||||
uint16_t rec_count; /**< 76: Number of records in the file */
|
||||
} MOBIPdbHeader;
|
||||
|
||||
/**
|
||||
@brief Metadata and data of a record. All records form a linked list.
|
||||
*/
|
||||
typedef struct MOBIPdbRecord {
|
||||
uint32_t offset; /**< Offset of the record data from the start of the database */
|
||||
size_t size; /**< Calculated size of the record data */
|
||||
uint8_t attributes; /**< Record attributes */
|
||||
uint32_t uid; /**< Record unique id, usually sequential even numbers */
|
||||
unsigned char *data; /**< Record data */
|
||||
struct MOBIPdbRecord *next; /**< Pointer to the next record or NULL */
|
||||
} MOBIPdbRecord;
|
||||
|
||||
/**
|
||||
@brief Metadata and data of a EXTH record. All records form a linked list.
|
||||
*/
|
||||
typedef struct MOBIExthHeader {
|
||||
uint32_t tag; /**< Record tag */
|
||||
uint32_t size; /**< Data size */
|
||||
void *data; /**< Record data */
|
||||
struct MOBIExthHeader *next; /**< Pointer to the next record or NULL */
|
||||
} MOBIExthHeader;
|
||||
|
||||
/**
|
||||
@brief EXTH tag metadata
|
||||
*/
|
||||
typedef struct {
|
||||
MOBIExthTag tag; /**< Record tag id */
|
||||
MOBIExthType type; /**< EXTH_NUMERIC, EXTH_STRING or EXTH_BINARY */
|
||||
char *name; /**< Tag name */
|
||||
} MOBIExthMeta;
|
||||
|
||||
/**
|
||||
@brief Header of the Record 0 meta-record
|
||||
*/
|
||||
typedef struct {
|
||||
/* PalmDOC header (extended), offset 0, length 16 */
|
||||
uint16_t compression_type; /**< 0; 1 == no compression, 2 = PalmDOC compression, 17480 = HUFF/CDIC compression */
|
||||
/* uint16_t unused; // 2; 0 */
|
||||
uint32_t text_length; /**< 4; uncompressed length of the entire text of the book */
|
||||
uint16_t text_record_count; /**< 8; number of PDB records used for the text of the book */
|
||||
uint16_t text_record_size; /**< 10; maximum size of each record containing text, always 4096 */
|
||||
uint16_t encryption_type; /**< 12; 0 == no encryption, 1 = Old Mobipocket Encryption, 2 = Mobipocket Encryption */
|
||||
uint16_t unknown1; /**< 14; usually 0 */
|
||||
} MOBIRecord0Header;
|
||||
|
||||
/**
|
||||
@brief MOBI header which follows Record 0 header
|
||||
|
||||
All MOBI header fields are pointers. Some fields are not present in the header, then the pointer is NULL.
|
||||
*/
|
||||
typedef struct {
|
||||
/* MOBI header, offset 16 */
|
||||
char mobi_magic[5]; /**< 16: M O B I { 77, 79, 66, 73 }, zero terminated */
|
||||
uint32_t *header_length; /**< 20: the length of the MOBI header, including the previous 4 bytes */
|
||||
uint32_t *mobi_type; /**< 24: mobipocket file type */
|
||||
MOBIEncoding *text_encoding; /**< 28: 1252 = CP1252, 65001 = UTF-8 */
|
||||
uint32_t *uid; /**< 32: unique id */
|
||||
uint32_t *version; /**< 36: mobipocket format */
|
||||
uint32_t *orth_index; /**< 40: section number of orthographic meta index. MOBI_NOTSET if index is not available. */
|
||||
uint32_t *infl_index; /**< 44: section number of inflection meta index. MOBI_NOTSET if index is not available. */
|
||||
uint32_t *names_index; /**< 48: section number of names meta index. MOBI_NOTSET if index is not available. */
|
||||
uint32_t *keys_index; /**< 52: section number of keys meta index. MOBI_NOTSET if index is not available. */
|
||||
uint32_t *extra0_index; /**< 56: section number of extra 0 meta index. MOBI_NOTSET if index is not available. */
|
||||
uint32_t *extra1_index; /**< 60: section number of extra 1 meta index. MOBI_NOTSET if index is not available. */
|
||||
uint32_t *extra2_index; /**< 64: section number of extra 2 meta index. MOBI_NOTSET if index is not available. */
|
||||
uint32_t *extra3_index; /**< 68: section number of extra 3 meta index. MOBI_NOTSET if index is not available. */
|
||||
uint32_t *extra4_index; /**< 72: section number of extra 4 meta index. MOBI_NOTSET if index is not available. */
|
||||
uint32_t *extra5_index; /**< 76: section number of extra 5 meta index. MOBI_NOTSET if index is not available. */
|
||||
uint32_t *non_text_index; /**< 80: first record number (starting with 0) that's not the book's text */
|
||||
uint32_t *full_name_offset; /**< 84: offset in record 0 (not from start of file) of the full name of the book */
|
||||
uint32_t *full_name_length; /**< 88: length of the full name */
|
||||
uint32_t *locale; /**< 92: first byte is main language: 09 = English, next byte is dialect, 08 = British, 04 = US */
|
||||
uint32_t *dict_input_lang; /**< 96: input language for a dictionary */
|
||||
uint32_t *dict_output_lang; /**< 100: output language for a dictionary */
|
||||
uint32_t *min_version; /**< 104: minimum mobipocket version support needed to read this file. */
|
||||
uint32_t *image_index; /**< 108: first record number (starting with 0) that contains an image (sequential) */
|
||||
uint32_t *huff_rec_index; /**< 112: first huffman compression record */
|
||||
uint32_t *huff_rec_count; /**< 116: huffman compression records count */
|
||||
uint32_t *datp_rec_index; /**< 120: section number of DATP record */
|
||||
uint32_t *datp_rec_count; /**< 124: DATP records count */
|
||||
uint32_t *exth_flags; /**< 128: bitfield. if bit 6 (0x40) is set, then there's an EXTH record */
|
||||
/* 32 unknown bytes, usually 0, related to encryption and unknown6 */
|
||||
/* unknown2 */
|
||||
/* unknown3 */
|
||||
/* unknown4 */
|
||||
/* unknown5 */
|
||||
uint32_t *unknown6; /**< 164: use MOBI_NOTSET , related to encryption*/
|
||||
uint32_t *drm_offset; /**< 168: offset to DRM key info in DRMed files. MOBI_NOTSET if no DRM */
|
||||
uint32_t *drm_count; /**< 172: number of entries in DRM info */
|
||||
uint32_t *drm_size; /**< 176: number of bytes in DRM info */
|
||||
uint32_t *drm_flags; /**< 180: some flags concerning DRM info, bit 0 set if password encryption */
|
||||
/* 8 unknown bytes 0? */
|
||||
/* unknown7 */
|
||||
/* unknown8 */
|
||||
uint16_t *first_text_index; /**< 192: section number of first text record */
|
||||
uint16_t *last_text_index; /**< 194: */
|
||||
uint32_t *fdst_index; /**< 192 (KF8) section number of FDST record */
|
||||
//uint32_t *unknown9; /**< 196: */
|
||||
uint32_t *fdst_section_count; /**< 196 (KF8) */
|
||||
uint32_t *fcis_index; /**< 200: section number of FCIS record */
|
||||
uint32_t *fcis_count; /**< 204: FCIS records count */
|
||||
uint32_t *flis_index; /**< 208: section number of FLIS record */
|
||||
uint32_t *flis_count; /**< 212: FLIS records count */
|
||||
uint32_t *unknown10; /**< 216: */
|
||||
uint32_t *unknown11; /**< 220: */
|
||||
uint32_t *srcs_index; /**< 224: section number of SRCS record */
|
||||
uint32_t *srcs_count; /**< 228: SRCS records count */
|
||||
uint32_t *unknown12; /**< 232: */
|
||||
uint32_t *unknown13; /**< 236: */
|
||||
/* uint16_t fill 0 */
|
||||
uint16_t *extra_flags; /**< 242: extra flags */
|
||||
uint32_t *ncx_index; /**< 244: section number of NCX record */
|
||||
uint32_t *unknown14; /**< 248: */
|
||||
uint32_t *fragment_index; /**< 248 (KF8) section number of fragments record */
|
||||
uint32_t *unknown15; /**< 252: */
|
||||
uint32_t *skeleton_index; /**< 252 (KF8) section number of SKEL record */
|
||||
uint32_t *datp_index; /**< 256: section number of DATP record */
|
||||
uint32_t *unknown16; /**< 260: */
|
||||
uint32_t *guide_index; /**< 260 (KF8) section number of guide record */
|
||||
uint32_t *unknown17; /**< 264: */
|
||||
uint32_t *unknown18; /**< 268: */
|
||||
uint32_t *unknown19; /**< 272: */
|
||||
uint32_t *unknown20; /**< 276: */
|
||||
char *full_name; /**< variable offset (full_name_offset): full name */
|
||||
} MOBIMobiHeader;
|
||||
|
||||
/**
|
||||
@brief Main structure holding all metadata and unparsed records data
|
||||
|
||||
In case of hybrid KF7/KF8 file there are two Records 0.
|
||||
In such case MOBIData is a circular linked list of two independent records, one structure per each Record 0 header.
|
||||
Records data (MOBIPdbRecord structure) is not duplicated in such case - each struct holds same pointers to all records data.
|
||||
*/
|
||||
typedef struct MOBIData {
|
||||
bool use_kf8; /**< Flag: if set to true (default), KF8 part of hybrid file is parsed, if false - KF7 part will be parsed */
|
||||
uint32_t kf8_boundary_offset; /**< Set to KF8 boundary rec number if present, otherwise: MOBI_NOTSET */
|
||||
unsigned char *drm_key; /**< @deprecated Will be removed in future versions */
|
||||
MOBIPdbHeader *ph; /**< Palmdoc database header structure or NULL if not loaded */
|
||||
MOBIRecord0Header *rh; /**< Record0 header structure or NULL if not loaded */
|
||||
MOBIMobiHeader *mh; /**< MOBI header structure or NULL if not loaded */
|
||||
MOBIExthHeader *eh; /**< Linked list of EXTH records or NULL if not loaded */
|
||||
MOBIPdbRecord *rec; /**< Linked list of palmdoc database records or NULL if not loaded */
|
||||
struct MOBIData *next; /**< Pointer to the other part of hybrid file or NULL if not a hybrid file */
|
||||
void *internals; /**< Used internally*/
|
||||
} MOBIData;
|
||||
|
||||
/** @} */ // end of raw_structs group
|
||||
|
||||
/**
|
||||
@defgroup parsed_structs Exported structures for the parsed records metadata and data
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
@brief Parsed FDST record
|
||||
|
||||
FDST record contains offsets of main sections in RAWML - raw text data.
|
||||
The sections are usually html part, css parts, svg part.
|
||||
*/
|
||||
typedef struct {
|
||||
size_t fdst_section_count; /**< Number of main sections */
|
||||
uint32_t *fdst_section_starts; /**< Array of section start offsets */
|
||||
uint32_t *fdst_section_ends; /**< Array of section end offsets */
|
||||
} MOBIFdst;
|
||||
|
||||
/**
|
||||
@brief Parsed tag for an index entry
|
||||
*/
|
||||
typedef struct {
|
||||
size_t tagid; /**< Tag id */
|
||||
size_t tagvalues_count; /**< Number of tag values */
|
||||
uint32_t *tagvalues; /**< Array of tag values */
|
||||
} MOBIIndexTag;
|
||||
|
||||
/**
|
||||
@brief Parsed INDX index entry
|
||||
*/
|
||||
typedef struct {
|
||||
char *label; /**< Entry string, zero terminated */
|
||||
size_t tags_count; /**< Number of tags */
|
||||
MOBIIndexTag *tags; /**< Array of tags */
|
||||
} MOBIIndexEntry;
|
||||
|
||||
/**
|
||||
@brief Parsed INDX record
|
||||
*/
|
||||
typedef struct {
|
||||
size_t type; /**< Index type: 0 - normal, 2 - inflection */
|
||||
size_t entries_count; /**< Index entries count */
|
||||
MOBIEncoding encoding; /**< Index encoding */
|
||||
size_t total_entries_count; /**< Total index entries count */
|
||||
size_t ordt_offset; /**< ORDT offset */
|
||||
size_t ligt_offset; /**< LIGT offset */
|
||||
size_t ligt_entries_count; /**< LIGT index entries count */
|
||||
size_t cncx_records_count; /**< Number of compiled NCX records */
|
||||
MOBIPdbRecord *cncx_record; /**< Link to CNCX record */
|
||||
MOBIIndexEntry *entries; /**< Index entries array */
|
||||
char *orth_index_name; /**< Orth index name */
|
||||
} MOBIIndx;
|
||||
|
||||
/**
|
||||
@brief Reconstructed source file.
|
||||
|
||||
All file parts are organized in a linked list.
|
||||
*/
|
||||
typedef struct MOBIPart {
|
||||
size_t uid; /**< Unique id */
|
||||
MOBIFiletype type; /**< File type */
|
||||
size_t size; /**< File size */
|
||||
unsigned char *data; /**< File data */
|
||||
struct MOBIPart *next; /**< Pointer to next part or NULL */
|
||||
} MOBIPart;
|
||||
|
||||
/**
|
||||
@brief Main structure containing reconstructed source parts and indices
|
||||
*/
|
||||
typedef struct {
|
||||
size_t version; /**< Version of Mobipocket document */
|
||||
MOBIFdst *fdst; /**< Parsed FDST record or NULL if not present */
|
||||
MOBIIndx *skel; /**< Parsed skeleton index or NULL if not present */
|
||||
MOBIIndx *frag; /**< Parsed fragments index or NULL if not present */
|
||||
MOBIIndx *guide; /**< Parsed guide index or NULL if not present */
|
||||
MOBIIndx *ncx; /**< Parsed NCX index or NULL if not present */
|
||||
MOBIIndx *orth; /**< Parsed orth index or NULL if not present */
|
||||
MOBIIndx *infl; /**< Parsed infl index or NULL if not present */
|
||||
MOBIPart *flow; /**< Linked list of reconstructed main flow parts or NULL if not present */
|
||||
MOBIPart *markup; /**< Linked list of reconstructed markup files or NULL if not present */
|
||||
MOBIPart *resources; /**< Linked list of reconstructed resources files or NULL if not present */
|
||||
} MOBIRawml;
|
||||
|
||||
/** @} */ // end of parsed_structs group
|
||||
|
||||
/**
|
||||
@defgroup mobi_export Functions exported by the library
|
||||
@{
|
||||
*/
|
||||
MOBI_EXPORT const char * mobi_version(void);
|
||||
MOBI_EXPORT MOBI_RET mobi_load_file(MOBIData *m, FILE *file);
|
||||
MOBI_EXPORT MOBI_RET mobi_load_filename(MOBIData *m, const char *path);
|
||||
|
||||
MOBI_EXPORT MOBIData * mobi_init(void);
|
||||
MOBI_EXPORT void mobi_free(MOBIData *m);
|
||||
|
||||
MOBI_EXPORT MOBI_RET mobi_parse_kf7(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_parse_kf8(MOBIData *m);
|
||||
|
||||
MOBI_EXPORT MOBI_RET mobi_parse_rawml(MOBIRawml *rawml, const MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_parse_rawml_opt(MOBIRawml *rawml, const MOBIData *m, bool parse_toc, bool parse_dict, bool reconstruct);
|
||||
|
||||
MOBI_EXPORT MOBI_RET mobi_get_rawml(const MOBIData *m, char *text, size_t *len);
|
||||
MOBI_EXPORT MOBI_RET mobi_dump_rawml(const MOBIData *m, FILE *file);
|
||||
MOBI_EXPORT MOBI_RET mobi_decode_font_resource(unsigned char **decoded_font, size_t *decoded_size, MOBIPart *part);
|
||||
MOBI_EXPORT MOBI_RET mobi_decode_audio_resource(unsigned char **decoded_resource, size_t *decoded_size, MOBIPart *part);
|
||||
MOBI_EXPORT MOBI_RET mobi_decode_video_resource(unsigned char **decoded_resource, size_t *decoded_size, MOBIPart *part);
|
||||
MOBI_EXPORT MOBI_RET mobi_get_embedded_source(unsigned char **data, size_t *size, const MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_get_embedded_log(unsigned char **data, size_t *size, const MOBIData *m);
|
||||
|
||||
MOBI_EXPORT MOBIPdbRecord * mobi_get_record_by_uid(const MOBIData *m, const size_t uid);
|
||||
MOBI_EXPORT MOBIPdbRecord * mobi_get_record_by_seqnumber(const MOBIData *m, const size_t uid);
|
||||
MOBI_EXPORT MOBIPart * mobi_get_flow_by_uid(const MOBIRawml *rawml, const size_t uid);
|
||||
MOBI_EXPORT MOBIPart * mobi_get_flow_by_fid(const MOBIRawml *rawml, const char *fid);
|
||||
MOBI_EXPORT MOBIPart * mobi_get_resource_by_uid(const MOBIRawml *rawml, const size_t uid);
|
||||
MOBI_EXPORT MOBIPart * mobi_get_resource_by_fid(const MOBIRawml *rawml, const char *fid);
|
||||
MOBI_EXPORT MOBIPart * mobi_get_part_by_uid(const MOBIRawml *rawml, const size_t uid);
|
||||
MOBI_EXPORT MOBI_RET mobi_get_fullname(const MOBIData *m, char *fullname, const size_t len);
|
||||
MOBI_EXPORT size_t mobi_get_first_resource_record(const MOBIData *m);
|
||||
MOBI_EXPORT size_t mobi_get_text_maxsize(const MOBIData *m);
|
||||
MOBI_EXPORT uint16_t mobi_get_textrecord_maxsize(const MOBIData *m);
|
||||
MOBI_EXPORT size_t mobi_get_kf8offset(const MOBIData *m);
|
||||
MOBI_EXPORT size_t mobi_get_kf8boundary_seqnumber(const MOBIData *m);
|
||||
MOBI_EXPORT size_t mobi_get_record_extrasize(const MOBIPdbRecord *record, const uint16_t flags);
|
||||
MOBI_EXPORT size_t mobi_get_record_mb_extrasize(const MOBIPdbRecord *record, const uint16_t flags);
|
||||
MOBI_EXPORT size_t mobi_get_fileversion(const MOBIData *m);
|
||||
MOBI_EXPORT size_t mobi_get_fdst_record_number(const MOBIData *m);
|
||||
MOBI_EXPORT MOBIExthHeader * mobi_get_exthrecord_by_tag(const MOBIData *m, const MOBIExthTag tag);
|
||||
MOBI_EXPORT MOBIExthHeader * mobi_next_exthrecord_by_tag(const MOBIData *m, const MOBIExthTag tag, MOBIExthHeader **start);
|
||||
MOBI_EXPORT MOBI_RET mobi_delete_exthrecord_by_tag(MOBIData *m, const MOBIExthTag tag);
|
||||
MOBI_EXPORT MOBI_RET mobi_add_exthrecord(MOBIData *m, const MOBIExthTag tag, const uint32_t size, const void *value);
|
||||
MOBI_EXPORT MOBIExthMeta mobi_get_exthtagmeta_by_tag(const MOBIExthTag tag);
|
||||
MOBI_EXPORT MOBIFileMeta mobi_get_filemeta_by_type(const MOBIFiletype type);
|
||||
MOBI_EXPORT uint32_t mobi_decode_exthvalue(const unsigned char *data, const size_t size);
|
||||
MOBI_EXPORT char * mobi_decode_exthstring(const MOBIData *m, const unsigned char *data, const size_t size);
|
||||
MOBI_EXPORT struct tm * mobi_pdbtime_to_time(const long pdb_time);
|
||||
MOBI_EXPORT const char * mobi_get_locale_string(const uint32_t locale);
|
||||
MOBI_EXPORT size_t mobi_get_locale_number(const char *locale_string);
|
||||
MOBI_EXPORT uint32_t mobi_get_orth_entry_offset(const MOBIIndexEntry *entry);
|
||||
MOBI_EXPORT uint32_t mobi_get_orth_entry_length(const MOBIIndexEntry *entry);
|
||||
MOBI_EXPORT MOBI_RET mobi_remove_hybrid_part(MOBIData *m, const bool remove_kf8);
|
||||
|
||||
MOBI_EXPORT bool mobi_exists_mobiheader(const MOBIData *m);
|
||||
MOBI_EXPORT bool mobi_exists_fdst(const MOBIData *m);
|
||||
MOBI_EXPORT bool mobi_exists_skel_indx(const MOBIData *m);
|
||||
MOBI_EXPORT bool mobi_exists_frag_indx(const MOBIData *m);
|
||||
MOBI_EXPORT bool mobi_exists_guide_indx(const MOBIData *m);
|
||||
MOBI_EXPORT bool mobi_exists_ncx(const MOBIData *m);
|
||||
MOBI_EXPORT bool mobi_exists_orth(const MOBIData *m);
|
||||
MOBI_EXPORT bool mobi_exists_infl(const MOBIData *m);
|
||||
MOBI_EXPORT bool mobi_is_hybrid(const MOBIData *m);
|
||||
MOBI_EXPORT bool mobi_is_encrypted(const MOBIData *m);
|
||||
MOBI_EXPORT bool mobi_is_mobipocket(const MOBIData *m);
|
||||
MOBI_EXPORT bool mobi_is_dictionary(const MOBIData *m);
|
||||
MOBI_EXPORT bool mobi_is_kf8(const MOBIData *m);
|
||||
MOBI_EXPORT bool mobi_is_replica(const MOBIData *m);
|
||||
MOBI_EXPORT bool mobi_is_rawml_kf8(const MOBIRawml *rawml);
|
||||
MOBI_EXPORT MOBIRawml * mobi_init_rawml(const MOBIData *m);
|
||||
MOBI_EXPORT void mobi_free_rawml(MOBIRawml *rawml);
|
||||
|
||||
MOBI_EXPORT char * mobi_meta_get_title(const MOBIData *m);
|
||||
MOBI_EXPORT char * mobi_meta_get_author(const MOBIData *m);
|
||||
MOBI_EXPORT char * mobi_meta_get_publisher(const MOBIData *m);
|
||||
MOBI_EXPORT char * mobi_meta_get_imprint(const MOBIData *m);
|
||||
MOBI_EXPORT char * mobi_meta_get_description(const MOBIData *m);
|
||||
MOBI_EXPORT char * mobi_meta_get_isbn(const MOBIData *m);
|
||||
MOBI_EXPORT char * mobi_meta_get_subject(const MOBIData *m);
|
||||
MOBI_EXPORT char * mobi_meta_get_publishdate(const MOBIData *m);
|
||||
MOBI_EXPORT char * mobi_meta_get_review(const MOBIData *m);
|
||||
MOBI_EXPORT char * mobi_meta_get_contributor(const MOBIData *m);
|
||||
MOBI_EXPORT char * mobi_meta_get_copyright(const MOBIData *m);
|
||||
MOBI_EXPORT char * mobi_meta_get_asin(const MOBIData *m);
|
||||
MOBI_EXPORT char * mobi_meta_get_language(const MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_set_title(MOBIData *m, const char *title);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_add_title(MOBIData *m, const char *title);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_delete_title(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_set_author(MOBIData *m, const char *author);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_add_author(MOBIData *m, const char *author);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_delete_author(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_set_publisher(MOBIData *m, const char *publisher);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_add_publisher(MOBIData *m, const char *publisher);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_delete_publisher(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_set_imprint(MOBIData *m, const char *imprint);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_add_imprint(MOBIData *m, const char *imprint);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_delete_imprint(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_set_description(MOBIData *m, const char *description);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_add_description(MOBIData *m, const char *description);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_delete_description(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_set_isbn(MOBIData *m, const char *isbn);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_add_isbn(MOBIData *m, const char *isbn);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_delete_isbn(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_set_subject(MOBIData *m, const char *subject);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_add_subject(MOBIData *m, const char *subject);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_delete_subject(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_set_publishdate(MOBIData *m, const char *publishdate);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_add_publishdate(MOBIData *m, const char *publishdate);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_delete_publishdate(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_set_review(MOBIData *m, const char *review);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_add_review(MOBIData *m, const char *review);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_delete_review(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_set_contributor(MOBIData *m, const char *contributor);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_add_contributor(MOBIData *m, const char *contributor);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_delete_contributor(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_set_copyright(MOBIData *m, const char *copyright);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_add_copyright(MOBIData *m, const char *copyright);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_delete_copyright(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_set_asin(MOBIData *m, const char *asin);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_add_asin(MOBIData *m, const char *asin);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_delete_asin(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_set_language(MOBIData *m, const char *language);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_add_language(MOBIData *m, const char *language);
|
||||
MOBI_EXPORT MOBI_RET mobi_meta_delete_language(MOBIData *m);
|
||||
|
||||
MOBI_EXPORT MOBI_RET mobi_drm_setkey(MOBIData *m, const char *pid);
|
||||
MOBI_EXPORT MOBI_RET mobi_drm_setkey_serial(MOBIData *m, const char *serial);
|
||||
MOBI_EXPORT MOBI_RET mobi_drm_addvoucher(MOBIData *m, const char *serial, const time_t valid_from, const time_t valid_to,
|
||||
const MOBIExthTag *tamperkeys, const size_t tamperkeys_count);
|
||||
MOBI_EXPORT MOBI_RET mobi_drm_delkey(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_drm_decrypt(MOBIData *m);
|
||||
MOBI_EXPORT MOBI_RET mobi_drm_encrypt(MOBIData *m);
|
||||
|
||||
MOBI_EXPORT MOBI_RET mobi_write_file(FILE *file, MOBIData *m);
|
||||
/** @} */ // end of mobi_export group
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
2059
app/src/main/cpp/libmobi/src/opf.c
vendored
Normal file
2059
app/src/main/cpp/libmobi/src/opf.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
164
app/src/main/cpp/libmobi/src/opf.h
vendored
Normal file
164
app/src/main/cpp/libmobi/src/opf.h
vendored
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
/** @file opf.h
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef libmobi_opf_h
|
||||
#define libmobi_opf_h
|
||||
|
||||
#include "config.h"
|
||||
#include "mobi.h"
|
||||
|
||||
/** @brief Maximum number of opf meta tags */
|
||||
#define OPF_META_MAX_TAGS 256
|
||||
|
||||
/**
|
||||
@defgroup mobi_opf OPF handling structures
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @brief OPF <dc:identifier/> element structure
|
||||
|
||||
At least one identifier must have an id specified,
|
||||
so it can be referenced from the package unique-identifier attribute.
|
||||
*/
|
||||
typedef struct {
|
||||
char *value; /**< element value */
|
||||
char *id; /**< id attribute */
|
||||
char *scheme; /**< opf:scheme (optional) */
|
||||
} OPFidentifier;
|
||||
|
||||
/** @brief OPF <dc:creator/> element structure
|
||||
|
||||
Also applies to <dc:contributor/> element
|
||||
*/
|
||||
typedef struct {
|
||||
char *value; /**< element value */
|
||||
char *file_as; /**< opf:file-as attribute (optional) */
|
||||
char *role; /**< opf:role attribute (optional) */
|
||||
} OPFcreator;
|
||||
|
||||
/** @brief OPF <dc:subject/> element structure */
|
||||
typedef struct {
|
||||
char *value; /**< element value */
|
||||
char *basic_code; /**< BASICCode attribute (optional, non-standard) */
|
||||
} OPFsubject;
|
||||
|
||||
/** @brief OPF <dc:date/> element structure
|
||||
|
||||
Format: YYYY[-MM[-DD]]
|
||||
*/
|
||||
typedef struct {
|
||||
char *value; /**< element value */
|
||||
char *event; /**< opf:event attribute (optional) */
|
||||
} OPFdate;
|
||||
|
||||
/** @brief OPF <dc-metadata/> element structure */
|
||||
typedef struct {
|
||||
OPFcreator **contributor; /**< <dc:contributor/> element (optional) */
|
||||
OPFcreator **creator; /**< <dc:creator/> element (optional) */
|
||||
OPFidentifier **identifier; /**< <dc:identifier/> element (required) */
|
||||
OPFsubject **subject; /**< <dc:subject/> element (optional) */
|
||||
OPFdate **date; /**< <dc:date/> element (optional) */
|
||||
char **description; /**< <dc:description/> element (optional) */
|
||||
char **language; /**< <dc:language/> element (required) */
|
||||
char **publisher; /**< <dc:publisher/> element (optional) */
|
||||
char **rights; /**< <dc:rights/> element (optional) */
|
||||
char **source; /**< <dc:source/> element (optional) */
|
||||
char **title; /**< <dc:title/> element (required) */
|
||||
char **type; /**< <dc:type/> element (optional) */
|
||||
} OPFdcmeta;
|
||||
|
||||
/** @brief OPF <srp/> element structure */
|
||||
typedef struct {
|
||||
char *value; /**< element value */
|
||||
char *currency; /**< currency attribute */
|
||||
} OPFsrp;
|
||||
|
||||
/** @brief OPF <x-metadata/> element structure */
|
||||
typedef struct {
|
||||
OPFsrp **srp; /**< <srp/> element */
|
||||
char **adult; /**< <adult/> element */
|
||||
char **default_lookup_index; /**< <DefaultLookupIndex/> element */
|
||||
char **dict_short_name; /**< <DictionaryVeryShortName/> element */
|
||||
char **dictionary_in_lang; /**< <DictionaryInLanguage/> element */
|
||||
char **dictionary_out_lang; /**< <DictionaryOutLanguage/> element */
|
||||
char **embedded_cover; /**< <EmbeddedCover/> element */
|
||||
char **imprint; /**< <imprint/> element */
|
||||
char **review; /**< <review/> element */
|
||||
} OPFxmeta;
|
||||
|
||||
/** @brief OPF <meta/> element structure */
|
||||
typedef struct {
|
||||
char *name; /**< name attribute (required) */
|
||||
char *content; /**< content attribute (required) */
|
||||
} OPFmeta;
|
||||
|
||||
/** @brief OPF <metadata/> element structure */
|
||||
typedef struct {
|
||||
OPFmeta **meta; /**< <meta/> element (optional) */
|
||||
OPFdcmeta *dc_meta; /**< <dc-metadata/> element */
|
||||
OPFxmeta *x_meta; /**< <x-metadata/> element */
|
||||
} OPFmetadata;
|
||||
|
||||
/** @brief OPF <item/> element structure */
|
||||
typedef struct {
|
||||
char *id; /**< id attribute (required) */
|
||||
char *href; /**< href attribute (required) */
|
||||
char *media_type; /**< media-type attribute (required) */
|
||||
} OPFitem;
|
||||
|
||||
/** @brief OPF <manifest/> element structure */
|
||||
typedef struct {
|
||||
OPFitem **item; /**< <item/> element */
|
||||
} OPFmanifest;
|
||||
|
||||
/** @brief OPF <spine/> element structure */
|
||||
typedef struct {
|
||||
char *toc; /**< toc attribute (required) */
|
||||
char **itemref; /**< <itemref idref="xxx"/> element */
|
||||
} OPFspine;
|
||||
|
||||
/** @brief OPF <reference/> tag structure */
|
||||
typedef struct {
|
||||
char *type; /**< type attribute (required) */
|
||||
char *title; /**< title attribute */
|
||||
char *href; /**< href attribute (required) */
|
||||
} OPFreference;
|
||||
|
||||
/** @brief OPF <guide/> element structure */
|
||||
typedef struct {
|
||||
OPFreference **reference; /**< <reference/> element tag */
|
||||
} OPFguide;
|
||||
|
||||
/** @brief OPF <package/> element structure */
|
||||
typedef struct {
|
||||
//char *uid; /**< <package unique-identifier="uid"/> */
|
||||
OPFmetadata *metadata; /**< <metadata/> (required) */
|
||||
OPFmanifest *manifest; /**< <manifest/> (required) */
|
||||
OPFspine *spine; /**< <spine/> (required) */
|
||||
OPFguide *guide; /**< <guide/> (optional) */
|
||||
} OPF;
|
||||
|
||||
/** @brief NCX index entry structure */
|
||||
typedef struct {
|
||||
size_t id; /**< Sequential id */
|
||||
char *text; /**< Entry text content */
|
||||
char *target; /**< Entry target reference */
|
||||
size_t level; /**< Entry level */
|
||||
size_t parent; /**< Entry parent */
|
||||
size_t first_child; /**< First child id */
|
||||
size_t last_child; /**< Last child id */
|
||||
} NCX;
|
||||
/** @} */
|
||||
|
||||
|
||||
MOBI_RET mobi_build_opf(MOBIRawml *rawml, const MOBIData *m);
|
||||
MOBI_RET mobi_build_ncx(MOBIRawml *rawml, const OPF *opf);
|
||||
|
||||
#endif
|
||||
2199
app/src/main/cpp/libmobi/src/parse_rawml.c
vendored
Normal file
2199
app/src/main/cpp/libmobi/src/parse_rawml.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
42
app/src/main/cpp/libmobi/src/parse_rawml.h
vendored
Normal file
42
app/src/main/cpp/libmobi/src/parse_rawml.h
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/** @file parse_rawml.h
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef mobi_parse_rawml_h
|
||||
#define mobi_parse_rawml_h
|
||||
|
||||
#include "config.h"
|
||||
#include "mobi.h"
|
||||
|
||||
#define MOBI_ATTRNAME_MAXSIZE 150 /**< Maximum length of tag attribute name, like "href" */
|
||||
#define MOBI_ATTRVALUE_MAXSIZE 150 /**< Maximum length of tag attribute value */
|
||||
|
||||
/**
|
||||
@brief Result data returned by mobi_search_links_kf7() and mobi_search_links_kf8()
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char *start; /**< Beginning data to be replaced */
|
||||
unsigned char *end; /**< End of data to be replaced */
|
||||
char value[MOBI_ATTRVALUE_MAXSIZE + 1]; /**< Attribute value */
|
||||
bool is_url; /**< True if value is part of css url attribute */
|
||||
} MOBIResult;
|
||||
|
||||
/**
|
||||
@brief HTML attribute type
|
||||
*/
|
||||
typedef enum {
|
||||
ATTR_ID = 0, /**< Attribute 'id' */
|
||||
ATTR_NAME /**< Attribute 'name' */
|
||||
} MOBIAttrType;
|
||||
|
||||
|
||||
MOBI_RET mobi_get_id_by_posoff(uint32_t *file_number, char *id, const MOBIRawml *rawml, const size_t pos_fid, const size_t pos_off, MOBIAttrType *pref_attr);
|
||||
MOBI_RET mobi_find_attrvalue(MOBIResult *result, const unsigned char *data_start, const unsigned char *data_end, const MOBIFiletype type, const char *needle);
|
||||
|
||||
#endif
|
||||
375
app/src/main/cpp/libmobi/src/randombytes.c
vendored
Normal file
375
app/src/main/cpp/libmobi/src/randombytes.c
vendored
Normal file
|
|
@ -0,0 +1,375 @@
|
|||
/** @file randombytes.c
|
||||
* @brief Portable function for generating random data
|
||||
*
|
||||
* Copyright (c) 2022 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is based on libsodium's randombytes_buf function
|
||||
* We just extract the single function we need from libsodium and adjust it for our use.
|
||||
* Most of the code originates from:
|
||||
* https://github.com/jedisct1/libsodium/blob/d250858c7445b7de94e912b529b81defe20d4aaa/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c
|
||||
* Original code uses following license:
|
||||
*
|
||||
* ISC License
|
||||
*
|
||||
* Copyright (c) 2013-2022
|
||||
* Frank Denis <j at pureftpd dot org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#ifndef _WIN32
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "randombytes.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifndef _WIN32
|
||||
# include <sys/stat.h>
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
# define _LINUX_SOURCE
|
||||
#endif
|
||||
#ifdef HAVE_SYS_RANDOM_H
|
||||
# include <sys/random.h>
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
# define BLOCK_ON_DEV_RANDOM
|
||||
# include <poll.h>
|
||||
# ifdef HAVE_GETRANDOM
|
||||
# define HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
# else
|
||||
# include <sys/syscall.h>
|
||||
# if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
# define getrandom(B, S, F) syscall(SYS_getrandom, (B), (int) (S), (F))
|
||||
# define HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
# endif
|
||||
# endif
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
# include <sys/param.h>
|
||||
# if (defined(__FreeBSD_version) && __FreeBSD_version >= 1200000) || \
|
||||
(defined(__DragonFly_version) && __DragonFly_version >= 500700)
|
||||
# define HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
typedef struct {
|
||||
int random_data_source_fd;
|
||||
int getrandom_available;
|
||||
} MOBIRandom;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
# include <windows.h>
|
||||
# define RtlGenRandom SystemFunction036
|
||||
# if defined(__cplusplus)
|
||||
extern "C"
|
||||
# endif
|
||||
BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
|
||||
# ifdef _MSC_VER
|
||||
# pragma comment(lib, "advapi32.lib")
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__CloudABI__) || defined(__wasi__)
|
||||
# define HAVE_SAFE_ARC4RANDOM
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SAFE_ARC4RANDOM
|
||||
|
||||
/**
|
||||
@brief Read a buffer of random bytes using arc4random_buf call
|
||||
|
||||
@param[in,out] handle Handle
|
||||
@param[in,out] buf Buffer
|
||||
@param[in] size Buffer size
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_randombytes_sysrandom_buf(MOBIRandom *handle, void *buf, const size_t size) {
|
||||
UNUSED(handle);
|
||||
arc4random_buf(buf, size);
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
#else /* HAVE_SAFE_ARC4RANDOM */
|
||||
|
||||
# ifndef _WIN32
|
||||
/**
|
||||
@brief Read a buffer of random bytes from file descriptoir
|
||||
|
||||
@param[in] fd File descriptior
|
||||
@param[in,out] buf_ Buffer
|
||||
@param[in] size Buffer size
|
||||
@return Number of bytes read
|
||||
*/
|
||||
static ssize_t mobi_safe_read(const int fd, void *buf_, size_t size) {
|
||||
unsigned char *buf = (unsigned char *) buf_;
|
||||
ssize_t readnb;
|
||||
|
||||
do {
|
||||
while ((readnb = read(fd, buf, size)) < (ssize_t) 0 && (errno == EINTR || errno == EAGAIN));
|
||||
if (readnb < (ssize_t) 0) {
|
||||
return readnb;
|
||||
}
|
||||
if (readnb == (ssize_t) 0) {
|
||||
break;
|
||||
}
|
||||
size -= (size_t) readnb;
|
||||
buf += readnb;
|
||||
} while (size > (ssize_t) 0);
|
||||
|
||||
return (ssize_t) (buf - (unsigned char *) buf_);
|
||||
}
|
||||
|
||||
# ifdef BLOCK_ON_DEV_RANDOM
|
||||
/**
|
||||
@brief Block on /dev/random until enough entropy is available
|
||||
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_randombytes_block_on_dev_random(void) {
|
||||
int fd = open("/dev/random", O_RDONLY);
|
||||
if (fd == -1) {
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
struct pollfd pfd;
|
||||
pfd.fd = fd;
|
||||
pfd.events = POLLIN;
|
||||
pfd.revents = 0;
|
||||
int pret;
|
||||
do {
|
||||
pret = poll(&pfd, 1, -1);
|
||||
} while (pret < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
if (pret != 1) {
|
||||
(void) close(fd);
|
||||
errno = EIO;
|
||||
return MOBI_DRM_RANDOM_ERR;
|
||||
}
|
||||
if (close(fd) != 0) {
|
||||
return MOBI_DRM_RANDOM_ERR;
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
# endif /* BLOCK_ON_DEV_RANDOM */
|
||||
|
||||
/**
|
||||
@brief Open random device, wait for enough entropy if supported
|
||||
|
||||
@return Random device file descriptor
|
||||
*/
|
||||
static int mobi_randombytes_sysrandom_random_dev_open(void) {
|
||||
|
||||
# ifdef BLOCK_ON_DEV_RANDOM
|
||||
if (mobi_randombytes_block_on_dev_random() != MOBI_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
# endif
|
||||
|
||||
static const char *devices[] = {
|
||||
"/dev/urandom",
|
||||
"/dev/random", NULL
|
||||
};
|
||||
const char **device = devices;
|
||||
|
||||
do {
|
||||
int fd = open(*device, O_RDONLY);
|
||||
if (fd != -1) {
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == 0 &&
|
||||
# ifdef S_ISNAM
|
||||
(S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))
|
||||
# else
|
||||
S_ISCHR(st.st_mode)
|
||||
# endif
|
||||
) {
|
||||
# if defined(F_SETFD) && defined(FD_CLOEXEC)
|
||||
(void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
|
||||
# endif
|
||||
return fd;
|
||||
}
|
||||
(void) close(fd);
|
||||
} else if (errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
device++;
|
||||
} while (*device != NULL);
|
||||
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
/**
|
||||
@brief Read a buffer of random bytes using getrandom system call
|
||||
In libmobi we only need small KEYSIZE buffer, so we don't have to handle buffers over 256 bytes and read chunks
|
||||
|
||||
@param[in,out] buf Buffer
|
||||
@param[in] size Buffer size (up to 256 bytes)
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_randombytes_linux_getrandom(void *buf, const size_t size) {
|
||||
|
||||
if (size > 256U) {
|
||||
debug_print("This function can only handle buffer size up to 256 bytes (%zu requested)\n", size);
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
int readnb;
|
||||
do {
|
||||
readnb = getrandom(buf, size, 0);
|
||||
} while (readnb < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
|
||||
if (readnb != (int) size) {
|
||||
debug_print("Getrandom failed (%s)\n", strerror(errno));
|
||||
return MOBI_DRM_RANDOM_ERR;
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
# endif /* HAVE_LINUX_COMPATIBLE_GETRANDOM */
|
||||
|
||||
/**
|
||||
@brief Initialize random data source
|
||||
|
||||
@param[in,out] handle Handle
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_randombytes_sysrandom_init(MOBIRandom *handle) {
|
||||
# define NEEDS_INIT
|
||||
const int errno_save = errno;
|
||||
|
||||
# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
{
|
||||
unsigned char fodder[16];
|
||||
|
||||
if (mobi_randombytes_linux_getrandom(fodder, sizeof fodder) == MOBI_SUCCESS) {
|
||||
handle->getrandom_available = 1;
|
||||
errno = errno_save;
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
handle->getrandom_available = 0;
|
||||
}
|
||||
# endif
|
||||
|
||||
if ((handle->random_data_source_fd = mobi_randombytes_sysrandom_random_dev_open()) == -1) {
|
||||
debug_print("Couldn't open random device (%s)\n", strerror(errno));
|
||||
return MOBI_DRM_RANDOM_ERR;
|
||||
}
|
||||
errno = errno_save;
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Initialize random data source
|
||||
|
||||
@param[in,out] handle Handle
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_randombytes_sysrandom_close(MOBIRandom *handle) {
|
||||
# define NEEDS_CLOSE
|
||||
MOBI_RET ret = MOBI_DRM_RANDOM_ERR;
|
||||
if (handle->random_data_source_fd != -1 && close(handle->random_data_source_fd) == 0) {
|
||||
handle->random_data_source_fd = -1;
|
||||
ret = MOBI_SUCCESS;
|
||||
}
|
||||
# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
if (handle->getrandom_available != 0) {
|
||||
ret = MOBI_SUCCESS;
|
||||
}
|
||||
# endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
# endif /* _WIN32 */
|
||||
|
||||
/**
|
||||
@brief Read a buffer of random bytes
|
||||
|
||||
@param[in,out] handle Handle
|
||||
@param[in,out] buf Buffer
|
||||
@param[in] size Buffer size (up to 256 bytes)
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_randombytes_sysrandom_buf(MOBIRandom *handle, void *buf, const size_t size) {
|
||||
# ifndef _WIN32
|
||||
# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
if (handle->getrandom_available != 0) {
|
||||
return mobi_randombytes_linux_getrandom(buf, size);
|
||||
}
|
||||
# endif
|
||||
if (handle->random_data_source_fd == -1 ||
|
||||
mobi_safe_read(handle->random_data_source_fd, buf, size) != (ssize_t) size) {
|
||||
return MOBI_DRM_RANDOM_ERR;
|
||||
}
|
||||
# else /* _WIN32 */
|
||||
UNUSED(handle);
|
||||
if (! RtlGenRandom((PVOID) buf, (ULONG) size)) {
|
||||
return MOBI_DRM_RANDOM_ERR;
|
||||
}
|
||||
# endif /* _WIN32 */
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* HAVE_SAFE_ARC4RANDOM */
|
||||
|
||||
/**
|
||||
@brief Fill buffer with random bytes
|
||||
|
||||
@param[in,out] buf Buffer
|
||||
@param[in] size Buffer size (up to 256 bytes)
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_randombytes(void *buf, const size_t size) {
|
||||
|
||||
MOBIRandom handle = {
|
||||
.random_data_source_fd = -1,
|
||||
.getrandom_available = 0
|
||||
};
|
||||
|
||||
MOBI_RET ret;
|
||||
#ifdef NEEDS_INIT
|
||||
ret = mobi_randombytes_sysrandom_init(&handle);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (size > (size_t) 0U) {
|
||||
ret = mobi_randombytes_sysrandom_buf(&handle, buf, size);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
debug_print("%s\n", "Generating random data failed");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#ifdef NEEDS_CLOSE
|
||||
if (mobi_randombytes_sysrandom_close(&handle) != MOBI_SUCCESS) {
|
||||
debug_print("%s\n", "Closing random data source failed");
|
||||
}
|
||||
#endif
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
25
app/src/main/cpp/libmobi/src/randombytes.h
vendored
Normal file
25
app/src/main/cpp/libmobi/src/randombytes.h
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/** @file randombytes.h
|
||||
*
|
||||
* Copyright (c) 2021 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef libmobi_randombytes_h
|
||||
#define libmobi_randombytes_h
|
||||
|
||||
#include "mobi.h"
|
||||
|
||||
/**
|
||||
@brief Write n random bytes of high quality to buf
|
||||
|
||||
@param[in,out] buf Buffer to be filled with random bytes
|
||||
@param[in] len Buffer length
|
||||
@return On success returns MOBI_SUCCESS
|
||||
*/
|
||||
MOBI_RET mobi_randombytes(void *buf, const size_t len);
|
||||
|
||||
#endif
|
||||
924
app/src/main/cpp/libmobi/src/read.c
vendored
Normal file
924
app/src/main/cpp/libmobi/src/read.c
vendored
Normal file
|
|
@ -0,0 +1,924 @@
|
|||
/** @file read.c
|
||||
* @brief Functions for reading and parsing of MOBI document
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "read.h"
|
||||
#include "util.h"
|
||||
#include "index.h"
|
||||
#include "debug.h"
|
||||
|
||||
/**
|
||||
@brief Read palm database header from file into MOBIData structure (MOBIPdbHeader)
|
||||
|
||||
@param[in,out] m MOBIData structure to be filled with read data
|
||||
@param[in] file Filedescriptor to read from
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_load_pdbheader(MOBIData *m, FILE *file) {
|
||||
if (m == NULL) {
|
||||
debug_print("%s", "Mobi structure not initialized\n");
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
if (!file) {
|
||||
return MOBI_FILE_NOT_FOUND;
|
||||
}
|
||||
MOBIBuffer *buf = mobi_buffer_init(PALMDB_HEADER_LEN);
|
||||
if (buf == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
const size_t len = fread(buf->data, 1, PALMDB_HEADER_LEN, file);
|
||||
if (len != PALMDB_HEADER_LEN) {
|
||||
mobi_buffer_free(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
m->ph = calloc(1, sizeof(MOBIPdbHeader));
|
||||
if (m->ph == NULL) {
|
||||
debug_print("%s", "Memory allocation for pdb header failed\n");
|
||||
mobi_buffer_free(buf);
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
/* parse header */
|
||||
mobi_buffer_getstring(m->ph->name, buf, PALMDB_NAME_SIZE_MAX);
|
||||
m->ph->attributes = mobi_buffer_get16(buf);
|
||||
m->ph->version = mobi_buffer_get16(buf);
|
||||
m->ph->ctime = mobi_buffer_get32(buf);
|
||||
m->ph->mtime = mobi_buffer_get32(buf);
|
||||
m->ph->btime = mobi_buffer_get32(buf);
|
||||
m->ph->mod_num = mobi_buffer_get32(buf);
|
||||
m->ph->appinfo_offset = mobi_buffer_get32(buf);
|
||||
m->ph->sortinfo_offset = mobi_buffer_get32(buf);
|
||||
mobi_buffer_getstring(m->ph->type, buf, 4);
|
||||
mobi_buffer_getstring(m->ph->creator, buf, 4);
|
||||
m->ph->uid = mobi_buffer_get32(buf);
|
||||
m->ph->next_rec = mobi_buffer_get32(buf);
|
||||
m->ph->rec_count = mobi_buffer_get16(buf);
|
||||
mobi_buffer_free(buf);
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Read list of database records from file into MOBIData structure (MOBIPdbRecord)
|
||||
|
||||
@param[in,out] m MOBIData structure to be filled with read data
|
||||
@param[in] file Filedescriptor to read from
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_load_reclist(MOBIData *m, FILE *file) {
|
||||
if (m == NULL) {
|
||||
debug_print("%s", "Mobi structure not initialized\n");
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
if (!file) {
|
||||
debug_print("%s", "File not ready\n");
|
||||
return MOBI_FILE_NOT_FOUND;
|
||||
}
|
||||
m->rec = calloc(1, sizeof(MOBIPdbRecord));
|
||||
if (m->rec == NULL) {
|
||||
debug_print("%s", "Memory allocation for pdb record failed\n");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
MOBIPdbRecord *curr = m->rec;
|
||||
for (int i = 0; i < m->ph->rec_count; i++) {
|
||||
MOBIBuffer *buf = mobi_buffer_init(PALMDB_RECORD_INFO_SIZE);
|
||||
if (buf == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
const size_t len = fread(buf->data, 1, PALMDB_RECORD_INFO_SIZE, file);
|
||||
if (len != PALMDB_RECORD_INFO_SIZE) {
|
||||
mobi_buffer_free(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
if (i > 0) {
|
||||
curr->next = calloc(1, sizeof(MOBIPdbRecord));
|
||||
if (curr->next == NULL) {
|
||||
debug_print("%s", "Memory allocation for pdb record failed\n");
|
||||
mobi_buffer_free(buf);
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
curr->offset = mobi_buffer_get32(buf);
|
||||
curr->attributes = mobi_buffer_get8(buf);
|
||||
const uint8_t h = mobi_buffer_get8(buf);
|
||||
const uint16_t l = mobi_buffer_get16(buf);
|
||||
curr->uid = (uint32_t) h << 16 | l;
|
||||
curr->next = NULL;
|
||||
mobi_buffer_free(buf);
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Read record data and size from file into MOBIData structure (MOBIPdbRecord)
|
||||
|
||||
@param[in,out] m MOBIData structure to be filled with read data
|
||||
@param[in] file Filedescriptor to read from
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_load_rec(MOBIData *m, FILE *file) {
|
||||
MOBI_RET ret;
|
||||
if (m == NULL) {
|
||||
debug_print("%s", "Mobi structure not initialized\n");
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
MOBIPdbRecord *curr = m->rec;
|
||||
while (curr != NULL) {
|
||||
MOBIPdbRecord *next;
|
||||
size_t size;
|
||||
if (curr->next != NULL) {
|
||||
next = curr->next;
|
||||
size = next->offset - curr->offset;
|
||||
} else {
|
||||
fseek(file, 0, SEEK_END);
|
||||
long diff = ftell(file) - curr->offset;
|
||||
if (diff <= 0) {
|
||||
debug_print("Wrong record size: %li\n", diff);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
size = (size_t) diff;
|
||||
next = NULL;
|
||||
}
|
||||
|
||||
curr->size = size;
|
||||
ret = mobi_load_recdata(curr, file);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
debug_print("Error loading record uid %i data\n", curr->uid);
|
||||
mobi_free_rec(m);
|
||||
return ret;
|
||||
}
|
||||
curr = next;
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Read record data from file into MOBIPdbRecord structure
|
||||
|
||||
@param[in,out] rec MOBIPdbRecord structure to be filled with read data
|
||||
@param[in] file Filedescriptor to read from
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_load_recdata(MOBIPdbRecord *rec, FILE *file) {
|
||||
const int ret = fseek(file, rec->offset, SEEK_SET);
|
||||
if (ret != 0) {
|
||||
debug_print("Record %i not found\n", rec->uid);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
rec->data = malloc(rec->size);
|
||||
if (rec->data == NULL) {
|
||||
debug_print("%s", "Memory allocation for pdb record data failed\n");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
const size_t len = fread(rec->data, 1, rec->size, file);
|
||||
if (len < rec->size) {
|
||||
debug_print("Truncated data in record %i\n", rec->uid);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Parse EXTH header from Record 0 into MOBIData structure (MOBIExthHeader)
|
||||
|
||||
@param[in,out] m MOBIData structure to be filled with parsed data
|
||||
@param[in] buf MOBIBuffer buffer to read from
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_parse_extheader(MOBIData *m, MOBIBuffer *buf) {
|
||||
if (m == NULL) {
|
||||
debug_print("%s", "Mobi structure not initialized\n");
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
char exth_magic[5];
|
||||
const size_t header_length = 12;
|
||||
mobi_buffer_getstring(exth_magic, buf, 4);
|
||||
const size_t exth_length = mobi_buffer_get32(buf) - header_length;
|
||||
const size_t rec_count = mobi_buffer_get32(buf);
|
||||
if (strncmp(exth_magic, EXTH_MAGIC, 4) != 0 ||
|
||||
exth_length + buf->offset > buf->maxlen ||
|
||||
rec_count == 0 || rec_count > MOBI_EXTH_MAXCNT) {
|
||||
debug_print("%s", "Sanity checks for EXTH header failed\n");
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
const size_t saved_maxlen = buf->maxlen;
|
||||
buf->maxlen = exth_length + buf->offset;
|
||||
m->eh = calloc(1, sizeof(MOBIExthHeader));
|
||||
if (m->eh == NULL) {
|
||||
debug_print("%s", "Memory allocation for EXTH header failed\n");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
MOBIExthHeader *curr = m->eh;
|
||||
for (size_t i = 0; i < rec_count; i++) {
|
||||
if (curr->data) {
|
||||
curr->next = calloc(1, sizeof(MOBIExthHeader));
|
||||
if (curr->next == NULL) {
|
||||
debug_print("%s", "Memory allocation for EXTH header failed\n");
|
||||
mobi_free_eh(m);
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
curr->tag = mobi_buffer_get32(buf);
|
||||
/* data size = record size minus 8 bytes for uid and size */
|
||||
curr->size = mobi_buffer_get32(buf) - 8;
|
||||
if (curr->size == 0) {
|
||||
debug_print("Skip record %i, data too short\n", curr->tag);
|
||||
continue;
|
||||
}
|
||||
if (buf->offset + curr->size > buf->maxlen) {
|
||||
debug_print("Record %i too long\n", curr->tag);
|
||||
mobi_free_eh(m);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
curr->data = malloc(curr->size);
|
||||
if (curr->data == NULL) {
|
||||
debug_print("Memory allocation for EXTH record %i failed\n", curr->tag);
|
||||
mobi_free_eh(m);
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
mobi_buffer_getraw(curr->data, buf, curr->size);
|
||||
curr->next = NULL;
|
||||
}
|
||||
buf->maxlen = saved_maxlen;
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Parse MOBI header from Record 0 into MOBIData structure (MOBIMobiHeader)
|
||||
|
||||
@param[in,out] m MOBIData structure to be filled with parsed data
|
||||
@param[in] buf MOBIBuffer buffer to read from
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_parse_mobiheader(MOBIData *m, MOBIBuffer *buf) {
|
||||
int isKF8 = 0;
|
||||
if (m == NULL) {
|
||||
debug_print("%s", "Mobi structure not initialized\n");
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
m->mh = calloc(1, sizeof(MOBIMobiHeader));
|
||||
if (m->mh == NULL) {
|
||||
debug_print("%s", "Memory allocation for MOBI header failed\n");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
mobi_buffer_getstring(m->mh->mobi_magic, buf, 4);
|
||||
mobi_buffer_dup32(&m->mh->header_length, buf);
|
||||
if (strcmp(m->mh->mobi_magic, MOBI_MAGIC) != 0 || m->mh->header_length == NULL) {
|
||||
debug_print("%s", "MOBI header not found\n");
|
||||
mobi_free_mh(m->mh);
|
||||
m->mh = NULL;
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
const size_t saved_maxlen = buf->maxlen;
|
||||
/* some old files declare zero length mobi header, try to read first 24 bytes anyway */
|
||||
uint32_t header_length = (*m->mh->header_length > 0) ? *m->mh->header_length : 24;
|
||||
/* read only declared MOBI header length (curr offset minus 8 already read bytes) */
|
||||
const size_t left_length = header_length + buf->offset - 8;
|
||||
buf->maxlen = saved_maxlen < left_length ? saved_maxlen : left_length;
|
||||
mobi_buffer_dup32(&m->mh->mobi_type, buf);
|
||||
uint32_t encoding = mobi_buffer_get32(buf);
|
||||
if (encoding == 1252) {
|
||||
m->mh->text_encoding = malloc(sizeof(MOBIEncoding));
|
||||
if (m->mh->text_encoding == NULL) {
|
||||
debug_print("%s", "Memory allocation for MOBI header failed\n");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
*m->mh->text_encoding = MOBI_CP1252;
|
||||
}
|
||||
else if (encoding == 65001) {
|
||||
m->mh->text_encoding = malloc(sizeof(MOBIEncoding));
|
||||
if (m->mh->text_encoding == NULL) {
|
||||
debug_print("%s", "Memory allocation for MOBI header failed\n");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
*m->mh->text_encoding = MOBI_UTF8;
|
||||
} else {
|
||||
debug_print("Unknown encoding in mobi header: %i\n", encoding);
|
||||
}
|
||||
mobi_buffer_dup32(&m->mh->uid, buf);
|
||||
mobi_buffer_dup32(&m->mh->version, buf);
|
||||
if (header_length >= MOBI_HEADER_V7_SIZE
|
||||
&& m->mh->version && *m->mh->version == 8) {
|
||||
isKF8 = 1;
|
||||
}
|
||||
mobi_buffer_dup32(&m->mh->orth_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->infl_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->names_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->keys_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->extra0_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->extra1_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->extra2_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->extra3_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->extra4_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->extra5_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->non_text_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->full_name_offset, buf);
|
||||
mobi_buffer_dup32(&m->mh->full_name_length, buf);
|
||||
mobi_buffer_dup32(&m->mh->locale, buf);
|
||||
mobi_buffer_dup32(&m->mh->dict_input_lang, buf);
|
||||
mobi_buffer_dup32(&m->mh->dict_output_lang, buf);
|
||||
mobi_buffer_dup32(&m->mh->min_version, buf);
|
||||
mobi_buffer_dup32(&m->mh->image_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->huff_rec_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->huff_rec_count, buf);
|
||||
mobi_buffer_dup32(&m->mh->datp_rec_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->datp_rec_count, buf);
|
||||
mobi_buffer_dup32(&m->mh->exth_flags, buf);
|
||||
mobi_buffer_seek(buf, 32); /* 32 unknown bytes */
|
||||
mobi_buffer_dup32(&m->mh->unknown6, buf);
|
||||
mobi_buffer_dup32(&m->mh->drm_offset, buf);
|
||||
mobi_buffer_dup32(&m->mh->drm_count, buf);
|
||||
mobi_buffer_dup32(&m->mh->drm_size, buf);
|
||||
mobi_buffer_dup32(&m->mh->drm_flags, buf);
|
||||
mobi_buffer_seek(buf, 8); /* 8 unknown bytes */
|
||||
if (isKF8) {
|
||||
mobi_buffer_dup32(&m->mh->fdst_index, buf);
|
||||
} else {
|
||||
mobi_buffer_dup16(&m->mh->first_text_index, buf);
|
||||
mobi_buffer_dup16(&m->mh->last_text_index, buf);
|
||||
}
|
||||
mobi_buffer_dup32(&m->mh->fdst_section_count, buf);
|
||||
mobi_buffer_dup32(&m->mh->fcis_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->fcis_count, buf);
|
||||
mobi_buffer_dup32(&m->mh->flis_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->flis_count, buf);
|
||||
mobi_buffer_dup32(&m->mh->unknown10, buf);
|
||||
mobi_buffer_dup32(&m->mh->unknown11, buf);
|
||||
mobi_buffer_dup32(&m->mh->srcs_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->srcs_count, buf);
|
||||
mobi_buffer_dup32(&m->mh->unknown12, buf);
|
||||
mobi_buffer_dup32(&m->mh->unknown13, buf);
|
||||
mobi_buffer_seek(buf, 2); /* 2 byte fill */
|
||||
mobi_buffer_dup16(&m->mh->extra_flags, buf);
|
||||
mobi_buffer_dup32(&m->mh->ncx_index, buf);
|
||||
if (isKF8) {
|
||||
mobi_buffer_dup32(&m->mh->fragment_index, buf);
|
||||
mobi_buffer_dup32(&m->mh->skeleton_index, buf);
|
||||
} else {
|
||||
mobi_buffer_dup32(&m->mh->unknown14, buf);
|
||||
mobi_buffer_dup32(&m->mh->unknown15, buf);
|
||||
}
|
||||
mobi_buffer_dup32(&m->mh->datp_index, buf);
|
||||
if (isKF8) {
|
||||
mobi_buffer_dup32(&m->mh->guide_index, buf);
|
||||
} else {
|
||||
mobi_buffer_dup32(&m->mh->unknown16, buf);
|
||||
}
|
||||
mobi_buffer_dup32(&m->mh->unknown17, buf);
|
||||
mobi_buffer_dup32(&m->mh->unknown18, buf);
|
||||
mobi_buffer_dup32(&m->mh->unknown19, buf);
|
||||
mobi_buffer_dup32(&m->mh->unknown20, buf);
|
||||
if (buf->maxlen > buf->offset) {
|
||||
debug_print("Skipping %zu unknown bytes in MOBI header\n", (buf->maxlen - buf->offset));
|
||||
mobi_buffer_setpos(buf, buf->maxlen);
|
||||
}
|
||||
buf->maxlen = saved_maxlen;
|
||||
/* get full name stored at m->mh->full_name_offset */
|
||||
if (m->mh->full_name_offset && m->mh->full_name_length) {
|
||||
const size_t saved_offset = buf->offset;
|
||||
const uint32_t full_name_length = min(*m->mh->full_name_length, MOBI_TITLE_SIZEMAX);
|
||||
mobi_buffer_setpos(buf, *m->mh->full_name_offset);
|
||||
m->mh->full_name = malloc(full_name_length + 1);
|
||||
if (m->mh->full_name == NULL) {
|
||||
debug_print("%s", "Memory allocation for full name failed\n");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
if (full_name_length) {
|
||||
mobi_buffer_getstring(m->mh->full_name, buf, full_name_length);
|
||||
} else {
|
||||
m->mh->full_name[0] = '\0';
|
||||
}
|
||||
mobi_buffer_setpos(buf, saved_offset);
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Parse Record 0 into MOBIData structure
|
||||
|
||||
This function will parse MOBIRecord0Header, MOBIMobiHeader and MOBIExthHeader
|
||||
|
||||
@param[in,out] m MOBIData structure to be filled with parsed data
|
||||
@param[in] seqnumber Sequential number of the palm database record
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_parse_record0(MOBIData *m, const size_t seqnumber) {
|
||||
MOBI_RET ret;
|
||||
if (m == NULL) {
|
||||
debug_print("%s", "Mobi structure not initialized\n");
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
const MOBIPdbRecord *record0 = mobi_get_record_by_seqnumber(m, seqnumber);
|
||||
if (record0 == NULL) {
|
||||
debug_print("%s", "Record 0 not loaded\n");
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
if (record0->size < RECORD0_HEADER_LEN) {
|
||||
debug_print("%s", "Record 0 too short\n");
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
MOBIBuffer *buf = mobi_buffer_init_null(record0->data, record0->size);
|
||||
if (buf == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
m->rh = calloc(1, sizeof(MOBIRecord0Header));
|
||||
if (m->rh == NULL) {
|
||||
debug_print("%s", "Memory allocation for record 0 header failed\n");
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
/* parse palmdoc header */
|
||||
const uint16_t compression = mobi_buffer_get16(buf);
|
||||
mobi_buffer_seek(buf, 2); // unused 2 bytes, zeroes
|
||||
if ((compression != MOBI_COMPRESSION_NONE &&
|
||||
compression != MOBI_COMPRESSION_PALMDOC &&
|
||||
compression != MOBI_COMPRESSION_HUFFCDIC)) {
|
||||
debug_print("Wrong record0 header: %c%c%c%c\n", record0->data[0], record0->data[1], record0->data[2], record0->data[3]);
|
||||
mobi_buffer_free_null(buf);
|
||||
free(m->rh);
|
||||
m->rh = NULL;
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
m->rh->compression_type = compression;
|
||||
m->rh->text_length = mobi_buffer_get32(buf);
|
||||
m->rh->text_record_count = mobi_buffer_get16(buf);
|
||||
m->rh->text_record_size = mobi_buffer_get16(buf);
|
||||
m->rh->encryption_type = mobi_buffer_get16(buf);
|
||||
m->rh->unknown1 = mobi_buffer_get16(buf);
|
||||
if (mobi_is_mobipocket(m)) {
|
||||
/* parse mobi header if present */
|
||||
ret = mobi_parse_mobiheader(m, buf);
|
||||
if (ret == MOBI_SUCCESS) {
|
||||
/* parse exth header if present */
|
||||
mobi_parse_extheader(m, buf);
|
||||
}
|
||||
}
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Calculate the size of extra bytes at the end of text record
|
||||
|
||||
@param[in] record MOBIPdbRecord structure containing the record
|
||||
@param[in] flags Flags from MOBI header (extra_flags)
|
||||
@return The size of trailing bytes, MOBI_NOTSET on failure
|
||||
*/
|
||||
size_t mobi_get_record_extrasize(const MOBIPdbRecord *record, const uint16_t flags) {
|
||||
size_t extra_size = 0;
|
||||
MOBIBuffer *buf = mobi_buffer_init_null(record->data, record->size);
|
||||
if (buf == NULL) {
|
||||
debug_print("%s", "Buffer init in extrasize failed\n");
|
||||
return MOBI_NOTSET;
|
||||
}
|
||||
/* set pointer at the end of the record data */
|
||||
mobi_buffer_setpos(buf, buf->maxlen - 1);
|
||||
for (int bit = 15; bit > 0; bit--) {
|
||||
if (flags & (1 << bit)) {
|
||||
/* bit is set */
|
||||
size_t len = 0;
|
||||
/* size contains varlen itself and optional data */
|
||||
const uint32_t size = mobi_buffer_get_varlen_dec(buf, &len);
|
||||
/* skip data */
|
||||
/* TODO: read and store in record struct */
|
||||
mobi_buffer_seek(buf, - (int)(size - len));
|
||||
extra_size += size;
|
||||
}
|
||||
}
|
||||
/* check bit 0 */
|
||||
if (flags & 1) {
|
||||
const uint8_t b = mobi_buffer_get8(buf);
|
||||
/* two first bits hold size */
|
||||
extra_size += (b & 0x3) + 1;
|
||||
}
|
||||
mobi_buffer_free_null(buf);
|
||||
return extra_size;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Calculate the size of extra multibyte section at the end of text record
|
||||
|
||||
@param[in] record MOBIPdbRecord structure containing the record
|
||||
@param[in] flags Flags from MOBI header (extra_flags)
|
||||
@return The size of trailing bytes, MOBI_NOTSET on failure
|
||||
*/
|
||||
size_t mobi_get_record_mb_extrasize(const MOBIPdbRecord *record, const uint16_t flags) {
|
||||
size_t extra_size = 0;
|
||||
if (flags & 1) {
|
||||
MOBIBuffer *buf = mobi_buffer_init_null(record->data, record->size);
|
||||
if (buf == NULL) {
|
||||
debug_print("%s", "Buffer init in extrasize failed\n");
|
||||
return MOBI_NOTSET;
|
||||
}
|
||||
/* set pointer at the end of the record data */
|
||||
mobi_buffer_setpos(buf, buf->maxlen - 1);
|
||||
for (int bit = 15; bit > 0; bit--) {
|
||||
if (flags & (1 << bit)) {
|
||||
/* bit is set */
|
||||
size_t len = 0;
|
||||
/* size contains varlen itself and optional data */
|
||||
const uint32_t size = mobi_buffer_get_varlen_dec(buf, &len);
|
||||
/* skip data */
|
||||
/* TODO: read and store in record struct */
|
||||
mobi_buffer_seek(buf, - (int)(size - len));
|
||||
}
|
||||
}
|
||||
/* read multibyte section */
|
||||
const uint8_t b = mobi_buffer_get8(buf);
|
||||
/* two first bits hold size */
|
||||
extra_size += (b & 0x3) + 1;
|
||||
mobi_buffer_free_null(buf);
|
||||
}
|
||||
return extra_size;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Parse HUFF record into MOBIHuffCdic structure
|
||||
|
||||
@param[in,out] huffcdic MOBIHuffCdic structure to be filled with parsed data
|
||||
@param[in] record MOBIPdbRecord structure containing the record
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_parse_huff(MOBIHuffCdic *huffcdic, const MOBIPdbRecord *record) {
|
||||
MOBIBuffer *buf = mobi_buffer_init_null(record->data, record->size);
|
||||
if (buf == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
char huff_magic[5];
|
||||
mobi_buffer_getstring(huff_magic, buf, 4);
|
||||
const size_t header_length = mobi_buffer_get32(buf);
|
||||
if (strncmp(huff_magic, HUFF_MAGIC, 4) != 0 || header_length < HUFF_HEADER_LEN) {
|
||||
debug_print("HUFF wrong magic: %s\n", huff_magic);
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
const size_t data1_offset = mobi_buffer_get32(buf);
|
||||
const size_t data2_offset = mobi_buffer_get32(buf);
|
||||
/* skip little-endian table offsets */
|
||||
mobi_buffer_setpos(buf, data1_offset);
|
||||
if (buf->offset + (256 * 4) > buf->maxlen) {
|
||||
debug_print("%s", "HUFF data1 too short\n");
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
/* read 256 indices from data1 big-endian */
|
||||
for (int i = 0; i < 256; i++) {
|
||||
huffcdic->table1[i] = mobi_buffer_get32(buf);
|
||||
}
|
||||
mobi_buffer_setpos(buf, data2_offset);
|
||||
if (buf->offset + (64 * 4) > buf->maxlen) {
|
||||
debug_print("%s", "HUFF data2 too short\n");
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
/* read 32 mincode-maxcode pairs from data2 big-endian */
|
||||
huffcdic->mincode_table[0] = 0;
|
||||
huffcdic->maxcode_table[0] = 0xFFFFFFFF;
|
||||
for (int i = 1; i < HUFF_CODETABLE_SIZE; i++) {
|
||||
const uint32_t mincode = mobi_buffer_get32(buf);
|
||||
const uint32_t maxcode = mobi_buffer_get32(buf);
|
||||
huffcdic->mincode_table[i] = mincode << (32 - i);
|
||||
huffcdic->maxcode_table[i] = ((maxcode + 1) << (32 - i)) - 1;
|
||||
}
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Parse CDIC record into MOBIHuffCdic structure
|
||||
|
||||
@param[in,out] huffcdic MOBIHuffCdic structure to be filled with parsed data
|
||||
@param[in] record MOBIPdbRecord structure containing the record
|
||||
@param[in] num Number of CDIC record in a set, starting from zero
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_parse_cdic(MOBIHuffCdic *huffcdic, const MOBIPdbRecord *record, const size_t num) {
|
||||
MOBIBuffer *buf = mobi_buffer_init_null(record->data, record->size);
|
||||
if (buf == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
char cdic_magic[5];
|
||||
mobi_buffer_getstring(cdic_magic, buf, 4);
|
||||
const size_t header_length = mobi_buffer_get32(buf);
|
||||
if (strncmp(cdic_magic, CDIC_MAGIC, 4) != 0 || header_length < CDIC_HEADER_LEN) {
|
||||
debug_print("CDIC wrong magic: %s or declared header length: %zu\n", cdic_magic, header_length);
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
/* variables in huffcdic initialized to zero with calloc */
|
||||
/* save initial count and length */
|
||||
size_t index_count = mobi_buffer_get32(buf);
|
||||
const size_t code_length = mobi_buffer_get32(buf);
|
||||
if (huffcdic->code_length && huffcdic->code_length != code_length) {
|
||||
debug_print("CDIC different code length %zu in record %i, previous was %zu\n", huffcdic->code_length, record->uid, code_length);
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
if (huffcdic->index_count && huffcdic->index_count != index_count) {
|
||||
debug_print("CDIC different index count %zu in record %i, previous was %zu\n", huffcdic->index_count, record->uid, index_count);
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
if (code_length == 0 || code_length > HUFF_CODELEN_MAX) {
|
||||
debug_print("Code length exceeds sanity checks (%zu)\n", code_length);
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
huffcdic->code_length = code_length;
|
||||
huffcdic->index_count = index_count;
|
||||
if (index_count == 0) {
|
||||
debug_print("%s", "CDIC index count is null");
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
/* allocate memory for symbol offsets if not already allocated */
|
||||
if (num == 0) {
|
||||
if (index_count > (1 << HUFF_CODELEN_MAX) * CDIC_RECORD_MAXCNT) {
|
||||
debug_print("CDIC index count too large %zu\n", index_count);
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
huffcdic->symbol_offsets = malloc(index_count * sizeof(*huffcdic->symbol_offsets));
|
||||
if (huffcdic->symbol_offsets == NULL) {
|
||||
debug_print("%s", "CDIC cannot allocate memory");
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
}
|
||||
index_count -= huffcdic->index_read;
|
||||
/* limit number of records read to code_length bits */
|
||||
if (index_count >> code_length) {
|
||||
index_count = (1 << code_length);
|
||||
}
|
||||
if (buf->offset + (index_count * 2) > buf->maxlen) {
|
||||
debug_print("%s", "CDIC indices data too short\n");
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
/* read i * 2 byte big-endian indices */
|
||||
while (index_count--) {
|
||||
const uint16_t offset = mobi_buffer_get16(buf);
|
||||
const size_t saved_pos = buf->offset;
|
||||
mobi_buffer_setpos(buf, offset + CDIC_HEADER_LEN);
|
||||
const size_t len = mobi_buffer_get16(buf) & 0x7fff;
|
||||
if (buf->error != MOBI_SUCCESS || buf->offset + len > buf->maxlen) {
|
||||
debug_print("%s", "CDIC offset beyond buffer\n");
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
mobi_buffer_setpos(buf, saved_pos);
|
||||
huffcdic->symbol_offsets[huffcdic->index_read++] = offset;
|
||||
}
|
||||
if (buf->offset + code_length > buf->maxlen) {
|
||||
debug_print("%s", "CDIC dictionary data too short\n");
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
/* copy pointer to data */
|
||||
huffcdic->symbols[num] = record->data + CDIC_HEADER_LEN;
|
||||
/* free buffer */
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Parse a set of HUFF and CDIC records into MOBIHuffCdic structure
|
||||
|
||||
@param[in] m MOBIData structure with loaded MOBI document
|
||||
@param[in,out] huffcdic MOBIHuffCdic structure to be filled with parsed data
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_parse_huffdic(const MOBIData *m, MOBIHuffCdic *huffcdic) {
|
||||
MOBI_RET ret;
|
||||
const size_t offset = mobi_get_kf8offset(m);
|
||||
if (m->mh == NULL || m->mh->huff_rec_index == NULL || m->mh->huff_rec_count == NULL) {
|
||||
debug_print("%s", "HUFF/CDIC records metadata not found in MOBI header\n");
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
const size_t huff_rec_index = *m->mh->huff_rec_index + offset;
|
||||
const size_t huff_rec_count = *m->mh->huff_rec_count;
|
||||
if (huff_rec_count > HUFF_RECORD_MAXCNT) {
|
||||
debug_print("Too many HUFF record (%zu)\n", huff_rec_count);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
const MOBIPdbRecord *curr = mobi_get_record_by_seqnumber(m, huff_rec_index);
|
||||
if (curr == NULL || huff_rec_count < 2) {
|
||||
debug_print("%s", "HUFF/CDIC record not found\n");
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
if (curr->size < HUFF_RECORD_MINSIZE) {
|
||||
debug_print("HUFF record too short (%zu b)\n", curr->size);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
ret = mobi_parse_huff(huffcdic, curr);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
debug_print("%s", "HUFF parsing failed\n");
|
||||
return ret;
|
||||
}
|
||||
curr = curr->next;
|
||||
/* allocate memory for symbols data in each CDIC record */
|
||||
huffcdic->symbols = malloc((huff_rec_count - 1) * sizeof(*huffcdic->symbols));
|
||||
if (huffcdic->symbols == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
/* get following CDIC records */
|
||||
size_t i = 0;
|
||||
while (i < huff_rec_count - 1) {
|
||||
if (curr == NULL) {
|
||||
debug_print("%s\n", "CDIC record not found");
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
ret = mobi_parse_cdic(huffcdic, curr, i++);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
debug_print("%s", "CDIC parsing failed\n");
|
||||
return ret;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
if (huffcdic->index_count != huffcdic->index_read) {
|
||||
debug_print("CDIC: wrong read index count: %zu, total: %zu\n", huffcdic->index_read, huffcdic->index_count);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Parse FDST record into MOBIRawml structure (MOBIFdst member)
|
||||
|
||||
@param[in] m MOBIData structure with loaded MOBI document
|
||||
@param[in,out] rawml MOBIRawml structure to be filled with parsed data
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_parse_fdst(const MOBIData *m, MOBIRawml *rawml) {
|
||||
if (m == NULL) {
|
||||
debug_print("%s", "Mobi structure not initialized\n");
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
const size_t fdst_record_number = mobi_get_fdst_record_number(m);
|
||||
if (fdst_record_number == MOBI_NOTSET) {
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
const MOBIPdbRecord *fdst_record = mobi_get_record_by_seqnumber(m, fdst_record_number);
|
||||
if (fdst_record == NULL) {
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
MOBIBuffer *buf = mobi_buffer_init_null(fdst_record->data, fdst_record->size);
|
||||
if (buf == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
char fdst_magic[5];
|
||||
mobi_buffer_getstring(fdst_magic, buf, 4);
|
||||
const size_t data_offset = mobi_buffer_get32(buf);
|
||||
const size_t section_count = mobi_buffer_get32(buf);
|
||||
if (strncmp(fdst_magic, FDST_MAGIC, 4) != 0 ||
|
||||
section_count <= 1 ||
|
||||
section_count != *m->mh->fdst_section_count ||
|
||||
data_offset != 12) {
|
||||
debug_print("FDST wrong magic: %s, sections count: %zu or data offset: %zu\n", fdst_magic, section_count, data_offset);
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
if ((buf->maxlen - buf->offset) < section_count * 8) {
|
||||
debug_print("%s", "Record FDST too short\n");
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
rawml->fdst = malloc(sizeof(MOBIFdst));
|
||||
if (rawml->fdst == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
rawml->fdst->fdst_section_count = section_count;
|
||||
rawml->fdst->fdst_section_starts = malloc(sizeof(*rawml->fdst->fdst_section_starts) * section_count);
|
||||
if (rawml->fdst->fdst_section_starts == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
mobi_buffer_free_null(buf);
|
||||
free(rawml->fdst);
|
||||
rawml->fdst = NULL;
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
rawml->fdst->fdst_section_ends = malloc(sizeof(*rawml->fdst->fdst_section_ends) * section_count);
|
||||
if (rawml->fdst->fdst_section_ends == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
mobi_buffer_free_null(buf);
|
||||
free(rawml->fdst->fdst_section_starts);
|
||||
free(rawml->fdst);
|
||||
rawml->fdst = NULL;
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
size_t i = 0;
|
||||
while (i < section_count) {
|
||||
rawml->fdst->fdst_section_starts[i] = mobi_buffer_get32(buf);
|
||||
rawml->fdst->fdst_section_ends[i] = mobi_buffer_get32(buf);
|
||||
debug_print("FDST[%zu]:\t%i\t%i\n", i, rawml->fdst->fdst_section_starts[i], rawml->fdst->fdst_section_ends[i]);
|
||||
i++;
|
||||
}
|
||||
mobi_buffer_free_null(buf);
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Read MOBI document from file into MOBIData structure
|
||||
|
||||
@param[in,out] m MOBIData structure to be filled with read data
|
||||
@param[in] file File descriptor to read from
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_load_file(MOBIData *m, FILE *file) {
|
||||
MOBI_RET ret;
|
||||
if (m == NULL) {
|
||||
debug_print("%s", "Mobi structure not initialized\n");
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
ret = mobi_load_pdbheader(m, file);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
if (strcmp(m->ph->type, "BOOK") != 0 && strcmp(m->ph->type, "TEXt") != 0) {
|
||||
debug_print("Unsupported file type: %s\n", m->ph->type);
|
||||
return MOBI_FILE_UNSUPPORTED;
|
||||
}
|
||||
if (m->ph->rec_count == 0) {
|
||||
debug_print("%s", "No records found\n");
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
ret = mobi_load_reclist(m, file);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
ret = mobi_load_rec(m, file);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
ret = mobi_parse_record0(m, 0);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
if (m->rh && m->rh->encryption_type == MOBI_ENCRYPTION_V1) {
|
||||
/* try to set key for encryption type 1 */
|
||||
debug_print("Trying to set key for encryption type 1%s", "\n");
|
||||
mobi_drm_setkey(m, NULL);
|
||||
}
|
||||
/* if EXTH is loaded parse KF8 record0 for hybrid KF7/KF8 file */
|
||||
if (m->eh) {
|
||||
const size_t boundary_rec_number = mobi_get_kf8boundary_seqnumber(m);
|
||||
if (boundary_rec_number != MOBI_NOTSET && boundary_rec_number < UINT32_MAX) {
|
||||
/* it is a hybrid KF7/KF8 file */
|
||||
m->kf8_boundary_offset = (uint32_t) boundary_rec_number;
|
||||
m->next = mobi_init();
|
||||
/* link pdb header and records data to KF8data structure */
|
||||
m->next->ph = m->ph;
|
||||
m->next->rec = m->rec;
|
||||
m->next->drm_key = m->drm_key;
|
||||
m->next->internals = m->internals;
|
||||
/* close next loop */
|
||||
m->next->next = m;
|
||||
ret = mobi_parse_record0(m->next, boundary_rec_number + 1);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
/* swap to kf8 part if use_kf8 flag is set */
|
||||
if (m->use_kf8) {
|
||||
mobi_swap_mobidata(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Read MOBI document from a path into MOBIData structure
|
||||
|
||||
@param[in,out] m MOBIData structure to be filled with read data
|
||||
@param[in] path Path to a MOBI document on disk (eg. /home/me/test.mobi)
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_load_filename(MOBIData *m, const char *path) {
|
||||
FILE *file = fopen(path, "rb");
|
||||
if (file == NULL) {
|
||||
debug_print("%s", "File not found\n");
|
||||
return MOBI_FILE_NOT_FOUND;
|
||||
}
|
||||
const MOBI_RET ret = mobi_load_file(m, file);
|
||||
fclose(file);
|
||||
return ret;
|
||||
}
|
||||
28
app/src/main/cpp/libmobi/src/read.h
vendored
Normal file
28
app/src/main/cpp/libmobi/src/read.h
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/** @file read.h
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef libmobi_read_h
|
||||
#define libmobi_read_h
|
||||
|
||||
#include "config.h"
|
||||
#include "mobi.h"
|
||||
#include "memory.h"
|
||||
#include "compression.h"
|
||||
|
||||
#define MOBI_EXTH_MAXCNT 1024
|
||||
|
||||
MOBI_RET mobi_parse_fdst(const MOBIData *m, MOBIRawml *rawml);
|
||||
MOBI_RET mobi_parse_huffdic(const MOBIData *m, MOBIHuffCdic *cdic);
|
||||
MOBI_RET mobi_load_pdbheader(MOBIData *m, FILE *file);
|
||||
MOBI_RET mobi_load_reclist(MOBIData *m, FILE *file);
|
||||
MOBI_RET mobi_load_rec(MOBIData *m, FILE *file);
|
||||
MOBI_RET mobi_load_recdata(MOBIPdbRecord *rec, FILE *file);
|
||||
|
||||
#endif
|
||||
281
app/src/main/cpp/libmobi/src/sha1.c
vendored
Normal file
281
app/src/main/cpp/libmobi/src/sha1.c
vendored
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
SHA-1 in C
|
||||
By Steve Reid <sreid@sea-to-sky.net>
|
||||
100% Public Domain
|
||||
-----------------
|
||||
Modified 7/98
|
||||
By James H. Brown <jbrown@burgoyne.com>
|
||||
Still 100% Public Domain
|
||||
Corrected a problem which generated improper hash values on 16 bit machines
|
||||
Routine SHA1Update changed from
|
||||
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
|
||||
len)
|
||||
to
|
||||
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
|
||||
long len)
|
||||
The 'len' parameter was declared an int which works fine on 32 bit machines.
|
||||
However, on 16 bit machines an int is too small for the shifts being done
|
||||
against
|
||||
it. This caused the hash function to generate incorrect values if len was
|
||||
greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
|
||||
Since the file IO in main() reads 16K at a time, any file 8K or larger would
|
||||
be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
|
||||
"a"s).
|
||||
I also changed the declaration of variables i & j in SHA1Update to
|
||||
unsigned long from unsigned int for the same reason.
|
||||
These changes should make no difference to any 32 bit implementations since
|
||||
an
|
||||
int and a long are the same size in those environments.
|
||||
--
|
||||
I also corrected a few compiler warnings generated by Borland C.
|
||||
1. Added #include <process.h> for exit() prototype
|
||||
2. Removed unused variable 'j' in SHA1Final
|
||||
3. Changed exit(0) to return(0) at end of main.
|
||||
ALL changes I made can be located by searching for comments containing 'JHB'
|
||||
-----------------
|
||||
Modified 8/98
|
||||
By Steve Reid <sreid@sea-to-sky.net>
|
||||
Still 100% public domain
|
||||
1- Removed #include <process.h> and used return() instead of exit()
|
||||
2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
|
||||
3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
|
||||
-----------------
|
||||
Modified 4/01
|
||||
By Saul Kravitz <Saul.Kravitz@celera.com>
|
||||
Still 100% PD
|
||||
Modified to run on Compaq Alpha hardware.
|
||||
-----------------
|
||||
Modified 07/2002
|
||||
By Ralph Giles <giles@ghostscript.com>
|
||||
Still 100% public domain
|
||||
modified for use with stdint types, autoconf
|
||||
code cleanup, removed attribution comments
|
||||
switched SHA1Final() argument order for consistency
|
||||
use SHA1_ prefix for public api
|
||||
move public api to sha1.h
|
||||
*/
|
||||
|
||||
/*
|
||||
Test Vectors (from FIPS PUB 180-1)
|
||||
"abc"
|
||||
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
||||
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
|
||||
A million repetitions of "a"
|
||||
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
|
||||
*/
|
||||
|
||||
/* #define SHA1HANDSOFF */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sha1.h"
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
|
||||
|
||||
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
|
||||
|
||||
/* blk0() and blk() perform the initial expand. */
|
||||
/* I got the idea of expanding during the round function from SSLeay */
|
||||
#define blk0(i) (block->l[i] = (((uint32_t)block->c[i*4 ] << 24) | \
|
||||
((uint32_t)block->c[i*4 + 1] << 16) | \
|
||||
((uint32_t)block->c[i*4 + 2] << 8) | \
|
||||
((uint32_t)block->c[i*4 + 3] )))
|
||||
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
|
||||
^block->l[(i+2)&15]^block->l[i&15],1))
|
||||
|
||||
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
|
||||
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
||||
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
||||
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
|
||||
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
|
||||
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
|
||||
|
||||
|
||||
#ifdef VERBOSE /* SAK */
|
||||
void SHAPrintContext(SHA1_CTX *context, char *msg) {
|
||||
printf("%s (%d,%d) %x %x %x %x %x\n",
|
||||
msg,
|
||||
context->count[0], context->count[1],
|
||||
context->state[0],
|
||||
context->state[1],
|
||||
context->state[2],
|
||||
context->state[3],
|
||||
context->state[4]);
|
||||
}
|
||||
#endif /* VERBOSE */
|
||||
|
||||
/* Hash a single 512-bit block. This is the core of the algorithm. */
|
||||
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]) {
|
||||
uint32_t a, b, c, d, e;
|
||||
typedef union {
|
||||
uint8_t c[64];
|
||||
uint32_t l[16];
|
||||
} CHAR64LONG16;
|
||||
CHAR64LONG16* block;
|
||||
|
||||
#ifdef SHA1HANDSOFF
|
||||
static uint8_t workspace[64];
|
||||
block = (CHAR64LONG16*) workspace;
|
||||
memcpy(block, buffer, 64);
|
||||
#else
|
||||
block = (CHAR64LONG16*) buffer;
|
||||
#endif
|
||||
|
||||
/* Copy context->state[] to working vars */
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
e = state[4];
|
||||
|
||||
/* 4 rounds of 20 operations each. Loop unrolled. */
|
||||
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
|
||||
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
|
||||
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
|
||||
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
|
||||
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
|
||||
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
|
||||
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
|
||||
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
|
||||
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
|
||||
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
|
||||
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
|
||||
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
|
||||
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
|
||||
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
|
||||
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
|
||||
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
|
||||
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
|
||||
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
||||
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
||||
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
||||
|
||||
/* Add the working vars back into context.state[] */
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
|
||||
/* Wipe variables */
|
||||
a = b = c = d = e = 0;
|
||||
UNUSED(a);UNUSED(b);UNUSED(c);UNUSED(d);UNUSED(e);
|
||||
}
|
||||
|
||||
|
||||
/* SHA1Init - Initialize new context */
|
||||
void SHA1_Init(SHA1_CTX* context) {
|
||||
/* SHA1 initialization constants */
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xEFCDAB89;
|
||||
context->state[2] = 0x98BADCFE;
|
||||
context->state[3] = 0x10325476;
|
||||
context->state[4] = 0xC3D2E1F0;
|
||||
context->count[0] = context->count[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Run your data through this. */
|
||||
void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len) {
|
||||
size_t i, j;
|
||||
|
||||
#ifdef VERBOSE
|
||||
SHAPrintContext(context, "before");
|
||||
#endif
|
||||
|
||||
j = (context->count[0] >> 3) & 63;
|
||||
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
|
||||
context->count[1] += (len >> 29);
|
||||
if ((j + len) > 63) {
|
||||
memcpy(&context->buffer[j], data, (i = 64-j));
|
||||
SHA1_Transform(context->state, context->buffer);
|
||||
for ( ; i + 63 < len; i += 64) {
|
||||
SHA1_Transform(context->state, data + i);
|
||||
}
|
||||
j = 0;
|
||||
}
|
||||
else i = 0;
|
||||
memcpy(&context->buffer[j], &data[i], len - i);
|
||||
|
||||
#ifdef VERBOSE
|
||||
SHAPrintContext(context, "after ");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Add padding and return the message digest. */
|
||||
void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]) {
|
||||
uint32_t i;
|
||||
uint8_t finalcount[8];
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
|
||||
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
|
||||
}
|
||||
SHA1_Update(context, (uint8_t *)"\200", 1);
|
||||
while ((context->count[0] & 504) != 448) {
|
||||
SHA1_Update(context, (uint8_t *)"\0", 1);
|
||||
}
|
||||
SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */
|
||||
for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
|
||||
digest[i] = (uint8_t)
|
||||
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
|
||||
}
|
||||
|
||||
/* Wipe variables */
|
||||
i = 0;
|
||||
UNUSED(i);
|
||||
memset(context->buffer, 0, 64);
|
||||
memset(context->state, 0, 20);
|
||||
memset(context->count, 0, 8);
|
||||
memset(finalcount, 0, 8); /* SWR */
|
||||
|
||||
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
|
||||
SHA1_Transform(context->state, context->buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
#ifdef TEST
|
||||
int main(int argc, char** argv) {
|
||||
int i, j;
|
||||
SHA1_CTX context;
|
||||
unsigned char digest[SHA1_DIGEST_SIZE], buffer[16384];
|
||||
FILE* file;
|
||||
if (argc > 2) {
|
||||
puts("Public domain SHA-1 implementation - by Steve Reid <sreid@sea-to-sky.net>");
|
||||
puts("Modified for 16 bit environments 7/98 - by James H. Brown <jbrown@burgoyne.com>"); /* JHB */
|
||||
puts("Produces the SHA-1 hash of a file, or stdin if no file is specified.");
|
||||
return(0);
|
||||
}
|
||||
if (argc < 2) {
|
||||
file = stdin;
|
||||
}
|
||||
else {
|
||||
if (!(file = fopen(argv[1], "rb"))) {
|
||||
fputs("Unable to open file.", stderr);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
SHA1_Init(&context);
|
||||
while (!feof(file)) { /* note: what if ferror(file) */
|
||||
i = fread(buffer, 1, 16384, file);
|
||||
SHA1_Update(&context, buffer, i);
|
||||
}
|
||||
SHA1_Final(&context, digest);
|
||||
fclose(file);
|
||||
for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
printf("%02X", digest[i*4+j]);
|
||||
}
|
||||
putchar(' ');
|
||||
}
|
||||
putchar('\n');
|
||||
return(0); /* JHB */
|
||||
}
|
||||
#endif
|
||||
27
app/src/main/cpp/libmobi/src/sha1.h
vendored
Normal file
27
app/src/main/cpp/libmobi/src/sha1.h
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/** @file sha1.h
|
||||
* @brief Header for sha1.c
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef mobi_sha1_h
|
||||
#define mobi_sha1_h
|
||||
|
||||
typedef struct {
|
||||
uint32_t state[5];
|
||||
uint32_t count[2];
|
||||
uint8_t buffer[64];
|
||||
} SHA1_CTX;
|
||||
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
void SHA1_Init(SHA1_CTX *context);
|
||||
void SHA1_Update(SHA1_CTX *context, const uint8_t *data, const size_t len);
|
||||
void SHA1_Final(SHA1_CTX *context, uint8_t digest[SHA1_DIGEST_SIZE]);
|
||||
|
||||
#endif /* sha1_h */
|
||||
566
app/src/main/cpp/libmobi/src/structure.c
vendored
Normal file
566
app/src/main/cpp/libmobi/src/structure.c
vendored
Normal file
|
|
@ -0,0 +1,566 @@
|
|||
/** @file structure.c
|
||||
* @brief Data structures
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "structure.h"
|
||||
#include "debug.h"
|
||||
#if defined(__BIONIC__) && !defined(SIZE_MAX)
|
||||
#include <limits.h> /* for SIZE_MAX */
|
||||
#endif
|
||||
|
||||
/**
|
||||
@brief Initializer for MOBIArray structure
|
||||
|
||||
It allocates memory for structure and for data: array of uint32_t variables.
|
||||
Memory should be freed with array_free().
|
||||
|
||||
@param[in] len Initial size of the array
|
||||
@return MOBIArray on success, NULL otherwise
|
||||
*/
|
||||
MOBIArray * array_init(const size_t len) {
|
||||
MOBIArray *arr = NULL;
|
||||
arr = malloc(sizeof(MOBIArray));
|
||||
if (arr == NULL) {
|
||||
debug_print("%s", "Array allocation failed\n");
|
||||
return NULL;
|
||||
}
|
||||
arr->data = malloc(len * sizeof(*arr->data));
|
||||
if (arr->data == NULL) {
|
||||
free(arr);
|
||||
debug_print("%s", "Array data allocation failed\n");
|
||||
return NULL;
|
||||
}
|
||||
arr->maxsize = len;
|
||||
arr->step = len ? len : 1;
|
||||
arr->size = 0;
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Inserts value into MOBIArray array
|
||||
|
||||
@param[in,out] arr MOBIArray array
|
||||
@param[in] value Value to be inserted
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET array_insert(MOBIArray *arr, const uint32_t value) {
|
||||
if (!arr || arr->maxsize == 0) {
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
if (arr->maxsize == arr->size) {
|
||||
arr->maxsize += arr->step;
|
||||
uint32_t *tmp = realloc(arr->data, arr->maxsize * sizeof(*arr->data));
|
||||
if (!tmp) {
|
||||
free(arr->data);
|
||||
arr->data = NULL;
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
arr->data = tmp;
|
||||
}
|
||||
arr->data[arr->size] = value;
|
||||
arr->size++;
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Helper for qsort in array_sort() function.
|
||||
|
||||
@param[in] a First element to compare
|
||||
@param[in] b Second element to compare
|
||||
@return -1 if a < b; 1 if a > b; 0 if a = b
|
||||
*/
|
||||
static int array_compare(const void *a, const void *b) {
|
||||
if (*(uint32_t *) a < *(uint32_t *) b) {
|
||||
return -1;
|
||||
};
|
||||
if (*(uint32_t *) a > *(uint32_t *) b) {
|
||||
return 1;
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Sort MOBIArray in ascending order.
|
||||
|
||||
When unique is set to true, duplicate values are discarded.
|
||||
|
||||
@param[in,out] arr MOBIArray array
|
||||
@param[in] unique Discard duplicate values if true
|
||||
*/
|
||||
void array_sort(MOBIArray *arr, const bool unique) {
|
||||
if (!arr || !arr->data || arr->size == 0) {
|
||||
return;
|
||||
}
|
||||
qsort(arr->data, arr->size, sizeof(*arr->data), array_compare);
|
||||
if (unique) {
|
||||
size_t i = 1;
|
||||
size_t j = 1;
|
||||
while (i < arr->size) {
|
||||
if (arr->data[j - 1] == arr->data[i]) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
arr->data[j++] = arr->data[i++];
|
||||
}
|
||||
arr->size = j;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get size of the array
|
||||
|
||||
@param[in] arr MOBIArray structure
|
||||
@return Array size
|
||||
*/
|
||||
size_t array_size(MOBIArray *arr) {
|
||||
return arr->size;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free MOBIArray structure and contained data
|
||||
|
||||
Free data initialized with array_init();
|
||||
|
||||
@param[in] arr MOBIArray structure
|
||||
*/
|
||||
void array_free(MOBIArray *arr) {
|
||||
if (!arr) { return; }
|
||||
if (arr->data) {
|
||||
free(arr->data);
|
||||
}
|
||||
free(arr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Create and return MOBITrie structure
|
||||
|
||||
@return MOBITrie stucture initialized with zeroes
|
||||
*/
|
||||
static MOBITrie * mobi_trie_mknode(void) {
|
||||
MOBITrie *node = calloc(1, sizeof(MOBITrie));
|
||||
if (node == NULL) {
|
||||
debug_print("Memory allocation failed%s", "\n");
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Recursively free MOBITrie trie starting from node
|
||||
|
||||
@param[in] node Starting node
|
||||
*/
|
||||
void mobi_trie_free(MOBITrie *node) {
|
||||
if (node) {
|
||||
mobi_trie_free(node->next);
|
||||
mobi_trie_free(node->children);
|
||||
free(node->values);
|
||||
free(node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Insert value into array at given MOBITrie node
|
||||
|
||||
@param[in,out] node Starting node
|
||||
@param[in] value Value to be inserted
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_trie_addvalue(MOBITrie *node, char *value) {
|
||||
if (node->values) {
|
||||
size_t cnt = ++node->values_count;
|
||||
void *new_values = realloc(node->values, cnt * sizeof(*node->values));
|
||||
if (new_values == NULL) {
|
||||
debug_print("Memory allocation failed%s", "\n");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
node->values = new_values;
|
||||
node->values[cnt - 1] = value;
|
||||
} else {
|
||||
node->values = malloc(sizeof(*node->values));
|
||||
if (node->values == NULL) {
|
||||
debug_print("Memory allocation failed%s", "\n");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
node->values[0] = value;
|
||||
node->values_count = 1;
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Insert key character and value (if given) at MOBITrie node
|
||||
|
||||
@param[in,out] node Starting node
|
||||
@param[in] c Key character
|
||||
@param[in] value Value to be inserted at terminal node, or NULL if not terminal
|
||||
@return MOBITrie node: current node if value inserted (terminal),
|
||||
children node (if transitional) or NULL on error
|
||||
*/
|
||||
static MOBITrie * mobi_trie_insert_char(MOBITrie *node, char c, char *value) {
|
||||
if (!node) { return NULL; }
|
||||
while (true) {
|
||||
if (node->c == c) {
|
||||
break;
|
||||
}
|
||||
if (node->next == NULL) {
|
||||
node->next = mobi_trie_mknode();
|
||||
node = node->next;
|
||||
break;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
if (node->c == 0) {
|
||||
node->c = c;
|
||||
}
|
||||
if (value) {
|
||||
/* terminal node */
|
||||
if (mobi_trie_addvalue(node, value) == MOBI_SUCCESS) {
|
||||
return node;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (node->children == NULL) {
|
||||
node->children = mobi_trie_mknode();
|
||||
}
|
||||
return node->children;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Insert reversed string into MOBITrie trie
|
||||
|
||||
@param[in,out] root Root node
|
||||
@param[in] string String to be inserted
|
||||
@param[in] value Value associated with the string
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_trie_insert_reversed(MOBITrie **root, char *string, char *value) {
|
||||
size_t length = strlen(string);
|
||||
if (length == 0) {
|
||||
debug_print("Skipping empty lookup string in trie node%s", "\n");
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
if (*root == NULL) {
|
||||
*root = mobi_trie_mknode();
|
||||
if (*root == NULL) {
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
}
|
||||
MOBITrie *node = *root;
|
||||
while (length > 1) {
|
||||
node = mobi_trie_insert_char(node, string[length - 1], NULL);
|
||||
if (node == NULL) {
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
length--;
|
||||
}
|
||||
node = mobi_trie_insert_char(node, string[length - 1], value);
|
||||
if (node == NULL) {
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Fetch values for key c from MOBITrie trie's current level starting at node
|
||||
|
||||
@param[in,out] values Array of values to be fetched
|
||||
@param[in,out] values_count Array size
|
||||
@param[in] node MOBITrie node to start search
|
||||
@param[in] c Key character
|
||||
@return MOBITrie children node of the node with c key or NULL if not found
|
||||
*/
|
||||
MOBITrie * mobi_trie_get_next(char ***values, size_t *values_count, const MOBITrie *node, const char c) {
|
||||
if (!node) { return NULL; }
|
||||
while (node) {
|
||||
if (node->c == c) {
|
||||
*values = (char**) node->values;
|
||||
*values_count = node->values_count;
|
||||
return node->children;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Simple imprementation of binary tree, storing key strings
|
||||
and associated arrays of values
|
||||
currently not used, save for later */
|
||||
|
||||
typedef struct MOBIBtree {
|
||||
char *key; /**< key */
|
||||
char **array; /**< array of strings */
|
||||
size_t value_count; /**< strings count */
|
||||
struct MOBIBtree *left; /**< left child */
|
||||
struct MOBIBtree *right; /**< right child */
|
||||
} MOBIBtree;
|
||||
|
||||
/**
|
||||
@brief Search MOBIBtree tree for string key
|
||||
|
||||
@param[in] node MOBIBtree node to start search
|
||||
@param[in] key Key string
|
||||
@return MOBIBtree node or NULL if not found
|
||||
*/
|
||||
MOBIBtree *mobi_btree_search(MOBIBtree *node, const char *key) {
|
||||
MOBIBtree *found = NULL;
|
||||
int compare = strcmp(key, node->key);
|
||||
if (compare < 0) {
|
||||
found = mobi_btree_search(node->left, key);
|
||||
} else if (compare > 0) {
|
||||
found = mobi_btree_search(node->right, key);
|
||||
} else {
|
||||
found = node;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Insert key and value (into array) into MOBIBtree tree
|
||||
|
||||
@param[in] node MOBIBtree root node
|
||||
@param[in] key Key string
|
||||
@param[in] value Value string will be inserted into array
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
MOBI_RET mobi_btree_insert(MOBIBtree **node, char *key, char *value) {
|
||||
MOBI_RET ret = MOBI_SUCCESS;
|
||||
if (*node == NULL) {
|
||||
*node = malloc(sizeof(MOBIBtree));
|
||||
if (*node == NULL) {
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
(*node)->key = key;
|
||||
(*node)->value_count = 1;
|
||||
(*node)->array = malloc(sizeof(*(*node)->array));
|
||||
if ((*node)->array == NULL) {
|
||||
free(*node);
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
(*node)->array[0] = value;
|
||||
(*node)->left = NULL;
|
||||
(*node)->right = NULL;
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
int compare = strcmp(key, (*node)->key);
|
||||
if (compare < 0) {
|
||||
ret = mobi_btree_insert(&(*node)->left, key, value);
|
||||
} else if (compare > 0) {
|
||||
ret = mobi_btree_insert(&(*node)->right, key, value);
|
||||
} else {
|
||||
size_t cnt = ++(*node)->value_count;
|
||||
char **new_array = realloc((*node)->array, cnt * sizeof(*(*node)->array));
|
||||
if (new_array) {
|
||||
(*node)->array = new_array;
|
||||
(*node)->array[cnt - 1] = value;
|
||||
} else {
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
@brief Allocate fragment, fill with data and return
|
||||
|
||||
@param[in] raw_offset Fragment offset in raw markup,
|
||||
SIZE_MAX if not present in original markup
|
||||
@param[in] fragment Fragment data
|
||||
@param[in] size Size data
|
||||
@param[in] is_malloc is_maloc data
|
||||
@return Fragment structure filled with data
|
||||
*/
|
||||
static MOBIFragment * mobi_list_init(size_t raw_offset, unsigned char *fragment, const size_t size, const bool is_malloc) {
|
||||
MOBIFragment *curr = calloc(1, sizeof(MOBIFragment));
|
||||
if (curr == NULL) {
|
||||
if (is_malloc) {
|
||||
free(fragment);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
curr->raw_offset = raw_offset;
|
||||
curr->fragment = fragment;
|
||||
curr->size = size;
|
||||
curr->is_malloc = is_malloc;
|
||||
return curr;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Allocate fragment, fill with data, append to linked list
|
||||
|
||||
@param[in] curr Last fragment in linked list
|
||||
@param[in] raw_offset Fragment offset in raw markup,
|
||||
SIZE_MAX if not present in original markup
|
||||
@param[in] fragment Fragment data
|
||||
@param[in] size Size data
|
||||
@param[in] is_malloc is_maloc data
|
||||
@return Fragment structure filled with data
|
||||
*/
|
||||
MOBIFragment * mobi_list_add(MOBIFragment *curr, size_t raw_offset, unsigned char *fragment, const size_t size, const bool is_malloc) {
|
||||
if (!curr) {
|
||||
return mobi_list_init(raw_offset, fragment, size, is_malloc);
|
||||
}
|
||||
curr->next = calloc(1, sizeof(MOBIFragment));
|
||||
if (curr->next == NULL) {
|
||||
if (is_malloc) {
|
||||
free(fragment);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
MOBIFragment *next = curr->next;
|
||||
next->raw_offset = raw_offset;
|
||||
next->fragment = fragment;
|
||||
next->size = size;
|
||||
next->is_malloc = is_malloc;
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Allocate fragment, fill with data,
|
||||
insert into linked list at given offset
|
||||
|
||||
Starts to search for offset at given fragment. The pointer to input fragment will be replaced by newly added one.
|
||||
|
||||
@param[in,out] fragment Fragment where search starts, on success pointer to new fragment structure filled with data
|
||||
@param[in] raw_offset Fragment offset in raw markup, SIZE_MAX if not present in original markup
|
||||
@param[in] data Fragment data
|
||||
@param[in] size Size data
|
||||
@param[in] is_malloc is_maloc data
|
||||
@param[in] offset offset where new chunk will be inserted
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS, on offset not found MOBI_DATA_CORRUPT)
|
||||
*/
|
||||
MOBI_RET mobi_list_insert(MOBIFragment **fragment, size_t raw_offset, unsigned char *data, const size_t size, const bool is_malloc, const size_t offset) {
|
||||
MOBIFragment *curr = *fragment;
|
||||
MOBIFragment *prev = NULL;
|
||||
while (curr) {
|
||||
if (curr->raw_offset != SIZE_MAX && curr->raw_offset <= offset && curr->raw_offset + curr->size >= offset ) {
|
||||
break;
|
||||
}
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
if (!curr) {
|
||||
debug_print("Offset not found: %zu\n", offset);
|
||||
if (is_malloc) {
|
||||
free(data);
|
||||
}
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
MOBIFragment *new = calloc(1, sizeof(MOBIFragment));
|
||||
if (new == NULL) {
|
||||
if (is_malloc) {
|
||||
free(data);
|
||||
}
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
new->raw_offset = raw_offset;
|
||||
new->fragment = data;
|
||||
new->size = size;
|
||||
new->is_malloc = is_malloc;
|
||||
MOBIFragment *new2 = NULL;
|
||||
if (curr->raw_offset == offset) {
|
||||
/* prepend chunk */
|
||||
if (prev) {
|
||||
prev->next = new;
|
||||
new->next = curr;
|
||||
} else {
|
||||
/* save curr */
|
||||
MOBIFragment tmp;
|
||||
tmp.raw_offset = curr->raw_offset;
|
||||
tmp.fragment = curr->fragment;
|
||||
tmp.size = curr->size;
|
||||
tmp.is_malloc = curr->is_malloc;
|
||||
tmp.next = curr->next;
|
||||
/* move new to curr */
|
||||
curr->raw_offset = new->raw_offset;
|
||||
curr->fragment = new->fragment;
|
||||
curr->size = new->size;
|
||||
curr->is_malloc = new->is_malloc;
|
||||
curr->next = new;
|
||||
/* restore tmp to new */
|
||||
new->raw_offset = tmp.raw_offset;
|
||||
new->fragment = tmp.fragment;
|
||||
new->size = tmp.size;
|
||||
new->is_malloc = tmp.is_malloc;
|
||||
new->next = tmp.next;
|
||||
*fragment = curr;
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
} else if (curr->raw_offset + curr->size == offset) {
|
||||
/* append chunk */
|
||||
new->next = curr->next;
|
||||
curr->next = new;
|
||||
} else {
|
||||
/* split fragment and insert new chunk */
|
||||
new2 = calloc(1, sizeof(MOBIFragment));
|
||||
if (new2 == NULL) {
|
||||
free(new);
|
||||
if (is_malloc) {
|
||||
free(data);
|
||||
}
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
size_t rel_offset = offset - curr->raw_offset;
|
||||
new2->next = curr->next;
|
||||
new2->size = curr->size - rel_offset;
|
||||
new2->raw_offset = offset;
|
||||
new2->fragment = curr->fragment + rel_offset;
|
||||
new2->is_malloc = false;
|
||||
curr->next = new;
|
||||
curr->size = rel_offset;
|
||||
new->next = new2;
|
||||
}
|
||||
/* correct offsets */
|
||||
if (raw_offset != SIZE_MAX) {
|
||||
curr = new->next;
|
||||
while (curr) {
|
||||
if (curr->raw_offset != SIZE_MAX) {
|
||||
curr->raw_offset += new->size;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
*fragment = new;
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete fragment from linked list
|
||||
|
||||
@param[in] curr Fragment to be deleted
|
||||
@return Next fragment in the linked list or NULL if absent
|
||||
*/
|
||||
MOBIFragment * mobi_list_del(MOBIFragment *curr) {
|
||||
MOBIFragment *del = curr;
|
||||
curr = curr->next;
|
||||
if (del->is_malloc) {
|
||||
free(del->fragment);
|
||||
}
|
||||
free(del);
|
||||
del = NULL;
|
||||
return curr;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Delete all fragments from linked list
|
||||
|
||||
@param[in] first First fragment from the list
|
||||
*/
|
||||
void mobi_list_del_all(MOBIFragment *first) {
|
||||
while (first) {
|
||||
first = mobi_list_del(first);
|
||||
}
|
||||
}
|
||||
66
app/src/main/cpp/libmobi/src/structure.h
vendored
Normal file
66
app/src/main/cpp/libmobi/src/structure.h
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/** @file structure.h
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef mobi_structure_h
|
||||
#define mobi_structure_h
|
||||
|
||||
#include "config.h"
|
||||
#include "mobi.h"
|
||||
|
||||
/**
|
||||
@brief Dynamic array of uint32_t values structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t *data; /**< Array */
|
||||
size_t maxsize; /**< Allocated size */
|
||||
size_t step; /**< Step by which array will be enlarged if out of memory */
|
||||
size_t size; /**< Current size */
|
||||
} MOBIArray;
|
||||
|
||||
MOBIArray * array_init(const size_t len);
|
||||
MOBI_RET array_insert(MOBIArray *arr, const uint32_t value);
|
||||
void array_sort(MOBIArray *arr, const bool unique);
|
||||
size_t array_size(MOBIArray *arr);
|
||||
void array_free(MOBIArray *arr);
|
||||
|
||||
/**
|
||||
@brief Trie storing arrays of values for character keys
|
||||
*/
|
||||
typedef struct MOBITrie {
|
||||
char c; /**< Key character */
|
||||
void **values; /**< Array of values */
|
||||
size_t values_count; /**< Array size */
|
||||
struct MOBITrie *next; /**< Next node at the same level */
|
||||
struct MOBITrie *children; /**< Link to children nodes, lower level */
|
||||
} MOBITrie;
|
||||
|
||||
MOBI_RET mobi_trie_insert_reversed(MOBITrie **root, char *string, char *value);
|
||||
MOBITrie * mobi_trie_get_next(char ***values, size_t *values_count, const MOBITrie *node, const char c);
|
||||
void mobi_trie_free(MOBITrie *node);
|
||||
|
||||
/**
|
||||
@brief Structure for links reconstruction.
|
||||
|
||||
Linked list of Fragment structures forms whole document part
|
||||
*/
|
||||
typedef struct MOBIFragment {
|
||||
size_t raw_offset; /**< fragment offset in raw markup, SIZE_MAX if not present in original markup */
|
||||
unsigned char *fragment; /**< Fragment data */
|
||||
size_t size; /**< Fragment size */
|
||||
bool is_malloc; /**< Is it needed to free this fragment or is it just an alias to part data */
|
||||
struct MOBIFragment *next; /**< Link to next fragment */
|
||||
} MOBIFragment;
|
||||
|
||||
MOBIFragment * mobi_list_add(MOBIFragment *curr, size_t raw_offset, unsigned char *fragment, const size_t size, const bool is_malloc);
|
||||
MOBIFragment * mobi_list_del(MOBIFragment *curr);
|
||||
MOBI_RET mobi_list_insert(MOBIFragment **curr, size_t raw_offset, unsigned char *fragment, const size_t size, const bool is_malloc, const size_t offset);
|
||||
void mobi_list_del_all(MOBIFragment *first);
|
||||
|
||||
#endif
|
||||
3561
app/src/main/cpp/libmobi/src/util.c
vendored
Normal file
3561
app/src/main/cpp/libmobi/src/util.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
157
app/src/main/cpp/libmobi/src/util.h
vendored
Normal file
157
app/src/main/cpp/libmobi/src/util.h
vendored
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/** @file util.h
|
||||
*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef libmobi_util_h
|
||||
#define libmobi_util_h
|
||||
|
||||
#include "config.h"
|
||||
#include "mobi.h"
|
||||
#include "memory.h"
|
||||
#include "buffer.h"
|
||||
#include "read.h"
|
||||
#include "compression.h"
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
/** @brief strdup replacement */
|
||||
#define strdup mobi_strdup
|
||||
#endif
|
||||
|
||||
#ifdef USE_MINIZ
|
||||
#include "miniz.h"
|
||||
#define m_uncompress mz_uncompress
|
||||
#define m_crc32 mz_crc32
|
||||
#define M_OK MZ_OK
|
||||
#else
|
||||
#include <zlib.h>
|
||||
#define m_uncompress uncompress
|
||||
#define m_crc32 crc32
|
||||
#define M_OK Z_OK
|
||||
#endif
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
/** @brief Magic numbers of records */
|
||||
#define AUDI_MAGIC "AUDI"
|
||||
#define CDIC_MAGIC "CDIC"
|
||||
#define CMET_MAGIC "CMET"
|
||||
#define EXTH_MAGIC "EXTH"
|
||||
#define FDST_MAGIC "FDST"
|
||||
#define FONT_MAGIC "FONT"
|
||||
#define HUFF_MAGIC "HUFF"
|
||||
#define IDXT_MAGIC "IDXT"
|
||||
#define INDX_MAGIC "INDX"
|
||||
#define LIGT_MAGIC "LIGT"
|
||||
#define MOBI_MAGIC "MOBI"
|
||||
#define ORDT_MAGIC "ORDT"
|
||||
#define RESC_MAGIC "RESC"
|
||||
#define SRCS_MAGIC "SRCS"
|
||||
#define TAGX_MAGIC "TAGX"
|
||||
#define VIDE_MAGIC "VIDE"
|
||||
#define BOUNDARY_MAGIC "BOUNDARY"
|
||||
#define EOF_MAGIC "\xe9\x8e\r\n"
|
||||
#define REPLICA_MAGIC "%MOP"
|
||||
|
||||
/** @brief Difference in seconds between epoch time and mac time */
|
||||
#define EPOCH_MAC_DIFF 2082844800UL
|
||||
|
||||
/**
|
||||
@defgroup mobi_pdb Params for pdb record header structure
|
||||
@{
|
||||
*/
|
||||
#define PALMDB_HEADER_LEN 78 /**< Length of header without record info headers */
|
||||
#define PALMDB_NAME_SIZE_MAX 32 /**< Max length of db name stored at offset 0 */
|
||||
#define PALMDB_RECORD_INFO_SIZE 8 /**< Record info header size of each pdb record */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@defgroup mobi_pdb_defs Default values for pdb record header structure
|
||||
@{
|
||||
*/
|
||||
#define PALMDB_ATTRIBUTE_DEFAULT 0
|
||||
#define PALMDB_VERSION_DEFAULT 0
|
||||
#define PALMDB_MODNUM_DEFAULT 0
|
||||
#define PALMDB_APPINFO_DEFAULT 0
|
||||
#define PALMDB_SORTINFO_DEFAULT 0
|
||||
#define PALMDB_TYPE_DEFAULT "BOOK"
|
||||
#define PALMDB_CREATOR_DEFAULT "MOBI"
|
||||
#define PALMDB_NEXTREC_DEFAULT 0
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@defgroup mobi_rec0 Params for record0 header structure
|
||||
@{
|
||||
*/
|
||||
#define RECORD0_HEADER_LEN 16 /**< Length of Record 0 header */
|
||||
#define RECORD0_TEXT_SIZE_MAX 4096 /**< Max size of uncompressed text record */
|
||||
#define RECORD0_FULLNAME_SIZE_MAX 1024 /**< Max size to full name string */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@defgroup mobi_len Header length / size of records
|
||||
@{
|
||||
*/
|
||||
#define CDIC_HEADER_LEN 16
|
||||
#define CDIC_RECORD_MAXCNT 1024
|
||||
#define HUFF_CODELEN_MAX 16
|
||||
#define HUFF_HEADER_LEN 24
|
||||
#define HUFF_RECORD_MAXCNT 1024
|
||||
#define HUFF_RECORD_MINSIZE 2584
|
||||
#define FONT_HEADER_LEN 24
|
||||
#define MEDIA_HEADER_LEN 12
|
||||
#define FONT_SIZEMAX (50 * 1024 * 1024)
|
||||
#define RAWTEXT_SIZEMAX 0xfffffff
|
||||
#define MOBI_HEADER_V2_SIZE 0x18
|
||||
#define MOBI_HEADER_V3_SIZE 0x74
|
||||
#define MOBI_HEADER_V4_SIZE 0xd0
|
||||
#define MOBI_HEADER_V5_SIZE 0xe4
|
||||
#define MOBI_HEADER_V6_SIZE 0xe4
|
||||
#define MOBI_HEADER_V6_EXT_SIZE 0xe8
|
||||
#define MOBI_HEADER_V7_SIZE 0xe4
|
||||
/** @} */
|
||||
|
||||
#ifndef max
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef min
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
|
||||
#define MOBI_TITLE_SIZEMAX 1024
|
||||
|
||||
int mobi_bitcount(const uint8_t byte);
|
||||
MOBI_RET mobi_delete_record_by_seqnumber(MOBIData *m, const size_t num);
|
||||
MOBI_RET mobi_swap_mobidata(MOBIData *m);
|
||||
char * mobi_strdup(const char *s);
|
||||
bool mobi_is_cp1252(const MOBIData *m);
|
||||
bool mobi_has_drmkey(const MOBIData *m);
|
||||
bool mobi_has_drmcookies(const MOBIData *m);
|
||||
MOBI_RET mobi_cp1252_to_utf8(char *output, const char *input, size_t *outsize, const size_t insize);
|
||||
MOBI_RET mobi_utf8_to_cp1252(char *output, const char *input, size_t *outsize, const size_t insize);
|
||||
uint8_t mobi_ligature_to_cp1252(const uint8_t byte1, const uint8_t byte2);
|
||||
uint16_t mobi_ligature_to_utf16(const uint32_t byte1, const uint32_t byte2);
|
||||
MOBIFiletype mobi_determine_resource_type(const MOBIPdbRecord *record);
|
||||
MOBIFiletype mobi_determine_flowpart_type(const MOBIRawml *rawml, const size_t part_number);
|
||||
MOBI_RET mobi_base32_decode(uint32_t *decoded, const char *encoded);
|
||||
MOBIFiletype mobi_get_resourcetype_by_uid(const MOBIRawml *rawml, const size_t uid);
|
||||
uint32_t mobi_get_exthsize(const MOBIData *m);
|
||||
uint32_t mobi_get_drmsize(const MOBIData *m);
|
||||
uint16_t mobi_get_records_count(const MOBIData *m);
|
||||
void mobi_remove_zeros(unsigned char *buffer, size_t *len);
|
||||
MOBI_RET mobi_add_audio_resource(MOBIPart *part);
|
||||
MOBI_RET mobi_add_video_resource(MOBIPart *part);
|
||||
MOBI_RET mobi_add_font_resource(MOBIPart *part);
|
||||
MOBI_RET mobi_set_fullname(MOBIData *m, const char *fullname);
|
||||
MOBI_RET mobi_set_pdbname(MOBIData *m, const char *name);
|
||||
void mobi_free_internals(MOBIData *m);
|
||||
uint32_t mobi_get32be(const unsigned char buf[4]);
|
||||
uint32_t mobi_get32le(const unsigned char buf[4]);
|
||||
#endif
|
||||
540
app/src/main/cpp/libmobi/src/write.c
vendored
Normal file
540
app/src/main/cpp/libmobi/src/write.c
vendored
Normal file
|
|
@ -0,0 +1,540 @@
|
|||
/** @file write.c
|
||||
* @brief Writing functions
|
||||
*
|
||||
* Copyright (c) 2016 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "write.h"
|
||||
#include "util.h"
|
||||
#include "debug.h"
|
||||
#ifdef USE_ENCRYPTION
|
||||
#include "encryption.h"
|
||||
#endif
|
||||
|
||||
#define MOBI_HEADER_MAXLEN 280
|
||||
#define MOBI_RECORD0_PADDING 0x2002
|
||||
|
||||
/**
|
||||
@brief Write buffer contents to file
|
||||
|
||||
@param[in,out] file File descriptor
|
||||
@param[in] buf Buffer
|
||||
@return MOBI_RET status code (MOBI_SUCCESS on success)
|
||||
*/
|
||||
MOBI_RET mobi_write_buffer(FILE *file, const MOBIBuffer *buf) {
|
||||
const size_t written = fwrite(buf->data, 1, buf->maxlen, file);
|
||||
if (written != buf->maxlen) {
|
||||
debug_print("Writing failed (%s)\n", strerror(errno));
|
||||
return MOBI_WRITE_FAILED;
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Write palm database header to file
|
||||
|
||||
@param[in,out] file File descriptor
|
||||
@param[in] m MOBIData structure
|
||||
@return MOBI_RET status code (MOBI_SUCCESS on success)
|
||||
*/
|
||||
MOBI_RET mobi_write_pdbheader(FILE *file, const MOBIData *m) {
|
||||
if (m == NULL || m->ph == NULL) {
|
||||
debug_print("%s", "Mobi structure not initialized\n");
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
if (file == NULL) {
|
||||
debug_print("%s", "File not initialized\n");
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
MOBIBuffer *buf = mobi_buffer_init(PALMDB_HEADER_LEN);
|
||||
if (buf == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
mobi_buffer_addstring(buf, m->ph->name);
|
||||
size_t len = strlen(m->ph->name);
|
||||
mobi_buffer_addzeros(buf, PALMDB_NAME_SIZE_MAX - len);
|
||||
mobi_buffer_add16(buf, m->ph->attributes);
|
||||
mobi_buffer_add16(buf, m->ph->version);
|
||||
mobi_buffer_add32(buf, m->ph->ctime);
|
||||
mobi_buffer_add32(buf, m->ph->mtime);
|
||||
mobi_buffer_add32(buf, m->ph->btime);
|
||||
mobi_buffer_add32(buf, m->ph->mod_num);
|
||||
mobi_buffer_add32(buf, m->ph->appinfo_offset);
|
||||
mobi_buffer_add32(buf, m->ph->sortinfo_offset);
|
||||
mobi_buffer_addstring(buf, m->ph->type);
|
||||
mobi_buffer_addstring(buf, m->ph->creator);
|
||||
mobi_buffer_add32(buf, m->ph->uid);
|
||||
mobi_buffer_add32(buf, m->ph->next_rec);
|
||||
m->ph->rec_count = mobi_get_records_count(m);
|
||||
if (m->ph->rec_count == 0) {
|
||||
mobi_buffer_free(buf);
|
||||
debug_print("%s", "Zero records count\n");
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
mobi_buffer_add16(buf, m->ph->rec_count);
|
||||
if (buf->error != MOBI_SUCCESS) {
|
||||
mobi_buffer_free(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
MOBI_RET ret = mobi_write_buffer(file, buf);
|
||||
mobi_buffer_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Serialize mobi header to buffer
|
||||
|
||||
@param[in,out] buf output buffer
|
||||
@param[in] m MOBIData structure
|
||||
@param[in] exthsize Size of exth record
|
||||
@return MOBI_RET status code (MOBI_SUCCESS on success)
|
||||
*/
|
||||
MOBI_RET mobi_serialize_mobiheader(MOBIBuffer *buf, const MOBIData *m, const uint32_t exthsize) {
|
||||
if (m == NULL || m->mh == NULL || buf == NULL) {
|
||||
debug_print("%s", "Mobi structure not initialized\n");
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
size_t buffer_init = buf->offset;
|
||||
mobi_buffer_addstring(buf, m->mh->mobi_magic);
|
||||
if (buf->offset > UINT32_MAX) {
|
||||
debug_print("Offset too large: %zu\n", buf->offset);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
uint32_t length_offset = (uint32_t) buf->offset;
|
||||
uint32_t name_offset = 0;
|
||||
uint32_t drm_offset = 0;
|
||||
mobi_buffer_add32(buf, 0); /* dummy length */
|
||||
if (m->mh->mobi_type) { mobi_buffer_add32(buf, *m->mh->mobi_type); } else { goto finalize; }
|
||||
if (m->mh->text_encoding) { mobi_buffer_add32(buf, *m->mh->text_encoding); } else { goto finalize; }
|
||||
if (m->mh->uid) { mobi_buffer_add32(buf, *m->mh->uid); } else { goto finalize; }
|
||||
bool isKF8 = false;
|
||||
if (m->mh->version) {
|
||||
mobi_buffer_add32(buf, *m->mh->version);
|
||||
if (*m->mh->version == 8) {
|
||||
isKF8 = true;
|
||||
}
|
||||
} else { goto finalize; }
|
||||
if (m->mh->orth_index) { mobi_buffer_add32(buf, *m->mh->orth_index); } else { goto finalize; }
|
||||
if (m->mh->infl_index) { mobi_buffer_add32(buf, *m->mh->infl_index); } else { goto finalize; }
|
||||
if (m->mh->names_index) { mobi_buffer_add32(buf, *m->mh->names_index); } else { goto finalize; }
|
||||
if (m->mh->keys_index) { mobi_buffer_add32(buf, *m->mh->keys_index); } else { goto finalize; }
|
||||
if (m->mh->extra0_index) { mobi_buffer_add32(buf, *m->mh->extra0_index); } else { goto finalize; }
|
||||
if (m->mh->extra1_index) { mobi_buffer_add32(buf, *m->mh->extra1_index); } else { goto finalize; }
|
||||
if (m->mh->extra2_index) { mobi_buffer_add32(buf, *m->mh->extra2_index); } else { goto finalize; }
|
||||
if (m->mh->extra3_index) { mobi_buffer_add32(buf, *m->mh->extra3_index); } else { goto finalize; }
|
||||
if (m->mh->extra4_index) { mobi_buffer_add32(buf, *m->mh->extra4_index); } else { goto finalize; }
|
||||
if (m->mh->extra5_index) { mobi_buffer_add32(buf, *m->mh->extra5_index); } else { goto finalize; }
|
||||
if (m->mh->non_text_index) { mobi_buffer_add32(buf, *m->mh->non_text_index); } else { goto finalize; }
|
||||
if (m->mh->full_name) {
|
||||
if (buf->offset > UINT32_MAX) {
|
||||
debug_print("Offset too large: %zu\n", buf->offset);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
name_offset = (uint32_t) buf->offset;
|
||||
mobi_buffer_add32(buf, MOBI_NOTSET);
|
||||
mobi_buffer_add32(buf, 0);
|
||||
} else { goto finalize; }
|
||||
if (m->mh->locale) { mobi_buffer_add32(buf, *m->mh->locale); } else { goto finalize; }
|
||||
if (m->mh->dict_input_lang) { mobi_buffer_add32(buf, *m->mh->dict_input_lang); } else { goto finalize; }
|
||||
if (m->mh->dict_output_lang) { mobi_buffer_add32(buf, *m->mh->dict_output_lang); } else { goto finalize; }
|
||||
if (m->mh->min_version) { mobi_buffer_add32(buf, *m->mh->min_version); } else { goto finalize; }
|
||||
if (m->mh->image_index) { mobi_buffer_add32(buf, *m->mh->image_index); } else { goto finalize; }
|
||||
if (m->mh->huff_rec_index) { mobi_buffer_add32(buf, *m->mh->huff_rec_index); } else { goto finalize; }
|
||||
if (m->mh->huff_rec_count) { mobi_buffer_add32(buf, *m->mh->huff_rec_count); } else { goto finalize; }
|
||||
if (m->mh->datp_rec_index) { mobi_buffer_add32(buf, *m->mh->datp_rec_index); } else { goto finalize; }
|
||||
if (m->mh->datp_rec_count) { mobi_buffer_add32(buf, *m->mh->datp_rec_count); } else { goto finalize; }
|
||||
if (m->mh->exth_flags) { mobi_buffer_add32(buf, *m->mh->exth_flags); } else { goto finalize; }
|
||||
mobi_buffer_addzeros(buf, 32); /* 32 unknown bytes */
|
||||
if (m->mh->unknown6) { mobi_buffer_add32(buf, *m->mh->unknown6); } else { goto finalize; }
|
||||
if (m->mh->drm_offset) {
|
||||
drm_offset = (uint32_t) buf->offset;
|
||||
mobi_buffer_add32(buf, *m->mh->drm_offset);
|
||||
} else { goto finalize; }
|
||||
if (m->mh->drm_count) { mobi_buffer_add32(buf, *m->mh->drm_count); } else { goto finalize; }
|
||||
if (m->mh->drm_size) { mobi_buffer_add32(buf, *m->mh->drm_size); } else { goto finalize; }
|
||||
if (m->mh->drm_flags) { mobi_buffer_add32(buf, *m->mh->drm_flags); } else { goto finalize; }
|
||||
mobi_buffer_addzeros(buf, 8); /* 8 unknown bytes */
|
||||
if (isKF8) {
|
||||
if (m->mh->fdst_index) { mobi_buffer_add32(buf, *m->mh->fdst_index); } else { goto finalize; }
|
||||
} else {
|
||||
if (m->mh->first_text_index) { mobi_buffer_add16(buf, *m->mh->first_text_index); } else { goto finalize; }
|
||||
if (m->mh->last_text_index) { mobi_buffer_add16(buf, *m->mh->last_text_index); } else { goto finalize; }
|
||||
}
|
||||
if (m->mh->fdst_section_count) { mobi_buffer_add32(buf, *m->mh->fdst_section_count); } else { goto finalize; }
|
||||
if (m->mh->fcis_index) { mobi_buffer_add32(buf, *m->mh->fcis_index); } else { goto finalize; }
|
||||
if (m->mh->fcis_count) { mobi_buffer_add32(buf, *m->mh->fcis_count); } else { goto finalize; }
|
||||
if (m->mh->flis_index) { mobi_buffer_add32(buf, *m->mh->flis_index); } else { goto finalize; }
|
||||
if (m->mh->flis_count) { mobi_buffer_add32(buf, *m->mh->flis_count); } else { goto finalize; }
|
||||
if (m->mh->unknown10) { mobi_buffer_add32(buf, *m->mh->unknown10); } else { goto finalize; }
|
||||
if (m->mh->unknown11) { mobi_buffer_add32(buf, *m->mh->unknown11); } else { goto finalize; }
|
||||
if (m->mh->srcs_index) { mobi_buffer_add32(buf, *m->mh->srcs_index); } else { goto finalize; }
|
||||
if (m->mh->srcs_count) { mobi_buffer_add32(buf, *m->mh->srcs_count); } else { goto finalize; }
|
||||
if (m->mh->unknown12) { mobi_buffer_add32(buf, *m->mh->unknown12); } else { goto finalize; }
|
||||
if (m->mh->unknown13) { mobi_buffer_add32(buf, *m->mh->unknown13); } else { goto finalize; }
|
||||
mobi_buffer_addzeros(buf, 2); /* 2 unknown bytes */
|
||||
if (m->mh->extra_flags) { mobi_buffer_add16(buf, *m->mh->extra_flags); } else { goto finalize; }
|
||||
if (m->mh->ncx_index) { mobi_buffer_add32(buf, *m->mh->ncx_index); } else { goto finalize; }
|
||||
if (isKF8) {
|
||||
if (m->mh->fragment_index) { mobi_buffer_add32(buf, *m->mh->fragment_index); } else { goto finalize; }
|
||||
if (m->mh->skeleton_index) { mobi_buffer_add32(buf, *m->mh->skeleton_index); } else { goto finalize; }
|
||||
} else {
|
||||
if (m->mh->unknown14) { mobi_buffer_add32(buf, *m->mh->unknown14); } else { goto finalize; }
|
||||
if (m->mh->unknown15) { mobi_buffer_add32(buf, *m->mh->unknown15); } else { goto finalize; }
|
||||
}
|
||||
if (m->mh->datp_index) { mobi_buffer_add32(buf, *m->mh->datp_index); } else { goto finalize; }
|
||||
if (isKF8) {
|
||||
if (m->mh->guide_index) { mobi_buffer_add32(buf, *m->mh->guide_index); } else { goto finalize; }
|
||||
} else {
|
||||
if (m->mh->unknown16) { mobi_buffer_add32(buf, *m->mh->unknown16); } else { goto finalize; }
|
||||
}
|
||||
if (m->mh->unknown17) { mobi_buffer_add32(buf, *m->mh->unknown17); } else { goto finalize; }
|
||||
if (m->mh->unknown18) { mobi_buffer_add32(buf, *m->mh->unknown18); } else { goto finalize; }
|
||||
if (m->mh->unknown19) { mobi_buffer_add32(buf, *m->mh->unknown19); } else { goto finalize; }
|
||||
if (m->mh->unknown20) { mobi_buffer_add32(buf, *m->mh->unknown20); } else { goto finalize; }
|
||||
|
||||
finalize:
|
||||
if (buf->error != MOBI_SUCCESS) {
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
size_t headersize = buf->offset - buffer_init;
|
||||
if (headersize > UINT32_MAX) {
|
||||
debug_print("Header too large: %zu\n", headersize);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
size_t saved_offset = buf->offset;
|
||||
/* write header length at offset 20 */
|
||||
mobi_buffer_setpos(buf, length_offset);
|
||||
mobi_buffer_add32(buf, (uint32_t) headersize);
|
||||
*m->mh->header_length = (uint32_t) headersize;
|
||||
uint32_t drmsize = 0;
|
||||
#ifdef USE_ENCRYPTION
|
||||
if (m->rh->encryption_type == MOBI_ENCRYPTION_V2 &&
|
||||
m->mh->drm_size && m->mh->drm_offset && *m->mh->drm_size > 0) {
|
||||
drmsize = mobi_get_drmsize(m);
|
||||
*m->mh->drm_offset = RECORD0_HEADER_LEN + (uint32_t) headersize + exthsize;
|
||||
mobi_buffer_setpos(buf, drm_offset);
|
||||
mobi_buffer_add32(buf, *m->mh->drm_offset);
|
||||
} else if (m->rh->encryption_type == MOBI_ENCRYPTION_V1) {
|
||||
drmsize = mobi_get_drmsize(m);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m->mh->full_name) {
|
||||
/* full name's offset is after exth records */
|
||||
uint32_t fullname_offset = RECORD0_HEADER_LEN + (uint32_t) headersize + exthsize + drmsize;
|
||||
size_t fullname_length = strlen(m->mh->full_name);
|
||||
if (fullname_length > MOBI_TITLE_SIZEMAX) {
|
||||
fullname_length = MOBI_TITLE_SIZEMAX;
|
||||
m->mh->full_name[MOBI_TITLE_SIZEMAX] = '\0';
|
||||
}
|
||||
/* write fullname offset and length */
|
||||
mobi_buffer_setpos(buf, name_offset);
|
||||
mobi_buffer_add32(buf, fullname_offset);
|
||||
mobi_buffer_add32(buf, (uint32_t) fullname_length);
|
||||
if (m->mh->full_name_offset == NULL) {
|
||||
m->mh->full_name_offset = malloc(sizeof(uint32_t));
|
||||
if (m->mh->full_name_offset == NULL) {
|
||||
debug_print("Memory allocation failed%s", "\n");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
}
|
||||
*m->mh->full_name_offset = fullname_offset;
|
||||
if (m->mh->full_name_length == NULL) {
|
||||
m->mh->full_name_length = malloc(sizeof(uint32_t));
|
||||
if (m->mh->full_name_length == NULL) {
|
||||
debug_print("Memory allocation failed%s", "\n");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
}
|
||||
*m->mh->full_name_length = (uint32_t) fullname_length;
|
||||
}
|
||||
mobi_buffer_setpos(buf, saved_offset);
|
||||
if (buf->error != MOBI_SUCCESS) {
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Serialize exth header to buffer
|
||||
|
||||
@param[in,out] buf output buffer
|
||||
@param[in] m MOBIData structure
|
||||
@return MOBI_RET status code (MOBI_SUCCESS on success)
|
||||
*/
|
||||
MOBI_RET mobi_serialize_extheader(MOBIBuffer *buf, const MOBIData *m) {
|
||||
if (m == NULL || m->eh == NULL) {
|
||||
debug_print("%s", "Mobi structure not initialized\n");
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
MOBIExthHeader *curr = m->eh;
|
||||
mobi_buffer_addstring(buf, EXTH_MAGIC);
|
||||
const size_t length_offset = buf->offset;
|
||||
size_t length = 12; /* start with header length */
|
||||
mobi_buffer_add32(buf, 0);
|
||||
const size_t count_offset = buf->offset;
|
||||
size_t count = 0;
|
||||
mobi_buffer_add32(buf, 0);
|
||||
while (curr) {
|
||||
/* total size = data size plus 8 bytes for uid and size */
|
||||
const uint32_t size = curr->size + 8;
|
||||
length += size;
|
||||
count++;
|
||||
mobi_buffer_add32(buf, curr->tag);
|
||||
mobi_buffer_add32(buf, size);
|
||||
mobi_buffer_addraw(buf, curr->data, curr->size);
|
||||
if (buf->error != MOBI_SUCCESS) {
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
if (length > UINT32_MAX || count > UINT32_MAX) {
|
||||
debug_print("Length (%zu) or count (%zu) too large\n", length, count);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
/* add padding */
|
||||
const size_t padding_size = length % 4;
|
||||
length += padding_size;
|
||||
mobi_buffer_addzeros(buf, padding_size);
|
||||
const size_t saved_offset = buf->offset;
|
||||
mobi_buffer_setpos(buf, length_offset);
|
||||
mobi_buffer_add32(buf, (uint32_t) length);
|
||||
mobi_buffer_setpos(buf, count_offset);
|
||||
mobi_buffer_add32(buf, (uint32_t) count);
|
||||
mobi_buffer_setpos(buf, saved_offset);
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Serialize record0 and update record in MOBIData structure.
|
||||
|
||||
Record0 sequential number may be greater than zero in case
|
||||
of hybrid file with two info records
|
||||
|
||||
@param[in,out] m MOBIData structure
|
||||
@param[in] seqnumber Record0 sequential number
|
||||
@return MOBI_RET status code (MOBI_SUCCESS on success)
|
||||
*/
|
||||
MOBI_RET mobi_update_record0(MOBIData *m, const size_t seqnumber) {
|
||||
if (m == NULL || m->rh == NULL || m->rec == NULL) {
|
||||
debug_print("%s", "Mobi structure not initialized\n");
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
size_t padding = MOBI_RECORD0_PADDING;
|
||||
if (!mobi_exists_mobiheader(m)) {
|
||||
padding = 0;
|
||||
} else if (mobi_get_fileversion(m) < 8) {
|
||||
padding -= 12;
|
||||
}
|
||||
size_t record0_maxlen = RECORD0_HEADER_LEN + MOBI_HEADER_MAXLEN;
|
||||
uint32_t exthsize = mobi_get_exthsize(m);
|
||||
uint32_t drmsize = mobi_get_drmsize(m);
|
||||
record0_maxlen += exthsize;
|
||||
record0_maxlen += drmsize;
|
||||
record0_maxlen += MOBI_TITLE_SIZEMAX;
|
||||
record0_maxlen += padding;
|
||||
MOBIBuffer *buf = mobi_buffer_init(record0_maxlen);
|
||||
if (buf == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
mobi_buffer_add16(buf, m->rh->compression_type);
|
||||
mobi_buffer_addzeros(buf, 2);
|
||||
mobi_buffer_add32(buf, m->rh->text_length);
|
||||
mobi_buffer_add16(buf, m->rh->text_record_count);
|
||||
mobi_buffer_add16(buf, m->rh->text_record_size);
|
||||
mobi_buffer_add16(buf, m->rh->encryption_type);
|
||||
mobi_buffer_add16(buf, m->rh->unknown1);
|
||||
|
||||
if (m->mh) {
|
||||
MOBI_RET ret = mobi_serialize_mobiheader(buf, m, exthsize);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
mobi_buffer_free(buf);
|
||||
return ret;
|
||||
}
|
||||
if (m->eh) {
|
||||
ret = mobi_serialize_extheader(buf, m);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
mobi_buffer_free(buf);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_ENCRYPTION
|
||||
if (m->rh->encryption_type == MOBI_ENCRYPTION_V1) {
|
||||
ret = mobi_drm_serialize_v1(buf, m);
|
||||
} else if (m->rh->encryption_type == MOBI_ENCRYPTION_V2) {
|
||||
ret = mobi_drm_serialize_v2(buf, m);
|
||||
}
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
mobi_buffer_free(buf);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
if (m->mh->full_name && m->mh->full_name_offset) {
|
||||
mobi_buffer_setpos(buf, *m->mh->full_name_offset);
|
||||
mobi_buffer_addstring(buf, m->mh->full_name);
|
||||
if (buf->error != MOBI_SUCCESS) {
|
||||
mobi_buffer_free(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef USE_ENCRYPTION
|
||||
else if (m->rh->encryption_type == MOBI_ENCRYPTION_V1) {
|
||||
MOBI_RET ret = mobi_drm_serialize_v1(buf, m);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
mobi_buffer_free(buf);
|
||||
return ret;
|
||||
}
|
||||
mobi_buffer_setpos(buf, 14 + drmsize);
|
||||
}
|
||||
#endif
|
||||
|
||||
mobi_buffer_addzeros(buf, padding);
|
||||
if (buf->error) {
|
||||
mobi_buffer_free(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
|
||||
MOBIPdbRecord *record0 = mobi_get_record_by_seqnumber(m, seqnumber);
|
||||
if (record0 == NULL) {
|
||||
debug_print("%s", "Record 0 not initialized\n");
|
||||
mobi_buffer_free(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
unsigned char *data = malloc(buf->offset);
|
||||
if (data == NULL) {
|
||||
mobi_buffer_free(buf);
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
memcpy(data, buf->data, buf->offset);
|
||||
record0->size = buf->offset;
|
||||
mobi_buffer_free(buf);
|
||||
if (record0->data) {
|
||||
free(record0->data);
|
||||
}
|
||||
record0->data = data;
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Write palm database records to file
|
||||
|
||||
@param[in,out] file File descriptor
|
||||
@param[in] m MOBIData structure
|
||||
@return MOBI_RET status code (MOBI_SUCCESS on success)
|
||||
*/
|
||||
MOBI_RET mobi_write_records(FILE *file, const MOBIData *m) {
|
||||
if (m == NULL || m->rec == NULL) {
|
||||
debug_print("%s", "Mobi structure not initialized\n");
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
if (file == NULL) {
|
||||
return MOBI_PARAM_ERR;
|
||||
}
|
||||
long pos = ftell(file);
|
||||
if (pos < 0) {
|
||||
return MOBI_WRITE_FAILED;
|
||||
}
|
||||
uint32_t offset = (uint32_t) pos;
|
||||
/* 8 bytes per record meta plus 2 bytes padding */
|
||||
offset += 8 * m->ph->rec_count + 2;
|
||||
MOBIPdbRecord *curr = m->rec;
|
||||
uint32_t i = 0;
|
||||
while (curr) {
|
||||
if (offset > UINT32_MAX) {
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
MOBIBuffer *buf = mobi_buffer_init(PALMDB_RECORD_INFO_SIZE);
|
||||
if (buf == NULL) {
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
mobi_buffer_add32(buf, (uint32_t) offset);
|
||||
offset += curr->size;
|
||||
mobi_buffer_add8(buf, curr->attributes);
|
||||
curr->uid = 2 * i++;
|
||||
const uint8_t h = (uint8_t) ((curr->uid & 0xff0000U) >> 16);
|
||||
const uint16_t l = (uint16_t) (curr->uid & 0xffffU);
|
||||
mobi_buffer_add8(buf, h);
|
||||
mobi_buffer_add16(buf, l);
|
||||
if (buf->error != MOBI_SUCCESS) {
|
||||
mobi_buffer_free(buf);
|
||||
return MOBI_DATA_CORRUPT;
|
||||
}
|
||||
MOBI_RET ret = mobi_write_buffer(file, buf);
|
||||
mobi_buffer_free(buf);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
char padding[2] = { 0 };
|
||||
size_t written = fwrite(padding, 1, sizeof(padding), file);
|
||||
if (written != sizeof(padding)) {
|
||||
debug_print("Writing failed (%s)\n", strerror(errno));
|
||||
return MOBI_WRITE_FAILED;
|
||||
}
|
||||
|
||||
curr = m->rec;
|
||||
while (curr) {
|
||||
written = fwrite(curr->data, 1, curr->size, file);
|
||||
if (written != curr->size) {
|
||||
debug_print("Writing failed (%s)\n", strerror(errno));
|
||||
return MOBI_WRITE_FAILED;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Write mobi document to file.
|
||||
|
||||
Serializes metadata from MOBIData into raw records also stored in MOBIData (m->rec).
|
||||
Later writes palm database to file.
|
||||
|
||||
@param[in,out] file File descriptor
|
||||
@param[in,out] m MOBIData structure
|
||||
@return MOBI_RET status code (MOBI_SUCCESS on success)
|
||||
*/
|
||||
MOBI_RET mobi_write_file(FILE *file, MOBIData *m) {
|
||||
MOBI_RET ret = mobi_write_pdbheader(file, m);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
MOBIData *m_kf7 = m;
|
||||
if (mobi_is_hybrid(m) && m->next) {
|
||||
MOBIData *m_kf8 = m;
|
||||
if (m->use_kf8 == false) {
|
||||
m_kf8 = m->next;
|
||||
} else {
|
||||
m_kf7 = m->next;
|
||||
}
|
||||
const size_t record0_kf8_offset = m_kf8->kf8_boundary_offset + 1;
|
||||
ret = mobi_update_record0(m_kf8, record0_kf8_offset);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = mobi_update_record0(m_kf7, 0);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
ret = mobi_write_records(file, m);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
|
||||
}
|
||||
18
app/src/main/cpp/libmobi/src/write.h
vendored
Normal file
18
app/src/main/cpp/libmobi/src/write.h
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef libmobi_write_h
|
||||
#define libmobi_write_h
|
||||
|
||||
#include "config.h"
|
||||
#include "mobi.h"
|
||||
#include "buffer.h"
|
||||
|
||||
|
||||
#endif
|
||||
918
app/src/main/cpp/libmobi/src/xmlwriter.c
vendored
Normal file
918
app/src/main/cpp/libmobi/src/xmlwriter.c
vendored
Normal file
|
|
@ -0,0 +1,918 @@
|
|||
/** @file xmlwriter.c
|
||||
* @brief Implements a simplified subset of libxml2 functions used in libmobi.
|
||||
*
|
||||
* Copyright (c) 2016 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
#ifndef __USE_BSD
|
||||
#define __USE_BSD /* for strdup on linux/glibc */
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "xmlwriter.h"
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
#include "parse_rawml.h"
|
||||
|
||||
#define MOBI_XML_BUFFERSIZE 4096
|
||||
#define MOBI_XML_STATESSIZE 200
|
||||
#define XML_ERROR -1
|
||||
#define XML_OK 0
|
||||
|
||||
/**
|
||||
@brief Initiate xml states with first name and mode pair
|
||||
|
||||
@param[in] name MOBIRawml State element name
|
||||
@param[in] mode MOBIRawml State mode
|
||||
@return New state
|
||||
*/
|
||||
static MOBIXmlState * mobi_xml_state_init(const char *name, const MOBI_XML_MODE mode) {
|
||||
MOBIXmlState *curr = calloc(1, sizeof(MOBIXmlState));
|
||||
if (curr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
curr->name = strdup(name);
|
||||
if (curr->name == NULL) {
|
||||
free(curr);
|
||||
return NULL;
|
||||
}
|
||||
curr->mode = mode;
|
||||
return curr;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get current active state from the list
|
||||
|
||||
@param[in] writer xmlTextWriter
|
||||
@return State
|
||||
*/
|
||||
static MOBIXmlState * mobi_xml_state_current(const xmlTextWriterPtr writer) {
|
||||
return writer->states;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Add new state to the list
|
||||
|
||||
@param[in,out] writer xmlTextWriter
|
||||
@param[in] name MOBIRawml State element name
|
||||
@param[in] mode MOBIRawml State mode
|
||||
@return Added state
|
||||
*/
|
||||
static MOBIXmlState * mobi_xml_state_push(xmlTextWriterPtr writer, const char *name, const MOBI_XML_MODE mode) {
|
||||
MOBIXmlState *new = mobi_xml_state_init(name, mode);
|
||||
MOBIXmlState *first = writer->states;
|
||||
if (!first) {
|
||||
writer->states = new;
|
||||
} else {
|
||||
new->next = first;
|
||||
writer->states = new;
|
||||
}
|
||||
return writer->states;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Remove state from the list
|
||||
|
||||
@param[in] state State structure that will be deleted
|
||||
@return Next state in the list or NULL if not present
|
||||
*/
|
||||
static MOBIXmlState * mobi_xml_state_del(MOBIXmlState *state) {
|
||||
MOBIXmlState *del = state;
|
||||
state = state->next;
|
||||
free(del->name);
|
||||
free(del);
|
||||
del = NULL;
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Remove state from the beginning of the list
|
||||
|
||||
@param[in,out] writer xmlTextWriter
|
||||
@return Next state or NULL if not present
|
||||
*/
|
||||
static MOBIXmlState * mobi_xml_state_pop(xmlTextWriterPtr writer) {
|
||||
writer->states = mobi_xml_state_del(writer->states);
|
||||
return writer->states;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Remove all states from the list
|
||||
|
||||
@param[in,out] first First state from the list
|
||||
*/
|
||||
static void mobi_xml_state_delall(MOBIXmlState *first) {
|
||||
while (first) {
|
||||
first = mobi_xml_state_del(first);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get current level of nested element
|
||||
|
||||
@param[in] writer xmlTextWriter
|
||||
@return Level
|
||||
*/
|
||||
static size_t mobi_xml_level(const xmlTextWriterPtr writer) {
|
||||
MOBIXmlState *curr = writer->states;
|
||||
size_t level = 0;
|
||||
while (curr) {
|
||||
level++;
|
||||
if (curr->next == NULL) {
|
||||
break;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Write string to xml buffer
|
||||
|
||||
@param[in,out] writer xmlTextWriter
|
||||
@param[in] string String
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_xml_buffer_addstring(xmlTextWriterPtr writer, const char *string) {
|
||||
if (writer == NULL || writer->xmlbuf == NULL || writer->xmlbuf->mobibuffer == NULL || string == NULL) {
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
MOBIBuffer *buf = writer->xmlbuf->mobibuffer;
|
||||
mobi_buffer_addstring(buf, string);
|
||||
if (buf->error == MOBI_BUFFER_END) {
|
||||
mobi_buffer_resize(buf, buf->maxlen * 2);
|
||||
if (buf->error != MOBI_SUCCESS) {
|
||||
return buf->error;
|
||||
}
|
||||
/* update xmlbuf->content */
|
||||
writer->xmlbuf->content = writer->xmlbuf->mobibuffer->data;
|
||||
mobi_xml_buffer_addstring(writer, string);
|
||||
}
|
||||
return buf->error;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Write character to xml buffer
|
||||
|
||||
@param[in,out] writer xmlTextWriter
|
||||
@param[in] c Character
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_xml_buffer_addchar(xmlTextWriterPtr writer, const unsigned char c) {
|
||||
if (writer == NULL || writer->xmlbuf == NULL || writer->xmlbuf->mobibuffer == NULL) {
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
MOBIBuffer *buf = writer->xmlbuf->mobibuffer;
|
||||
mobi_buffer_add8(buf, c);
|
||||
if (buf->error == MOBI_BUFFER_END) {
|
||||
mobi_buffer_resize(buf, buf->maxlen * 2);
|
||||
if (buf->error != MOBI_SUCCESS) {
|
||||
return buf->error;
|
||||
}
|
||||
/* update xmlbuf->content */
|
||||
writer->xmlbuf->content = writer->xmlbuf->mobibuffer->data;
|
||||
mobi_xml_buffer_addchar(writer, c);
|
||||
}
|
||||
return buf->error;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Write terminating null character to xml buffer
|
||||
|
||||
@param[in,out] writer xmlTextWriter
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_xml_buffer_flush(xmlTextWriterPtr writer) {
|
||||
return mobi_xml_buffer_addchar(writer, '\0');
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Write string with encoded reserved characters to xml buffer
|
||||
|
||||
@param[in,out] writer xmlTextWriter
|
||||
@param[in] string String
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_xml_buffer_addencoded(xmlTextWriterPtr writer, const char *string) {
|
||||
if (string == NULL) {
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
MOBI_RET ret = MOBI_SUCCESS;
|
||||
unsigned char *p = (unsigned char *)string;
|
||||
unsigned char c;
|
||||
while ((c = *p++)) {
|
||||
switch (c) {
|
||||
case '<':
|
||||
ret = mobi_xml_buffer_addstring(writer, "<");
|
||||
break;
|
||||
case '>':
|
||||
ret = mobi_xml_buffer_addstring(writer, ">");
|
||||
break;
|
||||
case '&':
|
||||
ret = mobi_xml_buffer_addstring(writer, "&");
|
||||
break;
|
||||
case '"':
|
||||
ret = mobi_xml_buffer_addstring(writer, """);
|
||||
break;
|
||||
case '\r':
|
||||
ret = mobi_xml_buffer_addstring(writer, " ");
|
||||
break;
|
||||
default:
|
||||
ret = mobi_xml_buffer_addchar(writer, c);
|
||||
break;
|
||||
}
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Write attribute value with encoded reserved characters to xml buffer
|
||||
|
||||
@param[in,out] writer xmlTextWriter
|
||||
@param[in] string String
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_xml_buffer_addencoded_attr(xmlTextWriterPtr writer, const char *string) {
|
||||
if (string == NULL) {
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
MOBI_RET ret = MOBI_SUCCESS;
|
||||
unsigned char *p = (unsigned char *)string;
|
||||
unsigned char c;
|
||||
while ((c = *p++)) {
|
||||
switch (c) {
|
||||
case '<':
|
||||
ret = mobi_xml_buffer_addstring(writer, "<");
|
||||
break;
|
||||
case '>':
|
||||
ret = mobi_xml_buffer_addstring(writer, ">");
|
||||
break;
|
||||
case '&':
|
||||
ret = mobi_xml_buffer_addstring(writer, "&");
|
||||
break;
|
||||
case '"':
|
||||
ret = mobi_xml_buffer_addstring(writer, """);
|
||||
break;
|
||||
case '\r':
|
||||
ret = mobi_xml_buffer_addstring(writer, " ");
|
||||
break;
|
||||
case '\n':
|
||||
ret = mobi_xml_buffer_addstring(writer, " ");
|
||||
break;
|
||||
case '\t':
|
||||
ret = mobi_xml_buffer_addstring(writer, "	");
|
||||
break;
|
||||
default:
|
||||
ret = mobi_xml_buffer_addchar(writer, c);
|
||||
break;
|
||||
}
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Write indent to xml buffer
|
||||
|
||||
@param[in,out] writer xmlTextWriter
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_xml_write_indent(xmlTextWriterPtr writer) {
|
||||
if (writer == NULL) {
|
||||
debug_print("%s\n", "XML writer init failed");
|
||||
return MOBI_INIT_FAILED;
|
||||
}
|
||||
size_t levels_count = mobi_xml_level(writer);
|
||||
if (levels_count > 0) {
|
||||
/* don't indent first level */
|
||||
levels_count--;
|
||||
}
|
||||
MOBI_RET ret = MOBI_SUCCESS;
|
||||
while (levels_count--) {
|
||||
ret = mobi_xml_buffer_addchar(writer, ' ');
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Write namespace declaration if needed
|
||||
|
||||
@param[in,out] writer xmlTextWriter
|
||||
*/
|
||||
static void mobi_xml_write_ns(xmlTextWriterPtr writer) {
|
||||
if (writer && writer->nsname && writer->nsvalue) {
|
||||
xmlTextWriterWriteAttribute(writer, (unsigned char *) writer->nsname, (unsigned char *) writer->nsvalue);
|
||||
free(writer->nsname);
|
||||
writer->nsname = NULL;
|
||||
free(writer->nsvalue);
|
||||
writer->nsvalue = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Save namespace declaration parameters
|
||||
|
||||
@param[in,out] writer xmlTextWriter
|
||||
@param[in] nsname NS attribute name
|
||||
@param[in] nsvalue NS attribute value
|
||||
@return MOBI_RET status code (on success MOBI_SUCCESS)
|
||||
*/
|
||||
static MOBI_RET mobi_xml_save_ns(xmlTextWriterPtr writer, const char *nsname, const char *nsvalue) {
|
||||
/* Only one declaration should be enough for libmobi */
|
||||
if (writer && writer->nsname == NULL && writer->nsvalue == NULL) {
|
||||
writer->nsname = strdup(nsname);
|
||||
if (writer->nsname == NULL) {
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
writer->nsvalue = strdup(nsvalue);
|
||||
if (writer->nsvalue == NULL) {
|
||||
return MOBI_MALLOC_FAILED;
|
||||
}
|
||||
}
|
||||
return MOBI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Libxml2 compatible functions
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
@brief Create xml buffer
|
||||
|
||||
Libxml2 compatibility wrapper for MOBIBuffer structure.
|
||||
Must be deallocated with xmlBufferFree
|
||||
|
||||
@return Buffer pointer
|
||||
*/
|
||||
xmlBufferPtr xmlBufferCreate(void) {
|
||||
xmlBufferPtr xmlbuf = NULL;
|
||||
xmlbuf = malloc(sizeof(xmlBuffer));
|
||||
if (xmlbuf == NULL) {
|
||||
debug_print("%s", "Buffer allocation failed\n");
|
||||
return NULL;
|
||||
}
|
||||
unsigned int size = MOBI_XML_BUFFERSIZE;
|
||||
MOBIBuffer *buf = mobi_buffer_init(size);
|
||||
if (buf == NULL) {
|
||||
free(xmlbuf);
|
||||
return NULL;
|
||||
}
|
||||
xmlbuf->content = buf->data;
|
||||
xmlbuf->mobibuffer = buf;
|
||||
return xmlbuf;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Free XML buffer
|
||||
|
||||
@param[in,out] buf XML buffer
|
||||
*/
|
||||
void xmlBufferFree(xmlBufferPtr buf) {
|
||||
if (buf == NULL) { return; }
|
||||
if (buf->mobibuffer != NULL) {
|
||||
mobi_buffer_free(buf->mobibuffer);
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Initialize TextWriter structure
|
||||
|
||||
@param[in] xmlbuf Initialized xml output buffer
|
||||
@param[in] compression Unused
|
||||
@return TextWriter pointer
|
||||
*/
|
||||
xmlTextWriterPtr xmlNewTextWriterMemory(xmlBufferPtr xmlbuf, int compression) {
|
||||
UNUSED(compression);
|
||||
if (xmlbuf == NULL) {
|
||||
debug_print("%s", "XML buffer not initialized\n");
|
||||
return NULL;
|
||||
}
|
||||
xmlTextWriterPtr writer = NULL;
|
||||
writer = malloc(sizeof(xmlTextWriter));
|
||||
if (writer == NULL) {
|
||||
debug_print("%s", "XML writer allocation failed\n");
|
||||
return NULL;
|
||||
}
|
||||
writer->xmlbuf = xmlbuf;
|
||||
writer->states = NULL;
|
||||
writer->nsname = NULL;
|
||||
writer->nsvalue = NULL;
|
||||
writer->indent_enable = false;
|
||||
writer->indent_next = false;
|
||||
return writer;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Deallocate TextWriter instance and all its resources
|
||||
|
||||
@param[in,out] writer TextWriter
|
||||
*/
|
||||
void xmlFreeTextWriter(xmlTextWriterPtr writer) {
|
||||
if (writer == NULL) { return; }
|
||||
if (writer->states != NULL) {
|
||||
mobi_xml_state_delall(writer->states);
|
||||
writer->states = NULL;
|
||||
}
|
||||
free(writer->nsname);
|
||||
free(writer->nsvalue);
|
||||
free(writer);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Start xml document
|
||||
|
||||
Only utf-8 encoding supported.
|
||||
|
||||
@param[in] writer TextWriter
|
||||
@param[in] version Value of version attribute, "1.0" if NULL
|
||||
@param[in] encoding Unused, defaults to utf-8
|
||||
@param[in] standalone Unused, omitted in declaration
|
||||
@return TextWriter pointer
|
||||
*/
|
||||
int xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
|
||||
const char *encoding, const char *standalone) {
|
||||
UNUSED(encoding);
|
||||
UNUSED(standalone);
|
||||
if (writer == NULL) {
|
||||
debug_print("%s\n", "XML writer init failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
if (mobi_xml_level(writer) > 0) {
|
||||
debug_print("%s\n", "XML document already started");
|
||||
return XML_ERROR;
|
||||
}
|
||||
MOBI_RET ret = mobi_xml_buffer_addstring(writer, "<?xml version=");
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
if (version == NULL) {
|
||||
ret = mobi_xml_buffer_addstring(writer, "\"1.0\"");
|
||||
} else {
|
||||
ret = mobi_xml_buffer_addstring(writer, version);
|
||||
}
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
ret = mobi_xml_buffer_addstring(writer, "?>\n");
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
return XML_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief End xml document
|
||||
|
||||
All open elements will be closed.
|
||||
xmlBuffer will be flushed.
|
||||
|
||||
@param[in] writer TextWriter
|
||||
@return XML_OK (0) on success, XML_ERROR (-1) on failure
|
||||
*/
|
||||
int xmlTextWriterEndDocument(xmlTextWriterPtr writer) {
|
||||
if (writer == NULL) {
|
||||
debug_print("%s\n", "XML writer init failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
MOBIXmlState *state = NULL;
|
||||
while((state = mobi_xml_state_current(writer))) {
|
||||
switch (state->mode) {
|
||||
case MOBI_XMLMODE_NAME:
|
||||
case MOBI_XMLMODE_ATTR:
|
||||
case MOBI_XMLMODE_TEXT:
|
||||
xmlTextWriterEndElement(writer);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
MOBI_RET ret;
|
||||
if (!writer->indent_enable) {
|
||||
ret = mobi_xml_buffer_addstring(writer, "\n");
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
}
|
||||
ret = mobi_xml_buffer_flush(writer);
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
return XML_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Start xml element
|
||||
|
||||
@param[in,out] writer TextWriter
|
||||
@param[in] name Element name
|
||||
@return XML_OK (0) on success, XML_ERROR (-1) on failure
|
||||
*/
|
||||
int xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar *name) {
|
||||
if (writer == NULL || name == NULL || *name == '\0') {
|
||||
debug_print("%s\n", "XML writer init failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
MOBI_RET ret = MOBI_SUCCESS;
|
||||
MOBIXmlState *state = mobi_xml_state_current(writer);
|
||||
if (state) {
|
||||
switch (state->mode) {
|
||||
case MOBI_XMLMODE_ATTR:
|
||||
if (xmlTextWriterEndAttribute(writer) == XML_ERROR) { return XML_ERROR; }
|
||||
/* fallthrough */
|
||||
case MOBI_XMLMODE_NAME:
|
||||
/* TODO: output ns declarations */
|
||||
mobi_xml_write_ns(writer);
|
||||
ret = mobi_xml_buffer_addstring(writer, ">");
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
if (writer->indent_enable) {
|
||||
ret = mobi_xml_buffer_addstring(writer, "\n");
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
}
|
||||
state->mode = MOBI_XMLMODE_TEXT;
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
mobi_xml_state_push(writer, (char *) name, MOBI_XMLMODE_NAME);
|
||||
if (writer->indent_enable) {
|
||||
ret = mobi_xml_write_indent(writer);
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
}
|
||||
ret = mobi_xml_buffer_addstring(writer, "<");
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
ret = mobi_xml_buffer_addstring(writer, (const char *) name);
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
return XML_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief End current element
|
||||
|
||||
@param[in] writer TextWriter
|
||||
@return XML_OK (0) on success, XML_ERROR (-1) on failure
|
||||
*/
|
||||
int xmlTextWriterEndElement(xmlTextWriterPtr writer) {
|
||||
if (writer == NULL) {
|
||||
debug_print("%s\n", "XML writer init failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
MOBI_RET ret = MOBI_SUCCESS;
|
||||
MOBIXmlState *state = mobi_xml_state_current(writer);
|
||||
if (state == NULL) { return XML_ERROR; }
|
||||
switch (state->mode) {
|
||||
case MOBI_XMLMODE_ATTR:
|
||||
if (xmlTextWriterEndAttribute(writer) == XML_ERROR) { return XML_ERROR; }
|
||||
mobi_xml_state_pop(writer);
|
||||
/* fallthrough */
|
||||
case MOBI_XMLMODE_NAME:
|
||||
/* output namespace declarations */
|
||||
mobi_xml_write_ns(writer);
|
||||
if (writer->indent_enable) {
|
||||
writer->indent_next = true;
|
||||
}
|
||||
ret = mobi_xml_buffer_addstring(writer, "/>");
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
break;
|
||||
case MOBI_XMLMODE_TEXT:
|
||||
if (writer->indent_enable && writer->indent_next) {
|
||||
ret = mobi_xml_write_indent(writer);
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
writer->indent_next = true;
|
||||
} else {
|
||||
writer->indent_next = true;
|
||||
}
|
||||
ret = mobi_xml_buffer_addstring(writer, "</");
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
ret = mobi_xml_buffer_addstring(writer, state->name);
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
ret = mobi_xml_buffer_addstring(writer, ">");
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (writer->indent_enable) {
|
||||
ret = mobi_xml_buffer_addstring(writer, "\n");
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
}
|
||||
mobi_xml_state_pop(writer);
|
||||
return XML_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Start attribute for current xml element
|
||||
|
||||
@param[in,out] writer TextWriter
|
||||
@param[in] name Attribute name
|
||||
@return XML_OK (0) on success, XML_ERROR (-1) on failure
|
||||
*/
|
||||
int xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar *name) {
|
||||
if (writer == NULL) {
|
||||
debug_print("%s\n", "XML writer init failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
if (name == NULL || *name == '\0') {
|
||||
debug_print("%s\n", "XML writer init failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
MOBI_RET ret = MOBI_SUCCESS;
|
||||
MOBIXmlState *state = mobi_xml_state_current(writer);
|
||||
if (state) {
|
||||
switch (state->mode) {
|
||||
case MOBI_XMLMODE_ATTR:
|
||||
if (xmlTextWriterEndAttribute(writer) == XML_ERROR) { return XML_ERROR; }
|
||||
/* fallthrough */
|
||||
case MOBI_XMLMODE_NAME:
|
||||
ret = mobi_xml_buffer_addstring(writer, " ");
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
ret = mobi_xml_buffer_addstring(writer, (const char *) name);
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
ret = mobi_xml_buffer_addstring(writer, "=\"");
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
state->mode = MOBI_XMLMODE_ATTR;
|
||||
break;
|
||||
|
||||
default:
|
||||
return XML_ERROR;
|
||||
}
|
||||
}
|
||||
return XML_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief End current attribute
|
||||
|
||||
@param[in,out] writer TextWriter
|
||||
@return XML_OK (0) on success, XML_ERROR (-1) on failure
|
||||
*/
|
||||
int xmlTextWriterEndAttribute(xmlTextWriterPtr writer) {
|
||||
if (writer == NULL) {
|
||||
debug_print("%s\n", "XML writer init failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
MOBI_RET ret = MOBI_SUCCESS;
|
||||
MOBIXmlState *state = mobi_xml_state_current(writer);
|
||||
if (state) {
|
||||
switch (state->mode) {
|
||||
case MOBI_XMLMODE_ATTR:
|
||||
state->mode = MOBI_XMLMODE_NAME;
|
||||
ret = mobi_xml_buffer_addstring(writer, "\"");
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
break;
|
||||
|
||||
default:
|
||||
return XML_ERROR;
|
||||
}
|
||||
}
|
||||
return XML_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Write attribute with given name and content
|
||||
|
||||
@param[in,out] writer TextWriter
|
||||
@param[in] name Attribute name
|
||||
@param[in] content Attribute content
|
||||
@return XML_OK (0) on success, XML_ERROR (-1) on failure
|
||||
*/
|
||||
int xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar *name,
|
||||
const xmlChar * content) {
|
||||
if (xmlTextWriterStartAttribute(writer, name) == XML_ERROR) { return XML_ERROR; }
|
||||
if (xmlTextWriterWriteString(writer, content) == XML_ERROR) { return XML_ERROR; }
|
||||
if (xmlTextWriterEndAttribute(writer) == XML_ERROR) { return XML_ERROR; }
|
||||
return XML_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Start attribute with namespace support for current xml element
|
||||
|
||||
@param[in,out] writer TextWriter
|
||||
@param[in] prefix Namespace prefix or NULL
|
||||
@param[in] name Attribute name
|
||||
@param[in] namespaceURI Namespace uri or NULL
|
||||
@return XML_OK (0) on success, XML_ERROR (-1) on failure
|
||||
*/
|
||||
int xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
|
||||
const xmlChar *prefix, const xmlChar *name,
|
||||
const xmlChar *namespaceURI) {
|
||||
if (writer == NULL || name == NULL || *name == '\0') {
|
||||
debug_print("%s\n", "XML writer init failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
if (namespaceURI != NULL) {
|
||||
char namespace[] = "xmlns";
|
||||
if (prefix != NULL) {
|
||||
size_t length = sizeof(namespace) - 1 + strlen((char *) prefix) + 1; /* add one for ":" */
|
||||
char *prefixed = malloc(length + 1);
|
||||
if (prefixed == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
snprintf(prefixed, length + 1, "%s:%s", namespace, prefix);
|
||||
MOBI_RET ret = mobi_xml_save_ns(writer, prefixed, (char *) namespaceURI);
|
||||
free(prefixed);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return XML_ERROR;
|
||||
}
|
||||
} else {
|
||||
MOBI_RET ret = mobi_xml_save_ns(writer, namespace, (char *) namespaceURI);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return XML_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (prefix != NULL) {
|
||||
size_t length = strlen((char *) prefix) + strlen((char *) name) + 1; /* add one for ":" */
|
||||
char *prefixed = malloc(length + 1);
|
||||
if (prefixed == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
snprintf(prefixed, length + 1, "%s:%s", prefix, name);
|
||||
int ret = xmlTextWriterStartAttribute(writer, (xmlChar *)prefixed);
|
||||
free(prefixed);
|
||||
if (ret == XML_ERROR) {
|
||||
return XML_ERROR;
|
||||
}
|
||||
} else {
|
||||
int ret = xmlTextWriterStartAttribute(writer, name);
|
||||
if (ret == XML_ERROR) {
|
||||
return XML_ERROR;
|
||||
}
|
||||
}
|
||||
return XML_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Write attribute with namespace support
|
||||
|
||||
@param[in,out] writer TextWriter
|
||||
@param[in] prefix Namespace prefix or NULL
|
||||
@param[in] name Attribute name
|
||||
@param[in] namespaceURI Namespace uri or NULL
|
||||
@param[in] content Attribute content
|
||||
@return XML_OK (0) on success, XML_ERROR (-1) on failure
|
||||
*/
|
||||
int xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
|
||||
const xmlChar *prefix, const xmlChar *name,
|
||||
const xmlChar *namespaceURI,
|
||||
const xmlChar *content) {
|
||||
|
||||
if (xmlTextWriterStartAttributeNS(writer, prefix, name, namespaceURI) == XML_ERROR) { return XML_ERROR; }
|
||||
if (xmlTextWriterWriteString(writer, content) == XML_ERROR) { return XML_ERROR; }
|
||||
if (xmlTextWriterEndAttribute(writer) == XML_ERROR) { return XML_ERROR; }
|
||||
return XML_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Start element with namespace support
|
||||
|
||||
@param[in,out] writer TextWriter
|
||||
@param[in] prefix Namespace prefix or NULL
|
||||
@param[in] name Element name
|
||||
@param[in] namespaceURI Namespace uri or NULL
|
||||
@return XML_OK (0) on success, XML_ERROR (-1) on failure
|
||||
*/
|
||||
int xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
|
||||
const xmlChar *prefix, const xmlChar *name,
|
||||
const xmlChar *namespaceURI) {
|
||||
if (writer == NULL || name == NULL || *name == '\0') {
|
||||
debug_print("%s\n", "XML writer init failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
if (prefix != NULL) {
|
||||
size_t length = strlen((char *) prefix) + strlen((char *) name) + 1;
|
||||
char *prefixed = malloc(length + 1);
|
||||
if (prefixed == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
snprintf(prefixed, length + 1, "%s:%s", prefix, name);
|
||||
int ret = xmlTextWriterStartElement(writer, (xmlChar *)prefixed);
|
||||
free(prefixed);
|
||||
if (ret == XML_ERROR) { return XML_ERROR; }
|
||||
} else {
|
||||
if (xmlTextWriterStartElement(writer, name) == XML_ERROR) { return XML_ERROR; }
|
||||
}
|
||||
if (namespaceURI != NULL) {
|
||||
char namespace[] = "xmlns";
|
||||
if (prefix != NULL) {
|
||||
size_t length = sizeof(namespace) - 1 + strlen((char *) prefix) + 1;
|
||||
char *prefixed = malloc(length + 1);
|
||||
if (prefixed == NULL) {
|
||||
debug_print("%s\n", "Memory allocation failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
snprintf(prefixed, length + 1, "%s:%s", namespace, prefix);
|
||||
MOBI_RET ret = mobi_xml_save_ns(writer, prefixed, (char *) namespaceURI);
|
||||
free(prefixed);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return XML_ERROR;
|
||||
}
|
||||
} else {
|
||||
MOBI_RET ret = mobi_xml_save_ns(writer, namespace, (char *) namespaceURI);
|
||||
if (ret != MOBI_SUCCESS) {
|
||||
return XML_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
return XML_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Write element with namespace support
|
||||
|
||||
@param[in,out] writer TextWriter
|
||||
@param[in] prefix Namespace prefix or NULL
|
||||
@param[in] name Element name
|
||||
@param[in] namespaceURI Namespace uri or NULL
|
||||
@param[in] content Element content
|
||||
@return XML_OK (0) on success, XML_ERROR (-1) on failure
|
||||
*/
|
||||
int xmlTextWriterWriteElementNS(xmlTextWriterPtr writer, const xmlChar *prefix,
|
||||
const xmlChar *name, const xmlChar *namespaceURI,
|
||||
const xmlChar *content) {
|
||||
if (xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI) == XML_ERROR) { return XML_ERROR; }
|
||||
if (xmlTextWriterWriteString(writer, content) == XML_ERROR) { return XML_ERROR; }
|
||||
if (xmlTextWriterEndElement(writer) == XML_ERROR) { return XML_ERROR; }
|
||||
return XML_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Write xml string
|
||||
|
||||
@param[in,out] writer TextWriter
|
||||
@param[in] content Attribute content
|
||||
@return XML_OK (0) on success, XML_ERROR (-1) on failure
|
||||
*/
|
||||
int xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar *content) {
|
||||
if (writer == NULL || content == NULL) {
|
||||
debug_print("%s\n", "XML writer init failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
MOBI_RET ret = MOBI_SUCCESS;
|
||||
MOBI_XML_MODE mode = MOBI_XMLMODE_NONE;
|
||||
MOBIXmlState *state = mobi_xml_state_current(writer);
|
||||
if (state != NULL) {
|
||||
mode = state->mode;
|
||||
}
|
||||
switch (mode) {
|
||||
case MOBI_XMLMODE_NAME:
|
||||
// output namespace decl
|
||||
mobi_xml_write_ns(writer);
|
||||
ret = mobi_xml_buffer_addstring(writer, ">");
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
state->mode = MOBI_XMLMODE_TEXT;
|
||||
/* fallthrough */
|
||||
case MOBI_XMLMODE_TEXT:
|
||||
ret = mobi_xml_buffer_addencoded(writer, (const char *) content);
|
||||
if (writer->indent_enable) {
|
||||
writer->indent_next = false;
|
||||
}
|
||||
break;
|
||||
case MOBI_XMLMODE_ATTR:
|
||||
ret = mobi_xml_buffer_addencoded_attr(writer, (const char *) content);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = mobi_xml_buffer_addstring(writer, (const char *) content);
|
||||
if (writer->indent_enable) {
|
||||
writer->indent_next = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ret != MOBI_SUCCESS) { return XML_ERROR; }
|
||||
return XML_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set indentation option
|
||||
|
||||
@param[in,out] writer TextWriter
|
||||
@param[in] indent Indent output if value greater than zero
|
||||
@return XML_OK (0) on success, XML_ERROR (-1) on failure
|
||||
*/
|
||||
int xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent) {
|
||||
if (writer == NULL) {
|
||||
debug_print("%s\n", "XML writer init failed");
|
||||
return XML_ERROR;
|
||||
}
|
||||
writer->indent_enable = (indent != 0);
|
||||
writer->indent_next = true;
|
||||
return XML_OK;
|
||||
}
|
||||
94
app/src/main/cpp/libmobi/src/xmlwriter.h
vendored
Normal file
94
app/src/main/cpp/libmobi/src/xmlwriter.h
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/** @file xmlwriter.h
|
||||
*
|
||||
* Copyright (c) 2016 Bartek Fabiszewski
|
||||
* http://www.fabiszewski.net
|
||||
*
|
||||
* This file is part of libmobi.
|
||||
* Licensed under LGPL, either version 3, or any later.
|
||||
* See <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef mobi_minixml_h
|
||||
#define mobi_minixml_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include "buffer.h"
|
||||
#include "structure.h"
|
||||
|
||||
#define BAD_CAST (xmlChar *)
|
||||
#define LIBXML_TEST_VERSION
|
||||
|
||||
#define xmlCleanupParser()
|
||||
|
||||
typedef unsigned char xmlChar;
|
||||
|
||||
/**
|
||||
@brief Buffer for xml output.
|
||||
For libxml2 compatibility, it is a wrapper for MOBIBuffer
|
||||
*/
|
||||
typedef struct {
|
||||
xmlChar *content; /**< Points to mobibuffer->data */
|
||||
MOBIBuffer *mobibuffer; /**< Dynamic buffer */
|
||||
} xmlBuffer;
|
||||
typedef xmlBuffer *xmlBufferPtr;
|
||||
|
||||
/**
|
||||
@brief Xml writer states
|
||||
*/
|
||||
typedef enum {
|
||||
MOBI_XMLMODE_NONE = 0,
|
||||
MOBI_XMLMODE_NAME,
|
||||
MOBI_XMLMODE_ATTR,
|
||||
MOBI_XMLMODE_TEXT
|
||||
} MOBI_XML_MODE;
|
||||
|
||||
/**
|
||||
@brief Xml writer states list structure
|
||||
First element in the list is currently processed element.
|
||||
Last element is root of the document
|
||||
*/
|
||||
typedef struct MOBIXmlState {
|
||||
char *name; /**< Element name */
|
||||
MOBI_XML_MODE mode; /**< State mode */
|
||||
struct MOBIXmlState *next; /**< Next list item */
|
||||
} MOBIXmlState;
|
||||
|
||||
/**
|
||||
@brief Xml TextWriter structure
|
||||
*/
|
||||
typedef struct {
|
||||
xmlBufferPtr xmlbuf; /**< XML buffer */
|
||||
MOBIXmlState *states; /**< TextWriter states list */
|
||||
char *nsname; /**< Namespace attribute name */
|
||||
char *nsvalue; /**< Namespace attribute value */
|
||||
bool indent_enable; /**< Enable indentation */
|
||||
bool indent_next; /**< Indentation needed */
|
||||
} xmlTextWriter;
|
||||
typedef xmlTextWriter *xmlTextWriterPtr;
|
||||
|
||||
xmlBufferPtr xmlBufferCreate(void);
|
||||
void xmlBufferFree(xmlBufferPtr buf);
|
||||
xmlTextWriterPtr xmlNewTextWriterMemory(xmlBufferPtr xmlbuf, int compression);
|
||||
void xmlFreeTextWriter(xmlTextWriterPtr writer);
|
||||
int xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
|
||||
const char *encoding, const char *standalone);
|
||||
int xmlTextWriterEndDocument(xmlTextWriterPtr writer);
|
||||
int xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar *name);
|
||||
int xmlTextWriterEndElement(xmlTextWriterPtr writer);
|
||||
int xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar *name,
|
||||
const xmlChar *content);
|
||||
int xmlTextWriterEndAttribute(xmlTextWriterPtr writer);
|
||||
int xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
|
||||
const xmlChar * prefix, const xmlChar * name,
|
||||
const xmlChar * namespaceURI,
|
||||
const xmlChar * content);
|
||||
int xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
|
||||
const xmlChar *prefix, const xmlChar *name,
|
||||
const xmlChar * namespaceURI);
|
||||
int xmlTextWriterWriteElementNS(xmlTextWriterPtr writer, const xmlChar *prefix,
|
||||
const xmlChar *name, const xmlChar *namespaceURI,
|
||||
const xmlChar *content);
|
||||
int xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar *content);
|
||||
int xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent);
|
||||
|
||||
#endif
|
||||
42
app/src/main/cpp/libmobi/tests/Makefile.am
vendored
Normal file
42
app/src/main/cpp/libmobi/tests/Makefile.am
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# Parallel tests suite
|
||||
|
||||
# Files for testing should be placed in samples directory.
|
||||
# Normal files must have ".mobi" extension.
|
||||
# Files that are expected to fail the tests should have ".fail" extension.
|
||||
# Test script will try to recreate markup sources and dump rawml file.
|
||||
# Script may additionally check md5 checksums of the produced output.
|
||||
# In order to enable md5 verification files with checksums must be present in md5 directory.
|
||||
# Name of the file with md5 checksums is md5 checksum of the sample file plus
|
||||
# suffix "_rawml" for rawml checksum and "_markup" for all markup files checksums.
|
||||
# Re-run ./configure after adding new samples
|
||||
|
||||
# Exclude large samples from dist package
|
||||
EXTRA_DIST = md5 \
|
||||
samples/sample-cp1252.mobi \
|
||||
samples/sample-dict-infl2.mobi \
|
||||
samples/sample-drm_pidLTKULBB^5V-v2.mobi \
|
||||
samples/sample-drm-v1.mobi \
|
||||
samples/sample-multimedia.mobi \
|
||||
samples/sample-ncx.mobi \
|
||||
samples/sample-obfuscated-fonts.mobi \
|
||||
samples/sample-textread.mobi \
|
||||
samples/sample-unicode-huffdic.mobi \
|
||||
samples/sample-unicode-uncompressed.mobi \
|
||||
samples/sample-invalid-indx.fail
|
||||
AUTOMAKE_OPTIONS = parallel-tests
|
||||
TESTS = @TESTLIST@
|
||||
XFAIL_TESTS = @FAILLIST@
|
||||
TEST_EXTENSIONS = .mobi .fail
|
||||
MOBI_LOG_COMPILER = ./test.sh
|
||||
FAIL_LOG_COMPILER = ./test.sh
|
||||
|
||||
clean-local:
|
||||
-rm -rf tmp
|
||||
|
||||
all-local:
|
||||
@if test x@RUN_TESTS@ = xno; then \
|
||||
echo "============================================================================"; \
|
||||
echo "WARNING: All tests will be skipped, because bash was not found in your PATH."; \
|
||||
echo " Please install bash and rerun configure script."; \
|
||||
echo "============================================================================"; \
|
||||
fi
|
||||
6
app/src/main/cpp/libmobi/tests/md5/1cddff555949348d7ca76c367e01b90a_markup.md5
vendored
Normal file
6
app/src/main/cpp/libmobi/tests/md5/1cddff555949348d7ca76c367e01b90a_markup.md5
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
4a7d6afd2ce8bac1333c6d46f74773a4 part00000.html
|
||||
0945cf5525eab95452b12e396d4f5ae4 resource00000.jpg
|
||||
0945cf5525eab95452b12e396d4f5ae4 resource00001.jpg
|
||||
90fdcc4e447f9e8babb418e9a8677311 resource00002.jpg
|
||||
62a722e40769ec8b222b6c788b8f3463 resource00003.ncx
|
||||
e2ba461f8530066d31572a57dde6129a resource00004.opf
|
||||
1
app/src/main/cpp/libmobi/tests/md5/1cddff555949348d7ca76c367e01b90a_rawml.md5
vendored
Normal file
1
app/src/main/cpp/libmobi/tests/md5/1cddff555949348d7ca76c367e01b90a_rawml.md5
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
9f397e35c0608a9777e02efa416665a0
|
||||
6
app/src/main/cpp/libmobi/tests/md5/25f2ef9bd45ffa68e8eaf6ecad0ca5a4_markup.md5
vendored
Normal file
6
app/src/main/cpp/libmobi/tests/md5/25f2ef9bd45ffa68e8eaf6ecad0ca5a4_markup.md5
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
5af19c35a5bcc1443bd661f4d226ea27 part00000.html
|
||||
2eb4a36ae5534b3e0d976ddc459d209a resource00000.jpg
|
||||
7ab80fa12ddee2f2bfc16498da537028 resource00001.jpg
|
||||
688aeffb0a078da56295bbc37ab2d28d resource00002.jpg
|
||||
a480fcdcf016467f646f283140457d1c resource00003.ncx
|
||||
2815cf0ccbf3acbbb2649200f337567a resource00004.opf
|
||||
1
app/src/main/cpp/libmobi/tests/md5/25f2ef9bd45ffa68e8eaf6ecad0ca5a4_rawml.md5
vendored
Normal file
1
app/src/main/cpp/libmobi/tests/md5/25f2ef9bd45ffa68e8eaf6ecad0ca5a4_rawml.md5
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
14118d6e0c526b307b94cec17d8d5395
|
||||
5
app/src/main/cpp/libmobi/tests/md5/29876458364495f42187000189b6b15b_markup.md5
vendored
Normal file
5
app/src/main/cpp/libmobi/tests/md5/29876458364495f42187000189b6b15b_markup.md5
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
72912a00456b9b3c194de09e651c70bc part00000.html
|
||||
b19e40b775c1727a8ff0311caeb5b098 part00001.html
|
||||
1ea860339fc7c535a801566dea0d5901 part00002.html
|
||||
547d4f2b211ddabc77fe1db54143b087 resource00000.ncx
|
||||
70b805f6b13dd9366bfc0d94c2f4f785 resource00001.opf
|
||||
1
app/src/main/cpp/libmobi/tests/md5/29876458364495f42187000189b6b15b_rawml.md5
vendored
Normal file
1
app/src/main/cpp/libmobi/tests/md5/29876458364495f42187000189b6b15b_rawml.md5
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
448a891b3bd94fb78045704fbb5988cc
|
||||
8
app/src/main/cpp/libmobi/tests/md5/31c42c70c3503fde5353c89ffa4e67ea_markup.md5
vendored
Normal file
8
app/src/main/cpp/libmobi/tests/md5/31c42c70c3503fde5353c89ffa4e67ea_markup.md5
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
f03d1a71d2ef80b53d9d48823e2aad2d part00000.html
|
||||
dd2fab65a653934d60369b0f9c4b84ee resource00000.jpg
|
||||
48e11be0e511cd31d5c1aca1dc52a644 resource00001.jpg
|
||||
8bf1a77a6df6333344bc0a97012d8ccb resource00002.jpg
|
||||
bf2727a10ab068bb5d3eafa0b7ace4e0 resource00004.jpg
|
||||
bbc069268a93c1153286924bf72a82b1 resource00005.jpg
|
||||
b898ff28a9c8236ea6fdc41aadadd527 resource00006.ncx
|
||||
3e5ae3fdd385fc6c9e7e592e66e5e255 resource00007.opf
|
||||
1
app/src/main/cpp/libmobi/tests/md5/31c42c70c3503fde5353c89ffa4e67ea_rawml.md5
vendored
Normal file
1
app/src/main/cpp/libmobi/tests/md5/31c42c70c3503fde5353c89ffa4e67ea_rawml.md5
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
c4158a8a1cf16101dd6ceeee53b6aef1
|
||||
4
app/src/main/cpp/libmobi/tests/md5/3248d6140918d441d8050861a05a85cb_markup.md5
vendored
Normal file
4
app/src/main/cpp/libmobi/tests/md5/3248d6140918d441d8050861a05a85cb_markup.md5
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
51d871a7dd9269977d26d8d3c48ca2d6 part00000.html
|
||||
3eb21f0515c65686a1339136bd70fc67 resource00025.bmp
|
||||
df1392d0768b9aa2a359af03f91224ed resource00026.ncx
|
||||
7c12f209822e2566e66173d1bfb74edf resource00027.opf
|
||||
1
app/src/main/cpp/libmobi/tests/md5/3248d6140918d441d8050861a05a85cb_rawml.md5
vendored
Normal file
1
app/src/main/cpp/libmobi/tests/md5/3248d6140918d441d8050861a05a85cb_rawml.md5
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
a644174e53c23cd0ac108b91200e0ff7
|
||||
6
app/src/main/cpp/libmobi/tests/md5/520361f44c43edfae98f44cbf57b3fce_markup.md5
vendored
Normal file
6
app/src/main/cpp/libmobi/tests/md5/520361f44c43edfae98f44cbf57b3fce_markup.md5
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
5af19c35a5bcc1443bd661f4d226ea27 part00000.html
|
||||
2eb4a36ae5534b3e0d976ddc459d209a resource00000.jpg
|
||||
7ab80fa12ddee2f2bfc16498da537028 resource00001.jpg
|
||||
688aeffb0a078da56295bbc37ab2d28d resource00002.jpg
|
||||
a480fcdcf016467f646f283140457d1c resource00003.ncx
|
||||
2815cf0ccbf3acbbb2649200f337567a resource00004.opf
|
||||
1
app/src/main/cpp/libmobi/tests/md5/520361f44c43edfae98f44cbf57b3fce_rawml.md5
vendored
Normal file
1
app/src/main/cpp/libmobi/tests/md5/520361f44c43edfae98f44cbf57b3fce_rawml.md5
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
14118d6e0c526b307b94cec17d8d5395
|
||||
9446
app/src/main/cpp/libmobi/tests/md5/53eac2194ef1addee323d2a7d149ddff_markup.md5
vendored
Normal file
9446
app/src/main/cpp/libmobi/tests/md5/53eac2194ef1addee323d2a7d149ddff_markup.md5
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
app/src/main/cpp/libmobi/tests/md5/53eac2194ef1addee323d2a7d149ddff_rawml.md5
vendored
Normal file
1
app/src/main/cpp/libmobi/tests/md5/53eac2194ef1addee323d2a7d149ddff_rawml.md5
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
a2756abde16983fda113fcabb09db648
|
||||
6
app/src/main/cpp/libmobi/tests/md5/5601259794edfe7e62283c6672c7fda0_markup.md5
vendored
Normal file
6
app/src/main/cpp/libmobi/tests/md5/5601259794edfe7e62283c6672c7fda0_markup.md5
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
3b25aa92cdb90e71f860506d7733b903 flow00001.css
|
||||
91203ddb7a64f4e72040512f73428aa4 flow00002.css
|
||||
aa9d0636b917baed54e6c68308adba07 part00000.html
|
||||
01ede3cdbd26439b7f30fdc2f7b525cb resource00000.otf
|
||||
0de6fa741a35160233f0ac1078afb02f resource00001.ncx
|
||||
eb550aed365cfb13b59bfb6589775c35 resource00002.opf
|
||||
1
app/src/main/cpp/libmobi/tests/md5/5601259794edfe7e62283c6672c7fda0_rawml.md5
vendored
Normal file
1
app/src/main/cpp/libmobi/tests/md5/5601259794edfe7e62283c6672c7fda0_rawml.md5
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
20c60c1766bdc00ae49cfd0631bff2c4
|
||||
7
app/src/main/cpp/libmobi/tests/md5/565e31312a70c5129f6674d540c46561_markup.md5
vendored
Normal file
7
app/src/main/cpp/libmobi/tests/md5/565e31312a70c5129f6674d540c46561_markup.md5
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
5d00d50e7d9d4ba11e87557d9f4edd1c part00000.html
|
||||
7dee30a6b9bc07b5ec92cda6f424b7db part00001.html
|
||||
ae0198f50c282044c65082a256852fa5 resource00000.jpg
|
||||
7ab80fa12ddee2f2bfc16498da537028 resource00001.jpg
|
||||
688aeffb0a078da56295bbc37ab2d28d resource00003.jpg
|
||||
815dea478c839572d5772819d2292f0c resource00004.ncx
|
||||
2c8e8b057b5511ace63e4343c7a43b6e resource00005.opf
|
||||
1
app/src/main/cpp/libmobi/tests/md5/565e31312a70c5129f6674d540c46561_rawml.md5
vendored
Normal file
1
app/src/main/cpp/libmobi/tests/md5/565e31312a70c5129f6674d540c46561_rawml.md5
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
02cf5a2f37faee76dfcafaefe4fd27cf
|
||||
3
app/src/main/cpp/libmobi/tests/md5/6798753f94feba073622f02c8c88e713_markup.md5
vendored
Normal file
3
app/src/main/cpp/libmobi/tests/md5/6798753f94feba073622f02c8c88e713_markup.md5
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
abf7fd0126f52f722b14129c7958e397 part00000.html
|
||||
e37c79f0fe27d40f85c66e59dbc725f3 resource00000.ncx
|
||||
99c3f883921a92fd97511f983a21691d resource00001.opf
|
||||
1
app/src/main/cpp/libmobi/tests/md5/6798753f94feba073622f02c8c88e713_rawml.md5
vendored
Normal file
1
app/src/main/cpp/libmobi/tests/md5/6798753f94feba073622f02c8c88e713_rawml.md5
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
b355c36f0d55450cedab86f0eefc2c82
|
||||
9
app/src/main/cpp/libmobi/tests/md5/7c1d5645d7f19fb25ca84e533671d3ac_markup.md5
vendored
Normal file
9
app/src/main/cpp/libmobi/tests/md5/7c1d5645d7f19fb25ca84e533671d3ac_markup.md5
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
6d1e99d90451bcda489bb7cbe014ba7e part00000.html
|
||||
c2691922730c85a07b30c558987cc478 resource00000.jpg
|
||||
06bc4024a3a146f8d0141336d3f6944a resource00001.gif
|
||||
c5e8e3dd8333e7227accfbdfcd120726 resource00002.gif
|
||||
0e6356f75416cf28601ba3efd2b4abf6 resource00003.gif
|
||||
c2691922730c85a07b30c558987cc478 resource00004.jpg
|
||||
8a3b469a251fcf8128982c6c1d30a12f resource00005.jpg
|
||||
3a7d9108f54fbee998fe9e0e22cc90b3 resource00006.ncx
|
||||
192f37b64ab8bb41dedb8c337de1f2d3 resource00007.opf
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue